{"thread":{"id":"7884","subject":"[PATCH 4/5] Add --remote option to send-pack","startedAt":"2007-04-28T17:05:18Z","lastAt":"2007-05-07T20:08:19Z","messageCount":15,"participants":["Daniel Barkalow","Junio C Hamano","Shawn O. Pearce","Loeliger Jon-LOELIGER"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"40661","messageId":"Pine.LNX.4.64.0704281304360.28708@iabervon.org","threadId":"7884","inReplyTo":null,"subject":"[PATCH 4/5] Add --remote option to send-pack","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-04-28T17:05:18Z","receivedAt":"2007-04-28T17:05:18Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"With the --remote option, send-pack will look at the remote\nconfiguration for the specified remote (which must match the\ndestination URL), and update the local tracking refs to match changes\nit causes in the remote heads they track.\n\nThe previous values of local tracking heads are ignored.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\n send-pack.c |   54 +++++++++++++++++++++++++++++++++++++++++++++---------\n 1 files changed, 45 insertions(+), 9 deletions(-)\n\ndiff --git a/send-pack.c b/send-pack.c\nindex d5b5162..7f76ef0 100644\n--- a/send-pack.c\n+++ b/send-pack.c\n@@ -4,6 +4,7 @@\n #include \"refs.h\"\n #include \"pkt-line.h\"\n #include \"run-command.h\"\n+#include \"remote.h\"\n \n static const char send_pack_usage[] =\n \"git-send-pack [--all] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\\n\"\n@@ -176,7 +177,7 @@ static int receive_status(int in)\n \treturn ret;\n }\n \n-static int send_pack(int in, int out, int nr_refspec, char **refspec)\n+static int send_pack(int in, int out, struct remote *remote, int nr_refspec, char **refspec)\n {\n \tstruct ref *ref;\n \tint new_refs;\n@@ -213,18 +214,18 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)\n \tnew_refs = 0;\n \tfor (ref = remote_refs; ref; ref = ref->next) {\n \t\tchar old_hex[60], *new_hex;\n-\t\tint delete_ref;\n+\t\tint will_delete_ref;\n \n \t\tif (!ref->peer_ref)\n \t\t\tcontinue;\n \n-\t\tdelete_ref = is_null_sha1(ref->peer_ref->new_sha1);\n-\t\tif (delete_ref && !allow_deleting_refs) {\n+\t\twill_delete_ref = is_null_sha1(ref->peer_ref->new_sha1);\n+\t\tif (will_delete_ref && !allow_deleting_refs) {\n \t\t\terror(\"remote does not support deleting refs\");\n \t\t\tret = -2;\n \t\t\tcontinue;\n \t\t}\n-\t\tif (!delete_ref &&\n+\t\tif (!will_delete_ref &&\n \t\t    !hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {\n \t\t\tif (verbose)\n \t\t\t\tfprintf(stderr, \"'%s': up-to-date\\n\", ref->name);\n@@ -251,7 +252,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)\n \t\t */\n \n \t\tif (!force_update &&\n-\t\t    !delete_ref &&\n+\t\t    !will_delete_ref &&\n \t\t    !is_null_sha1(ref->old_sha1) &&\n \t\t    !ref->force) {\n \t\t\tif (!has_sha1_file(ref->old_sha1) ||\n@@ -275,7 +276,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)\n \t\t\t}\n \t\t}\n \t\thashcpy(ref->new_sha1, ref->peer_ref->new_sha1);\n-\t\tif (!delete_ref)\n+\t\tif (!will_delete_ref)\n \t\t\tnew_refs++;\n \t\tstrcpy(old_hex, sha1_to_hex(ref->old_sha1));\n \t\tnew_hex = sha1_to_hex(ref->new_sha1);\n@@ -290,7 +291,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)\n \t\telse\n \t\t\tpacket_write(out, \"%s %s %s\",\n \t\t\t\t     old_hex, new_hex, ref->name);\n-\t\tif (delete_ref)\n+\t\tif (will_delete_ref)\n \t\t\tfprintf(stderr, \"deleting '%s'\\n\", ref->name);\n \t\telse {\n \t\t\tfprintf(stderr, \"updating '%s'\", ref->name);\n@@ -300,6 +301,27 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)\n \t\t\tfprintf(stderr, \"\\n  from %s\\n  to   %s\\n\",\n \t\t\t\told_hex, new_hex);\n \t\t}\n+\t\tif (remote) {\n+\t\t\tchar *track =\n+\t\t\t\tremote_fetch_to(remote, ref->name);\n+\t\t\tif (track) {\n+\t\t\t\tstruct ref_lock *lock;\n+\t\t\t\tfprintf(stderr, \" Also local %s\\n\", track);\n+\t\t\t\tif (will_delete_ref) {\n+\t\t\t\t\tif (delete_ref(track, NULL)) {\n+\t\t\t\t\t\terror(\"Failed to delete\");\n+\t\t\t\t\t}\n+\t\t\t\t} else {\n+\t\t\t\t\tlock = lock_any_ref_for_update(track, NULL);\n+\t\t\t\t\tif (!lock)\n+\t\t\t\t\t\terror(\"Failed to lock\");\n+\t\t\t\t\telse\n+\t\t\t\t\t\twrite_ref_sha1(lock, ref->new_sha1,\n+\t\t\t\t\t\t\t       \"update by push\");\n+\t\t\t\t}\n+\t\t\t\tfree(track);\n+\t\t\t}\n+\t\t}\n \t}\n \n \tpacket_flush(out);\n@@ -344,6 +366,8 @@ int main(int argc, char **argv)\n \tchar **heads = NULL;\n \tint fd[2], ret;\n \tpid_t pid;\n+\tchar *remote_name = NULL;\n+\tstruct remote *remote = NULL;\n \n \tsetup_git_directory();\n \tgit_config(git_default_config);\n@@ -361,6 +385,10 @@ int main(int argc, char **argv)\n \t\t\t\treceivepack = arg + 7;\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!prefixcmp(arg, \"--remote=\")) {\n+\t\t\t\tremote_name = arg + 9;\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--all\")) {\n \t\t\t\tsend_all = 1;\n \t\t\t\tcontinue;\n@@ -393,10 +421,18 @@ int main(int argc, char **argv)\n \t\tusage(send_pack_usage);\n \tverify_remote_names(nr_heads, heads);\n \n+\tif (remote_name) {\n+\t\tremote = remote_get(remote_name);\n+\t\tif (!remote_has_uri(remote, dest)) {\n+\t\t\tdie(\"Destination %s is not a uri for %s\",\n+\t\t\t    dest, remote_name);\n+\t\t}\n+\t}\n+\n \tpid = git_connect(fd, dest, receivepack);\n \tif (pid < 0)\n \t\treturn 1;\n-\tret = send_pack(fd[0], fd[1], nr_heads, heads);\n+\tret = send_pack(fd[0], fd[1], remote, nr_heads, heads);\n \tclose(fd[0]);\n \tclose(fd[1]);\n \tret |= finish_connect(pid);\n-- \n1.5.1.2.255.g6ead4-dirty\n"},{"id":"40688","messageId":"7vtzuzg26l.fsf@assigned-by-dhcp.cox.net","threadId":"7884","inReplyTo":"Pine.LNX.4.64.0704281304360.28708@iabervon.org","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-04-29T05:49:38Z","receivedAt":"2007-04-29T05:49:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> With the --remote option, send-pack will look at the remote\n> configuration for the specified remote (which must match the\n> destination URL), and update the local tracking refs to match changes\n> it causes in the remote heads they track.\n>\n> The previous values of local tracking heads are ignored.\n\nI didn't actually look at the code of this patch, as I am\nrejecting the initial round of [PATCH 2/5] this depends on, but\nthis is one thing Cogito did that we don't, and I think it makes\nsort of sense.  We pretend as if we fetched back immediately\nafter we pushed without giving anybody a chance to further\nupdate the refs we updated at the remote.  I generally do not\nlike \"pretend that we did something\" when talking about reliable\noperations (and SCM _is_ all about reliable operation), and this\nbehaviour is exactly it, but I think this one is excusable.\n"},{"id":"40691","messageId":"Pine.LNX.4.64.0704290152410.28708@iabervon.org","threadId":"7884","inReplyTo":"7vtzuzg26l.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-04-29T06:01:10Z","receivedAt":"2007-04-29T06:01:10Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sat, 28 Apr 2007, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > With the --remote option, send-pack will look at the remote\n> > configuration for the specified remote (which must match the\n> > destination URL), and update the local tracking refs to match changes\n> > it causes in the remote heads they track.\n> >\n> > The previous values of local tracking heads are ignored.\n> \n> I didn't actually look at the code of this patch, as I am\n> rejecting the initial round of [PATCH 2/5] this depends on, but\n> this is one thing Cogito did that we don't, and I think it makes\n> sort of sense.  We pretend as if we fetched back immediately\n> after we pushed without giving anybody a chance to further\n> update the refs we updated at the remote.  I generally do not\n> like \"pretend that we did something\" when talking about reliable\n> operations (and SCM _is_ all about reliable operation), and this\n> behaviour is exactly it, but I think this one is excusable.\n\nI'll redo the series soon, but I wanted to respond to the commentary on \nthe general concept.\n\nWe're not pretending anything; remote has confirmed that the head that the \nref tracks has a particular new value (which we provided), so we should be \nable to update the tracking ref to that value. I don't think it's \nparticularly important that we came by this information in the course of \nan exchange that wasn't a fetch.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"40692","messageId":"20070429061006.GU5942@spearce.org","threadId":"7884","inReplyTo":"Pine.LNX.4.64.0704290152410.28708@iabervon.org","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-04-29T06:10:06Z","receivedAt":"2007-04-29T06:10:06Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> wrote:\n> We're not pretending anything; remote has confirmed that the head that the \n> ref tracks has a particular new value (which we provided), so we should be \n> able to update the tracking ref to that value. I don't think it's \n> particularly important that we came by this information in the course of \n> an exchange that wasn't a fetch.\n\ns/remote has confirmed/remote has claimed/\n\nThe only way to know the remote really did remember that\nrefs/heads/foo is now at 3c1718... is to perform some sort of\noperation against it that makes it dump its refs back.  Trying to\npush again, or trying to fetch does that.\n\nThere is also the possibility that a post-update or post-receive\nhook will actually modify the ref *after* the push is \"complete\".\nBut that's like so crazy that I really don't think anyone has a\nworkflow that does that.  They might have such a hook that creates\na new ref however, or updates a totally unrelated ref (e.g. compile\nthe code and then update a \"last-built\" ref).\n\nSo in this particular case I have to agree with Daniel, its probably\nOK to do what Cogito does and update the tracking branch after the\npush was claimed to be successful by the remote.\n\n-- \nShawn.\n"},{"id":"40693","messageId":"7vejm3g0dg.fsf@assigned-by-dhcp.cox.net","threadId":"7884","inReplyTo":"Pine.LNX.4.64.0704290152410.28708@iabervon.org","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-04-29T06:28:43Z","receivedAt":"2007-04-29T06:28:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> We're not pretending anything; remote has confirmed that the head that the \n> ref tracks has a particular new value (which we provided), so we should be \n> able to update the tracking ref to that value. I don't think it's \n> particularly important that we came by this information in the course of \n> an exchange that wasn't a fetch.\n>\n\nWe are indeed pretending.  Consider:\n\n (1) You push, and push succeeds.\n\n (2) Somebody fetches your result, works on it and pushes back;\n     this might happen in post-receive hook.\n\n (3) You fetch.  You should see somebody else's commit at the\n     tip, not what you pushed in (1).\n\nBy not fetching but instead of storing what you pushed, you are\npretending that you re-fetched so fast that you gave no chance\nto anybody to perform (2) quickly enough.\n\nBut my conclusion is that this does not matter in practice, and\nI am agreeing with what you tried to do.  That does not change\nthe fact that we are pretending.\n"},{"id":"40934","messageId":"Pine.LNX.4.64.0705022330460.28708@iabervon.org","threadId":"7884","inReplyTo":"7vejm3g0dg.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-05-03T04:04:41Z","receivedAt":"2007-05-03T04:04:41Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sat, 28 Apr 2007, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > We're not pretending anything; remote has confirmed that the head that the \n> > ref tracks has a particular new value (which we provided), so we should be \n> > able to update the tracking ref to that value. I don't think it's \n> > particularly important that we came by this information in the course of \n> > an exchange that wasn't a fetch.\n> >\n> \n> We are indeed pretending.  Consider:\n> \n>  (1) You push, and push succeeds.\n> \n>  (2) Somebody fetches your result, works on it and pushes back;\n>      this might happen in post-receive hook.\n> \n>  (3) You fetch.  You should see somebody else's commit at the\n>      tip, not what you pushed in (1).\n> \n> By not fetching but instead of storing what you pushed, you are\n> pretending that you re-fetched so fast that you gave no chance\n> to anybody to perform (2) quickly enough.\n\nBut you did effectively re-fetch instantaneously by doing an operation \nthat atomicly updates the ref and reports success. If you consider the \noperation that updates tracking refs not to be necessarily \"git-fetch\" but \nrather \"having a connection that discusses refs\", this sequence isn't any \ndifferent from (1) being a fetch instead of a push; there's always the \nchance that your interaction with the server is shortly before the ref \nvalues you update to being replaced, whether the operation you're doing is \ngetting the remote's value or setting the remote's value.\n\nEven if a post-update hook further changes the ref you push to, it had \nbetter not change it to a non-descendant of the value you pushed, since \nthere would be a race with other people fetching your value with the \npost-update hook is running and seeing history roll back. So, at worst, \nyou could have the situation where, effectively, you *always* miss out on \nthe latest thing, but it's already the case that you would *sometimes* \nmiss out on the latest thing, if the post-update hook is running more \nslowly than your next fetch.\n\nThe fact that the config option is \"fetch\" isn't really an argument that \nthe way you have to get the knowledge of the value of the ref at the \ninstant you remember locally has to be \"git-fetch\"; any way of getting \nknowledge of that value at some instant should suffice.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"40940","messageId":"7virba31wd.fsf@assigned-by-dhcp.cox.net","threadId":"7884","inReplyTo":"Pine.LNX.4.64.0705022330460.28708@iabervon.org","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-03T05:35:30Z","receivedAt":"2007-05-03T05:35:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> On Sat, 28 Apr 2007, Junio C Hamano wrote:\n>\n>> We are indeed pretending.  Consider:\n>> \n>>  (1) You push, and push succeeds.\n>> \n>>  (2) Somebody fetches your result, works on it and pushes back;\n>>      this might happen in post-receive hook.\n>> \n>>  (3) You fetch.  You should see somebody else's commit at the\n>>      tip, not what you pushed in (1).\n>> \n>> By not fetching but instead of storing what you pushed, you are\n>> pretending that you re-fetched so fast that you gave no chance\n>> to anybody to perform (2) quickly enough.\n>\n> But you did effectively re-fetch instantaneously by doing an operation \n> that atomicly updates the ref and reports success.\n\nI do not think there is much point arguing over this; I am not\nfundamentally opposed to keeping a copy of what we just pushed\nto the other side.\n\nBut I think it needs to be documented that hooks on the remote\nside could do funny things, and probably we should strongly\ndiscourage people from doing such.\n\nYou do need to take care of the case where we are _not_ tracking\nthe remote side, though (i.e. lack of colon in the fetch\nrefspecs).\n"},{"id":"40941","messageId":"Pine.LNX.4.64.0705030137520.28708@iabervon.org","threadId":"7884","inReplyTo":"7virba31wd.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-05-03T05:45:48Z","receivedAt":"2007-05-03T05:45:48Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 2 May 2007, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > On Sat, 28 Apr 2007, Junio C Hamano wrote:\n> >\n> >> We are indeed pretending.  Consider:\n> >> \n> >>  (1) You push, and push succeeds.\n> >> \n> >>  (2) Somebody fetches your result, works on it and pushes back;\n> >>      this might happen in post-receive hook.\n> >> \n> >>  (3) You fetch.  You should see somebody else's commit at the\n> >>      tip, not what you pushed in (1).\n> >> \n> >> By not fetching but instead of storing what you pushed, you are\n> >> pretending that you re-fetched so fast that you gave no chance\n> >> to anybody to perform (2) quickly enough.\n> >\n> > But you did effectively re-fetch instantaneously by doing an operation \n> > that atomicly updates the ref and reports success.\n> \n> I do not think there is much point arguing over this; I am not\n> fundamentally opposed to keeping a copy of what we just pushed\n> to the other side.\n> \n> But I think it needs to be documented that hooks on the remote\n> side could do funny things, and probably we should strongly\n> discourage people from doing such.\n\nI don't see what's any *more* odd about this situation with my change than \notherwise (and I'm afraid I'm missing something, which is why I'm still \ndiscussing it).\n\n> You do need to take care of the case where we are _not_ tracking\n> the remote side, though (i.e. lack of colon in the fetch\n> refspecs).\n\nIndeed. Is there documentation on all the possibilities for refspecs \nsomewhere all together? I could only find it for particular programs, and \ndidn't see a no-colon option permitted anywhere.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"40943","messageId":"7vejly305u.fsf@assigned-by-dhcp.cox.net","threadId":"7884","inReplyTo":"Pine.LNX.4.64.0705030137520.28708@iabervon.org","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-03T06:13:01Z","receivedAt":"2007-05-03T06:13:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> Indeed. Is there documentation on all the possibilities for refspecs \n> somewhere all together? I could only find it for particular programs, and \n> didn't see a no-colon option permitted anywhere.\n\nDocumentation/pull-fetch-param.txt which is included by various\nmanpages would be the best place to start.\n\n    <refspec>::\n            The canonical format of a <refspec> parameter is\n            `+?<src>:<dst>`; that is, an optional plus `+`, followed\n            by the source ref, followed by a colon `:`, followed by\n            the destination ref.\n    +\n    The remote ref that matches <src>\n    is fetched, and if <dst> is not empty string, the local\n    ref that matches it is fast forwarded using <src>.\n    Again, if the optional plus `+` is used, the local ref\n    is updated even if it does not result in a fast forward\n    update.\n\nHmph.  So <dst> could be empty, and in such a case there is no\ntracking.  But this does not say missing colon is allowed (but\nthat was intentionally left out as we clarify it later).  Let's\nread on.  After a few [Notes], we find this.\n\n    Some short-cut notations are also supported.\n    +\n    * `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`; \n      it requests fetching everything up to the given tag.\n    * A parameter <ref> without a colon is equivalent to\n      <ref>: when pulling/fetching, so it merges <ref> into the current\n      branch without storing the remote branch anywhere locally\n\nAhh, so a refspec that does not have a colon, and ends with a\ncolon (hence an empty <dst>) are equivalent, and does not result\nin remote tracking.\n"},{"id":"41119","messageId":"Pine.LNX.4.64.0705050115270.28708@iabervon.org","threadId":"7884","inReplyTo":"7vejly305u.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-05-05T05:21:42Z","receivedAt":"2007-05-05T05:21:42Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 2 May 2007, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > Indeed. Is there documentation on all the possibilities for refspecs \n> > somewhere all together? I could only find it for particular programs, and \n> > didn't see a no-colon option permitted anywhere.\n> \n> Documentation/pull-fetch-param.txt which is included by various\n> manpages would be the best place to start.\n> \n>     <refspec>::\n>             The canonical format of a <refspec> parameter is\n>             `+?<src>:<dst>`; that is, an optional plus `+`, followed\n>             by the source ref, followed by a colon `:`, followed by\n>             the destination ref.\n>     +\n>     The remote ref that matches <src>\n>     is fetched, and if <dst> is not empty string, the local\n>     ref that matches it is fast forwarded using <src>.\n>     Again, if the optional plus `+` is used, the local ref\n>     is updated even if it does not result in a fast forward\n>     update.\n> \n> Hmph.  So <dst> could be empty, and in such a case there is no\n> tracking.  But this does not say missing colon is allowed (but\n> that was intentionally left out as we clarify it later).  Let's\n> read on.  After a few [Notes], we find this.\n> \n>     Some short-cut notations are also supported.\n>     +\n>     * `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`; \n>       it requests fetching everything up to the given tag.\n>     * A parameter <ref> without a colon is equivalent to\n>       <ref>: when pulling/fetching, so it merges <ref> into the current\n>       branch without storing the remote branch anywhere locally\n> \n> Ahh, so a refspec that does not have a colon, and ends with a\n> colon (hence an empty <dst>) are equivalent, and does not result\n> in remote tracking.\n\nIs this actually supported in config files? At least for pulls, the \"tag \n<tag>\" notation is only available on the command line, afaict. For that \nmatter, I think that having \"<ref>:\" or \"<ref>\" in a config file fetch \nline would be really bad; these refs would always be merged into any \ncurrent head (without any remote tracking) when the remote is fetched \nfrom?\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"41120","messageId":"7vr6pvn5k0.fsf@assigned-by-dhcp.cox.net","threadId":"7884","inReplyTo":"Pine.LNX.4.64.0705050115270.28708@iabervon.org","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-05T06:33:03Z","receivedAt":"2007-05-05T06:33:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> Is this actually supported in config files? At least for pulls, the \"tag \n> <tag>\" notation is only available on the command line, afaict.\n\nThat is the only difference as far as I remember.  But you are\nright in that the set of refspecs allowed on the command line\ndoes not have to coincide with the ones in remotes file or the\nconfig (the latter two should match, though), and the latter may\nnot be documented (the intention was to match all of them so the\nquoted documentation was enough, but having \"tag <tag>\" in\nconfig does not make sense).  Documentation/config.txt could use\na bit of updates.  Hint, hint.\n\n> I think that having \"<ref>:\" or \"<ref>\" in a config file fetch \n> line would be really bad; these refs would always be merged into any \n> current head (without any remote tracking) when the remote is fetched \n> from?\n\nIt's not bad at all.  Why people are so eager to _force_\ntracking on other people, I do not understand.\n\nI had a moral equivalent of this in .git/remotes/origin (back\nthen .git/config did not exist) when I was a contributor:\n\n\t[remote \"origin\"]\n        \turl = git.kernel.org:/pub/scm/git/git.git/\n                fetch = refs/heads/master\n\nIf the user does not want to track, he does not have to.\n"},{"id":"41122","messageId":"Pine.LNX.4.64.0705050235210.28708@iabervon.org","threadId":"7884","inReplyTo":"7vr6pvn5k0.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-05-05T06:52:55Z","receivedAt":"2007-05-05T06:52:55Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Fri, 4 May 2007, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > Is this actually supported in config files? At least for pulls, the \"tag \n> > <tag>\" notation is only available on the command line, afaict.\n> \n> That is the only difference as far as I remember.  But you are\n> right in that the set of refspecs allowed on the command line\n> does not have to coincide with the ones in remotes file or the\n> config (the latter two should match, though), and the latter may\n> not be documented (the intention was to match all of them so the\n> quoted documentation was enough, but having \"tag <tag>\" in\n> config does not make sense).  Documentation/config.txt could use\n> a bit of updates.  Hint, hint.\n\nOnce I've figured out what the intended behavior is, and have a canonical \nimplementation so that it clearly does that, I'll document it. Until then, \nit's a bit tricky. :)\n\n> > I think that having \"<ref>:\" or \"<ref>\" in a config file fetch \n> > line would be really bad; these refs would always be merged into any \n> > current head (without any remote tracking) when the remote is fetched \n> > from?\n> \n> It's not bad at all.  Why people are so eager to _force_\n> tracking on other people, I do not understand.\n> \n> I had a moral equivalent of this in .git/remotes/origin (back\n> then .git/config did not exist) when I was a contributor:\n> \n> \t[remote \"origin\"]\n>         \turl = git.kernel.org:/pub/scm/git/git.git/\n>                 fetch = refs/heads/master\n> \n> If the user does not want to track, he does not have to.\n\nWouldn't it be better to to this as:\n\n[remote \"origin\"]\n\turl = git.kernel.org:/pub/scm/git/git.git/\n[branch \"master\"]\n\tremote = origin\n\tmerge = refs/heads/master\n\nIf you're not tracking, the only thing you do with remote refs is merge \nthem (after getting an anonymous temporary copy, of course), which should \nbe the \"merge\" line, not the \"fetch\" line. Furthermore, you certainly \ndon't want to merge refs/heads/master if you fetch (or pull) when you have \ntodo (or a branch derived from it) checked out.\n\nMerging without tracking is fine, in general; the \"without tracking\" was \nintentionally parenthetical. I just don't think always merging a \nparticular remote head into the current branch, regardless of what branch \nis current, is a good idea.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"41123","messageId":"7vr6pvln89.fsf@assigned-by-dhcp.cox.net","threadId":"7884","inReplyTo":"Pine.LNX.4.64.0705050235210.28708@iabervon.org","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-05T07:54:14Z","receivedAt":"2007-05-05T07:54:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> Wouldn't it be better to to this as:\n>\n> [remote \"origin\"]\n> \turl = git.kernel.org:/pub/scm/git/git.git/\n> [branch \"master\"]\n> \tremote = origin\n> \tmerge = refs/heads/master\n\nAs I am likely to pull from other people, and I happen to expect\nthe old fashioned \"git pull gfi\" without explicit refspec on the\ncommand line to get the first Pull: line from remotes file to\ntell which one to merge from, I am in favor of _not_ having that\n[branch \"master\"] stuff in my repository.\n\nremote.*.fetch is about what remote branches are fetched;\ntracking may or may not happen as a side effect.  What I do with\nthe resulting .git/FETCH_HEAD is my business and branch.*.merge\nshould _not_ be the only way to access it.\n\n> Merging without tracking is fine, in general; the \"without tracking\" was \n> intentionally parenthetical. \n\nActually, fetching with or without tracking are both valid\noptions, and it does not make much sense to say which one is\nnorm and which one is exception.\n\n> I just don't think always merging a \n> particular remote head into the current branch, regardless of what branch \n> is current, is a good idea.\n\nExactly.  That's why I do not think [branch \"master\"] for\ntoplevel maintainer usage is not very useful.\n\nThere are a few improvements we probably would want.\n\nOne is the interaction between the config \"fetch =...\" refspecs\nand the command line ones.  Currently the rule is:\n\n - If you do not say refspecs on the command line, fetch config\n   (or Pull: lines from remotes/* file) are used.\n\n - If you do have refspecs on the command line, fetch config are\n   not used (they are ignored).\n\nWhich is fine when we talk about \"git fetch\", but if you _are_\nusing remote tracking, and if you are running \"git fetch\" as an\nimplementation detail of running \"git pull\" (IOW, you said \"git\npull origin next\"), it is less than optimum.  Instead of \"only\nfetch 'next' without tracking and then merge it\", we would\ncertainly want \"fetch to track everything as usual, and then\nmerge 'next' instead of what is usually merged\".\n\nAnother thing is that which branch is merged into the current\nbranch should not be a function of the current branch, as the\ncurrent configuration mechanism suggests.  The current way maps\nthe current branch to \"which repository's which branch\".  In\naddition to that, I think it should be a function of (\"current\nbranch\", \"remote repository\") pair.  IOW, allow you to say \"If I\npull from this remote without saying which one to merge, merge\nthat branch.  If I pull from this other remote, merge that other\nbranch\".  Something like:\n\n        [branch \"master\"]\n                ; Use this when \"git pull\" did not say which remote\n                remote = origin\n\n                ; Use this when \"git pull origin\" did not say which\n                ; branch(es) to merge\n                merge = refs/heads/master\n                ; the above should be a synonym for\n\t\t; merge = refs/heads/master for origin\n\n                ; \"git pull fast-import\" while on my \"master\"\n                ; would merge 'for-junio' branch there.\n                merge = refs/heads/for-junio for fast-import\n\n                ; similarly, but use subtree strategy.\n                merge = refs/heads/for-junio with subtree for git-gui\n\n        [remote \"origin\"]\n                url = git://git.kernel.org/pub/scm/git/git.git/\n                fetch = refs/heads/*:remotes/origin/*\n        [remote \"fast-import\"]\n                url = git://repo.or.cz/git/fastimport.git/\n                fetch = refs/heads/*:remotes/gfi/*\n        [remote \"git-gui\"]\n                url = git://repo.or.cz/git-gui.git/\n                fetch = refs/heads/*:refs/remotes/git-gui/*\n"},{"id":"41152","messageId":"Pine.LNX.4.64.0705051307080.28708@iabervon.org","threadId":"7884","inReplyTo":"7vr6pvln89.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 4/5] Add --remote option to send-pack","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-05-05T17:56:58Z","receivedAt":"2007-05-05T17:56:58Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sat, 5 May 2007, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > Wouldn't it be better to to this as:\n> >\n> > [remote \"origin\"]\n> > \turl = git.kernel.org:/pub/scm/git/git.git/\n> > [branch \"master\"]\n> > \tremote = origin\n> > \tmerge = refs/heads/master\n> \n> As I am likely to pull from other people, and I happen to expect\n> the old fashioned \"git pull gfi\" without explicit refspec on the\n> command line to get the first Pull: line from remotes file to\n> tell which one to merge from, I am in favor of _not_ having that\n> [branch \"master\"] stuff in my repository.\n> \n> remote.*.fetch is about what remote branches are fetched;\n> tracking may or may not happen as a side effect.  What I do with\n> the resulting .git/FETCH_HEAD is my business and branch.*.merge\n> should _not_ be the only way to access it.\n\nAh, okay. So FETCH_HEAD gets: (1) if something is specified on the \ncommand line, that; (2) if there is a branch.*.merge, that; (3) the first \nrefspec (without a *?) listed in remote.*.fetch. Right?\n\n> There are a few improvements we probably would want.\n> \n> One is the interaction between the config \"fetch =...\" refspecs\n> and the command line ones.  Currently the rule is:\n> \n>  - If you do not say refspecs on the command line, fetch config\n>    (or Pull: lines from remotes/* file) are used.\n> \n>  - If you do have refspecs on the command line, fetch config are\n>    not used (they are ignored).\n> \n> Which is fine when we talk about \"git fetch\", but if you _are_\n> using remote tracking, and if you are running \"git fetch\" as an\n> implementation detail of running \"git pull\" (IOW, you said \"git\n> pull origin next\"), it is less than optimum.  Instead of \"only\n> fetch 'next' without tracking and then merge it\", we would\n> certainly want \"fetch to track everything as usual, and then\n> merge 'next' instead of what is usually merged\".\n\nI think that might be confusing; I'd expect that the tracking for next \nwould be updated, but the tracking for other heads wouldn't. I'm not sure \nI'd ever actually complain about origin/master being more up-to-date than \ncan be intuitively explained, but I don't think a \"git pull origin next\" \nwould make me expect origin/master to be up-to-date right after. So I'd \nsay, \"only fetch 'next'; if you track 'next' normally, update that.\"\n\nOn the other hand, I've been doing a lot of \"git diff origin all-my-work\" \nand removing hunks I don't want to send, and this makes the implicit \nassumption that origin == merge_base(origin, all-my-work), which is true \nonly because I merge origin whenever I fetch it.\n\n> Another thing is that which branch is merged into the current\n> branch should not be a function of the current branch, as the\n> current configuration mechanism suggests.  The current way maps\n> the current branch to \"which repository's which branch\".  In\n> addition to that, I think it should be a function of (\"current\n> branch\", \"remote repository\") pair.  IOW, allow you to say \"If I\n> pull from this remote without saying which one to merge, merge\n> that branch.  If I pull from this other remote, merge that other\n> branch\".  Something like:\n> \n>         [branch \"master\"]\n>                 ; Use this when \"git pull\" did not say which remote\n>                 remote = origin\n> \n>                 ; Use this when \"git pull origin\" did not say which\n>                 ; branch(es) to merge\n>                 merge = refs/heads/master\n>                 ; the above should be a synonym for\n> \t\t; merge = refs/heads/master for origin\n> \n>                 ; \"git pull fast-import\" while on my \"master\"\n>                 ; would merge 'for-junio' branch there.\n>                 merge = refs/heads/for-junio for fast-import\n> \n>                 ; similarly, but use subtree strategy.\n>                 merge = refs/heads/for-junio with subtree for git-gui\n> \n>         [remote \"origin\"]\n>                 url = git://git.kernel.org/pub/scm/git/git.git/\n>                 fetch = refs/heads/*:remotes/origin/*\n>         [remote \"fast-import\"]\n>                 url = git://repo.or.cz/git/fastimport.git/\n>                 fetch = refs/heads/*:remotes/gfi/*\n>         [remote \"git-gui\"]\n>                 url = git://repo.or.cz/git-gui.git/\n>                 fetch = refs/heads/*:refs/remotes/git-gui/*\n\nI think this is a good feature, but maybe the syntax should be:\n\n merge = fast-import refs/heads/for-junio\n\nsince the remote name is user-chosen, arbitrary, and has to be typed on \nthe command line, and therefore people won't put in spaces, and \"git fetch \nfast-import refs/heads/for-junio\" is what you'd type on the command line \nthat this abbreviates, so it's intuitive.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"41356","messageId":"AF0367BA48C55940A43CCF08DF35553C012AA326@az33exm24.fsl.freescale.net","threadId":"7884","inReplyTo":"7vr6pvln89.fsf@assigned-by-dhcp.cox.net","subject":"RE: [PATCH 4/5] Add --remote option to send-pack","fromName":"Loeliger Jon-LOELIGER","fromEmail":"jdl@freescale.com","sentAt":"2007-05-07T20:08:19Z","receivedAt":"2007-05-07T20:08:19Z","isPatch":true,"sender":{"key":"jdl@jdl.com","avatar":"https://gravatar.com/avatar/75ce9a10b151acd2c28ec4ab2136dba7b2ff1634530bd04b155981a749d08a64?d=mp&s=160"},"body":"\n> Another thing is that which branch is merged into the current\n> branch should not be a function of the current branch, as the\n> current configuration mechanism suggests.  The current way maps\n> the current branch to \"which repository's which branch\".  In\n> addition to that, I think it should be a function of (\"current\n> branch\", \"remote repository\") pair.  IOW, allow you to say \"If I\n> pull from this remote without saying which one to merge, merge\n> that branch.  If I pull from this other remote, merge that other\n> branch\".  Something like:\n> \n>         [branch \"master\"]\n>                 ; Use this when \"git pull\" did not say which remote\n>                 remote = origin\n> \n>                 ; Use this when \"git pull origin\" did not say which\n>                 ; branch(es) to merge\n>                 merge = refs/heads/master\n>                 ; the above should be a synonym for\n> \t\t; merge = refs/heads/master for origin\n> \n>                 ; \"git pull fast-import\" while on my \"master\"\n>                 ; would merge 'for-junio' branch there.\n>                 merge = refs/heads/for-junio for fast-import\n> \n>                 ; similarly, but use subtree strategy.\n>                 merge = refs/heads/for-junio with subtree for git-gui\n> \n>         [remote \"origin\"]\n>                 url = git://git.kernel.org/pub/scm/git/git.git/\n>                 fetch = refs/heads/*:remotes/origin/*\n>         [remote \"fast-import\"]\n>                 url = git://repo.or.cz/git/fastimport.git/\n>                 fetch = refs/heads/*:remotes/gfi/*\n>         [remote \"git-gui\"]\n>                 url = git://repo.or.cz/git-gui.git/\n>                 fetch = refs/heads/*:refs/remotes/git-gui/*\n>\n\nYes, please!\n\nJdl\n"}]}