{"thread":{"id":"12123","subject":"[RFC PATCH 1/2] git-branch: allow --track to work w/local branches","startedAt":"2008-02-16T03:45:56Z","lastAt":"2008-02-17T18:05:36Z","messageCount":6,"participants":["Jay Soffian","Junio C Hamano","Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"68860","messageId":"1203133557-50013-1-git-send-email-jaysoffian@gmail.com","threadId":"12123","inReplyTo":null,"subject":"[RFC PATCH 1/2] git-branch: allow --track to work w/local branches","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-16T03:45:56Z","receivedAt":"2008-02-16T03:45:56Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"When given --track (or if branch.autosetupmerge is true) and basing off\na local branch, set branch.<newbranch>.remote to \".\" and\nbranch.<newbranch>.merge to the local branch. This allows us to use \"git\npull\" (w/o options) on the new branch.\n\nPreviously --track was silently ignored when basing off a local branch.\n\nSigned-off-by: Jay Soffian <jaysoffian@gmail.com>\n---\n builtin-branch.c |   10 ++++++++++\n 1 files changed, 10 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex e414c88..94ab195 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -402,6 +402,16 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)\n \t\treturn error(\"Tracking not set up: name too long: %s\",\n \t\t\t\tnew_ref);\n \n+\tif (!prefixcmp(orig_ref, \"refs/heads/\")) {\n+\t\tsprintf(key, \"branch.%s.remote\", new_ref);\n+\t\tgit_config_set(key, \".\");\n+\t\tsprintf(key, \"branch.%s.merge\", new_ref);\n+\t\tgit_config_set(key, orig_ref);\n+\t\tprintf(\"Branch %s set up to track local branch %s.\\n\",\n+\t\t\t       new_ref, orig_ref);\n+\t\treturn 0;\n+\t}\n+\n \tmemset(&tracking, 0, sizeof(tracking));\n \ttracking.spec.dst = (char *)orig_ref;\n \tif (for_each_remote(find_tracked_branch, &tracking) ||\n-- \n1.5.4.1.1281.g75df\n"},{"id":"68861","messageId":"1203133557-50013-2-git-send-email-jaysoffian@gmail.com","threadId":"12123","inReplyTo":"1203133557-50013-1-git-send-email-jaysoffian@gmail.com","subject":"[RFC PATCH 2/2] new --rebase option to set branch.*.rebase for new branches","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-16T03:45:57Z","receivedAt":"2008-02-16T03:45:57Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"Add a --rebase option to git-branch and git-checkout. If given, it\nimplies --track but additionally sets branch.<newbranch>.rebase to true.\n\nSigned-off-by: Jay Soffian <jaysoffian@gmail.com>\n---\n builtin-branch.c |   18 ++++++++++++++----\n git-checkout.sh  |   11 ++++++++---\n 2 files changed, 22 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex 94ab195..1404d8b 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -393,7 +393,7 @@ static int find_tracked_branch(struct remote *remote, void *priv)\n  * to infer the settings for branch.<new_ref>.{remote,merge} from the\n  * config.\n  */\n-static int setup_tracking(const char *new_ref, const char *orig_ref)\n+static int setup_tracking(const char *new_ref, const char *orig_ref, int rebase)\n {\n \tchar key[1024];\n \tstruct tracking tracking;\n@@ -407,6 +407,10 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)\n \t\tgit_config_set(key, \".\");\n \t\tsprintf(key, \"branch.%s.merge\", new_ref);\n \t\tgit_config_set(key, orig_ref);\n+\t\tif (rebase) {\n+\t\t\tsprintf(key, \"branch.%s.rebase\", new_ref);\n+\t\t\tgit_config_set(key, \"true\");\n+\t\t}\n \t\tprintf(\"Branch %s set up to track local branch %s.\\n\",\n \t\t\t       new_ref, orig_ref);\n \t\treturn 0;\n@@ -428,6 +432,10 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)\n \t\tsprintf(key, \"branch.%s.merge\", new_ref);\n \t\tgit_config_set(key, tracking.src);\n \t\tfree(tracking.src);\n+\t\tif (rebase) {\n+\t\t\tsprintf(key, \"branch.%s.rebase\", new_ref);\n+\t\t\tgit_config_set(key, \"true\");\n+\t\t}\n \t\tprintf(\"Branch %s set up to track remote branch %s.\\n\",\n \t\t\t       new_ref, orig_ref);\n \t}\n@@ -436,7 +444,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)\n }\n \n static void create_branch(const char *name, const char *start_name,\n-\t\t\t  int force, int reflog, int track)\n+\t\t\t  int force, int reflog, int track, int rebase)\n {\n \tstruct ref_lock *lock;\n \tstruct commit *commit;\n@@ -495,7 +503,7 @@ static void create_branch(const char *name, const char *start_name,\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\tsetup_tracking(name, real_ref, rebase);\n \n \tif (write_ref_sha1(lock, sha1, msg) < 0)\n \t\tdie(\"Failed to write ref: %s.\", strerror(errno));\n@@ -566,12 +574,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tint verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;\n \tint reflog = 0, track;\n \tint kinds = REF_LOCAL_BRANCH;\n+\tint rebase = 0;\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_BOOLEAN( 0 , \"rebase\",  &rebase, \"set up branch to rebase (see git-pull(1))\"),\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@@ -625,7 +635,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\trename_branch(argv[0], argv[1], rename > 1);\n \telse if (argc <= 2)\n \t\tcreate_branch(argv[0], (argc == 2) ? argv[1] : head,\n-\t\t\t      force_create, reflog, track);\n+\t\t\t      force_create, reflog, track, rebase);\n \telse\n \t\tusage_with_options(builtin_branch_usage, options);\n \ndiff --git a/git-checkout.sh b/git-checkout.sh\nindex bd74d70..569e29c 100755\n--- a/git-checkout.sh\n+++ b/git-checkout.sh\n@@ -7,6 +7,7 @@ git-checkout [options] [<branch>] [<paths>...]\n b=          create a new branch started at <branch>\n l           create the new branch's reflog\n track       arrange that the new branch tracks the remote branch\n+rebase      arrange that the new branch rebases\n f           proceed even if the index or working tree is not HEAD\n m           merge local modifications into the new branch\n q,quiet     be quiet\n@@ -23,6 +24,7 @@ new_name=\n force=\n branch=\n track=\n+rebase=\n newbranch=\n newbranch_log=\n merge=\n@@ -49,6 +51,9 @@ while test $# != 0; do\n \t--track|--no-track)\n \t\ttrack=\"$1\"\n \t\t;;\n+\t--rebase)\n+\t\trebase=\"$1\"\n+\t\t;;\n \t-f)\n \t\tforce=1\n \t\t;;\n@@ -92,9 +97,9 @@ then\n fi\n [ \"$1\" = \"--\" ] && shift\n \n-case \"$newbranch,$track\" in\n+case \"$newbranch,$track,$rebase\" in\n ,--*)\n-\tdie \"git checkout: --track and --no-track require -b\"\n+\tdie \"git checkout: --track, --no-track and --rebase require -b\"\n esac\n \n case \"$force$merge\" in\n@@ -261,7 +266,7 @@ fi\n #\n if [ \"$?\" -eq 0 ]; then\n \tif [ \"$newbranch\" ]; then\n-\t\tgit branch $track $newbranch_log \"$newbranch\" \"$new_name\" || exit\n+\t\tgit branch $track $rebase $newbranch_log \"$newbranch\" \"$new_name\" || exit\n \t\tbranch=\"$newbranch\"\n \tfi\n \tif test -n \"$branch\"\n-- \n1.5.4.1.1281.g75df\n"},{"id":"68872","messageId":"7v7ih5fpve.fsf@gitster.siamese.dyndns.org","threadId":"12123","inReplyTo":"1203133557-50013-1-git-send-email-jaysoffian@gmail.com","subject":"Re: [RFC PATCH 1/2] git-branch: allow --track to work w/local branches","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-02-16T05:10:29Z","receivedAt":"2008-02-16T05:10:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jay Soffian <jaysoffian@gmail.com> writes:\n\n> diff --git a/builtin-branch.c b/builtin-branch.c\n> index e414c88..94ab195 100644\n> --- a/builtin-branch.c\n> +++ b/builtin-branch.c\n> @@ -402,6 +402,16 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)\n>  \t\treturn error(\"Tracking not set up: name too long: %s\",\n>  \t\t\t\tnew_ref);\n>  \n> +\tif (!prefixcmp(orig_ref, \"refs/heads/\")) {\n> +\t\tsprintf(key, \"branch.%s.remote\", new_ref);\n> +\t\tgit_config_set(key, \".\");\n> +\t\tsprintf(key, \"branch.%s.merge\", new_ref);\n> +\t\tgit_config_set(key, orig_ref);\n> +\t\tprintf(\"Branch %s set up to track local branch %s.\\n\",\n> +\t\t\t       new_ref, orig_ref);\n> +\t\treturn 0;\n> +\t}\n> +\n>  \tmemset(&tracking, 0, sizeof(tracking));\n>  \ttracking.spec.dst = (char *)orig_ref;\n>  \tif (for_each_remote(find_tracked_branch, &tracking) ||\n\nAlthough I am not so familiar with this area, the patch somehow\ndid not feel right, so I ended up doing a bit of digging.\n\nAfter the context of the patch, we have this:\n\n\tif (tracking.matches == 1) {\n\t\tsprintf(key, \"branch.%s.remote\", new_ref);\n\t\tgit_config_set(key, tracking.remote ?  tracking.remote : \".\");\n\t\tsprintf(key, \"branch.%s.merge\", new_ref);\n\t\tgit_config_set(key, tracking.src);\n\nSo it looks to me that the code already has intention to set the\n\"branch.*.remote\" variable to \".\" when certain condition is met.\nAnd the condition is \"when tracking.remote is NULL, or it is\nalready a dot\".\n\nfor_each_remote() iterates thru the remotes and\nfind_tracked_branch() does this:\n\n        static int find_tracked_branch(struct remote *remote, void *priv)\n        {\n                struct tracking *tracking = priv;\n\n                if (!remote_find_tracking(remote, &tracking->spec)) {\n                        if (++tracking->matches == 1) {\n                                tracking->src = tracking->spec.src;\n                                tracking->remote = remote->name;\n                        } else {\n                                free(tracking->spec.src);\n                                if (tracking->src) {\n                                        free(tracking->src);\n                                        tracking->src = NULL;\n                                }\n                        }\n                        tracking->spec.src = NULL;\n                }\n\n                return 0;\n        }\n\nSo if there is a remote whose name is \".\" (or NULL, but I do not\nknow when that can happen --- remote.c::make_remote() does not\nallow creating such a remote as far as I can tell), that would\nbe found without the added extra code, wouldn't it?\n\nI did a bit of experiment and with this in .git/config:\n\n\t[remote \".\"]\n                fetch = refs/*:refs/*\n\nit turns out that you do not have to patch the code at all.  The\nabove manual configuration feels somewhat like an ugly hack but\nperhaps we should make the above two lines implied?  This area\nwas last cleaned up in 6f084a5 (branch --track: code cleanup and\nsaner handling of local branches).  I do not know if the\noriginal intention of the code was to allow a hack like this to\nwork, or it is just an unintended accident that it happens to\nwork.  Dscho, any ideas?\n"},{"id":"68879","messageId":"76718490802152307h37796d32tfccb7571d48a3221@mail.gmail.com","threadId":"12123","inReplyTo":"7v7ih5fpve.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC PATCH 1/2] git-branch: allow --track to work w/local branches","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-16T07:07:30Z","receivedAt":"2008-02-16T07:07:30Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Feb 16, 2008 12:10 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Although I am not so familiar with this area, the patch somehow\n> did not feel right, so I ended up doing a bit of digging.\n>\n> After the context of the patch, we have this:\n>\n>         if (tracking.matches == 1) {\n>                 sprintf(key, \"branch.%s.remote\", new_ref);\n>                 git_config_set(key, tracking.remote ?  tracking.remote : \".\");\n>                 sprintf(key, \"branch.%s.merge\", new_ref);\n>                 git_config_set(key, tracking.src);\n>\n> So it looks to me that the code already has intention to set the\n> \"branch.*.remote\" variable to \".\" when certain condition is met.\n> And the condition is \"when tracking.remote is NULL, or it is\n> already a dot\".\n\nI was confused by the use of the ternary operator. I couldn't figure\nout how tracking.remote could be NULL. I chalked it up to bit-rot\nbut them forget to mention that in my email. I'm glad you took\nanother look, but I still don't understand how tracking.remote can\nbe NULL and tracking.matches == 1.\n\n> So if there is a remote whose name is \".\" (or NULL, but I do not\n> know when that can happen --- remote.c::make_remote() does not\n> allow creating such a remote as far as I can tell), that would\n> be found without the added extra code, wouldn't it?\n>\n> I did a bit of experiment and with this in .git/config:\n>\n>         [remote \".\"]\n>                 fetch = refs/*:refs/*\n>\n> it turns out that you do not have to patch the code at all.  The\n> above manual configuration feels somewhat like an ugly hack but\n> perhaps we should make the above two lines implied?\n\nHmm, that just causes tracking.remote to be set to \".\", not to NULL?\nRight?\n\nj.\n"},{"id":"68894","messageId":"alpine.LSU.1.00.0802161143290.30505@racer.site","threadId":"12123","inReplyTo":"7v7ih5fpve.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC PATCH 1/2] git-branch: allow --track to work w/local branches","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-02-16T11:45:26Z","receivedAt":"2008-02-16T11:45:26Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn 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\nAFAIR the problem was that you were (rightfully) annoyed when you were \nsetting up your local branches, and all of a sudden, they were set up with \nloads of tracking information, cluttering your config.\n\nBasically, that is the reason why we disallowed tracking information to be \nset up for local branching.\n\nCiao,\nDscho\n"},{"id":"69006","messageId":"76718490802171005xaed572dkd59ed822897fdb3a@mail.gmail.com","threadId":"12123","inReplyTo":"alpine.LSU.1.00.0802161143290.30505@racer.site","subject":"Re: [RFC PATCH 1/2] git-branch: allow --track to work w/local branches","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-17T18:05:36Z","receivedAt":"2008-02-17T18:05:36Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Feb 16, 2008 6:45 AM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\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\nHrmm, I was annoyed that when setting up my local branches, they *don't*\nget tracking information. Otherwise I can't use \"git pull\" with them,\nwhich I'd like to. So maybe something like:\n\n * Using --track or --notrack adds (or doesn't) the information, because\n  well, I specified it explicitly.\n\n * Otherwise (if neither --track nor --notrack) is specified, check the\n  setting of branch.autosetupmerge. Currently it's a boolean, but\n  perhaps it can take on a new setting and have:\n - false\n - true\n - always ; new setting which means to setup tracking information for\n          ; both local and remote branches\n\n?\n\nj.\n"}]}