diff mbox series

contrib: New remotes structure for vendor and personal refs

Message ID 5b1cede7-76d5-1b1f-533e-75af5bed84b5@arm.com
State New
Headers show
Series contrib: New remotes structure for vendor and personal refs | expand

Commit Message

Richard Earnshaw (lists) Jan. 16, 2020, 5:06 p.m. UTC
The initial structure for vendor and personal branches makes use of the 
default remote (normally origin) for the upstream repository). 
Unfortunately, this causes some confusion, especially for personal 
branches because a push will not push to the correct upstream location. 
This can be 'fixed' by adding a push refspec for the remote, but that 
has the unfortunate consequence of breaking the push.default behaviour 
for git push, and it becomes too easy to accidentally commit something 
unintended to the main parts of the repository.

To work around this, this patch changes the configuration to use 
separate 'remotes' for these additional refs, with one remote for the 
personal space and another remote for each vendor's space.  The personal 
space is called after the user's preferred branch-space prefix (default 
'me'), the vendor spaces are called vendor-<vendor-name>.

As far as possible, I've made the script automatically restructure any 
existing fetch or push lines that earlier versions of the scripts may 
have created - the gcc-git-customization.sh script will convert all 
vendor refs that it can find, so it is not necessary to re-add any 
vendors you've already added.

You might, however, want to run
   git remote prune <origin>
after running to clean up any stale upstream-refs that might still be in 
your local repo, and then
   git fetch vendor-<vendor>
or
   git fetch <me>
to re-populate the remotes/ structures.

Also, for any branch you already have that tracks a personal or vendor 
branch upstream, you might need to run
   git config branch.<name>.remote <new-remote>

so that merges and pushes go to the right place (I haven't attempted to 
automate this last part).

Please be aware that if you have multiple personal branches set up, then

   git push <me>

will still consider all of them for pushing.  If you only want to push 
one branch, then either write
   git push <me> HEAD
or
   git push <me> <me>/branch
as appropriate.

And don't forget '-n' (--dry-run) to see what would be done if this were 
not a dry run.

	* gcc-git-customization.sh: New personal and vendor layout.
	Convert any existing fetch/push rules to new layout.
	* git-fetch-vendor.sh: New vendor layout.

I'll wait a bit before pushing this, just in case someone spots an issue.

R.
diff mbox series

Patch

diff --git a/contrib/gcc-git-customization.sh b/contrib/gcc-git-customization.sh
index 26f4389bcc8..b62397314c6 100755
--- a/contrib/gcc-git-customization.sh
+++ b/contrib/gcc-git-customization.sh
@@ -81,6 +81,13 @@  then
     upstream="origin"
 fi
 ask "Local name for upstream repository" "origin" upstream
+
+v=$(git config --get-all "remote.${upstream}.fetch")
+if [ "x$v" = "x" ]
+then
+    echo "Remote $upstream does not seem to exist as a remote"
+    exit 1
+fi
 git config "gcc-config.upstream" "$upstream"
 
 remote_id=$(git config --get "gcc-config.user")
@@ -113,22 +120,38 @@  echo "(local branches starting <prefix>/ can be pushed directly to your"
 ask "personal area on the gcc server)" $old_pfx new_pfx
 git config "gcc-config.userpfx" "$new_pfx"
 
-echo "Setting up tracking for personal namespace $remote_id in remotes/$upstream/${new_pfx}"
-git config --replace-all "remote.${upstream}.fetch" "+refs/users/${remote_id}/heads/*:refs/remotes/${upstream}/${new_pfx}/*" ":refs/remotes/${upstream}/${old_pfx}/"
-git config --replace-all "remote.${upstream}.fetch" "+refs/users/${remote_id}/tags/*:refs/tags/${new_pfx}/*" ":refs/tags/${old_pfx}/"
+# Scan the existing settings to see if there are any we need to rewrite.
+vendors=$(git config --get-all "remote.${upstream}.fetch" "refs/vendors/" | sed -r "s:.*refs/vendors/([^/]+)/.*:\1:" | sort | uniq)
+url=$(git config --get "remote.${upstream}.url")
+pushurl=$(git config --get "remote.${upstream}.pushurl")
+for v in $vendors
+do
+    echo "Migrating vendor $v to new remote vendor-$v"
+    git config --unset-all "remote.${upstream}.fetch" "refs/vendors/$v/"
+    git config --unset-all "remote.${upstream}.push" "refs/vendors/$v/"
+    git config "remote.vendor-${v}.url" "${url}"
+    if [ "x$pushurl" != "x" ]
+    then
+	git config "remote.vendor-${v}.pushurl" "${pushurl}"
+    fi
+    git config --add "remote.vendor-${v}.fetch" "+refs/vendors/$v/heads/*:refs/remotes/vendor-${v}/*"
+    git config --add "remote.vendor-${v}.fetch" "+refs/vendors/$v/tags/*:refs/tags/vendor-${v}/*"
+done
+
+echo "Setting up tracking for personal namespace $remote_id in remotes/${new_pfx}"
+git config "remote.${new_pfx}.url" "${url}"
+if [ "x$pushurl" != "x" ]
+then
+    git config "remote.${new_pfx}.pushurl" "${pushurl}"
+fi
+git config --replace-all "remote.${new_pfx}.fetch" "+refs/users/${remote_id}/heads/*:refs/remotes/${new_pfx}/*" ":refs/remotes/${old_pfx}/"
+git config --replace-all "remote.${new_pfx}.fetch" "+refs/users/${remote_id}/tags/*:refs/tags/${new_pfx}/*" ":refs/tags/${old_pfx}/"
+git config --replace-all "remote.${new_pfx}.push" "refs/heads/${new_pfx}/*:refs/users/${remote_id}/heads/*" ":refs/users/${remote_id}"
 
