{"thread":{"id":"1566","subject":"Multi-head pulling series","startedAt":"2005-08-18T07:24:28Z","lastAt":"2005-08-23T05:37:40Z","messageCount":9,"participants":["Junio C Hamano","Josef Weidendorfer"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"7487","messageId":"7vek8rlnbn.fsf@assigned-by-dhcp.cox.net","threadId":"1566","inReplyTo":null,"subject":"Multi-head pulling series","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-18T07:24:28Z","receivedAt":"2005-08-18T07:24:28Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Here is the current status of the multi-head download support.\n\n    [PATCH 1/3] Start adding the $GIT_DIR/remotes/ support.\n    [PATCH 2/3] Multi-head fetch.\n    [PATCH 3/3] Update git-pull to match updated git-fetch.\n\nThe first one in the series adds support for the long promised\n$GIT_DIR/remotes/ files; they use the following format:\n\n\t$ cat $GIT_DIR/remotes/www\n\tURL: http://www.kernel.org/pub/scm/git/git.git/\n\tPull: master:ko-master pu:ko-pu\n\n\t$ cat $GIT_DIR/remotes/mko\n\tURL: master.kernel.org:/pub/scm/git/git.git/\n\tPull: master:ko-master pu:ko-pu\n\tPush: master:master pu:pu foo:bar\n\nThe idea is that you should be able to say:\n\n\t$ git push mko ;# push our master and pu to the same\n\t\t\t# name, foo to .git/refs/heads/bar.\n        \n\t$ git push mko pu:refs/heads/testing\n\t\t\t# instead of pushing to the usual ref,\n                        # push our pu to refs/heads/testing,\n                        # this time only. \n        \n\t$ git fetch www ;# get their master and pu to our ko-master\n \t\t\t # and ko-pu.\n\n\t$ git pull www bar\n \t\t\t# instead of fetching from usual ref,\n                        # fetch from there bar, and merge with it.\n\nHaving a Push: entry that uses anything but hostname:/path or\njust local directory as its URL does not make any sense at this\nmoment, because git native send-pack transport is the only one\nthat is supported for push, as before.\n\nNote that using a $GIT_DIR/branches/ file as a short-cut is\nstill supported, for both upload and download.\n\nThe second one extends \"git fetch\" to allow pulling from more\nthan one head.  Earlier, \"git fetch <remote>\" with shorthand\nform (i.e. a file $GIT_DIR/branches/<remote> exists and\ndescribes the URL) always overwrote\n$GIT_DIR/refs/heads/<remote>, but it does the \"reverse push\",\nmeaning it does not overwrite when the update does not result in\na fast-forward merge with the existing value of the reference.\nThe above \"git fetch www\" example would fetch both their master\nand pu, and tries to fast forward our ko-master and ko-pu with\nthem.  When fast forwarding fails, currently it just stops and\ndoes not try to download all the heads.  This may need to\nchange.  The fetch results, whether they update the local\nrefs/heads/ hierarchy by fast forwarding or not, will be also\nstored in $GIT_DIR/FETCH_HEAD.\n\nNote that the format of this file has changed to accomodate\nmultiple heads.  I've checked that neither Cogito nor StGIT\nlooks at this file, so this change should hopefully be a safe\none.\n\nThe third one is to update the \"git pull\" to prevent people from\nabusing the extended \"git fetch\" and attempt to create a king\nghidorah.  \"git resolve\" has not been updated to do anything but\ntwo-head merge yet, so when you say \"git pull www master pu rc\",\nit would run \"git fetch www master pu rc\" but stops without\nrunning the resolving step.  While it would not make much sense\nxsto do an octopus merge against master, pu and rc from git.git\nrepository, doing an octopus would probably make a lot more\nsense when pulling from a repository like what Jeff Garzik has,\nso that would be an interesting future project.\n\nI have tested the very basic form of the above works reasonably\nwell, but there probably are bugs, maybe attempting to pull\nheads to a wrong local heads, or something silly like that.\nPlease handle it with care.  It will stay in \"pu\" branch for\nnow.\n"},{"id":"7489","messageId":"1124350765883-git-send-email-junkio@cox.net","threadId":"1566","inReplyTo":"7vek8rlnbn.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 1/3] Start adding the $GIT_DIR/remotes/ support.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-18T07:39:25Z","receivedAt":"2005-08-18T07:39:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"All the necessary parsing code is in git-parse-remote-script;\nupdate git-push-script to use it.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n Makefile                |    2 -\n git-parse-remote-script |  122 +++++++++++++++++++++++++++++++++++++++++++++++\n git-push-script         |   28 ++---------\n 3 files changed, 129 insertions(+), 23 deletions(-)\n create mode 100755 git-parse-remote-script\n\nf8892bf17675056cd18a252d3bc4e4ba381fb3bc\ndiff --git a/Makefile b/Makefile\n--- a/Makefile\n+++ b/Makefile\n@@ -64,7 +64,7 @@ SCRIPTS=git git-apply-patch-script git-m\n \tgit-reset-script git-add-script git-checkout-script git-clone-script \\\n \tgitk git-cherry git-rebase-script git-relink-script git-repack-script \\\n \tgit-format-patch-script git-sh-setup-script git-push-script \\\n-\tgit-branch-script git-parse-remote git-verify-tag-script \\\n+\tgit-branch-script git-parse-remote git-parse-remote-script git-verify-tag-script \\\n \tgit-ls-remote-script git-clone-dumb-http git-rename-script \\\n \tgit-request-pull-script git-bisect-script\n \ndiff --git a/git-parse-remote-script b/git-parse-remote-script\nnew file mode 100755\n--- /dev/null\n+++ b/git-parse-remote-script\n@@ -0,0 +1,122 @@\n+#!/bin/sh\n+\n+. git-sh-setup-script || die \"Not a git archive\"\n+\n+get_data_source () {\n+\tcase \"$1\" in\n+\t*/*)\n+\t\t# Not so fast.  This could be the partial URL shorthand...\n+\t\ttoken=$(expr \"$1\" : '\\([^/]*\\)/')\n+\t\tremainder=$(expr \"$1\" : '[^/]*/\\(.*\\)')\n+\t\tif test -f \"$GIT_DIR/branches/$token\"\n+\t\tthen\n+\t\t\techo branches-partial\n+\t\telse\n+\t\t\techo ''\n+\t\tfi\n+\t\t;;\n+\t*)\n+\t\tif test -f \"$GIT_DIR/remotes/$1\"\n+\t\tthen\n+\t\t\techo remotes\n+\t\telif test -f \"$GIT_DIR/branches/$1\"\n+\t\tthen\n+\t\t\techo branches\n+\t\telse\n+\t\t\techo ''\n+\t\tfi ;;\n+\tesac\n+}\n+\n+get_remote_url () {\n+\tdata_source=$(get_data_source \"$1\")\n+\tcase \"$data_source\" in\n+\t'')\n+\t\techo \"$1\" ;;\n+\tremotes)\n+\t\tsed -ne '/^URL: */{\n+\t\t\ts///p\n+\t\t\tq\n+\t\t}' \"$GIT_DIR/remotes/$1\" ;;\n+\tbranches)\n+\t\tsed -e 's/#.*//' \"$GIT_DIR/branches/$1\" ;;\n+\tbranches-partial)\n+\t\ttoken=$(expr \"$1\" : '\\([^/]*\\)/')\n+\t\tremainder=$(expr \"$1\" : '[^/]*/\\(.*\\)')\n+\t\turl=$(sed -e 's/#.*//' \"$GIT_DIR/branches/$token\")\n+\t\techo \"$url/$remainder\"\n+\t\t;;\n+\t*)\n+\t\tdie \"internal error: get-remote-url $1\" ;;\n+\tesac\n+}\n+\n+get_remote_default_refs_for_push () {\n+\tdata_source=$(get_data_source \"$1\")\n+\tcase \"$data_source\" in\n+\t'' | branches | branches-partial)\n+\t\t;; # no default push mapping, just send matching refs.\n+\tremotes)\n+\t\tsed -ne '/^Push: */{\n+\t\t\ts///p\n+\t\t}' \"$GIT_DIR/remotes/$1\" ;;\n+\t*)\n+\t\tdie \"internal error: get-remote-default-ref-for-push $1\" ;;\n+\tesac\n+}\n+\n+# Subroutine to caninicalize remote:local notation\n+canon_refs_list_for_fetch () {\n+\tfor ref\n+\tdo\n+\t\texpr \"$ref\" : '.*:' >/dev/null || ref=\"${ref}:\"\n+\t\tremote=$(expr \"$ref\" : '\\([^:]*\\):')\n+\t\tlocal=$(expr \"$ref\" : '[^:]*:\\(.*\\)')\n+\t\tcase \"$remote\" in\n+\t\t'') remote=HEAD ;;\n+\t\t*) remote=\"refs/heads/$remote\" ;;\n+\t\tesac\n+\t\tcase \"$local\" in\n+\t\t'') local= ;;\n+\t\t*) local=\"refs/heads/$local\" ;;\n+\t\tesac\n+\t\techo \"${remote}:${local}\"\n+\tdone\n+}\n+\n+# Returns list of src: (no store), or src:dst (store)\n+get_remote_default_refs_for_fetch () {\n+\tdata_source=$(get_data_source \"$1\")\n+\tcase \"$data_source\" in\n+\t'' | branches-partial)\n+\t\techo \"HEAD:\" ;;\n+\tbranches)\n+\t\tremote_branch=$(sed -ne '/#/s/.*#//p' \"$GIT_DIR/branches/$1\")\n+\t\tcase \"$remote_branch\" in '') remote_branch=master ;; esac\n+\t\techo \"refs/heads/${remote_branch}:refs/heads/$1\"\n+\t\t;;\n+\tremotes)\n+\t\tcanon_refs_list_for_fetch $(sed -ne '/^Pull: */{\n+\t\t\t\t\t\ts///p\n+\t\t\t\t\t}' \"$GIT_DIR/remotes/$1\")\n+\t\t;;\n+\t*)\n+\t\tdie \"internal error: get-remote-default-ref-for-push $1\" ;;\n+\tesac\n+}\n+\n+get_remote_refs_for_push () {\n+\tcase \"$#\" in\n+\t0) die \"internal error: get-remote-refs-for-push.\" ;;\n+\t1) get_remote_default_refs_for_push \"$@\" ;;\n+\t*) shift; echo \"$@\" ;;\n+\tesac\n+}\n+\n+get_remote_refs_for_fetch () {\n+\tcase \"$#\" in\n+\t0) die \"internal error: get-remote-refs-for-fetch.\" ;;\n+\t1) get_remote_default_refs_for_fetch \"$@\" ;;\n+\t*) shift; canon_refs_list_for_fetch \"$@\" ;;\n+\tesac\n+}\ndiff --git a/git-push-script b/git-push-script\n--- a/git-push-script\n+++ b/git-push-script\n@@ -20,8 +20,6 @@ do\n \t-*)\n \t\tdie \"Unknown parameter $1\" ;;\n         *)\n-\t\tremote=\"$1\"\n-\t\tshift\n \t\tset x \"$@\"\n \t\tshift\n \t\tbreak ;;\n@@ -29,27 +27,13 @@ do\n \tshift\n done\n \n-case \"$remote\" in\n-*:* | /* | ../* | ./* )\n-\t# An URL, host:/path/to/git, absolute and relative paths.\n-\t;;\n-* )\n-\t# Shorthand\n-\tif expr \"$remote\" : '..*/..*' >/dev/null\n-\tthen\n-\t\t# a short-hand followed by a trailing path\n-\t\tshorthand=$(expr \"$remote\" : '\\([^/]*\\)')\n-\t\tremainder=$(expr \"$remote\" : '[^/]*\\(/.*\\)$')\n-\telse\n-\t\tshorthand=\"$remote\"\n-\t\tremainder=\n-\tfi\n-\tremote=$(sed -e 's/#.*//' \"$GIT_DIR/branches/$remote\") &&\n-\texpr \"$remote\" : '..*:' >/dev/null &&\n-\tremote=\"$remote$remainder\" ||\n-\tdie \"Cannot parse remote $remote\"\n-\t;;\n+. git-parse-remote-script\n+remote=$(get_remote_url \"$@\")\n+case \"$has_all\" in\n+--all) set x ;;\n+'')    set x $(get_remote_refs_for_push \"$@\") ;;\n esac\n+shift\n \n case \"$remote\" in\n http://* | https://* | git://* | rsync://* )\n"},{"id":"7488","messageId":"11243507702006-git-send-email-junkio@cox.net","threadId":"1566","inReplyTo":"7vek8rlnbn.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 2/3] Multi-head fetch.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-18T07:39:30Z","receivedAt":"2005-08-18T07:39:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Traditionally, fetch takes these forms:\n\n    $ git fetch <remote>\n    $ git fetch <remote> <head>\n    $ git fetch <remote> tag <tag>\n\nThis patch updates it to take\n\n    $ git fetch <remote> <refspec>...\n\nwhere:\n\n    - A <refspec> of form \"<src>:<dst>\" is to fetch the objects\n      needed for the remote ref that matches <src>, and if <dst>\n      is not empty, store it as a local <dst>.\n\n    - \"tag\" followed by <next> is just an old way of saying\n      \"refs/tags/<next>:refs/tags/<next>\"; this mimics the\n      current behaviour of the third form above and means \"fetch\n      that tag and store it under the same name\".\n\n    - A single token <refspec> without colon is a shorthand for\n      \"<refspec>:\"  That is, \"fetch that ref but do not store\n      anywhere\".\n\n    - when there is no <refspec> specified\n\n      - if <remote> is the name of a file under $GIT_DIR/remotes/\n\t(i.e. a new-style shorthand), then it is the same as giving\n\tthe <refspec>s listed on Pull: line in that file.\n\n      - if <remote> is the name of a file under $GIT_DIR/branches/\n\t(i.e. an old-style shorthand, without trailing path), then it\n\tis the same as giving a single <refspec>\n\t\"<remote-name>:refs/heads/<remote>\" on the command line, where\n\t<remote-name> is the remote branch name (defaults to HEAD, but\n\tcan be overridden by .git/branches/<remote> file having the\n\tURL fragment notation).  That is, \"fetch that branch head and\n\tstore it in refs/heads/<remote>\".\n\n      - otherwise, it is the same as giving a single <refspec>\n        that is \"HEAD:\".\n\nThe SHA1 object names of fetched refs are stored in FETCH_HEAD,\none name per line.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n git-fetch-script |  154 ++++++++++++++++++++++++++++++++++++++----------------\n 1 files changed, 108 insertions(+), 46 deletions(-)\n\n7dbfeb149dfc049015f27f15dd9135fd15d5f99f\ndiff --git a/git-fetch-script b/git-fetch-script\n--- a/git-fetch-script\n+++ b/git-fetch-script\n@@ -1,54 +1,116 @@\n #!/bin/sh\n #\n . git-sh-setup-script || die \"Not a git archive\"\n-. git-parse-remote \"$@\"\n-merge_repo=\"$_remote_repo\"\n-merge_head=\"$_remote_head\"\n-merge_store=\"$_remote_store\"\n-\n-TMP_HEAD=\"$GIT_DIR/TMP_HEAD\"\n-\n-case \"$merge_repo\" in\n-http://* | https://*)\n-        if [ -n \"$GIT_SSL_NO_VERIFY\" ]; then\n-            curl_extra_args=\"-k\"\n-        fi\n-\t_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' &&\n-\t_x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\" &&\n-\thead=$(curl -nsf $curl_extra_args \"$merge_repo/$merge_head\") &&\n-\texpr \"$head\" : \"$_x40\\$\" >/dev/null || {\n-\t\techo >&2 \"Failed to fetch $merge_head from $merge_repo\"\n-\t        exit 1\n-\t}\n-\techo Fetching \"$merge_head\" using http\n-\tgit-http-pull -v -a \"$head\" \"$merge_repo/\" || exit\n-\t;;\n-rsync://*)\n-\trsync -L \"$merge_repo/$merge_head\" \"$TMP_HEAD\" || exit 1\n-\thead=$(git-rev-parse TMP_HEAD)\n-\trm -f \"$TMP_HEAD\"\n-\trsync -avz --ignore-existing \"$merge_repo/objects/\" \"$GIT_OBJECT_DIRECTORY/\"\n-\t;;\n-*)\n-\thead=$(git-fetch-pack \"$merge_repo\" \"$merge_head\")\n-\tif h=`expr \"$head\" : '\\([^ ][^ ]*\\) '`\n+. git-parse-remote-script\n+_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n+_x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n+\n+remote_nick=\"$1\"\n+remote=$(get_remote_url \"$@\")\n+refs=\n+rref=\n+prev_was_literal_tag=\n+rsync_slurped_objects=\n+: >$GIT_DIR/FETCH_HEAD\n+\n+fast_forward_local () {\n+\n+\t# NEEDSWORK: probably use the same cmpxchg protocol here...\n+\techo \"$2\" >\"$GIT_DIR/$1.lock\"\n+\tif test -f \"$GIT_DIR/$1\"\n \tthen\n-\t    head=$h\n+\t\tlocal=$(git-rev-parse --verify \"$1^0\") &&\n+\t\tmb=$(git-merge-base \"$local\" \"$2\") &&\n+\t\ttest \"$mb\" = \"$local\" || {\n+\t\t\trm -f \"$GIT_DIR/$1.lock\"\n+\t\t\tdie \"$1 does not fast forward to $4 from $3.\";\n+\t\t}\n \tfi\n-\t;;\n-esac || exit 1\n-\n-git-rev-parse --verify \"$head\" > /dev/null || exit 1\n+\tmv \"$GIT_DIR/$1.lock\" \"$GIT_DIR/$1\"\n+}\n \n-case \"$merge_store\" in\n-'')\n-\t;;\n-*)\n-\techo \"$head\" > \"$GIT_DIR/$merge_store\"\n-esac &&\n+for ref in $(get_remote_refs_for_fetch \"$@\")\n+do\n+\tif test \"$prev_was_literal_tag\"\n+\tthen\n+\t\tref=\"refs/tags/${ref}:refs/tags/${ref}\"\n+\t\tprev_was_literal_tag=\n+\telse\n+\t\tcase \"$ref\" in\n+\t\ttag)\n+\t\t\tprev_was_literal_tag=yes\n+\t\t\tcontinue\n+\t\t\t;;\n+\t\tesac\n+\tfi\n \n-# FETCH_HEAD is fed to git-resolve-script which will eventually be\n-# passed to git-commit-tree as one of the parents.  Make sure we do\n-# not give a tag object ID.\n+\trefs=\"$refs $ref\"\n \n-git-rev-parse \"$head^0\" >\"$GIT_DIR/FETCH_HEAD\"\n+\t# These are relative path from $GIT_DIR, typically starting at refs/\n+\t# but may be HEAD\n+\tremote_name=$(expr \"$ref\" : '\\([^:]*\\):')\n+\tlocal_name=$(expr \"$ref\" : '[^:]*:\\(.*\\)')\n+\n+\trref=\"$rref $remote_name\"\n+\n+\t# There are transports that can fetch only one head at a time...\n+\tcase \"$remote\" in\n+\thttp://* | https://*)\n+\t\tif [ -n \"$GIT_SSL_NO_VERIFY\" ]; then\n+\t\t    curl_extra_args=\"-k\"\n+\t\tfi\n+\t\thead=$(curl -nsf $curl_extra_args \"$remote/$remote_name\") &&\n+\t\texpr \"$head\" : \"$_x40\\$\" >/dev/null ||\n+\t\t\tdie \"Failed to fetch $remote_name from $remote\"\n+\t\techo Fetching \"$remote_name from $remote\" using http\n+\t\tgit-http-pull -v -a \"$head\" \"$remote/\" || exit\n+\t\t;;\n+\trsync://*)\n+\t\tTMP_HEAD=\"$GIT_DIR/TMP_HEAD\"\n+\t\trsync -L \"$remote/$remote_name\" \"$TMP_HEAD\" || exit 1\n+\t\thead=$(git-rev-parse TMP_HEAD)\n+\t\trm -f \"$TMP_HEAD\"\n+\t\ttest \"$rsync_slurped_objects\" || {\n+\t\t\trsync -avz --ignore-existing \"$remote/objects/\" \\\n+\t\t\t\t\"$GIT_OBJECT_DIRECTORY/\" || exit\n+\t\t\trsync_slurped_objects=t\n+\t\t}\n+\t\t;;\n+\t*)\n+\t\t# We will do git native transport at one go.\n+\t\tcontinue ;;\n+\tesac\n+\thead=$(git-rev-parse --verify \"$head^0\") || exit\n+\techo \"$head\t$remote_name from $remote_nick\" >>$GIT_DIR/FETCH_HEAD\n+\tcase \"$local_name\" in '') continue ;; esac\n+\n+\t# We are storing the head locally.  Make sure that it is\n+\t# a fast forward (aka \"reverse push\").\n+\tfast_forward_local \"$local_name\" \"$head\" \"$remote\" \"$remote_name\"\n+\n+done\n+\n+case \"$remote\" in\n+http://* | https://* | rsync://* )\n+\t;; # we are already done.\n+*)\n+\tgit-fetch-pack \"$remote\" $rref |\n+\twhile read sha1 remote_name\n+\tdo\n+\t\tfound=\n+\t\tfor ref in $refs\n+\t\tdo\n+\t\t\tcase \"$ref\" in\n+\t\t\t$remote_name:*)\n+\t\t\t\tfound=\"$ref\"\n+\t\t\t\tbreak ;;\n+\t\t\tesac\n+\t\tdone\n+\t\thead=$(git-rev-parse --verify \"$sha1^0\") || exit\n+\t\techo \"$head\t$remote_name from $remote_nick\" >>$GIT_DIR/FETCH_HEAD\n+\t\tcase \"$found\" in '' | *:) continue ;; esac\n+\t\tlocal=$(expr \"$found\" : '[^:]*:\\(.*\\)')\n+\t\tfast_forward_local \"$local\" \"$sha1\" \"$remote\" \"$remote_name\"\n+\tdone\n+\t;;\n+esac\n"},{"id":"7490","messageId":"11243507711980-git-send-email-junkio@cox.net","threadId":"1566","inReplyTo":"7vek8rlnbn.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 3/3] Update git-pull to match updated git-fetch.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-18T07:39:31Z","receivedAt":"2005-08-18T07:39:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This retires the git-parse-remote script, and allows pull to fetch\nfrom multiple remote references.  There is no support for resolving\nmore than two heads, so that would be next.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n Makefile         |    2 +\n git-parse-remote |   79 ------------------------------------------------------\n git-pull-script  |   14 ++++++----\n 3 files changed, 10 insertions(+), 85 deletions(-)\n delete mode 100755 git-parse-remote\n\n3a071a02828c71bbfdc2749d25814906cd9c8b18\ndiff --git a/Makefile b/Makefile\n--- a/Makefile\n+++ b/Makefile\n@@ -64,7 +64,7 @@ SCRIPTS=git git-apply-patch-script git-m\n \tgit-reset-script git-add-script git-checkout-script git-clone-script \\\n \tgitk git-cherry git-rebase-script git-relink-script git-repack-script \\\n \tgit-format-patch-script git-sh-setup-script git-push-script \\\n-\tgit-branch-script git-parse-remote git-parse-remote-script git-verify-tag-script \\\n+\tgit-branch-script git-parse-remote-script git-verify-tag-script \\\n \tgit-ls-remote-script git-clone-dumb-http git-rename-script \\\n \tgit-request-pull-script git-bisect-script\n \ndiff --git a/git-parse-remote b/git-parse-remote\ndeleted file mode 100755\n--- a/git-parse-remote\n+++ /dev/null\n@@ -1,79 +0,0 @@\n-: To be included in git-pull and git-fetch scripts.\n-\n-# A remote repository can be specified on the command line\n-# in one of the following formats:\n-#\n-#\t<repo>\n-#\t<repo> <head>\n-#\t<repo> tag <tag>\n-#\n-# where <repo> could be one of:\n-#\n-#\ta URL (including absolute or local pathname)\n-#\ta short-hand\n-#\ta short-hand followed by a trailing path\n-#\n-# A short-hand <name> has a corresponding file $GIT_DIR/branches/<name>,\n-# whose contents is a URL, possibly followed by a URL fragment #<head>\n-# to name the default branch on the remote side to fetch from.\n-\n-_remote_repo= _remote_store= _remote_head= _remote_name=\n-\n-case \"$1\" in\n-*:* | /* | ../* | ./* )\n-\t_remote_repo=\"$1\"\n-\t;;\n-* )\n-\t# otherwise, it is a short hand.\n-\tcase \"$1\" in\n-\t*/*)\n-\t\t# a short-hand followed by a trailing path\n-\t\t_token=$(expr \"$1\" : '\\([^/]*\\)/')\n-\t\t_rest=$(expr \"$1\" : '[^/]*\\(/.*\\)$')\n-\t\t;;\n-\t*)\n-\t\t_token=\"$1\"\n-\t\t_rest=\n-\t\t_remote_store=\"refs/heads/$_token\"\n-\t\t;;\n-\tesac\n-\ttest -f \"$GIT_DIR/branches/$_token\" ||\n-\tdie \"No such remote branch: $_token\"\n-\n-\t_remote_repo=$(cat \"$GIT_DIR/branches/$_token\")\"$_rest\"\n-\t;;\n-esac\n-\n-case \"$_remote_repo\" in\n-*\"#\"*)\n-\t_remote_head=`expr \"$_remote_repo\" : '.*#\\(.*\\)$'`\n-\t_remote_repo=`expr \"$_remote_repo\" : '\\(.*\\)#'`\n-\t;;\n-esac\n-\n-_remote_name=$(echo \"$_remote_repo\" | sed 's|\\.git/*$||')\n-\n-case \"$2\" in\n-tag)\n-\t_remote_name=\"tag '$3' of $_remote_name\"\n-\t_remote_head=\"refs/tags/$3\"\n-\t_remote_store=\"$_remote_head\"\n-\t;;\n-?*)\n-\t# command line specified a head explicitly; do not\n-\t# store the fetched head as a branch head.\n-\t_remote_name=\"head '$2' of $_remote_name\"\n-\t_remote_head=\"refs/heads/$2\"\n-\t_remote_store=''\n-\t;;\n-'')\n-\tcase \"$_remote_head\" in\n-\t'')\n-\t\t_remote_head=HEAD ;;\n-\t*)\n-\t\t_remote_name=\"head '$_remote_head' of $_remote_name\"\n-\t\t_remote_head=\"refs/heads/$_remote_head\"\n-\t\t;;\n-\tesac\n-\t;;\n-esac\ndiff --git a/git-pull-script b/git-pull-script\n--- a/git-pull-script\n+++ b/git-pull-script\n@@ -1,12 +1,16 @@\n #!/bin/sh\n #\n . git-sh-setup-script || die \"Not a git archive\"\n-. git-parse-remote \"$@\"\n-merge_name=\"$_remote_name\"\n-\n git-fetch-script \"$@\" || exit 1\n+merge_head=$(sed -e 's/\t.*//' \"$GIT_DIR\"/FETCH_HEAD | tr '\\012' ' ')\n+merge_name=$(sed -e 's/^[0-9a-f]*\t//' \"$GIT_DIR\"/FETCH_HEAD |\n+\t tr '\\012' ' ')\n+\n+case \"$merge_head\" in\n+'' | *' '?*) die \"Cannot resolve multiple heads at the same time (yet).\" ;;\n+esac\n+\n \n git-resolve-script \\\n \t\"$(cat \"$GIT_DIR\"/HEAD)\" \\\n-\t\"$(cat \"$GIT_DIR\"/FETCH_HEAD)\" \\\n-\t\"Merge $merge_name\"\n+\t$merge_head \"Merge $merge_name\"\n"},{"id":"7497","messageId":"200508181245.58250.Josef.Weidendorfer@gmx.de","threadId":"1566","inReplyTo":"7vek8rlnbn.fsf@assigned-by-dhcp.cox.net","subject":"Re: Multi-head pulling series","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2005-08-18T10:45:58Z","receivedAt":"2005-08-18T10:45:58Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Thursday 18 August 2005 09:24, Junio C Hamano wrote:\n> \t$ cat $GIT_DIR/remotes/www\n> \tURL: http://www.kernel.org/pub/scm/git/git.git/\n> \tPull: master:ko-master pu:ko-pu\n>       Push: master:master pu:pu foo:bar\n\nIsn't this mixing two kinds of information:\n1) Some default/persistent mapping of local to remote heads\n2) The default heads which are pulled/pushed when only giving the remote, like \nin:\n\n> \t$ git push mko ;# push our master and pu to the same\n> \t\t\t# name, foo to .git/refs/heads/bar.\n\nI think it makes sense to be able to store mappings without adding the head to\nthe default group of heads pulled.\n\nCan we put the default pull/push actions in separate lines, like\n\n \t$ cat $GIT_DIR/remotes/mko\n \tURL: master.kernel.org:/pub/scm/git/git.git/\n \tPull: master:ko-master pu:ko-pu mylocal:myremote\n\tPush: master:master pu:pu foo:bar\n\tDefault-Pull: master pu\n\tDefault-Push: master pu foo\n\t\n> \t$ git push mko pu:refs/heads/testing\n> \t\t\t# instead of pushing to the usual ref,\n>                         # push our pu to refs/heads/testing,\n>                         # this time only.\n\nWith a command (push/fetch/pull) giving an explicit local/remote mapping, it \nwould be cool to automatically add the given mapping to the remotes/ file if \nthere is no push-mapping for pu yet, so that you can have the same later with \nonly\n\n\tgit push mko pu\n\nAnd finally, it would be nice to specify a default mapping for arbitrary heads\n\n\t$ cat $GIT_DIR/remotes/www\n \tURL: http://www.kernel.org/pub/scm/git/git.git/\n \tPull: www#*:*\n\nSuch that\n\n\tgit fetch www#pu\n\nwill fetch head pu into local head .refs/heads/www#pu\n\n\nJosef\n\nPS: I know I should provide patches for my proposals. But let discuss them \nfirst.\n"},{"id":"7596","messageId":"7vfyt4l9q9.fsf@assigned-by-dhcp.cox.net","threadId":"1566","inReplyTo":"200508181245.58250.Josef.Weidendorfer@gmx.de","subject":"Re: Multi-head pulling series","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-20T18:54:54Z","receivedAt":"2005-08-20T18:54:54Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n\n>> \t$ cat $GIT_DIR/remotes/www\n>> \tURL: http://www.kernel.org/pub/scm/git/git.git/\n>>\tPull: master:ko-master pu:ko-pu\n>>\tPush: master:master pu:pu foo:bar\n>\n> Isn't this mixing two kinds of information:\n> 1) Some default/persistent mapping of local to remote heads\n> 2) The default heads which are pulled/pushed when only giving the remote\n\nI am not convinced myself that default/persistent mapping makes\nmuch sense, and updating the stored mappings dynamically when\nthe user uses non-default mappings in push/pull as a one-shot\noperation does not make any sense at all at least to me.  You\nshould rather consider that the current specification does not\ndeal with (1) at all.  The set of default pull/push refs does\nnot make much sense without mappings for them, so that is what\nthe file records.\n"},{"id":"7623","messageId":"200508221835.31275.Josef.Weidendorfer@gmx.de","threadId":"1566","inReplyTo":"7vfyt4l9q9.fsf@assigned-by-dhcp.cox.net","subject":"Re: Multi-head pulling series","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2005-08-22T16:35:31Z","receivedAt":"2005-08-22T16:35:31Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Saturday 20 August 2005 20:54, Junio C Hamano wrote:\n> Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n> >> \t$ cat $GIT_DIR/remotes/www\n> >> \tURL: http://www.kernel.org/pub/scm/git/git.git/\n> >>\tPull: master:ko-master pu:ko-pu\n> >>\tPush: master:master pu:pu foo:bar\n> >\n> > Isn't this mixing two kinds of information:\n> > 1) Some default/persistent mapping of local to remote heads\n> > 2) The default heads which are pulled/pushed when only giving the remote\n>\n> I am not convinced myself that default/persistent mapping makes\n> much sense,\n\nI think that both, default and non-default persistant mappings, are only a \nhandy convenience issue for less typing. If GIT core is not doing this, some \n(most?) porcelains will invent their own way for storing these mappings (like \nCogito is doing with branches/). I think it is better if this is \n\"standardized\".\n\nCurrently missing here is automatic detection of the remote repository for a \ngiven head to be pulled/pushed. But this is no format issue.\n\n> and updating the stored mappings dynamically when \n> the user uses non-default mappings in push/pull as a one-shot\n> operation does not make any sense at all at least to me.\n\nYes, you are right.\n\nJosef\n"},{"id":"7634","messageId":"7vbr3p1mws.fsf@assigned-by-dhcp.cox.net","threadId":"1566","inReplyTo":"200508221835.31275.Josef.Weidendorfer@gmx.de","subject":"Re: Multi-head pulling series","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-23T01:07:15Z","receivedAt":"2005-08-23T01:07:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n\n> I think that both, default and non-default persistant\n> mappings, are only a handy convenience issue for less\n> typing. If GIT core is not doing this, some (most?) porcelains\n> will invent their own way for storing these mappings (like\n> Cogito is doing with branches/). I think it is better if this\n> is \"standardized\".\n\nI agree in principle, and it should not be hard to add support\nfor optional \"Default-pull\" and \"Default-push\" keywords to\nremotes/ files (lack of which means to use LHS of refspecs on\n\"Pull\" or \"Push\" lines) to git-parse-remote-script.  Patches\nwelcome.\n\n> Currently missing here is automatic detection of the remote\n> repository for a given head to be pulled/pushed. But this is\n> no format issue.\n\n\"git ls-remote <repo>\" perhaps?\n"},{"id":"7641","messageId":"7virxxw6vv.fsf@assigned-by-dhcp.cox.net","threadId":"1566","inReplyTo":"200508221835.31275.Josef.Weidendorfer@gmx.de","subject":"Re: Multi-head pulling series","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-23T05:37:40Z","receivedAt":"2005-08-23T05:37:40Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n\n> I think that both, default and non-default persistant\n> mappings, are only a handy convenience issue for less\n> typing. If GIT core is not doing this, some (most?) porcelains\n> will invent their own way for storing these mappings.\n\nSuppose I have something like this in $GIT_DIR/remotes/ko:\n\n    URL: master.kernel.org:/pub/scm/git/git.git/\n    Pull: master:ko-master rc:ko-rc pu:ko-pu\n    Push: master:master pu:pu rc:rc\n    Default-Pull: master rc\n\nThat is, \"Pull/Push\" describe only the default mappings, and\n\"Default-Pull/Default-Push\" names the refs pulled or pushed when\nonly the shorthand (ko) is specified.  I think that is what your\nproposal boils down to.  Lack of \"Default-Push\" just means use\nthe heads listed on \"Push\" line for the default.\n\nAm I reading you right so far?\n\nWith that definition, what these would do would be intuitive and\nobvious:\n\n    $ git push ko  ;# my master, rc, and pu goes there, under\n                    # the same name.\n    $ git fetch ko ;# their master comes to my ko-master, rc to my ko-rc\n                    # pu is not touched.\n\nBut now, what should this do?\n\n    $ git fetch ko master\n\n(1) does it use \"Pull\" mappings and use their \"master\" to fast\n    forward my \"ko-master\"?\n\nor\n\n(2) does it obey \"the command line overrides the configuration\n    file\" principle and fetch their \"master\" but not touch my\n    local refs (remember, refspec \"master\" without colon is\n    equivalent to \"master:\" in fetch, which means \"get the\n    objects to complete it, but do not store the ref locally\")?\n\nIf (1), then I would need to say \"master:something\" on the\ncommand line almost all the time, because the point of remotes/\nconfiguration file is that I do not have to remember which\nremote head corresponds to my local head, and by definition I\nwould not (and should not have to) know if \"master\" has the\ndefault mappings specified there and to which head, so even that\n\"something\" happens to be exactly what is in the remotes/ file,\nI would end up typing that explicitly.  Which means that it\ndefeats the point of having the configuration file to begin\nwith.\n\nIf (2), then I would again need to say master:ko-master if I\nwanted to mean \"usually I pull from some heads (I do not\nremember which ones offhand, but my .git/remotes/ file would\nknow), but this time I want to only pull from master and update\nko-master\".\n\nWhat this suggests to me is that making set of default refs to\nbe pulled from and set of ref mappings orthgonal sounds like a\ngood and clean way in theory, but would not be that much useful\nin practice.\n"}]}