contrib: Change 'remote' for personal branches and add branch creation script
diff mbox series

Message ID
State New
Headers show
  • contrib: Change 'remote' for personal branches and add branch creation script
Related show

Commit Message

Richard Earnshaw (lists) Jan. 24, 2020, 2:16 p.m. UTC
Whilst trying to convert the add vendor branch script to work with 
personal branches I encountered a minor issue where git would report 
ambiguous refs when checking out the new branch.

It turns out that this is because git considers <me>/<topic> to be 
ambiguous if both




exist in the list of known branches.

Having thought about this a bit, I think the best solution is to adopt 
something more like the vendors space and call the remote users/<me> 
(this also works better if you want to set up remotes to track other 
users branches as well).

So this patch has two parts.

1) It updates to set up the new 'remote' and 
converts any existing remote and branches tracking that to the new format
2) It adds a new script to set up a personal branch on the gcc git 

I'll produce an update to wwwdocs/.../gitwrite.html to cover these 
changes shortly.


	* Use users/<pfx> for the personal remote
	rather than just <pfx>.  Convert any existing user branches to the
	new remote.
	* New file.

diff mbox series

diff --git a/contrib/ b/contrib/
index c16db747503..f3e48316ead 100755
--- a/contrib/
+++ b/contrib/
@@ -128,7 +128,7 @@  url=$(git config --get "remote.${upstream}.url")
 pushurl=$(git config --get "remote.${upstream}.pushurl")
 for v in $vendors
-    echo "Migrating vendor $v to new remote vendors/$v"
+    echo "Migrating vendor \"$v\" to new remote \"vendors/$v\""
     git config --unset-all "remote.${upstream}.fetch" "refs/vendors/$v/"
     git config --unset-all "remote.${upstream}.push" "refs/vendors/$v/"
     git config "remote.vendors/${v}.url" "${url}"
@@ -140,15 +140,36 @@  do
     git config --add "remote.vendors/${v}.fetch" "+refs/vendors/$v/tags/*:refs/tags/vendors/${v}/*"
-echo "Setting up tracking for personal namespace $remote_id in remotes/${new_pfx}"
-git config "remote.${new_pfx}.url" "${url}"
+# Convert the remote 'pfx' to users/pfx to avoid problems with ambiguous refs
+# on user branches
+old_remote=$(git config --get "remote.${old_pfx}.url")
+if [ -n "${old_remote}" ]
+    echo "Migrating remote \"${old_pfx}\" to new remote \"users/${new_pfx}\""
+    # Create a dummy fetch rule that will cause the subsequent prune to remove the old remote refs.
+    git config --replace-all "remote.${old_pfx}.fetch" "+refs/empty/*:refs/remotes/${old_pfx}/*"
+    # Remove any remotes
+    git remote prune ${old_pfx}
+    git config --remove-section "remote.${old_pfx}"
+    for br in $(git branch --list "${old_pfx}/*")
+    do
+	old_remote=$(git config --get "branch.${br}.remote")
+	if [ "${old_remote}" = "${old_pfx}" ]
+	then
+	    git config "branch.${br}.remote" "users/${new_pfx}"
+	fi
+    done
+echo "Setting up tracking for personal namespace $remote_id in remotes/users/${new_pfx}"
+git config "remote.users/${new_pfx}.url" "${url}"
 if [ "x$pushurl" != "x" ]
-    git config "remote.${new_pfx}.pushurl" "${pushurl}"
+    git config "remote.users/${new_pfx}.pushurl" "${pushurl}"
-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}"
+git config --replace-all "remote.users/${new_pfx}.fetch" "+refs/users/${remote_id}/heads/*:refs/remotes/users/${new_pfx}/*" "refs/users/${remote_id}/heads/"
+git config --replace-all "remote.users/${new_pfx}.fetch" "+refs/users/${remote_id}/tags/*:refs/tags/users/${new_pfx}/*" "refs/users/${remote_id}/tags/"
+git config --replace-all "remote.users/${new_pfx}.push" "refs/heads/${new_pfx}/*:refs/users/${remote_id}/heads/*" "refs/users/${remote_id}"
 if [ "$old_pfx" != "$new_pfx" -a "$old_pfx" != "${upstream}" ]
@@ -157,3 +178,5 @@  fi
 git config --unset-all "remote.${upstream}.fetch" "refs/users/${remote_id}/"
 git config --unset-all "remote.${upstream}.push" "refs/users/${remote_id}/"
+git fetch "users/${new_pfx}"
diff --git a/contrib/ b/contrib/
new file mode 100755
index 00000000000..e014f7518fb
--- /dev/null
+++ b/contrib/
@@ -0,0 +1,46 @@ 
+#! /bin/sh -e
+# Create a new upstream user branch.
+# Usage:
+#  contrib/ [<personal-prefix>/]<branch-name> <base>
+usage ()
+    echo "Usage:"
+    echo "  $0 [<personal-prefix>/]<branch-name> <start-point>"
+    echo
+    echo "personal space must already have been set up using"
+    echo "contrib/"
+    exit 1
+if [ $# != 2 ]
+    usage
+userpfx=$(git config --get "gcc-config.userpfx")
+user=$(git config --get "gcc-config.user")
+if [ -z "$userpfx" -o -z "$user" ]
+    usage
+branch=$(echo "$1" | sed -r "s:(${userpfx}/)?(.*)$:\2:")
+# Sanity check the new branch argument.  If there is no '/', then the
+# vendor will be the same as the entire first argument.
+if [ -z "$branch" ]
+    usage
+git push users/${userpfx} ${start}:refs/users/${user}/heads/${branch}
+git fetch -q users/${userpfx}
+git branch ${userpfx}/${branch} remotes/users/${userpfx}/${branch}
+echo "You are now ready to check out ${userpfx}/${branch}"
+echo "To push the branch upstream use:"
+echo "  git push users/${userpfx} ${userpfx}/${branch}"