{"thread":{"id":"6744","subject":"[PATCH/RFC] git-clone: add --copy-remotes option","startedAt":"2007-02-09T08:07:20Z","lastAt":"2007-02-09T08:07:20Z","messageCount":1,"participants":["Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"34039","messageId":"20070209080720.GA19750@coredump.intra.peff.net","threadId":"6744","inReplyTo":null,"subject":"[PATCH/RFC] git-clone: add --copy-remotes option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-02-09T08:07:20Z","receivedAt":"2007-02-09T08:07:20Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"When invoked as\n\n  git clone --copy-remotes origin:grandparent parent child\n\nthe repo 'child' will clone and track all branches of the parent's\nrefs/remotes/origin/*, storing them as refs/remotes/grandparent/*.\n\n---\n\nSince the move to separate remotes, I occasionally have the desire to\n\"fully\" clone a repository, including its remotes. For example, I\nsometimes want to work on a topic branch in a fresh working directory,\nso I use \"git clone -s git topic\". However, later on in topic I want to\ncompare my work against upstream branches, but they may not have been\ncloned into 'topic' (e.g., I want to look at Junio's 'next', but there\nwas no 'next' branch in my 'git' repository, only 'remotes/origin/next',\nso it didn't get cloned).\n\nUsing this patch, I can do\n  git clone -s --copy-remotes origin:junio git topic\nand access the resulting branches as 'junio/next'.\n\nSome thoughts:\n  - the implementation is a little ugly, but making key/value pairs in\n    shell variables is inherently ugly. Suggestions are welcome.\n  - The child tracks the remote tracking branches of the parent, which\n    is very simple. To solve my problem, I could instead automagically\n    copy the remotes config from the parent, and the child could then\n    track upstream itself. That seems a bit ugly to me (I end up with\n    two repos tracking the same data, potentially downloading it twice).\n  - making a mapping of names (origin -> junio) is more complex than I\n    would like, but otherwise you run a high risk of collision (remote's\n    origin/master becoming your origin/master conflicts with remote's\n    master becoming your origin/master).\n\nAre people interested in this?\n\n git-clone.sh |   24 ++++++++++++++++++++++++\n 1 files changed, 24 insertions(+), 0 deletions(-)\n\ndiff --git a/git-clone.sh b/git-clone.sh\nindex 1bd54de..1f3530b 100755\n--- a/git-clone.sh\n+++ b/git-clone.sh\n@@ -128,6 +128,14 @@ while\n \t*,--depth)\n \t\tshift\n \t\tdepth=\"--depth=$1\";;\n+\t1,--copy-remotes) usage ;;\n+\t*,--copy-remotes)\n+\t\tshift\n+\t\tfrom=`echo $1 | cut -d: -f1`\n+\t\tto=`echo $1 | cut -d: -f2`\n+\t\teval \"copy_remotes_$from=\\\"$to\\\"\"\n+\t\tcopy_remotes=\"$copy_remotes $from\"\n+\t\t;;\n \t*,-*) usage ;;\n \t*) break ;;\n \tesac\n@@ -321,6 +329,17 @@ then\n \t\t\tdestname=\"refs/$branch_top/${name#refs/heads/}\" ;;\n \t\trefs/tags/*)\n \t\t\tdestname=\"refs/$tag_top/${name#refs/tags/}\" ;;\n+\t\trefs/remotes/*)\n+\t\t\tfor i in $copy_remotes; do\n+\t\t\t  case \"$name\" in\n+\t\t\t    refs/remotes/$i/*)\n+\t\t\t      eval \"destremote=\\$copy_remotes_$i\"\n+\t\t\t      destname=\"refs/remotes/$destremote/${name#refs/remotes/$i/}\"\n+\t\t\t      break\n+\t\t\t      ;;\n+\t\t\t  esac\n+\t\t\tdone\n+\t\t\t;;\n \t\t*)\n \t\t\tcontinue ;;\n \t\tesac\n@@ -383,6 +402,11 @@ then\n \t\t# Set up the mappings to track the remote branches.\n \t\tgit-config remote.\"$origin\".fetch \\\n \t\t\t\"+refs/heads/*:$remote_top/*\" '^$' &&\n+\t\tfor i in $copy_remotes; do\n+\t\t\teval \"destremote=\\$copy_remotes_$i\"\n+\t\t\tgit-config --add remote.\"$origin\".fetch \\\n+\t\t\t\t\"+refs/remotes/$i/*:refs/remotes/$destremote/*\"\n+\t\tdone\n \t\trm -f \"refs/remotes/$origin/HEAD\"\n \t\tgit-symbolic-ref \"refs/remotes/$origin/HEAD\" \\\n \t\t\t\"refs/remotes/$origin/$head_points_at\" &&\n-- \n1.5.0.rc4.502.g6a6e-dirty\n"}]}