diff options
| author | Mark Johnston <markj@FreeBSD.org> | 2026-01-05 14:17:11 +0000 |
|---|---|---|
| committer | Mark Johnston <markj@FreeBSD.org> | 2026-01-05 14:17:11 +0000 |
| commit | 684c762485d31d769b9e1ebeaababa31f684d2de (patch) | |
| tree | 06ed6ab858bd10acf19b0e30cfb4b3039e0c3168 | |
| parent | 4a1b69ade6b5e8665dfb4d0cb683854705192a68 (diff) | |
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
| -rwxr-xr-x | tools/tools/git/git-arc.sh | 79 |
1 files 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 } |
