git: 684c762485d3 - main - git-arc: Try to make patching more useful
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 05 Jan 2026 14:17:58 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=684c762485d31d769b9e1ebeaababa31f684d2de
commit 684c762485d31d769b9e1ebeaababa31f684d2de
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-01-05 14:17:11 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-01-05 14:17:11 +0000
git-arc: Try to make patching more useful
Add a raw mode, which fetches the patch file and applies it manually
rather than using arc patch. This is handy because arc patch will
always try to fetch your remotes if it can't find the base commit in
your repo (even if you ask it not to make a commit). This is basically
unusable in some of my workspaces where I have 20+ remotes configured,
some of which may be unreachable.
Add a stack mode, which causes git-arc to recursively apply parent
revisions, going up the patch stack. Thus, to apply a full patch stack,
just apply the final patch with -s.
Reviewed by: ngie
Differential Revision: https://reviews.freebsd.org/D54403
---
tools/tools/git/git-arc.sh | 79 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 70 insertions(+), 9 deletions(-)
diff --git a/tools/tools/git/git-arc.sh b/tools/tools/git/git-arc.sh
index 98d29809d636..bff9b0607761 100755
--- a/tools/tools/git/git-arc.sh
+++ b/tools/tools/git/git-arc.sh
@@ -59,7 +59,7 @@ Usage: git arc [-vy] <command> <arguments>
Commands:
create [-l] [-r <reviewer1>[,<reviewer2>...]] [-s subscriber[,...]] [<commit>|<commit range>]
list <commit>|<commit range>
- patch [-bc] <diff1> [<diff2> ...]
+ patch [-bcrs] <diff1> [<diff2> ...]
stage [-b branch] [<commit>|<commit range>]
update [-l] [-m message] [<commit>|<commit range>]
@@ -226,6 +226,20 @@ diff2phid()
jq -r "select(.response != []) | .response.${diff}.phid"
}
+phid2diff()
+{
+ local diff phid
+
+ phid=$1
+ if ! expr "$phid" : 'PHID-DREV-[0-9A-Za-z]*$' >/dev/null; then
+ err "invalid diff PHID $phid"
+ fi
+ diff=$(echo '{"constraints": {"phids": ["'"$phid"'"]}}' |
+ arc_call_conduit -- differential.revision.search |
+ jq -r '.response.data[0].id')
+ echo "D${diff}"
+}
+
diff2status()
{
local diff tmp status summary
@@ -244,6 +258,19 @@ diff2status()
printf "%-14s %s\n" "${status}" "${summary}"
}
+diff2parents()
+{
+ local dep dependencies diff parents phid
+
+ diff=$1
+ phid=$(diff2phid "$diff")
+ for dep in $(echo '{"phids": ["'"$phid"'"]}' |
+ arc_call_conduit -- differential.query |
+ jq -r '.response[0].auxiliary."phabricator:depends-on"[]'); do
+ echo $(phid2diff $dep)
+ done
+}
+
log2diff()
{
local diff
@@ -651,13 +678,46 @@ patch_commit()
git commit --author "${author}" --file "$tmp"
}
+apply_rev()
+{
+ local commit parent parents raw rev stack
+
+ rev=$1
+ commit=$2
+ raw=$3
+ stack=$4
+
+ if $stack; then
+ parents=$(diff2parents "$rev")
+ for parent in $parents; do
+ echo "Applying parent ${parent}..."
+ if ! apply_rev $parent $commit $raw $stack; then
+ return 1
+ fi
+ done
+ fi
+
+ if $raw; then
+ fetch -o /dev/stdout "https://reviews.freebsd.org/${rev}.diff" | git apply --index
+ else
+ arc patch --skip-dependencies --nobranch --nocommit --force $rev
+ fi
+
+ if ${commit}; then
+ patch_commit $rev
+ fi
+ return 0
+}
+
gitarc__patch()
{
- local branch commit rev
+ local branch commit o raw rev stack
branch=false
commit=false
- while getopts bc o; do
+ raw=false
+ stack=false
+ while getopts bcrs o; do
case "$o" in
b)
require_clean_work_tree "patch -b"
@@ -667,6 +727,12 @@ gitarc__patch()
require_clean_work_tree "patch -c"
commit=true
;;
+ r)
+ raw=true
+ ;;
+ s)
+ stack=true
+ ;;
*)
err_usage
;;
@@ -682,13 +748,8 @@ gitarc__patch()
patch_branch "$@"
fi
for rev in "$@"; do
- if ! arc patch --skip-dependencies --nobranch --nocommit --force "$rev"; then
- break
- fi
echo "Applying ${rev}..."
- if ${commit}; then
- patch_commit $rev
- fi
+ apply_rev $rev $commit $raw $stack
done
}