{"thread":{"id":"43370","subject":"[PATCH/RFC] Implemented glob support in pull refspecs","startedAt":"2006-11-22T22:13:44Z","lastAt":"2006-11-23T07:24:04Z","messageCount":2,"participants":["Andy Parkins","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"294524","messageId":"200611222213.44336.andyparkins@gmail.com","threadId":"43370","inReplyTo":null,"subject":"[PATCH/RFC] Implemented glob support in pull refspecs","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2006-11-22T22:13:44Z","receivedAt":"2006-11-22T22:13:44Z","isPatch":true,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"git-ls-remote is now called early on and the list categorised into heads and\ntags.  Any time a refspec has a \"*\" in the remote part, the git-ls-remote head\nlist is searched for matches against that refspec.  If found then the part of\nthe remote ref that matches the \"*\" is substituted into the local part of the\nrefspec.\n\nThis allows refspecs like\n refs/heads/*:refs/remotes/origin/*\nWhich will ensure that all branches on the remote are created locally.\n\nNote, no local branch will be deleted, so if it is deleted upstream it will\nremain in the local repository.\n\nAs an added bonus, because the output of git-ls-remote is now stored, the other\ncalls to it for tag processing are replaced with simple accesses to the\npreviously stored remote tag list\n\nSigned-off-by: Andy Parkins <andyparkins@gmail.com>\n---\nThe problem with this patch is that I had to disable the safety check \nin git-parse-remote.sh to allow the \"*\" in the refspec.  I'm not sure what\nthe appropriate place to put that call now is?  Perhaps after the expansion\nof the globbed refspecs?\n\n git-fetch.sh        |   77 +++++++++++++++++++++++++++++++++++++++++++++-----\n git-parse-remote.sh |   10 +++---\n 2 files changed, 74 insertions(+), 13 deletions(-)\n\ndiff --git a/git-fetch.sh b/git-fetch.sh\nindex eb32476..1875fe9 100755\n--- a/git-fetch.sh\n+++ b/git-fetch.sh\n@@ -224,6 +224,24 @@ case \"$update_head_ok\" in\n \t;;\n esac\n \n+# Prefetch the remote list and categorise it into tags and heads\n+remotereflist=$(git-ls-remote $upload_pack \"$remote\")\n+remoteheads=\n+remotetags=\n+for ref in $remotereflist\n+do\n+\t# Convert the tab to a comma so that the case below works\n+\tref=$(echo $ref | sed -e \"s/\\t/,/\")\n+\tcase $ref in\n+\t*,refs/heads/*)\n+\t\tremoteheads=\"$remoteheads$ref$LF\"\n+\t\t;;\n+\t*,refs/tags/*)\n+\t\tremotetags=\"$remotetags$ref$LF\"\n+\t\t;;\n+\tesac\n+done\n+\n # If --tags (and later --heads or --all) is specified, then we are\n # not talking about defaults stored in Pull: line of remotes or\n # branches file, and just fetch those and refspecs explicitly given.\n@@ -232,12 +250,9 @@ esac\n reflist=$(get_remote_refs_for_fetch \"$@\")\n if test \"$tags\"\n then\n-\ttaglist=`IFS=\"\t\" &&\n-\t\t  (\n-\t\t\tgit-ls-remote $upload_pack --tags \"$remote\" ||\n-\t\t\techo fail ouch\n-\t\t  ) |\n-\t          while read sha1 name\n+\ttaglist=`IFS=\",\" &&\n+\t\t  echo -n $remotetags |\n+\t      while read sha1 name\n \t\t  do\n \t\t\tcase \"$sha1\" in\n \t\t\tfail)\n@@ -263,6 +278,52 @@ then\n \tfi\n fi\n \n+# Expand any refspecs that contain \"*\"\n+newreflist=\n+for refspec in $reflist\n+do\n+\tremotename=$(expr \"z$refspec\" : 'z\\([^:]*\\):')\n+\tlocalname=$(expr \"z$refspec\" : 'z[^:]*:\\(.*\\)')\n+\tif gotglob=$(expr \"z$remotename\" : 'zrefs/.*/\\*$')\n+\tthen\n+\t\t# If this is a glob-containing ref, then expand it using every\n+\t\t# matching remote head\n+\t\tfor remoteref in $remoteheads\n+\t\tdo\n+\t\t\t# remoteheads stores the heads with the hashes still present\n+\t\t\tremoteref=$(expr \"$remoteref\" : \"$_x40,\\\\(.*\\\\)\")\n+\n+\t\t\t# For example, if\n+\t\t\t#  remotename = refs/heads/*\n+\t\t\t#  localname = refs/remotes/up/*\n+\t\t\t# Then we find a potential remote head of\n+\t\t\t#  remoteref = refs/heads/branchname\n+\n+\t\t\t# First see if it matches the remotename glob\n+\t\t\tcase $remoteref in\n+\t\t\t$remotename)\n+\t\t\t\t# So we know remoteref is the going to be the remote\n+\t\t\t\t# in the new fetch line, however we need to substitute the\n+\t\t\t\t# \"*\" in the local part to get the local name\n+\t\t\t\t# First we manufacture the regexps to do the work\n+\t\t\t\tremotereg=$(echo $remotename | sed -e 's/\\*/\\\\(.*\\\\)/')\n+\t\t\t\tremotebranch=$(expr \"$remoteref\" : \"$remotereg\")\n+\t\t\t\t# Now substitute this into the localname\n+\t\t\t\tlocalref=$(echo $localname | sed -e \"s|\\\\*|$remotebranch|\")\n+\t\t\t\t# And construct the new refspec\n+\t\t\t\tnewreflist=\"$newreflist$remoteref:$localref$LF\"\n+\t\t\t\t;;\n+\t\t\tesac\n+\n+\t\tdone\n+\telse\n+\t\t# Non glob refs just get copied literally\n+\t\tnewreflist=\"$newreflist$ref$LF\"\n+\tfi\n+done\n+reflist=$newreflist\n+\n+\n fetch_main () {\n   reflist=\"$1\"\n   refs=\n@@ -430,8 +491,8 @@ case \"$no_tags$tags\" in\n \t*:refs/*)\n \t\t# effective only when we are following remote branch\n \t\t# using local tracking branch.\n-\t\ttaglist=$(IFS=\" \" &&\n-\t\tgit-ls-remote $upload_pack --tags \"$remote\" |\n+\t\ttaglist=$(IFS=\",\" &&\n+\t\techo -n $remotetags |\n \t\tsed -n\t-e 's|^\\('\"$_x40\"'\\)\t\\(refs/tags/.*\\)^{}$|\\1 \\2|p' \\\n \t\t\t-e 's|^\\('\"$_x40\"'\\)\t\\(refs/tags/.*\\)$|\\1 \\2|p' |\n \t\twhile read sha1 name\ndiff --git a/git-parse-remote.sh b/git-parse-remote.sh\nindex c325ef7..e541144 100755\n--- a/git-parse-remote.sh\n+++ b/git-parse-remote.sh\n@@ -145,11 +145,11 @@ canon_refs_list_for_fetch () {\n \t\t*) local=\"refs/heads/$local\" ;;\n \t\tesac\n \n-\t\tif local_ref_name=$(expr \"z$local\" : 'zrefs/\\(.*\\)')\n-\t\tthen\n-\t\t   git-check-ref-format \"$local_ref_name\" ||\n-\t\t   die \"* refusing to create funny ref '$local_ref_name' locally\"\n-\t\tfi\n+#\t\tif local_ref_name=$(expr \"z$local\" : 'zrefs/\\(.*\\)')\n+#\t\tthen\n+#\t\t   git-check-ref-format \"$local_ref_name\" ||\n+#\t\t   die \"* refusing to create funny ref '$local_ref_name' locally\"\n+#\t\tfi\n \t\techo \"${dot_prefix}${force}${remote}:${local}\"\n \tdone\n }\n-- \n1.4.3.5\n"},{"id":"296638","messageId":"7vbqmylj6z.fsf@assigned-by-dhcp.cox.net","threadId":"43370","inReplyTo":"200611222213.44336.andyparkins@gmail.com","subject":"[PATCH 1/3] git-fetch: reuse ls-remote result.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-23T07:24:04Z","receivedAt":"2006-11-23T07:24:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This will become necessary to update the dumb protocol\ntransports to fetch from a repository with packed and then\npruned tags.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n * I am doing this to allow dumb protocol transports to work\n   with a repository with packed and then pruned refs, but it\n   should be reusable for other purposes, such as wildcarding the\n   refspecs Andy is interested in.\n\n git-fetch.sh |   13 ++++++++-----\n 1 files changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/git-fetch.sh b/git-fetch.sh\nindex eb32476..170c2cb 100755\n--- a/git-fetch.sh\n+++ b/git-fetch.sh\n@@ -88,6 +88,10 @@ then\n \t: >\"$GIT_DIR/FETCH_HEAD\"\n fi\n \n+# Global that is reused later\n+ls_remote_result=$(git ls-remote $upload_pack \"$remote\") ||\n+\tdie \"Cannot find the reflist at $remote\"\n+\n append_fetch_head () {\n     head_=\"$1\"\n     remote_=\"$2\"\n@@ -233,10 +237,7 @@ reflist=$(get_remote_refs_for_fetch \"$@\"\n if test \"$tags\"\n then\n \ttaglist=`IFS=\"\t\" &&\n-\t\t  (\n-\t\t\tgit-ls-remote $upload_pack --tags \"$remote\" ||\n-\t\t\techo fail ouch\n-\t\t  ) |\n+\t\t  echo \"$ls_remote_result\" |\n \t          while read sha1 name\n \t\t  do\n \t\t\tcase \"$sha1\" in\n@@ -245,6 +246,8 @@ then\n \t\t\tesac\n \t\t\tcase \"$name\" in\n \t\t\t*^*) continue ;;\n+\t\t\trefs/tags/*) ;;\n+\t\t\t*) continue ;;\n \t\t\tesac\n \t\t  \tif git-check-ref-format \"$name\"\n \t\t\tthen\n@@ -431,7 +434,7 @@ case \"$no_tags$tags\" in\n \t\t# effective only when we are following remote branch\n \t\t# using local tracking branch.\n \t\ttaglist=$(IFS=\" \" &&\n-\t\tgit-ls-remote $upload_pack --tags \"$remote\" |\n+\t\techo \"$ls_remote_result\" |\n \t\tsed -n\t-e 's|^\\('\"$_x40\"'\\)\t\\(refs/tags/.*\\)^{}$|\\1 \\2|p' \\\n \t\t\t-e 's|^\\('\"$_x40\"'\\)\t\\(refs/tags/.*\\)$|\\1 \\2|p' |\n \t\twhile read sha1 name\n-- \n1.4.4.1.g77614\n\n"}]}