-push_rule=$(git config --get "remote.${upstream}.push")
-if [ "x$push_rule" != "x" ]
+if [ "$old_pfx" != "$new_pfx" -a "$old_pfx" != "${upstream}" ]
 then
-    echo "***********************************************"
-    echo "                  Warning"
-    echo "***********************************************"
-    echo
-    echo "Old versions of this script used to add custom push"
-    echo "rules to simplify pushing to personal branches."
-    echo "Your configuration contains such rules, but we no-longer"
-    echo "recommend doing this."
-    echo
-    echo "To delete these rules run:"
-    echo "  git config --unset-all \"remote.${upstream}.push\""
+    git config --remove-section "remote.${old_pfx}"
 fi
+
+git config --unset-all "remote.${upstream}.fetch" "refs/users/${remote_id}/"
+git config --unset-all "remote.${upstream}.push" "refs/users/${remote_id}/"
diff --git a/contrib/git-fetch-vendor.sh b/contrib/git-fetch-vendor.sh
index d2d3ed56ad7..75b0f110927 100755
--- a/contrib/git-fetch-vendor.sh
+++ b/contrib/git-fetch-vendor.sh
@@ -1,20 +1,30 @@ 
 #!/bin/sh
 
+upstream=`git config --get "gcc-config.upstream"`
+if [ x"$upstream" = x ]
+then
+    echo "Config gcc-config.upstream not set, run contrib/gcc-git-customization"
+    exit 1
+fi
+
 if [ $# != 1 ]
 then
     echo "Usage: $0 <vendor>"
+    echo "The following vendors are already known:"
+    git ls-remote ${upstream} "*/vendors/*" | sed -r "s:.*/vendors/([^/]+)/.*:\1:"|sort|uniq
     exit 1
 fi
 
 vendor=$1
-upstream=`git config --get "gcc-config.upstream"`
-if [ x"$upstream" = x ]
+
+echo "setting up git to fetch vendor ${vendor} to remotes/vendor-${vendor}"
+url=$(git config --get "remote.${upstream}.url")
+pushurl=$(git config --get "remote.${upstream}.pushurl")
+git config "remote.vendor-${vendor}.url" "${url}"
+if [ "x$pushurl" != "x" ]
 then
-    echo "Config gcc-config.upstream not set, run contrib/gcc-git-customization"
-    exit 1
+    git config "remote.vendor-${vendor}.pushurl" "${pushurl}"
 fi
-
-echo "setting up git to fetch vendor ${vendor} to remotes/${upstream}/${vendor}"
-git config --replace-all "remote.${upstream}.fetch" "+refs/vendors/${vendor}/heads/*:refs/remotes/${upstream}/${vendor}/*" ":refs/remotes/${upstream}/${vendor}/"
-git config --replace-all "remote.${upstream}.fetch" "+refs/vendors/${vendor}/tags/*:refs/tags/${vendor}/*" ":refs/tags/${vendor}/"
-git fetch
+git config --replace-all "remote.vendor-${vendor}.fetch" "+refs/vendors/${vendor}/heads/*:refs/remotes/vendor-${vendor}/*" ":refs/remotes/vendor-${vendor}/"
+git config --replace-all "remote.vendor-${vendor}.fetch" "+refs/vendors/${vendor}/tags/*:refs/tags/${vendor}/*" ":refs/tags/${vendor}/"
+git fetch vendor-${vendor}