{"thread":{"id":"12174","subject":"[PATCH] branch: optionally setup branch.*.merge from upstream local branches","startedAt":"2008-02-18T12:04:08Z","lastAt":"2008-02-18T13:24:54Z","messageCount":4,"participants":["Jay Soffian","Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"69128","messageId":"1203336248-9308-1-git-send-email-jaysoffian@gmail.com","threadId":"12174","inReplyTo":null,"subject":"[PATCH] branch: optionally setup branch.*.merge from upstream local branches","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-18T12:04:08Z","receivedAt":"2008-02-18T12:04:08Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"git branch / git checkout -b now honor --track when the upstream branch\nis local. Previously --track was silently ignored for local upstream\nbranches.\n\nThe configuration setting branch.autosetupmerge can now be set to\n\"always\" which is equivalent to using --track. Setting\nbranch.autosetupmerge to boolean true will retains the former behavior\nof only setting up branch.*.merge for remote upstream branches.\n\nSigned-off-by: Jay Soffian <jaysoffian@gmail.com>\n---\nOn Feb 16, 2008 6:45 AM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n> \n> On Fri, 15 Feb 2008, Junio C Hamano wrote:\n> \n> > This area was last cleaned up in 6f084a5 (branch --track: code cleanup\n> > and saner handling of local branches).  I do not know if the original\n> > intention of the code was to allow a hack like this to work, or it is\n> > just an unintended accident that it happens to work.  Dscho, any ideas?\n> \n> AFAIR the problem was that you were (rightfully) annoyed when you were\n> setting up your local branches, and all of a sudden, they were set up with\n> loads of tracking information, cluttering your config.\n> \n> Basically, that is the reason why we disallowed tracking information to be\n> set up for local branching.\n\nHopefully this is an acceptable compromise? Junio suggested making this \nimplicit:\n\n   [remote \".\"]\n      fetch = refs/*:refs/*\n\nBut I thought that might affect other areas, and I don't think this is too bad.\n\n branch.c           |   12 ++++++++++--\n branch.h           |    8 +++++++-\n builtin-branch.c   |   11 ++++++++---\n builtin-checkout.c |   15 ++++++++++-----\n 4 files changed, 35 insertions(+), 11 deletions(-)\n\ndiff --git a/branch.c b/branch.c\nindex 1fc8788..24e98dd 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -71,7 +71,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)\n \n void create_branch(const char *head,\n \t\t   const char *name, const char *start_name,\n-\t\t   int force, int reflog, int track)\n+\t\t   int force, int reflog, enum branch_track track)\n {\n \tstruct ref_lock *lock;\n \tstruct commit *commit;\n@@ -130,7 +130,15 @@ void create_branch(const char *head,\n \t   automatically merges from there.  So far, this is only done for\n \t   remotes registered via .git/config.  */\n \tif (real_ref && track)\n-\t\tsetup_tracking(name, real_ref);\n+\t\tif (setup_tracking(name, real_ref) == 1 && track == BRANCH_TRACK_ALWAYS) {\n+\t\t\tchar key[1024];\n+\t\t\tsprintf(key, \"branch.%s.remote\", name);\n+\t\t\tgit_config_set(key, \".\");\n+\t\t\tsprintf(key, \"branch.%s.merge\", name);\n+\t\t\tgit_config_set(key, real_ref);\n+\t\t\tprintf(\"Branch %s set up with upstream branch %s.\\n\",\n+\t\t\t       name, real_ref);\n+\t\t}\n \n \tif (write_ref_sha1(lock, sha1, msg) < 0)\n \t\tdie(\"Failed to write ref: %s.\", strerror(errno));\ndiff --git a/branch.h b/branch.h\nindex d30abe0..771d6ce 100644\n--- a/branch.h\n+++ b/branch.h\n@@ -1,6 +1,12 @@\n #ifndef BRANCH_H\n #define BRANCH_H\n \n+enum branch_track {\n+\tBRANCH_TRACK_FALSE = 0,\n+\tBRANCH_TRACK_TRUE = 1,\n+\tBRANCH_TRACK_ALWAYS = 2,\n+};\n+\n /* Functions for acting on the information about branches. */\n \n /*\n@@ -13,7 +19,7 @@\n  * branch for (if any).\n  */\n void create_branch(const char *head, const char *name, const char *start_name,\n-\t\t   int force, int reflog, int track);\n+\t\t   int force, int reflog, enum branch_track track);\n \n /*\n  * Remove information about the state of working on the current\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex 5094e0d..231bff4 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -30,7 +30,7 @@ static const char * const builtin_branch_usage[] = {\n static const char *head;\n static unsigned char head_sha1[20];\n \n-static int branch_track = 1;\n+static enum branch_track branch_track = BRANCH_TRACK_FALSE;\n \n static int branch_use_color;\n static char branch_colors[][COLOR_MAXLEN] = {\n@@ -77,6 +77,10 @@ static int git_branch_config(const char *var, const char *value)\n \t\treturn 0;\n \t}\n \tif (!strcmp(var, \"branch.autosetupmerge\")) {\n+\t\tif (value && !strcasecmp(value, \"always\")) {\n+\t\t\tbranch_track = BRANCH_TRACK_ALWAYS;\n+\t\t\treturn 0;\n+\t\t}\n \t\tbranch_track = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n@@ -420,14 +424,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n {\n \tint delete = 0, rename = 0, force_create = 0;\n \tint verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;\n-\tint reflog = 0, track;\n+\tint reflog = 0;\n+\tenum branch_track track;\n \tint kinds = REF_LOCAL_BRANCH;\n \tstruct commit_list *with_commit = NULL;\n \n \tstruct option options[] = {\n \t\tOPT_GROUP(\"Generic options\"),\n \t\tOPT__VERBOSE(&verbose),\n-\t\tOPT_BOOLEAN( 0 , \"track\",  &track, \"set up tracking mode (see git-pull(1))\"),\n+\t\tOPT_SET_INT( 0 , \"track\",  &track, \"set up tracking mode (see git-pull(1))\", BRANCH_TRACK_ALWAYS),\n \t\tOPT_BOOLEAN( 0 , \"color\",  &branch_use_color, \"use colored output\"),\n \t\tOPT_SET_INT('r', NULL,     &kinds, \"act on remote-tracking branches\",\n \t\t\tREF_REMOTE_BRANCH),\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 0d19835..d77ee9c 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -186,7 +186,7 @@ struct checkout_opts {\n \n \tchar *new_branch;\n \tint new_branch_log;\n-\tint track;\n+\tenum branch_track track;\n };\n \n struct branch_info {\n@@ -521,13 +521,18 @@ static int switch_branches(struct checkout_opts *opts,\n \treturn post_checkout_hook(old.commit, new->commit, 1);\n }\n \n-static int branch_track = 0;\n+static enum branch_track branch_track = BRANCH_TRACK_FALSE;\n \n static int git_checkout_config(const char *var, const char *value)\n {\n-\tif (!strcmp(var, \"branch.autosetupmerge\"))\n+\tif (!strcmp(var, \"branch.autosetupmerge\")) {\n+\t\tif (value && !strcasecmp(value, \"always\")) {\n+\t\t\tbranch_track = BRANCH_TRACK_ALWAYS;\n+\t\t\treturn 0;\n+\t\t}\n \t\tbranch_track = git_config_bool(var, value);\n-\n+\t\treturn 0;\n+\t}\n \treturn git_default_config(var, value);\n }\n \n@@ -542,7 +547,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\tOPT__QUIET(&opts.quiet),\n \t\tOPT_STRING('b', NULL, &opts.new_branch, \"new branch\", \"branch\"),\n \t\tOPT_BOOLEAN('l', NULL, &opts.new_branch_log, \"log for new branch\"),\n-\t\tOPT_BOOLEAN( 0 , \"track\", &opts.track, \"track\"),\n+\t\tOPT_SET_INT( 0 , \"track\",  &opts.track, \"track\", BRANCH_TRACK_ALWAYS),\n \t\tOPT_BOOLEAN('f', NULL, &opts.force, \"force\"),\n \t\tOPT_BOOLEAN('m', NULL, &opts.merge, \"merge\"),\n \t\tOPT_END(),\n-- \n1.5.4.2.183.g9fe5b\n"},{"id":"69129","messageId":"alpine.LSU.1.00.0802181209210.30505@racer.site","threadId":"12174","inReplyTo":"1203336248-9308-1-git-send-email-jaysoffian@gmail.com","subject":"Re: [PATCH] branch: optionally setup branch.*.merge from upstream local branches","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-02-18T12:14:25Z","receivedAt":"2008-02-18T12:14:25Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 18 Feb 2008, Jay Soffian wrote:\n\n> diff --git a/branch.h b/branch.h\n> index d30abe0..771d6ce 100644\n> --- a/branch.h\n> +++ b/branch.h\n> @@ -1,6 +1,12 @@\n>  #ifndef BRANCH_H\n>  #define BRANCH_H\n>  \n> +enum branch_track {\n> +\tBRANCH_TRACK_FALSE = 0,\n> +\tBRANCH_TRACK_TRUE = 1,\n\nBRANCH_TRACK_REMOTES would be a better name here.  And you do not need the \n\"= 1\" and \"= 2\".\n\n> +\tBRANCH_TRACK_ALWAYS = 2,\n> +};\n> +\n>  /* Functions for acting on the information about branches. */\n>  \n>  /*\n> diff --git a/builtin-branch.c b/builtin-branch.c\n> index 5094e0d..231bff4 100644\n> --- a/builtin-branch.c\n> +++ b/builtin-branch.c\n> @@ -30,7 +30,7 @@ static const char * const builtin_branch_usage[] = {\n>  static const char *head;\n>  static unsigned char head_sha1[20];\n>  \n> -static int branch_track = 1;\n> +static enum branch_track branch_track = BRANCH_TRACK_FALSE;\n\nThat is a clear regression.\n\n> @@ -77,6 +77,10 @@ static int git_branch_config(const char *var, const char *value)\n>  \t\treturn 0;\n>  \t}\n>  \tif (!strcmp(var, \"branch.autosetupmerge\")) {\n> +\t\tif (value && !strcasecmp(value, \"always\")) {\n> +\t\t\tbranch_track = BRANCH_TRACK_ALWAYS;\n> +\t\t\treturn 0;\n> +\t\t}\n>  \t\tbranch_track = git_config_bool(var, value);\n>  \t\treturn 0;\n>  \t}\n\nYou have this in builtin-branch.c and builtin-checkout.c.  Duplicated \ncode.  IMHO it is time to move this into the git_default_config() function \n(with \"branch_track\" being renamed to \"git_branch_track\", and moved to \nenvironment.c).\n\nPersonally, I have no problem with typing \"git merge <branch>\" in your \nworkflow.  I would even avoid saying \"git pull\" for obviously-local \nbranches, because I would have forgotten which branch it tracked \noriginally.\n\nBut hey, if you really want to... ;-)\n\nCiao,\nDscho\n"},{"id":"69132","messageId":"76718490802180440o3041b1ffh4764199e2aeaa52b@mail.gmail.com","threadId":"12174","inReplyTo":"alpine.LSU.1.00.0802181209210.30505@racer.site","subject":"Re: [PATCH] branch: optionally setup branch.*.merge from upstream local branches","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-18T12:40:45Z","receivedAt":"2008-02-18T12:40:45Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Feb 18, 2008 7:14 AM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n\n> On Mon, 18 Feb 2008, Jay Soffian wrote:\n>\n> > +enum branch_track {\n> > +     BRANCH_TRACK_FALSE = 0,\n> > +     BRANCH_TRACK_TRUE = 1,\n>\n> BRANCH_TRACK_REMOTES would be a better name here.  And you do not need the\n> \"= 1\" and \"= 2\".\n\nI was just following along. Plenty of enum examples in the current code\ndo this. Am I missing something subtle about when assigning explicit\nvalues should be done?\n\n> >\n> > -static int branch_track = 1;\n> > +static enum branch_track branch_track = BRANCH_TRACK_FALSE;\n>\n> That is a clear regression.\n\nPerhaps. It's consistent with builtin-checkout.c though (which was\ninitializing it to 0). Who to believe?\n\n> > @@ -77,6 +77,10 @@ static int git_branch_config(const char *var, const char *value)\n> >               return 0;\n> >       }\n> >       if (!strcmp(var, \"branch.autosetupmerge\")) {\n> > +             if (value && !strcasecmp(value, \"always\")) {\n> > +                     branch_track = BRANCH_TRACK_ALWAYS;\n> > +                     return 0;\n> > +             }\n> >               branch_track = git_config_bool(var, value);\n> >               return 0;\n> >       }\n>\n> You have this in builtin-branch.c and builtin-checkout.c.  Duplicated\n> code.  IMHO it is time to move this into the git_default_config() function\n> (with \"branch_track\" being renamed to \"git_branch_track\", and moved to\n> environment.c).\n\nMkay, builtin-checkout.c author didn't do it, so...\n\n> Personally, I have no problem with typing \"git merge <branch>\" in your\n> workflow.  I would even avoid saying \"git pull\" for obviously-local\n> branches, because I would have forgotten which branch it tracked\n> originally.\n\nUm, well, apply this patch, set branch.autosetupmerge=always and then\nbranch.*.merge will tell you which branch it tracked originally. :-)\n\nAside, then how do you figure out the upstream branch is if you've\nforgotten?\n\nj.\n"},{"id":"69139","messageId":"alpine.LSU.1.00.0802181320200.30505@racer.site","threadId":"12174","inReplyTo":"76718490802180440o3041b1ffh4764199e2aeaa52b@mail.gmail.com","subject":"Re: [PATCH] branch: optionally setup branch.*.merge from upstream local branches","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-02-18T13:24:54Z","receivedAt":"2008-02-18T13:24:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 18 Feb 2008, Jay Soffian wrote:\n\n> On Feb 18, 2008 7:14 AM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> \n> > On Mon, 18 Feb 2008, Jay Soffian wrote:\n> >\n> > > -static int branch_track = 1;\n> > > +static enum branch_track branch_track = BRANCH_TRACK_FALSE;\n> >\n> > That is a clear regression.\n> \n> Perhaps. It's consistent with builtin-checkout.c though (which was \n> initializing it to 0). Who to believe?\n\nWell, in the way _you_ implemented it, it is a clear regression, since \n_your_ patch changes the 1 to a 0.\n\n> > Personally, I have no problem with typing \"git merge <branch>\" in your \n> > workflow.  I would even avoid saying \"git pull\" for obviously-local \n> > branches, because I would have forgotten which branch it tracked \n> > originally.\n> \n> Um, well, apply this patch, set branch.autosetupmerge=always and then \n> branch.*.merge will tell you which branch it tracked originally. :-)\n\nThat's what I meant.  Rather than _looking it up_, and then saying \"git \npull\", I'd do \"git merge <branch>\" _directly_.  One command.  Not two.\n\n> Aside, then how do you figure out the upstream branch is if you've \n> forgotten?\n\nWell, that's easy.  I would look at the output of \"git show-branch --all\".\n\nBut then, I usually do not care too much which branch I branched off, but \nwhich branch to merge with/rebase on.\n\nCiao,\nDscho\n"}]}