{"thread":{"id":"12176","subject":"[PATCH] branch: optionally setup branch.*.merge from upstream local branches","startedAt":"2008-02-18T13:24:44Z","lastAt":"2008-02-18T19:00:43Z","messageCount":3,"participants":["Jay Soffian","Johannes Schindelin","Mike Hommey"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"69140","messageId":"1203341084-18543-1-git-send-email-jaysoffian@gmail.com","threadId":"12176","inReplyTo":null,"subject":"[PATCH] branch: optionally setup branch.*.merge from upstream local branches","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-18T13:24:44Z","receivedAt":"2008-02-18T13:24:44Z","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---\nIncorporated Johannes' feedback and updated documentation as well.\n\n Documentation/config.txt       |   13 ++++++++-----\n Documentation/git-branch.txt   |   24 ++++++++++++------------\n Documentation/git-checkout.txt |   25 ++++++++++++-------------\n branch.c                       |   12 ++++++++++--\n branch.h                       |    2 +-\n builtin-branch.c               |   13 ++++---------\n builtin-checkout.c             |   13 ++++---------\n cache.h                        |    8 ++++++++\n config.c                       |    8 ++++++++\n environment.c                  |    1 +\n 10 files changed, 68 insertions(+), 51 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex fb6dae0..f15fe0a 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -378,11 +378,14 @@ apply.whitespace::\n \tas the '--whitespace' option. See linkgit:git-apply[1].\n \n branch.autosetupmerge::\n-\tTells `git-branch` and `git-checkout` to setup new branches\n-\tso that linkgit:git-pull[1] will appropriately merge from that\n-\tremote branch.  Note that even if this option is not set,\n-\tthis behavior can be chosen per-branch using the `--track`\n-\tand `--no-track` options.  This option defaults to true.\n+\tTells `git-branch` and `git-checkout` to setup `branch.*.remote`\n+\tand `branch.*.merge` for new branches so that linkgit:git-pull[1]\n+\twill appropriately merge from that upstream branch. Note that even\n+\tif this option is not set, this behavior can be chosen per-branch\n+\tusing the `--track`\tand `--no-track` options. This option defaults\n+\tto true, which will setup tracking for remote branches. Set it to\n+\t`always` to automatically setup the aforementioned options for local\n+\tupstream branches as well.\n \n branch.<name>.remote::\n \tWhen in branch <name>, it tells `git fetch` which remote to fetch.\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 7e8874a..ce2fc64 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -105,20 +105,20 @@ OPTIONS\n \tDisplay the full sha1s in output listing rather than abbreviating them.\n \n --track::\n-\tSet up configuration so that git-pull will automatically\n-\tretrieve data from the remote branch.  Use this if you always\n-\tpull from the same remote branch into the new branch, or if you\n-\tdon't want to use \"git pull <repository> <refspec>\" explicitly.\n-\tThis behavior is the default.  Set the\n-\tbranch.autosetupmerge configuration variable to false if you\n-\twant git-checkout and git-branch to always behave as if\n-\t'--no-track' were given.\n+\tSet up configuration so that git-pull will\n+\tautomatically retrieve data from the upstream branch.  Use this if\n+\tyou always pull from the same upstream branch into the new branch,\n+\tor if you don't want to use \"git pull <repository> <refspec>\"\n+\texplicitly. This behavior is the default for remote branches.\n+\tSet the branch.autosetupmerge configuration variable to false if you\n+\twant git-checkout and git-branch to always behave as if '--no-track'\n+\twere given. Set it to 'always' if you want git-checkout and git-branch\n+\tto always behave as if '--track' were given.\n \n --no-track::\n-\tWhen a branch is created off a remote branch,\n-\tset up configuration so that git-pull will not retrieve data\n-\tfrom the remote branch, ignoring the branch.autosetupmerge\n-\tconfiguration variable.\n+\tIgnore the branch.autosetupmerge configuration variable. When\n+\tusing git pull with the new branch, a <refspec> will have to be\n+\tgiven explicitly.\n \n <branchname>::\n \tThe name of the branch to create or delete.\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex b4cfa04..ad2ab51 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -48,21 +48,20 @@ OPTIONS\n \tmay restrict the characters allowed in a branch name.\n \n --track::\n-\tWhen -b is given and a branch is created off a remote branch,\n-\tset up configuration so that git-pull will automatically\n-\tretrieve data from the remote branch.  Use this if you always\n-\tpull from the same remote branch into the new branch, or if you\n-\tdon't want to use \"git pull <repository> <refspec>\" explicitly.\n-\tThis behavior is the default.  Set the\n-\tbranch.autosetupmerge configuration variable to false if you\n-\twant git-checkout and git-branch to always behave as if\n-\t'--no-track' were given.\n+\tWhen -b is given set up configuration so that git-pull will\n+\tautomatically retrieve data from the upstream branch.  Use this if\n+\tyou always pull from the same upstream branch into the new branch,\n+\tor if you don't want to use \"git pull <repository> <refspec>\"\n+\texplicitly. This behavior is the default for remote branches.\n+\tSet the branch.autosetupmerge configuration variable to false if you\n+\twant git-checkout and git-branch to always behave as if '--no-track'\n+\twere given. Set it to 'always' if you want git-checkout and git-branch\n+\tto always behave as if '--track' were given.\n \n --no-track::\n-\tWhen -b is given and a branch is created off a remote branch,\n-\tset up configuration so that git-pull will not retrieve data\n-\tfrom the remote branch, ignoring the branch.autosetupmerge\n-\tconfiguration variable.\n+\tIgnore the branch.autosetupmerge configuration variable. When\n+\tusing git pull with the new branch, a <refspec> will have to be\n+\tgiven explicitly.\n \n -l::\n \tCreate the new branch's reflog.  This activates recording of\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..9f0c2a2 100644\n--- a/branch.h\n+++ b/branch.h\n@@ -13,7 +13,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 7e99103..3b53bb7 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -30,8 +30,6 @@ 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-\n static int branch_use_color = -1;\n static char branch_colors[][COLOR_MAXLEN] = {\n \t\"\\033[m\",\t/* reset */\n@@ -76,10 +74,6 @@ static int git_branch_config(const char *var, const char *value)\n \t\tcolor_parse(value, var, branch_colors[slot]);\n \t\treturn 0;\n \t}\n-\tif (!strcmp(var, \"branch.autosetupmerge\")) {\n-\t\tbranch_track = git_config_bool(var, value);\n-\t\treturn 0;\n-\t}\n \treturn git_color_default_config(var, value);\n }\n \n@@ -420,14 +414,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),\n@@ -458,7 +453,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tif (branch_use_color == -1)\n \t\tbranch_use_color = git_use_color_default;\n \n-\ttrack = branch_track;\n+\ttrack = git_branch_track;\n \targc = parse_options(argc, argv, options, builtin_branch_usage, 0);\n \tif (!!delete + !!rename + !!force_create > 1)\n \t\tusage_with_options(builtin_branch_usage, options);\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 0d19835..cf26e10 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,8 @@ 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-\n static int git_checkout_config(const char *var, const char *value)\n {\n-\tif (!strcmp(var, \"branch.autosetupmerge\"))\n-\t\tbranch_track = git_config_bool(var, value);\n-\n \treturn git_default_config(var, value);\n }\n \n@@ -542,7 +537,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@@ -553,7 +548,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_checkout_config);\n \n-\topts.track = branch_track;\n+\topts.track = git_branch_track;\n \n \targc = parse_options(argc, argv, options, checkout_usage, 0);\n \tif (argc) {\n@@ -582,7 +577,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\targc--;\n \t}\n \n-\tif (!opts.new_branch && (opts.track != branch_track))\n+\tif (!opts.new_branch && (opts.track != git_branch_track))\n \t\tdie(\"git checkout: --track and --no-track require -b\");\n \n \tif (opts.force && opts.merge)\ndiff --git a/cache.h b/cache.h\nindex 2b59c44..90b3a9e 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -393,6 +393,14 @@ enum safe_crlf {\n \n extern enum safe_crlf safe_crlf;\n \n+enum branch_track {\n+\tBRANCH_TRACK_REMOTES_FALSE = 0,\n+\tBRANCH_TRACK_REMOTES_TRUE,\n+\tBRANCH_TRACK_ALWAYS,\n+};\n+\n+extern enum branch_track git_branch_track;\n+\n #define GIT_REPO_VERSION 0\n extern int repository_format_version;\n extern int check_repository_format(void);\ndiff --git a/config.c b/config.c\nindex 8064cae..556b2ec 100644\n--- a/config.c\n+++ b/config.c\n@@ -464,6 +464,14 @@ int git_default_config(const char *var, const char *value)\n \t\twhitespace_rule_cfg = parse_whitespace_rule(value);\n \t\treturn 0;\n \t}\n+\tif (!strcmp(var, \"branch.autosetupmerge\")) {\n+\t\tif (value && !strcasecmp(value, \"always\")) {\n+\t\t\tgit_branch_track = BRANCH_TRACK_ALWAYS;\n+\t\t\treturn 0;\n+\t\t}\n+\t\tgit_branch_track = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n \n \t/* Add other config variables here and to Documentation/config.txt. */\n \treturn 0;\ndiff --git a/environment.c b/environment.c\nindex 3527f16..24334a2 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -37,6 +37,7 @@ const char *excludes_file;\n int auto_crlf = 0;\t/* 1: both ways, -1: only when adding git objects */\n enum safe_crlf safe_crlf = SAFE_CRLF_WARN;\n unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;\n+enum branch_track git_branch_track = BRANCH_TRACK_REMOTES_TRUE;\n \n /* This is set by setup_git_dir_gently() and/or git_default_config() */\n char *git_work_tree_cfg;\n-- \n1.5.4.2.203.gf8d86\n"},{"id":"69141","messageId":"alpine.LSU.1.00.0802181328380.30505@racer.site","threadId":"12176","inReplyTo":"1203341084-18543-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-18T13:29:55Z","receivedAt":"2008-02-18T13:29:55Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nsorry, I overlooked that earlier:\n\nOn Mon, 18 Feb 2008, Jay Soffian wrote:\n\n> diff --git a/branch.c b/branch.c\n> index 1fc8788..24e98dd 100644\n> --- a/branch.c\n> +++ b/branch.c\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\nThis line is too long.\n\n> +\t\t\tchar key[1024];\n> +\t\t\tsprintf(key, \"branch.%s.remote\", name);\n\nTo stay safe, you should use snprintf() and test the return value.\n\n> +\t\t\tgit_config_set(key, \".\");\n> +\t\t\tsprintf(key, \"branch.%s.merge\", name);\n\nSame here.\n\nThanks,\nDscho\n"},{"id":"69189","messageId":"20080218190043.GA24240@glandium.org","threadId":"12176","inReplyTo":"alpine.LSU.1.00.0802181328380.30505@racer.site","subject":"Re: [PATCH] branch: optionally setup branch.*.merge from upstream local branches","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2008-02-18T19:00:43Z","receivedAt":"2008-02-18T19:00:43Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Mon, Feb 18, 2008 at 01:29:55PM +0000, Johannes Schindelin wrote:\n> Hi,\n> \n> sorry, I overlooked that earlier:\n> \n> On Mon, 18 Feb 2008, Jay Soffian wrote:\n> \n> > diff --git a/branch.c b/branch.c\n> > index 1fc8788..24e98dd 100644\n> > --- a/branch.c\n> > +++ b/branch.c\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> \n> This line is too long.\n> \n> > +\t\t\tchar key[1024];\n> > +\t\t\tsprintf(key, \"branch.%s.remote\", name);\n> \n> To stay safe, you should use snprintf() and test the return value.\n\nOr use strbufs.\n\nMike\n"}]}