{"thread":{"id":"22233","subject":"[PATCH] Add push --set-upstream","startedAt":"2010-01-15T16:36:47Z","lastAt":"2010-01-15T22:08:00Z","messageCount":9,"participants":["Ilari Liusvaara","Matthieu Moy","Johannes Schindelin","Jeff King","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"131732","messageId":"1263573407-13642-1-git-send-email-ilari.liusvaara@elisanet.fi","threadId":"22233","inReplyTo":null,"subject":"[PATCH] Add push --set-upstream","fromName":"Ilari Liusvaara","fromEmail":"ilari.liusvaara@elisanet.fi","sentAt":"2010-01-15T16:36:47Z","receivedAt":"2010-01-15T16:36:47Z","isPatch":true,"sender":{"key":"ilari.liusvaara@elisanet.fi","avatar":null},"body":"Frequent complaint is lack of easy way to set up upstream (tracking)\nreferences for git pull to work as part of push command. So add switch\n--set-upstream (-u) to do just that.\n\nSigned-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>\n---\nThis is built on top of master.\n\n Documentation/git-push.txt |    8 +++++++-\n builtin-push.c             |    1 +\n transport.c                |   35 +++++++++++++++++++++++++++++++++++\n transport.h                |    1 +\n 4 files changed, 44 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\nindex e3eb1e8..6c68978 100644\n--- a/Documentation/git-push.txt\n+++ b/Documentation/git-push.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n --------\n [verse]\n 'git push' [--all | --mirror | --tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]\n-\t   [--repo=<repository>] [-f | --force] [-v | --verbose]\n+\t   [--repo=<repository>] [-f | --force] [-v | --verbose] [-u | --set-upstream]\n \t   [<repository> <refspec>...]\n \n DESCRIPTION\n@@ -122,6 +122,12 @@ nor in any Push line of the corresponding remotes file---see below).\n \tthe name \"origin\" is used. For this latter case, this option\n \tcan be used to override the name \"origin\". In other words,\n \tthe difference between these two commands\n+\n+-u::\n+--set-upstream::\n+\tFor every branch that is up to date or successfully pushed, add\n+\tupstream (tracking) reference for argument-less git pull.\n+\n +\n --------------------------\n git push public         #1\ndiff --git a/builtin-push.c b/builtin-push.c\nindex 28a26e7..75ddaf4 100644\n--- a/builtin-push.c\n+++ b/builtin-push.c\n@@ -218,6 +218,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOLEAN( 0 , \"thin\", &thin, \"use thin pack\"),\n \t\tOPT_STRING( 0 , \"receive-pack\", &receivepack, \"receive-pack\", \"receive pack program\"),\n \t\tOPT_STRING( 0 , \"exec\", &receivepack, \"receive-pack\", \"receive pack program\"),\n+\t\tOPT_BIT('u', \"set-upstream\", &flags, \"Set upstream for git pull\", TRANSPORT_PUSH_SET_UPSTREAM),\n \t\tOPT_END()\n \t};\n \ndiff --git a/transport.c b/transport.c\nindex b5332c0..956d2ed 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -8,6 +8,7 @@\n #include \"bundle.h\"\n #include \"dir.h\"\n #include \"refs.h\"\n+#include \"branch.h\"\n \n /* rsync support */\n \n@@ -135,6 +136,33 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)\n \t}\n }\n \n+static void set_upstreams(struct transport *trans, struct ref *refs)\n+{\n+\tstruct ref *i;\n+\tfor (i = refs; i; i = i->next) {\n+\t\t/*\n+\t\t * Check suitability for tracking. Must be successful /\n+\t\t * alreay up-to-date ref create/modify (not delete) and\n+\t\t * both sides must be local branches.\n+\t\t */\n+\t\tif (i->status != REF_STATUS_OK &&\n+\t\t\ti->status != REF_STATUS_UPTODATE)\n+\t\t\tcontinue;\n+\t\tif (!i->peer_ref)\n+\t\t\tcontinue;\n+\t\tif (!i->new_sha1 || is_null_sha1(i->new_sha1))\n+\t\t\tcontinue;\n+\t\tif (prefixcmp(i->peer_ref->name, \"refs/heads/\"))\n+\t\t\tcontinue;\n+\t\tif (prefixcmp(i->name, \"refs/heads/\"))\n+\t\t\tcontinue;\n+\n+\t\tinstall_branch_config(BRANCH_CONFIG_VERBOSE,\n+\t\t\ti->peer_ref->name + 11, trans->remote->name,\n+\t\t\ti->name);\n+\t}\n+}\n+\n static const char *rsync_url(const char *url)\n {\n \treturn prefixcmp(url, \"rsync://\") ? skip_prefix(url, \"rsync:\") : url;\n@@ -974,6 +1002,10 @@ int transport_push(struct transport *transport,\n \tverify_remote_names(refspec_nr, refspec);\n \n \tif (transport->push) {\n+\t\t/* Maybe FIXME. But no important transport uses this case. */\n+\t\tif (flags & TRANSPORT_PUSH_SET_UPSTREAM)\n+\t\t\tdie(\"This transport does not support using --set-upstream\");\n+\n \t\treturn transport->push(transport, refspec_nr, refspec, flags);\n \t} else if (transport->push_refs) {\n \t\tstruct ref *remote_refs =\n@@ -1002,6 +1034,9 @@ int transport_push(struct transport *transport,\n \t\t\t\t\tverbose | porcelain, porcelain,\n \t\t\t\t\tnonfastforward);\n \n+\t\tif (flags & TRANSPORT_PUSH_SET_UPSTREAM)\n+\t\t\tset_upstreams(transport, remote_refs);\n+\n \t\tif (!(flags & TRANSPORT_PUSH_DRY_RUN)) {\n \t\t\tstruct ref *ref;\n \t\t\tfor (ref = remote_refs; ref; ref = ref->next)\ndiff --git a/transport.h b/transport.h\nindex 97ba251..c4314dd 100644\n--- a/transport.h\n+++ b/transport.h\n@@ -91,6 +91,7 @@ struct transport {\n #define TRANSPORT_PUSH_VERBOSE 16\n #define TRANSPORT_PUSH_PORCELAIN 32\n #define TRANSPORT_PUSH_QUIET 64\n+#define TRANSPORT_PUSH_SET_UPSTREAM 128\n \n /* Returns a transport suitable for the url */\n struct transport *transport_get(struct remote *, const char *);\n-- \n1.6.6.102.gd6f8f.dirty\n"},{"id":"131734","messageId":"vpqy6jzuwpv.fsf@bauges.imag.fr","threadId":"22233","inReplyTo":"1263573407-13642-1-git-send-email-ilari.liusvaara@elisanet.fi","subject":"Re: [PATCH] Add push --set-upstream","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2010-01-15T17:03:24Z","receivedAt":"2010-01-15T17:03:24Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Ilari Liusvaara <ilari.liusvaara@elisanet.fi> writes:\n\n> +\n> +-u::\n> +--set-upstream::\n> +\tFor every branch that is up to date or successfully pushed, add\n> +\tupstream (tracking) reference for argument-less git pull.\n\nNot just argument-less git pull. git status is also impacted for\nexample. Actually, we already have documentation for it in git-branch\n(--track option), and git-config (branch.<name>.merge configuration\nvariable), so you should add a pointer to one of them.\n\nHow about\n\n--set-upstream::\n\tFor every branch that is up to date or successfully pushed, add\n\tupstream (tracking) reference, used by argument-less\n\tlinkgit:git-pull[1] and other commands. For more information,\n\tsee 'branch.<name>.merge' in linkgit:git-config[1].\n\n?\n\n> +\t\tOPT_BIT('u', \"set-upstream\", &flags, \"Set upstream for git pull\", TRANSPORT_PUSH_SET_UPSTREAM),\n\nI'd be in favor of --track for the option name. Not that it's the best\nname ever, but this is really doing the same job as branch --track and\ncheckout --track, so it should have the same name.\n\nOr the --track option of branch and checkout should be renamed as\n--set-upstream, but that seems a lot of trouble for little benefit.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"131735","messageId":"alpine.DEB.1.00.1001151811270.3106@intel-tinevez-2-302","threadId":"22233","inReplyTo":"vpqy6jzuwpv.fsf@bauges.imag.fr","subject":"Re: [PATCH] Add push --set-upstream","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-15T17:12:41Z","receivedAt":"2010-01-15T17:12:41Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 15 Jan 2010, Matthieu Moy wrote:\n\n> Ilari Liusvaara <ilari.liusvaara@elisanet.fi> writes:\n> \n> > +\t\tOPT_BIT('u', \"set-upstream\", &flags, \"Set upstream for git pull\", TRANSPORT_PUSH_SET_UPSTREAM),\n> \n> I'd be in favor of --track for the option name. Not that it's the best\n> name ever, but this is really doing the same job as branch --track and\n> checkout --track, so it should have the same name.\n> \n> Or the --track option of branch and checkout should be renamed as\n> --set-upstream, but that seems a lot of trouble for little benefit.\n\nJunio already complained that it is a bad name, basically because it is \nambiguous.  If you are really pushing for --track, you will have to think \nof a compelling reasoning.\n\nCiao,\nDscho\n\nP.S.: FWIW I think --set-upstream is really a good name.\n"},{"id":"131736","messageId":"20100115171745.GB2115@coredump.intra.peff.net","threadId":"22233","inReplyTo":"1263573407-13642-1-git-send-email-ilari.liusvaara@elisanet.fi","subject":"Re: [PATCH] Add push --set-upstream","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-01-15T17:17:45Z","receivedAt":"2010-01-15T17:17:45Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jan 15, 2010 at 06:36:47PM +0200, Ilari Liusvaara wrote:\n\n> Frequent complaint is lack of easy way to set up upstream (tracking)\n> references for git pull to work as part of push command. So add switch\n> --set-upstream (-u) to do just that.\n\nHuzzah, finally this feature is done right. I even like the name.\n\n>  Documentation/git-push.txt |    8 +++++++-\n>  builtin-push.c             |    1 +\n>  transport.c                |   35 +++++++++++++++++++++++++++++++++++\n>  transport.h                |    1 +\n>  4 files changed, 44 insertions(+), 1 deletions(-)\n\nNo tests. But since in writing this you have crossed an item off of my\nlong-term todo, I feel obliged to help out by providing some. :)\n\nThe patch below is squash-able, but note that the final test, \"git push\n-u HEAD\" is marked as broken. We should probably support that. I suspect\nis is an issue of dereferencing symrefs before doing the\nprefixcmp(\"refs/heads/\", ...) but I haven't checked yet.\n\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nnew file mode 100755\nindex 0000000..e977553\n--- /dev/null\n+++ b/t/t5523-push-upstream.sh\n@@ -0,0 +1,48 @@\n+#!/bin/sh\n+\n+test_description='push with --set-upstream'\n+. ./test-lib.sh\n+\n+test_expect_success 'setup bare parent' '\n+\tgit init --bare parent &&\n+\tgit remote add upstream parent\n+'\n+\n+test_expect_success 'setup local commit' '\n+\techo content >file &&\n+\tgit add file &&\n+\tgit commit -m one\n+'\n+\n+check_config() {\n+\t(echo $2; echo $3) >expect.$1\n+\t(git config branch.$1.remote\n+\t git config branch.$1.merge) >actual.$1\n+\ttest_cmp expect.$1 actual.$1\n+}\n+\n+test_expect_success 'push -u master:master' '\n+\tgit push -u upstream master:master &&\n+\tcheck_config master upstream refs/heads/master\n+'\n+\n+test_expect_success 'push -u master:other' '\n+\tgit push -u upstream master:other &&\n+\tcheck_config master upstream refs/heads/other\n+'\n+\n+test_expect_success 'push -u --all' '\n+\tgit branch all1 &&\n+\tgit branch all2 &&\n+\tgit push -u --all &&\n+\tcheck_config all1 upstream refs/heads/all1 &&\n+\tcheck_config all2 upstream refs/heads/all2\n+'\n+\n+test_expect_failure 'push -u HEAD' '\n+\tgit checkout -b headbranch &&\n+\tgit push -u upstream HEAD &&\n+\tcheck_config headbranch upstream refs/heads/headbranch\n+'\n+\n+test_done\n"},{"id":"131738","messageId":"20100115174220.GA15821@coredump.intra.peff.net","threadId":"22233","inReplyTo":"20100115171745.GB2115@coredump.intra.peff.net","subject":"Re: [PATCH] Add push --set-upstream","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-01-15T17:42:20Z","receivedAt":"2010-01-15T17:42:20Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jan 15, 2010 at 12:17:45PM -0500, Jeff King wrote:\n\n> The patch below is squash-able, but note that the final test, \"git push\n> -u HEAD\" is marked as broken. We should probably support that. I suspect\n> is is an issue of dereferencing symrefs before doing the\n> prefixcmp(\"refs/heads/\", ...) but I haven't checked yet.\n\nThe patch below fixes it, but I am not 100% happy with it. Calling\nresolve_ref means we actually bother to look up the ref again, which is\nwasted effort. The ref struct has a \"symref\" field which should contain\nthis information, but for some reason it is not recorded. So we can\nprobably do better by simply recording the information properly when we\nresolve the ref in the first place.\n\nUnfortunately, I don't have time to look at it anymore right now, so it\nwill have to wait.\n\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex e977553..d43473f 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -39,7 +39,7 @@ test_expect_success 'push -u --all' '\n \tcheck_config all2 upstream refs/heads/all2\n '\n \n-test_expect_failure 'push -u HEAD' '\n+test_expect_success 'push -u HEAD' '\n \tgit checkout -b headbranch &&\n \tgit push -u upstream HEAD &&\n \tcheck_config headbranch upstream refs/heads/headbranch\ndiff --git a/transport.c b/transport.c\nindex 956d2ed..01ff364 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -140,6 +140,7 @@ static void set_upstreams(struct transport *trans, struct ref *refs)\n {\n \tstruct ref *i;\n \tfor (i = refs; i; i = i->next) {\n+\t\tconst char *branch;\n \t\t/*\n \t\t * Check suitability for tracking. Must be successful /\n \t\t * alreay up-to-date ref create/modify (not delete) and\n@@ -152,14 +153,20 @@ static void set_upstreams(struct transport *trans, struct ref *refs)\n \t\t\tcontinue;\n \t\tif (!i->new_sha1 || is_null_sha1(i->new_sha1))\n \t\t\tcontinue;\n-\t\tif (prefixcmp(i->peer_ref->name, \"refs/heads/\"))\n-\t\t\tcontinue;\n \t\tif (prefixcmp(i->name, \"refs/heads/\"))\n \t\t\tcontinue;\n \n+\t\tif (!prefixcmp(i->peer_ref->name, \"refs/heads/\"))\n+\t\t\tbranch = i->peer_ref->name;\n+\t\telse {\n+\t\t\tunsigned char sha1[20];\n+\t\t\tbranch = resolve_ref(i->peer_ref->name, sha1, 1, NULL);\n+\t\t\tif (!branch || prefixcmp(branch, \"refs/heads/\"))\n+\t\t\t\tcontinue;\n+\t\t}\n+\n \t\tinstall_branch_config(BRANCH_CONFIG_VERBOSE,\n-\t\t\ti->peer_ref->name + 11, trans->remote->name,\n-\t\t\ti->name);\n+\t\t\tbranch + 11, trans->remote->name, i->name);\n \t}\n }\n \n"},{"id":"131747","messageId":"7vhbqnz0vl.fsf@alter.siamese.dyndns.org","threadId":"22233","inReplyTo":"1263573407-13642-1-git-send-email-ilari.liusvaara@elisanet.fi","subject":"Re: [PATCH] Add push --set-upstream","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-15T18:19:58Z","receivedAt":"2010-01-15T18:19:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Very competently done.  Will look forward to see the conclusion of the\nfollow-up discussions I haven't read but see in my mailreader.\n\nThanks.\n"},{"id":"131768","messageId":"7vvdf3ulol.fsf@alter.siamese.dyndns.org","threadId":"22233","inReplyTo":"vpqy6jzuwpv.fsf@bauges.imag.fr","subject":"Re: [PATCH] Add push --set-upstream","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-15T21:01:46Z","receivedAt":"2010-01-15T21:01:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:\n\n> Ilari Liusvaara <ilari.liusvaara@elisanet.fi> writes:\n>\n>> +\n>> +-u::\n>> +--set-upstream::\n>> +\tFor every branch that is up to date or successfully pushed, add\n>> +\tupstream (tracking) reference for argument-less git pull.\n>\n> Not just argument-less git pull. git status is also impacted for\n> example. Actually, we already have documentation for it in git-branch\n> (--track option), and git-config (branch.<name>.merge configuration\n> variable), so you should add a pointer to one of them.\n>\n> How about\n>\n> --set-upstream::\n> \tFor every branch that is up to date or successfully pushed, add\n> \tupstream (tracking) reference, used by argument-less\n> \tlinkgit:git-pull[1] and other commands. For more information,\n> \tsee 'branch.<name>.merge' in linkgit:git-config[1].\n\nYeah, if we talked only about the configuration variable it wouldn't help\nusers, but this description is reayy good.\n\n> Or the --track option of branch and checkout should be renamed as\n> --set-upstream, but that seems a lot of trouble for little benefit.\n\nIt might make sense to do so in the longer term UI clean-up, but I think\nthat is largely an independent topic.  By not introducing new places the\nconfusing --track is used, we are at least not making things worse.\n"},{"id":"131788","messageId":"20100115220658.GA14755@Knoppix","threadId":"22233","inReplyTo":"20100115171745.GB2115@coredump.intra.peff.net","subject":"Re: [PATCH] Add push --set-upstream","fromName":"Ilari Liusvaara","fromEmail":"ilari.liusvaara@elisanet.fi","sentAt":"2010-01-15T22:06:58Z","receivedAt":"2010-01-15T22:06:58Z","isPatch":true,"sender":{"key":"ilari.liusvaara@elisanet.fi","avatar":null},"body":"On Fri, Jan 15, 2010 at 12:17:45PM -0500, Jeff King wrote:\n> On Fri, Jan 15, 2010 at 06:36:47PM +0200, Ilari Liusvaara wrote:\n> \n> No tests. But since in writing this you have crossed an item off of my\n> long-term todo, I feel obliged to help out by providing some. :)\n \nSignoff for those tests? Or do they need it anyway?\n\n<Snip testscript> \n"},{"id":"131790","messageId":"20100115220800.GA25262@coredump.intra.peff.net","threadId":"22233","inReplyTo":"20100115220658.GA14755@Knoppix","subject":"Re: [PATCH] Add push --set-upstream","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-01-15T22:08:00Z","receivedAt":"2010-01-15T22:08:00Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Jan 16, 2010 at 12:06:58AM +0200, Ilari Liusvaara wrote:\n\n> On Fri, Jan 15, 2010 at 12:17:45PM -0500, Jeff King wrote:\n> > On Fri, Jan 15, 2010 at 06:36:47PM +0200, Ilari Liusvaara wrote:\n> > \n> > No tests. But since in writing this you have crossed an item off of my\n> > long-term todo, I feel obliged to help out by providing some. :)\n>  \n> Signoff for those tests? Or do they need it anyway?\n\nSorry, yes:\n\nSigned-off-by: Jeff King <peff@peff.net>\n\n-Peff\n"}]}