Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 05 Jan 2026 14:17:58 +0000
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 684c762485d3 - main - git-arc: Try to make patching more useful
Message-ID:  <695bc816.46403.2733a59@gitrepo.freebsd.org>

index | next in thread | raw e-mail

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
 }
 


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?695bc816.46403.2733a59>