{"thread":{"id":"7018","subject":"defaults for where to merge from","startedAt":"2007-02-28T14:53:03Z","lastAt":"2007-03-02T19:06:44Z","messageCount":48,"participants":["Paolo Bonzini","Johannes Schindelin","Andy Parkins","Julian Phillips","Peter Baumann","Alex Riesen","Junio C Hamano","Jeff King","Jakub Narebski","J. Bruce Fields"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"35809","messageId":"es450f$d58$1@sea.gmane.org","threadId":"7018","inReplyTo":null,"subject":"defaults for where to merge from","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2007-02-28T14:53:03Z","receivedAt":"2007-02-28T14:53:03Z","isPatch":false,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"As can be seen from my other messages, I'm experimenting a little with \ngit and trying to understand how its workflow compares with arch.  Right \nnow, my procedure for branching off a remote archive is:\n\n   git checkout -b branchname remote/upstreambranch\n   git config --add branch.branchname.remote remote\n   git config --add branch.branchname.merge refs/heads/upstreambranch\n\nIs there a reason why \"git branch\" and \"git checkout -b\" should not \nautomatically do the two \"git-config --add\"s when the source branch is \nremote?\n\nIn case the source branch is not remote, would \"origin\" be a good choice \nfor the \"branch.branchname.remote\" variable?\n\nPaolo\n"},{"id":"35813","messageId":"Pine.LNX.4.63.0702281611140.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7018","inReplyTo":"es450f$d58$1@sea.gmane.org","subject":"Re: defaults for where to merge from","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-28T15:13:24Z","receivedAt":"2007-02-28T15:13:24Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 28 Feb 2007, Paolo Bonzini wrote:\n\n> As can be seen from my other messages, I'm experimenting a little with \n> git and trying to understand how its workflow compares with arch.  \n> Right now, my procedure for branching off a remote archive is:\n> \n>   git checkout -b branchname remote/upstreambranch\n>   git config --add branch.branchname.remote remote\n>   git config --add branch.branchname.merge refs/heads/upstreambranch\n> \n> Is there a reason why \"git branch\" and \"git checkout -b\" should not \n> automatically do the two \"git-config --add\"s when the source branch is \n> remote?\n\nI like it.\n\n> In case the source branch is not remote, would \"origin\" be a good choice \n> for the \"branch.branchname.remote\" variable?\n\nIn case source branch is not a remote, I would not want that DWIMery.\n\nCiao,\nDscho\n"},{"id":"35816","messageId":"200702281522.14965.andyparkins@gmail.com","threadId":"7018","inReplyTo":"es450f$d58$1@sea.gmane.org","subject":"Re: defaults for where to merge from","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2007-02-28T15:22:13Z","receivedAt":"2007-02-28T15:22:13Z","isPatch":false,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"On Wednesday 2007 February 28 14:53, Paolo Bonzini wrote:\n> As can be seen from my other messages, I'm experimenting a little with\n> git and trying to understand how its workflow compares with arch.  Right\n> now, my procedure for branching off a remote archive is:\n>\n>    git checkout -b branchname remote/upstreambranch\n>    git config --add branch.branchname.remote remote\n>    git config --add branch.branchname.merge refs/heads/upstreambranch\n>\n> Is there a reason why \"git branch\" and \"git checkout -b\" should not\n> automatically do the two \"git-config --add\"s when the source branch is\n> remote?\n\nI can see why that would be handy, but I often make short lived branches off a \nremote; and I wouldn't want my config cluttered up with branch defintions.\n\n> In case the source branch is not remote, would \"origin\" be a good choice\n> for the \"branch.branchname.remote\" variable?\n\nNo.  That would still reference a remote.  As in:\n\n[remote \"origin\"]\n        url = git://git.kernel.org/pub/scm/git/git.git\n        fetch = refs/heads/master:refs/remotes/origin/master\n[branch \"master\"]\n        remote = origin\n        merge = refs/heads/master\n\nThe remote = origin tells git to use the [remote \"origin\"] section.\n\nI think what you want is something that I would like too.  If you specify \".\" \nto a git-pull it means to use the local repository not a remote.  It would be \ngreat if one could have:\n\n[remote \"origin\"]\n        url = git://git.kernel.org/pub/scm/git/git.git\n        fetch = refs/heads/master:refs/remotes/origin/master\n[branch \"master\"]\n        remote = .\n        merge = refs/remotes/origin/master\n\nThat way a \"git pull\" on master wouldn't need to make a remote connection in \norder to do a merge (which is the way I like it).  However, I remember there \nwas a reason this wouldn't work, but I don't remember what it was :-)\n\n\nAndy\n-- \nDr Andy Parkins, M Eng (hons), MIET\nandyparkins@gmail.com\n"},{"id":"35820","messageId":"45E5A01F.7060204@lu.unisi.ch","threadId":"7018","inReplyTo":"200702281522.14965.andyparkins@gmail.com","subject":"Re: defaults for where to merge from","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@lu.unisi.ch","sentAt":"2007-02-28T15:30:39Z","receivedAt":"2007-02-28T15:30:39Z","isPatch":false,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"\n>>    git checkout -b branchname remote/upstreambranch\n>>    git config --add branch.branchname.remote remote\n>>    git config --add branch.branchname.merge refs/heads/upstreambranch\n>>\n>> Is there a reason why \"git branch\" and \"git checkout -b\" should not\n>> automatically do the two \"git-config --add\"s when the source branch is\n>> remote?\n> \n> I can see why that would be handy, but I often make short lived branches off a \n> remote; and I wouldn't want my config cluttered up with branch defintions.\n\nSo, is there a reason why the config not could be cleared out by branch -d?\n\n(The \"is there a reason\" has the same meaning: it seems obvious to me, \nbut I surely miss a lot of usecases because of inexperience).\n\nPaolo\n"},{"id":"35821","messageId":"Pine.LNX.4.64.0702281526270.15314@reaper.quantumfyre.co.uk","threadId":"7018","inReplyTo":"200702281522.14965.andyparkins@gmail.com","subject":"Re: defaults for where to merge from","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2007-02-28T15:30:42Z","receivedAt":"2007-02-28T15:30:42Z","isPatch":false,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Wed, 28 Feb 2007, Andy Parkins wrote:\n\n> On Wednesday 2007 February 28 14:53, Paolo Bonzini wrote:\n>> As can be seen from my other messages, I'm experimenting a little with\n>> git and trying to understand how its workflow compares with arch.  Right\n>> now, my procedure for branching off a remote archive is:\n>>\n>>    git checkout -b branchname remote/upstreambranch\n>>    git config --add branch.branchname.remote remote\n>>    git config --add branch.branchname.merge refs/heads/upstreambranch\n>>\n>> Is there a reason why \"git branch\" and \"git checkout -b\" should not\n>> automatically do the two \"git-config --add\"s when the source branch is\n>> remote?\n>\n> I can see why that would be handy, but I often make short lived branches off a\n> remote; and I wouldn't want my config cluttered up with branch defintions.\n\nHow about adding an option to tell checkout/branch that a tracking branch \nis wanted (-t perhaps) - or perhaps a way to say that you don't want to \ntrack the remote (depending on which is more popular)?\n\nCertainly would be a nice feature to have ...\n\n-- \nJulian\n\n  ---\nMeg Griffin:  Somebody's in the closet!\nJeff Foxworthy:  You know you're a redneck when your gun rack has a gun rack on it.\nStewie Griffin:  You suck!\n"},{"id":"35826","messageId":"200702281543.30730.andyparkins@gmail.com","threadId":"7018","inReplyTo":"45E5A01F.7060204@lu.unisi.ch","subject":"Re: defaults for where to merge from","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2007-02-28T15:43:29Z","receivedAt":"2007-02-28T15:43:29Z","isPatch":false,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"On Wednesday 2007 February 28 15:30, Paolo Bonzini wrote:\n\n> So, is there a reason why the config not could be cleared out by branch -d?\n\nGood point.  I can't think of one.\n\n\nAndy\n-- \nDr Andy Parkins, M Eng (hons), MIET\nandyparkins@gmail.com\n"},{"id":"35827","messageId":"Pine.LNX.4.63.0702281643200.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7018","inReplyTo":"Pine.LNX.4.64.0702281526270.15314@reaper.quantumfyre.co.uk","subject":"Re: defaults for where to merge from","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-28T15:46:32Z","receivedAt":"2007-02-28T15:46:32Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 28 Feb 2007, Julian Phillips wrote:\n\n> On Wed, 28 Feb 2007, Andy Parkins wrote:\n> \n> > On Wednesday 2007 February 28 14:53, Paolo Bonzini wrote:\n> > > As can be seen from my other messages, I'm experimenting a little with\n> > > git and trying to understand how its workflow compares with arch.  Right\n> > > now, my procedure for branching off a remote archive is:\n> > > \n> > >    git checkout -b branchname remote/upstreambranch\n> > >    git config --add branch.branchname.remote remote\n> > >    git config --add branch.branchname.merge refs/heads/upstreambranch\n> > > \n> > > Is there a reason why \"git branch\" and \"git checkout -b\" should not\n> > > automatically do the two \"git-config --add\"s when the source branch is\n> > > remote?\n> > \n> > I can see why that would be handy, but I often make short lived \n> > branches off a remote; and I wouldn't want my config cluttered up with \n> > branch defintions.\n> \n> How about adding an option to tell checkout/branch that a tracking \n> branch is wanted (-t perhaps) - or perhaps a way to say that you don't \n> want to track the remote (depending on which is more popular)?\n\nI don't think that you should be forced to do it explicitely. If you want \nto merge in another branch, you can do that _explicitely_. So, defaulting \nto what most people want anyway is A Good Thing.\n\nJust my 2 cents,\nDscho\n"},{"id":"35850","messageId":"45E5B7B4.9080605@lu.unisi.ch","threadId":"7018","inReplyTo":"Pine.LNX.4.63.0702281643200.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: defaults for where to merge from","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@lu.unisi.ch","sentAt":"2007-02-28T17:11:16Z","receivedAt":"2007-02-28T17:11:16Z","isPatch":false,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"\n> I don't think that you should be forced to do it explicitely. If you want \n> to merge in another branch, you can do that _explicitely_. So, defaulting \n> to what most people want anyway is A Good Thing.\n\nHere is a prototype patch to implement this functionality.  One problem \nis that config.c does not remove cleaned sections, so after \"git-branch \n-d mybranch\" one is left with a useless \"[branch \"mybranch\"]\" section in \n.git/config.  Other than this, it seems to work well in my experiments.\n\nPaolo\n\n\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex d0179b0..4c42825 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -147,8 +147,21 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)\n \t\t\terror(\"Error deleting %sbranch '%s'\", remote,\n \t\t\t       argv[i]);\n \t\t\tret = 1;\n-\t\t} else\n+\t\t} else {\n+\t\t\tif (kinds == REF_LOCAL_BRANCH) {\n+\t\t\t\t/* Remove git-config keys.  */\n+\t\t\t\tchar *config_key = xmalloc(strlen(argv[i]) + 15);\n+\t\t\t\tsprintf(config_key, \"branch.%s.remote\", argv[i]);\n+\t\t\t\tgit_config_set(config_key, NULL);\n+\n+\t\t\t\tsprintf(config_key, \"branch.%s.merge\", argv[i]);\n+\t\t\t\tgit_config_set(config_key, NULL);\n+\t\t\t\tsprintf(config_key, \"branch.%s\", argv[i]);\n+\t\t\t\tgit_config_set(config_key, NULL);\n+\t\t\t}\n+\n \t\t\tprintf(\"Deleted %sbranch %s.\\n\", remote, argv[i]);\n+\t\t}\n \n \t}\n \n@@ -316,7 +330,7 @@ static void create_branch(const char *name, const char *start_name,\n \tstruct commit *commit;\n \tunsigned char sha1[20];\n \tchar ref[PATH_MAX], msg[PATH_MAX + 20];\n-\tint forcing = 0;\n+\tint forcing = 0, remote = 0;\n \n \tsnprintf(ref, sizeof ref, \"refs/heads/%s\", name);\n \tif (check_ref_format(ref))\n@@ -335,6 +349,13 @@ static void create_branch(const char *name, const char *start_name,\n \t\thashcpy(sha1, start_sha1);\n \telse if (get_sha1(start_name, sha1))\n \t\tdie(\"Not a valid object name: '%s'.\", start_name);\n+\telse {\n+\t\tunsigned char remote_sha1[20];\n+\t\tremote = strchr(start_name, '/')\n+\t\t\t && read_ref(mkpath(\"refs/remotes/%s\", start_name),\n+\t\t\t\t     remote_sha1) != -1\n+\t\t\t && !memcmp(sha1, remote_sha1, 20);\n+\t}\n \n \tif ((commit = lookup_commit_reference(sha1)) == NULL)\n \t\tdie(\"Not a valid branch point: '%s'.\", start_name);\n@@ -354,6 +375,23 @@ static void create_branch(const char *name, const char *start_name,\n \t\tsnprintf(msg, sizeof msg, \"branch: Created from %s\",\n \t\t\t start_name);\n \n+\tif (remote) {\n+\t\t/* Branching off a remote branch.  Set up so that git-pull\n+\t\t   automatically merges from there.  */\n+\t\tchar *config_key = xmalloc(strlen(name) + 15);\n+\t\tchar *merge_value = xmalloc(strlen(start_name) + 10);\n+\t\tchar *slash = strchr(start_name, '/');\n+\n+\t\tchar *remote_value = xstrdup(start_name);\n+\t\tremote_value[slash - start_name] = 0;\n+\t\tsprintf(config_key, \"branch.%s.remote\", name);\n+\t\tgit_config_set(config_key, remote_value);\n+\n+\t\tsprintf(merge_value, \"refs/heads/%s\", slash + 1);\n+\t\tsprintf(config_key, \"branch.%s.merge\", name);\n+\t\tgit_config_set(config_key, merge_value);\n+\t}\n+\n \tif (write_ref_sha1(lock, sha1, msg) < 0)\n \t\tdie(\"Failed to write ref: %s.\", strerror(errno));\n }\n"},{"id":"35852","messageId":"slrneubf3e.54h.siprbaum@xp.machine.xx","threadId":"7018","inReplyTo":"200702281522.14965.andyparkins@gmail.com","subject":"Re: defaults for where to merge from","fromName":"Peter Baumann","fromEmail":"siprbaum@stud.informatik.uni-erlangen.de","sentAt":"2007-02-28T17:31:26Z","receivedAt":"2007-02-28T17:31:26Z","isPatch":false,"sender":{"key":"waste.manager@gmx.de","avatar":null},"body":"Andy Parkins <andyparkins@gmail.com> schrieb:\n> On Wednesday 2007 February 28 14:53, Paolo Bonzini wrote:\n>> As can be seen from my other messages, I'm experimenting a little with\n>> git and trying to understand how its workflow compares with arch.  Right\n>> now, my procedure for branching off a remote archive is:\n>>\n>>    git checkout -b branchname remote/upstreambranch\n>>    git config --add branch.branchname.remote remote\n>>    git config --add branch.branchname.merge refs/heads/upstreambranch\n>>\n>> Is there a reason why \"git branch\" and \"git checkout -b\" should not\n>> automatically do the two \"git-config --add\"s when the source branch is\n>> remote?\n>\n> I can see why that would be handy, but I often make short lived branches off a \n> remote; and I wouldn't want my config cluttered up with branch defintions.\n>\n>> In case the source branch is not remote, would \"origin\" be a good choice\n>> for the \"branch.branchname.remote\" variable?\n>\n> No.  That would still reference a remote.  As in:\n>\n> [remote \"origin\"]\n>         url = git://git.kernel.org/pub/scm/git/git.git\n>         fetch = refs/heads/master:refs/remotes/origin/master\n> [branch \"master\"]\n>         remote = origin\n>         merge = refs/heads/master\n>\n> The remote = origin tells git to use the [remote \"origin\"] section.\n>\n> I think what you want is something that I would like too.  If you specify \".\" \n> to a git-pull it means to use the local repository not a remote.  It would be \n> great if one could have:\n>\n> [remote \"origin\"]\n>         url = git://git.kernel.org/pub/scm/git/git.git\n>         fetch = refs/heads/master:refs/remotes/origin/master\n> [branch \"master\"]\n>         remote = .\n>         merge = refs/remotes/origin/master\n>\n> That way a \"git pull\" on master wouldn't need to make a remote connection in \n> order to do a merge (which is the way I like it).  However, I remember there \n> was a reason this wouldn't work, but I don't remember what it was :-)\n>\n>\n> Andy\n\nThis doesn't work (AIUI). In your example you need to have a remote named \".\",\nwhich you havened (and I don't think . is valid for a remote name ).\n\nBut this works for me:\n\n[remote \"origin\"]\n        url = host:/path/to/your/repo\n        fetch = refs/heads/*:refs/remotes/origin/*\n\n[remote \"local\"]\n        url = .\n        fetch = refs/remotes/*:refs/remotes/*\t# fetch into itself -> do nothing\n\t\t\t\t\t\t# needed to get the LHS of the fetch\n\n[branch \"testbranch\"]\n        remote = local\n        merge = refs/remotes/origin/master\t# specifying the LHS of the fetch\n\n\nWhen on branch 'testbranch', a\t'git pull local' merges\n'refs/remotes/origin/master'.\n\nPeter\n"},{"id":"35859","messageId":"Pine.LNX.4.63.0702281903470.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7018","inReplyTo":"45E5B7B4.9080605@lu.unisi.ch","subject":"Re: defaults for where to merge from","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-28T18:06:27Z","receivedAt":"2007-02-28T18:06:27Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 28 Feb 2007, Paolo Bonzini wrote:\n\n> \n> > I don't think that you should be forced to do it explicitely. If you \n> > want to merge in another branch, you can do that _explicitely_. So, \n> > defaulting to what most people want anyway is A Good Thing.\n> \n> Here is a prototype patch to implement this functionality.  One problem \n> is that config.c does not remove cleaned sections, so after \"git-branch \n> -d mybranch\" one is left with a useless \"[branch \"mybranch\"]\" section in \n> .git/config.  Other than this, it seems to work well in my experiments.\n\nI'd rather remove the complete section (However, that means that you have \nto introduce a function to do that in config.c) instead of unsetting \nseveral hardcoded values.\n\nAlso, the second part of your patch would be clearer (methinks) if you \nreplaced the call to get_sha1() with dwim_ref(). You'd get the real \nrefname for free...\n\nCiao,\nDscho\n"},{"id":"35868","messageId":"81b0412b0702281045u2e511ebfie14a7b718531f8c4@mail.gmail.com","threadId":"7018","inReplyTo":"Pine.LNX.4.63.0702281643200.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: defaults for where to merge from","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-02-28T18:45:39Z","receivedAt":"2007-02-28T18:45:39Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 2/28/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > How about adding an option to tell checkout/branch that a tracking\n> > branch is wanted (-t perhaps) - or perhaps a way to say that you don't\n> > want to track the remote (depending on which is more popular)?\n>\n> I don't think that you should be forced to do it explicitely. If you want\n> to merge in another branch, you can do that _explicitely_. So, defaulting\n> to what most people want anyway is A Good Thing.\n>\n\nAs is an option to disable the feature. I.e. for scripts, which create branches\nblindly, without knowing they working on a remote branch.\nSo, please, provide an option to do what git-checkout/git-branch did before:\nwhich is just create the branch, nothing more.\n"},{"id":"35881","messageId":"45E5DE8A.2080101@lu.unisi.ch","threadId":"7018","inReplyTo":"81b0412b0702281045u2e511ebfie14a7b718531f8c4@mail.gmail.com","subject":"Re: defaults for where to merge from","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@lu.unisi.ch","sentAt":"2007-02-28T19:56:58Z","receivedAt":"2007-02-28T19:56:58Z","isPatch":false,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"\n> As is an option to disable the feature. I.e. for scripts, which create \n> branches\n> blindly, without knowing they working on a remote branch.\n> So, please, provide an option to do what git-checkout/git-branch did \n> before:\n> which is just create the branch, nothing more.\n\nThis does create the branch and nothing more.  It sets up \"git pull\" to \ndo the obvious thing, but does not do anything more.  The branch is left \nin the same state than without the patch.  So the scripts will still \nwork unless they create branches blindly, and blindly do a \"git pull\" \nexpecting it to do the unobvious thing.\n\nPaolo\n"},{"id":"35905","messageId":"81b0412b0702281607l6f9b1cadg9f3a84b06b9acd7d@mail.gmail.com","threadId":"7018","inReplyTo":"45E5DE8A.2080101@lu.unisi.ch","subject":"Re: defaults for where to merge from","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-01T00:07:07Z","receivedAt":"2007-03-01T00:07:07Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 2/28/07, Paolo Bonzini <paolo.bonzini@lu.unisi.ch> wrote:\n> > As is an option to disable the feature. I.e. for scripts, which create\n> > branches\n> > blindly, without knowing they working on a remote branch.\n> > So, please, provide an option to do what git-checkout/git-branch did\n> > before:\n> > which is just create the branch, nothing more.\n>\n> This does create the branch and nothing more.\n\n... except ...\n\n> It sets up \"git pull\" to\n> do the obvious thing, but does not do anything more.  The branch is left\n> in the same state than without the patch.  So the scripts will still\n> work unless they create branches blindly, and blindly do a \"git pull\"\n> expecting it to do the unobvious thing.\n\nWell, I find it unobvious for pull to magically starting merging.\nPerhaps I'm using branch configuration in .git/config for too long,\nand actually expect nothing to be merged if there is no appropriate\nbranch configuration.\n"},{"id":"35909","messageId":"Pine.LNX.4.63.0703010221000.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7018","inReplyTo":"81b0412b0702281607l6f9b1cadg9f3a84b06b9acd7d@mail.gmail.com","subject":"Re: defaults for where to merge from","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-01T01:25:35Z","receivedAt":"2007-03-01T01:25:35Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 1 Mar 2007, Alex Riesen wrote:\n\n> Well, I find it unobvious for pull to magically starting merging.\n\nPull is _all_ about merging.\n\n> Perhaps I'm using branch configuration in .git/config for too long, and \n> actually expect nothing to be merged if there is no appropriate branch \n> configuration.\n\nIt is not possible that you use that feature you described for too long, \nsince it was not there in 1.4.x. There, whenever you said \"git pull\", it \nwould try to blindly pull the default branch of the remote \"origin\", which \nmight have been correct for the default branch (i.e. the branch \nautomatically set up by git-clone), but not necessarily for the other \nbranches.\n\nAnd I want to stress a very important point: this automatic setting of the \ndefault remote and branch-to-merge should be _only_ triggered when \nbranching from refs in $GIT_DIR/refs/remotes. Even if you _do_ branch them \nfrom scripts, I doubt that you'll break _anything_, except of course when \nthe scripts are buggy to begin with.\n\nThere is a good chance that some user wants to merge something \ndifferent, but in that case you have to specify what to merge _anyway_.\n\nHowever, with the proposed behaviour, more new users would get less \"Huh?\" \nexperiences.\n\nCiao,\nDscho\n"},{"id":"35923","messageId":"45E68648.6090407@lu.unisi.ch","threadId":"7018","inReplyTo":"Pine.LNX.4.63.0702281903470.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"[PATCH] defaults for where to merge from (take 2)","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-01T07:52:40Z","receivedAt":"2007-03-01T07:52:40Z","isPatch":true,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"\n> I'd rather remove the complete section (However, that means that you have \n> to introduce a function to do that in config.c)\n\nNo problem.\n\n> Also, the second part of your patch would be clearer (methinks) if you \n> replaced the call to get_sha1() with dwim_ref(). You'd get the real \n> refname for free...\n\nNot only that, my previous version did not work if somebody specified\nremotes/remote/upstreambranch instead of remote/upstreambranch.\n\nUpdated version attached.\n\nPaolo\n\n\n\n\n* git-branch: register where to merge from, when branching off a remote branch.\n\nA rather standard (in 1.5) procedure for branching off a remote archive is:\n\n  git checkout -b branchname remote/upstreambranch\n  git config --add branch.branchname.remote remote\n  git config --add branch.branchname.merge refs/heads/upstreambranch\n\nIn this case, we can save the user some effort if \"git branch\" (and\n\"git checkout -b\") automatically do the two \"git-config --add\"s when the\nsource branch is remote.  There is a good chance that some user wants\nto merge something different, but in that case they have to specify what\nto merge _anyway_.\n\nDually, we remove the branch.branchname section when the user does\n\"git branch -d\".\n\n\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex d0179b0..c1563cf 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -147,8 +147,16 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)\n \t\t\terror(\"Error deleting %sbranch '%s'\", remote,\n \t\t\t       argv[i]);\n \t\t\tret = 1;\n-\t\t} else\n+\t\t} else {\n+\t\t\t/* Remove git-config keys.  */\n+\t\t\tif (kinds == REF_LOCAL_BRANCH) {\n+\t\t\t\tchar *config_key = xmalloc(strlen(argv[i]) + 8);\n+\t\t\t\tsprintf(config_key, \"branch.%s\", argv[i]);\n+\t\t\t\tgit_config_remove_section(config_key);\n+\t\t\t}\n+\n \t\t\tprintf(\"Deleted %sbranch %s.\\n\", remote, argv[i]);\n+\t\t}\n \n \t}\n \n@@ -308,6 +316,27 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)\n \tfree_ref_list(&ref_list);\n }\n \n+static void register_branch_pull (const char *name, const char *remote_name)\n+{\n+\tchar *slash = strchr(remote_name, '/');\n+\n+\tchar *config_key = xmalloc(strlen(name) + 15);\n+\tchar *merge_value = xmalloc(strlen(remote_name) + 10);\n+\n+\tchar *remote_value = xstrdup(remote_name);\n+\tremote_value[slash - remote_name] = 0;\n+\tsprintf(config_key, \"branch.%s.remote\", name);\n+\tgit_config_set(config_key, remote_value);\n+\n+\tsprintf(merge_value, \"refs/heads/%s\", slash + 1);\n+\tsprintf(config_key, \"branch.%s.merge\", name);\n+\tgit_config_set(config_key, merge_value);\n+\n+\tfree (config_key);\n+\tfree (remote_value);\n+\tfree (merge_value);\n+}\n+\n static void create_branch(const char *name, const char *start_name,\n \t\t\t  unsigned char *start_sha1,\n \t\t\t  int force, int reflog)\n@@ -315,8 +344,8 @@ static void create_branch(const char *name, const char *start_name,\n \tstruct ref_lock *lock;\n \tstruct commit *commit;\n \tunsigned char sha1[20];\n-\tchar ref[PATH_MAX], msg[PATH_MAX + 20];\n-\tint forcing = 0;\n+\tchar *real_ref = NULL, ref[PATH_MAX], msg[PATH_MAX + 20];\n+\tint forcing = 0, remote = 0;\n \n \tsnprintf(ref, sizeof ref, \"refs/heads/%s\", name);\n \tif (check_ref_format(ref))\n@@ -333,7 +362,9 @@ static void create_branch(const char *name, const char *start_name,\n \tif (start_sha1)\n \t\t/* detached HEAD */\n \t\thashcpy(sha1, start_sha1);\n-\telse if (get_sha1(start_name, sha1))\n+\telse if (dwim_ref(start_name, strlen (start_name), sha1, &real_ref))\n+\t\tremote = !prefixcmp(real_ref, \"refs/remotes/\");\n+\telse\n \t\tdie(\"Not a valid object name: '%s'.\", start_name);\n \n \tif ((commit = lookup_commit_reference(sha1)) == NULL)\n@@ -354,8 +385,16 @@ static void create_branch(const char *name, const char *start_name,\n \t\tsnprintf(msg, sizeof msg, \"branch: Created from %s\",\n \t\t\t start_name);\n \n+\t/* When branching off a remote branch, set up so that git-pull\n+\t   automatically merges from there.  */\n+\tif (remote)\n+\t\tregister_branch_pull (name, real_ref + 13);\n+\n \tif (write_ref_sha1(lock, sha1, msg) < 0)\n \t\tdie(\"Failed to write ref: %s.\", strerror(errno));\n+\n+\tif (real_ref)\n+\t\tfree (real_ref);\n }\n \n static void rename_branch(const char *oldname, const char *newname, int force)\ndiff --git a/cache.h b/cache.h\nindex 8bbc142..797483b 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -438,6 +438,7 @@ extern int git_config_bool(const char *, const char *);\n extern int git_config_set(const char *, const char *);\n extern int git_config_set_multivar(const char *, const char *, const char *, int);\n extern int git_config_rename_section(const char *, const char *);\n+extern int git_config_remove_section(const char *);\n extern int check_repository_format_version(const char *var, const char *value);\n \n #define MAX_GITNAME (1000)\ndiff --git a/config.c b/config.c\nindex 0ff413b..acd83aa 100644\n--- a/config.c\n+++ b/config.c\n@@ -854,6 +854,33 @@ write_err_out:\n \n }\n \n+static int section_name_match (const char *buf, const char *name)\n+{\n+\tint i = 0, j = 0, dot = 0;\n+\tfor (; buf[i] && buf[i] != ']'; i++) {\n+\t\tif (!dot && isspace(buf[i])) {\n+\t\t\tdot = 1;\n+\t\t\tif (name[j++] != '.')\n+\t\t\t\tbreak;\n+\t\t\tfor (i++; isspace(buf[i]); i++)\n+\t\t\t\t; /* do nothing */\n+\t\t\tif (buf[i] != '\"')\n+\t\t\t\tbreak;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (buf[i] == '\\\\' && dot)\n+\t\t\ti++;\n+\t\telse if (buf[i] == '\"' && dot) {\n+\t\t\tfor (i++; isspace(buf[i]); i++)\n+\t\t\t\t; /* do_nothing */\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (buf[i] != name[j++])\n+\t\t\tbreak;\n+\t}\n+\treturn (buf[i] == ']' && name[j] == 0);\n+}\n+\n int git_config_rename_section(const char *old_name, const char *new_name)\n {\n \tint ret = 0;\n@@ -885,40 +912,15 @@ int git_config_rename_section(const char *old_name, const char *new_name)\n \t\tint length;\n \t\tfor (i = 0; buf[i] && isspace(buf[i]); i++)\n \t\t\t; /* do nothing */\n-\t\tif (buf[i] == '[') {\n+\t\tif (buf[i] == '[' && section_name_match (&buf[i+1], old_name)) {\n \t\t\t/* it's a section */\n-\t\t\tint j = 0, dot = 0;\n-\t\t\tfor (i++; buf[i] && buf[i] != ']'; i++) {\n-\t\t\t\tif (!dot && isspace(buf[i])) {\n-\t\t\t\t\tdot = 1;\n-\t\t\t\t\tif (old_name[j++] != '.')\n-\t\t\t\t\t\tbreak;\n-\t\t\t\t\tfor (i++; isspace(buf[i]); i++)\n-\t\t\t\t\t\t; /* do nothing */\n-\t\t\t\t\tif (buf[i] != '\"')\n-\t\t\t\t\t\tbreak;\n-\t\t\t\t\tcontinue;\n-\t\t\t\t}\n-\t\t\t\tif (buf[i] == '\\\\' && dot)\n-\t\t\t\t\ti++;\n-\t\t\t\telse if (buf[i] == '\"' && dot) {\n-\t\t\t\t\tfor (i++; isspace(buf[i]); i++)\n-\t\t\t\t\t\t; /* do_nothing */\n-\t\t\t\t\tbreak;\n-\t\t\t\t}\n-\t\t\t\tif (buf[i] != old_name[j++])\n-\t\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\tif (buf[i] == ']' && old_name[j] == 0) {\n-\t\t\t\t/* old_name matches */\n-\t\t\t\tret++;\n-\t\t\t\tstore.baselen = strlen(new_name);\n-\t\t\t\tif (!store_write_section(out_fd, new_name)) {\n-\t\t\t\t\tret = write_error();\n-\t\t\t\t\tgoto out;\n-\t\t\t\t}\n-\t\t\t\tcontinue;\n+\t\t\tret++;\n+\t\t\tstore.baselen = strlen(new_name);\n+\t\t\tif (!store_write_section(out_fd, new_name)) {\n+\t\t\t\tret = write_error();\n+\t\t\t\tgoto out;\n \t\t\t}\n+\t\t\tcontinue;\n \t\t}\n \t\tlength = strlen(buf);\n \t\tif (write_in_full(out_fd, buf, length) != length) {\n@@ -934,3 +936,58 @@ int git_config_rename_section(const char *old_name, const char *new_name)\n \treturn ret;\n }\n \n+int git_config_remove_section(const char *name)\n+{\n+\tint ret = 0;\n+\tchar *config_filename;\n+\tstruct lock_file *lock = xcalloc(sizeof(struct lock_file), 1);\n+\tint out_fd;\n+\tint removing = 0;\n+\tchar buf[1024];\n+\n+\tconfig_filename = getenv(CONFIG_ENVIRONMENT);\n+\tif (!config_filename) {\n+\t\tconfig_filename = getenv(CONFIG_LOCAL_ENVIRONMENT);\n+\t\tif (!config_filename)\n+\t\t\tconfig_filename  = git_path(\"config\");\n+\t}\n+\tconfig_filename = xstrdup(config_filename);\n+\tout_fd = hold_lock_file_for_update(lock, config_filename, 0);\n+\tif (out_fd < 0) {\n+\t\tret = error(\"Could not lock config file!\");\n+\t\tgoto out;\n+\t}\n+\n+\tif (!(config_file = fopen(config_filename, \"rb\"))) {\n+\t\tret = error(\"Could not open config file!\");\n+\t\tgoto out;\n+\t}\n+\n+\twhile (fgets(buf, sizeof(buf), config_file)) {\n+\t\tint i;\n+\t\tint length;\n+\t\tfor (i = 0; buf[i] && isspace(buf[i]); i++)\n+\t\t\t; /* do nothing */\n+\t\tif (buf[i] == '[') {\n+\t\t\tif (section_name_match (&buf[i + 1], name)) {\n+\t\t\t\t/* name matches */\n+\t\t\t\tret++;\n+\t\t\t\tremoving = 1;\n+\t\t\t} else\n+\t\t\t\tremoving = 0;\n+\t\t}\n+\t\tif (removing)\n+\t\t\tcontinue;\n+\t\tlength = strlen(buf);\n+\t\tif (write_in_full(out_fd, buf, length) != length) {\n+\t\t\tret = write_error();\n+\t\t\tgoto out;\n+\t\t}\n+\t}\n+\tfclose(config_file);\n+\tif (close(out_fd) || commit_lock_file(lock) < 0)\n+\t\t\tret = error(\"Cannot commit config file!\");\n+ out:\n+\tfree(config_filename);\n+\treturn ret;\n+}\n\n\n"},{"id":"35924","messageId":"81b0412b0702282355i176ad7e5t7b9e417b27e524fb@mail.gmail.com","threadId":"7018","inReplyTo":"Pine.LNX.4.63.0703010221000.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: defaults for where to merge from","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-01T07:55:18Z","receivedAt":"2007-03-01T07:55:18Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/1/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n>\n> > Well, I find it unobvious for pull to magically starting merging.\n>\n> Pull is _all_ about merging.\n>\n\n... from what the user _conciously_ meant it to.\n\n> > Perhaps I'm using branch configuration in .git/config for too long, and\n> > actually expect nothing to be merged if there is no appropriate branch\n> > configuration.\n>\n> It is not possible that you use that feature you described for too long,\n> since it was not there in 1.4.x. There, whenever you said \"git pull\", it\n\nthe syntax was introduced about half a year ago. Plenty of time\nto get used to it\n\n> would try to blindly pull the default branch of the remote \"origin\", which\n> might have been correct for the default branch (i.e. the branch\n> automatically set up by git-clone), but not necessarily for the other\n> branches.\n\nwhich everyone hated. With this change it will not that blindly,\nbut still unexpectedly jump to some remote branch.\n\n> However, with the proposed behaviour, more new users would get less \"Huh?\"\n> experiences.\n\nyes, it will be the old users who'd get the experiences. What do they\ndo, edit out unwanted tracking from .git/config everytime a branch\nfrom remote is created?\n\nBesides, I'm was just asking about providing an option (command-line\nparameter) to change the behavior to what it was before!\nJust \"--no-tracking\"?\n"},{"id":"35925","messageId":"45E68897.8000607@lu.unisi.ch","threadId":"7018","inReplyTo":"81b0412b0702282355i176ad7e5t7b9e417b27e524fb@mail.gmail.com","subject":"Re: defaults for where to merge from","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-01T08:02:31Z","receivedAt":"2007-03-01T08:02:31Z","isPatch":false,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"\n > which everyone hated. With this change it will not that blindly,\n > but still unexpectedly jump to some remote branch.\n >\n >> However, with the proposed behaviour, more new users would get less\n >> \"Huh?\" experiences.\n >\n > yes, it will be the old users who'd get the experiences. What do they\n > do, edit out unwanted tracking from .git/config everytime a branch\n > from remote is created?\n\nIf everyone hated the old behavior, old users should already be careful \nabout not git-pull'ing (without options) from any branch but master.  So \nthey won't see any difference.\n\nComing from arch, which is not really a masterpiece of intuitiveness, \nthis detail (as well as others for which I may try writing patches \nlater) struck me as *extremely* unintuitive...\n\nPaolo\n"},{"id":"35927","messageId":"81b0412b0703010010o24513f60x937b5af52362e0c8@mail.gmail.com","threadId":"7018","inReplyTo":"45E68897.8000607@lu.unisi.ch","subject":"Re: defaults for where to merge from","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-01T08:10:25Z","receivedAt":"2007-03-01T08:10:25Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/1/07, Paolo Bonzini <paolo.bonzini@gmail.com> wrote:\n>\n>  > which everyone hated. With this change it will not that blindly,\n>  > but still unexpectedly jump to some remote branch.\n>  >\n>  >> However, with the proposed behaviour, more new users would get less\n>  >> \"Huh?\" experiences.\n>  >\n>  > yes, it will be the old users who'd get the experiences. What do they\n>  > do, edit out unwanted tracking from .git/config everytime a branch\n>  > from remote is created?\n>\n> If everyone hated the old behavior, old users should already be careful\n> about not git-pull'ing (without options) from any branch but master.  So\n> they won't see any difference.\n\nexcept for .git/config growing uncontrollably\n"},{"id":"35929","messageId":"7vejo9xtot.fsf@assigned-by-dhcp.cox.net","threadId":"7018","inReplyTo":"81b0412b0703010010o24513f60x937b5af52362e0c8@mail.gmail.com","subject":"Re: defaults for where to merge from","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-01T08:18:58Z","receivedAt":"2007-03-01T08:18:58Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Alex Riesen\" <raa.lkml@gmail.com> writes:\n\n>> If everyone hated the old behavior, old users should already be careful\n>> about not git-pull'ing (without options) from any branch but master.  So\n>> they won't see any difference.\n>\n> except for .git/config growing uncontrollably\n\nI think this should be a new option, not the _modified default_.\nOtherwise it would be harder to sell to olde timers.\n\n\t$ git checkout -B <newbranch> remotes/<blah>\n        $ git branch --track <newbranch> remotes/<blah>\n\nmight be a good compromise.\n"},{"id":"35931","messageId":"45E68EDE.2090405@lu.unisi.ch","threadId":"7018","inReplyTo":"81b0412b0703010010o24513f60x937b5af52362e0c8@mail.gmail.com","subject":"Re: defaults for where to merge from","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-01T08:29:18Z","receivedAt":"2007-03-01T08:29:18Z","isPatch":false,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"\n>> If everyone hated the old behavior, old users should already be careful\n>> about not git-pull'ing (without options) from any branch but master.  So\n>> they won't see any difference.\n> \n> except for .git/config growing uncontrollably\n\nWhile I am probably going to modify the patch to satisfy Junio, have you \nnoticed that \"git branch -d\" will delete the section, hence .git/config \nwill not be growing uncontrollably?\n\nPaolo\n"},{"id":"35932","messageId":"81b0412b0703010033w2e1079a3l6ac6e38c59bdefd5@mail.gmail.com","threadId":"7018","inReplyTo":"45E68EDE.2090405@lu.unisi.ch","subject":"Re: defaults for where to merge from","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-01T08:33:43Z","receivedAt":"2007-03-01T08:33:43Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/1/07, Paolo Bonzini <paolo.bonzini@gmail.com> wrote:\n>\n> >> If everyone hated the old behavior, old users should already be careful\n> >> about not git-pull'ing (without options) from any branch but master.  So\n> >> they won't see any difference.\n> >\n> > except for .git/config growing uncontrollably\n>\n> While I am probably going to modify the patch to satisfy Junio, have you\n> noticed that \"git branch -d\" will delete the section, hence .git/config\n> will not be growing uncontrollably?\n>\n\nMaybe you also have noticed that it will remove also the reference?\nHow do I remove the garbage you added for TRACKING?!\n"},{"id":"35934","messageId":"45E69297.8070001@lu.unisi.ch","threadId":"7018","inReplyTo":"81b0412b0703010033w2e1079a3l6ac6e38c59bdefd5@mail.gmail.com","subject":"Re: defaults for where to merge from","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-01T08:45:11Z","receivedAt":"2007-03-01T08:45:11Z","isPatch":false,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"\n>> While I am probably going to modify the patch to satisfy Junio, have you\n>> noticed that \"git branch -d\" will delete the section, hence .git/config\n>> will not be growing uncontrollably?\n> \n> Maybe you also have noticed that it will remove also the reference?\n\nSure I have.\n\n> How do I remove the garbage you added for TRACKING?!\n\nI see two possibilities:\n\n1) I can add a \"git-config --remove-section\" option.  So you can do \n\"git-pull\" to merge onto your branches, and then remove the tracking \nsection.\n\n2) I can add a \"git-branch --stop-tracking\" option, which just removes \nthe section.\n\n3) Same as 2), plus I add a \"git-branch --no-track\" option, which does \nnot add the section in the first place.  But I do believe that there is \nno reason why this cannot be the default.\n\nPaolo\n"},{"id":"35935","messageId":"81b0412b0703010059w52a33b54n4d3c25ada6b96369@mail.gmail.com","threadId":"7018","inReplyTo":"45E69297.8070001@lu.unisi.ch","subject":"Re: defaults for where to merge from","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-01T08:59:24Z","receivedAt":"2007-03-01T08:59:24Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/1/07, Paolo Bonzini <paolo.bonzini@gmail.com> wrote:\n> > How do I remove the garbage you added for TRACKING?!\n>\n> I see two possibilities:\n>\n> 1) I can add a \"git-config --remove-section\" option.  So you can do\n> \"git-pull\" to merge onto your branches, and then remove the tracking\n> section.\n\nThis is irrelevant in this particular context. It is just wrong here:\nare you sure you _CAN_ know what it is you are removing?\nGit config syntax is loosely defined, and branch or remote sections\ncan have important user information. Which he does not immediately\nsee typing git config --remove-section branch.abc _JUST_ to get\nrid of the configuration he did not want in first place!\n\n> 2) I can add a \"git-branch --stop-tracking\" option, which just removes\n> the section.\n\nThis is independent and _probably_ not really needed. It is also\nprobably more complex than you think. Consider:\n\n[remote \"abc\"]\n  url = ...\n  fetch = refs/heads/*:refs/remotes/abc/*\n  fetch = refs/heads/test:refs/heads/abc-test\n\n> 3) Same as 2), plus I add a \"git-branch --no-track\" option, which does\n> not add the section in the first place.  But I do believe that there is\n> no reason why this cannot be the default.\n\nThis is just what I asked for except for the first part.\nAnd I see no reason for it to _BE_ the default.\nActually, how about making the default configurable _AND_ have\nthe --no-track option (for scripting)?\n"},{"id":"35947","messageId":"45E69EEE.8070905@lu.unisi.ch","threadId":"7018","inReplyTo":"81b0412b0703010059w52a33b54n4d3c25ada6b96369@mail.gmail.com","subject":"[PATCH] defaults for where to merge from (take 3)","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-01T09:37:50Z","receivedAt":"2007-03-01T09:37:50Z","isPatch":true,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"\n> Actually, how about making the default configurable _AND_ have\n> the --no-track option (for scripting)?\n\nFine by me.  And also --track in case you want to try it out.  ;-)\n\nI made it default true, environment.c can be changed by Junio if he \napplies the patch.\n\nPatch attached.  --remove-section will go in a separate patch.\n\nPaolo\n\n\n* git-branch: register where to merge from, when branching off a remote branch.\n\nA rather standard (in 1.5) procedure for branching off a remote archive is:\n\n  git checkout -b branchname remote/upstreambranch\n  git config --add branch.branchname.remote remote\n  git config --add branch.branchname.merge refs/heads/upstreambranch\n\nIn this case, we can save the user some effort if \"git branch\" (and\n\"git checkout -b\") automatically do the two \"git-config --add\"s when the\nsource branch is remote.  There is a good chance that some user wants\nto merge something different, but in that case they have to specify what\nto merge _anyway_.\n\nThe behavior is controlled by core.trackremotebranches, and can be\nfine-grained to a specific invocation of \"git branch\" using the new\n--track and --no-track options.\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex aa1fdd4..14dc07d 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git-branch' [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\n-'git-branch' [-l] [-f] <branchname> [<start-point>]\n+'git-branch' [--track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git-branch' (-m | -M) [<oldbranch>] <newbranch>\n 'git-branch' (-d | -D) [-r] <branchname>...\n \n@@ -25,6 +25,12 @@ It will start out with a head equal to the one given as <start-point>.\n If no <start-point> is given, the branch will be created with a head\n equal to that of the currently checked out branch.\n \n+When a local branch is started off a remote branch, git will setup\n+the branch so that gitlink:git-pull[1] will appropriately merge from\n+that remote branch.  If this behavior is undesired, it is possible\n+to change it using the `core.trackremotebranches` option, or the\n+`--track` and `--no-track` options.\n+\n With a '-m' or '-M' option, <oldbranch> will be renamed to <newbranch>.\n If <oldbranch> had a corresponding reflog, it is renamed to match\n <newbranch>, and a reflog entry is created to remember the branch\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex d0179b0..20de049 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -12,7 +12,7 @@\n #include \"builtin.h\"\n \n static const char builtin_branch_usage[] =\n-  \"git-branch [-r] (-d | -D) <branchname> | [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\";\n+  \"git-branch [-r] (-d | -D) <branchname> | [--track | --no-track] [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\";\n \n #define REF_UNKNOWN_TYPE    0x00\n #define REF_LOCAL_BRANCH    0x01\n@@ -308,15 +307,36 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)\n \tfree_ref_list(&ref_list);\n }\n \n+static void register_branch_pull (const char *name, const char *remote_name)\n+{\n+\tchar *slash = strchr(remote_name, '/');\n+\n+\tchar *config_key = xmalloc(strlen(name) + 15);\n+\tchar *merge_value = xmalloc(strlen(remote_name) + 10);\n+\n+\tchar *remote_value = xstrdup(remote_name);\n+\tremote_value[slash - remote_name] = 0;\n+\tsprintf(config_key, \"branch.%s.remote\", name);\n+\tgit_config_set(config_key, remote_value);\n+\n+\tsprintf(merge_value, \"refs/heads/%s\", slash + 1);\n+\tsprintf(config_key, \"branch.%s.merge\", name);\n+\tgit_config_set(config_key, merge_value);\n+\n+\tfree (config_key);\n+\tfree (remote_value);\n+\tfree (merge_value);\n+}\n+\n static void create_branch(const char *name, const char *start_name,\n \t\t\t  unsigned char *start_sha1,\n-\t\t\t  int force, int reflog)\n+\t\t\t  int force, int reflog, int track)\n {\n \tstruct ref_lock *lock;\n \tstruct commit *commit;\n \tunsigned char sha1[20];\n-\tchar ref[PATH_MAX], msg[PATH_MAX + 20];\n-\tint forcing = 0;\n+\tchar *real_ref = NULL, ref[PATH_MAX], msg[PATH_MAX + 20];\n+\tint forcing = 0, remote = 0;\n \n \tsnprintf(ref, sizeof ref, \"refs/heads/%s\", name);\n \tif (check_ref_format(ref))\n@@ -333,7 +353,9 @@ static void create_branch(const char *name, const char *start_name,\n \tif (start_sha1)\n \t\t/* detached HEAD */\n \t\thashcpy(sha1, start_sha1);\n-\telse if (get_sha1(start_name, sha1))\n+\telse if (dwim_ref(start_name, strlen (start_name), sha1, &real_ref))\n+\t\tremote = !prefixcmp(real_ref, \"refs/remotes/\");\n+\telse\n \t\tdie(\"Not a valid object name: '%s'.\", start_name);\n \n \tif ((commit = lookup_commit_reference(sha1)) == NULL)\n@@ -354,8 +376,16 @@ static void create_branch(const char *name, const char *start_name,\n \t\tsnprintf(msg, sizeof msg, \"branch: Created from %s\",\n \t\t\t start_name);\n \n+\t/* When branching off a remote branch, set up so that git-pull\n+\t   automatically merges from there.  */\n+\tif (remote && track)\n+\t\tregister_branch_pull (name, real_ref + 13);\n+\n \tif (write_ref_sha1(lock, sha1, msg) < 0)\n \t\tdie(\"Failed to write ref: %s.\", strerror(errno));\n+\n+\tif (real_ref)\n+\t\tfree (real_ref);\n }\n \n static void rename_branch(const char *oldname, const char *newname, int force)\n@@ -397,11 +427,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tint delete = 0, force_delete = 0, force_create = 0;\n \tint rename = 0, force_rename = 0;\n \tint verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;\n-\tint reflog = 0;\n+\tint reflog = 0, track;\n \tint kinds = REF_LOCAL_BRANCH;\n \tint i;\n \n \tgit_config(git_branch_config);\n+\ttrack = track_remote_branches;\n \n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n@@ -412,6 +443,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\t\ti++;\n \t\t\tbreak;\n \t\t}\n+\t\tif (!strcmp(arg, \"--track\")) {\n+\t\t\ttrack = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"--no-track\")) {\n+\t\t\ttrack = 0;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (!strcmp(arg, \"-d\")) {\n \t\t\tdelete = 1;\n \t\t\tcontinue;\n@@ -490,9 +529,11 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \telse if (rename && (i == argc - 2))\n \t\trename_branch(argv[i], argv[i + 1], force_rename);\n \telse if (i == argc - 1)\n-\t\tcreate_branch(argv[i], head, head_sha1, force_create, reflog);\n+\t\tcreate_branch(argv[i], head, head_sha1, force_create, reflog,\n+\t\t\t      track);\n \telse if (i == argc - 2)\n-\t\tcreate_branch(argv[i], argv[i+1], NULL, force_create, reflog);\n+\t\tcreate_branch(argv[i], argv[i+1], NULL, force_create, reflog,\n+\t\t\t      track);\n \telse\n \t\tusage(builtin_branch_usage);\n \ndiff --git a/cache.h b/cache.h\nindex 8bbc142..585a9b4 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -205,6 +205,7 @@ extern int trust_executable_bit;\n extern int assume_unchanged;\n extern int prefer_symlink_refs;\n extern int log_all_ref_updates;\n+extern int track_remote_branches;\n extern int warn_ambiguous_refs;\n extern int shared_repository;\n extern const char *apply_default_whitespace;\ndiff --git a/config.c b/config.c\nindex 0ff413b..49df7bd 100644\n--- a/config.c\n+++ b/config.c\n@@ -294,6 +294,11 @@ int git_default_config(const char *var, const char *value)\n \t\treturn 0;\n \t}\n \n+\tif (!strcmp(var, \"core.trackremotebranches\")) {\n+\t\ttrack_remote_branches = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n+\n \tif (!strcmp(var, \"core.legacyheaders\")) {\n \t\tuse_legacy_headers = git_config_bool(var, value);\n \t\treturn 0;\ndiff --git a/environment.c b/environment.c\nindex 570e32a..e440d05 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -17,6 +17,7 @@ int assume_unchanged;\n int prefer_symlink_refs;\n int is_bare_repository_cfg = -1; /* unspecified */\n int log_all_ref_updates = -1; /* unspecified */\n+int track_remote_branches = 1;\n int warn_ambiguous_refs = 1;\n int repository_format_version;\n char *git_commit_encoding;\n"},{"id":"35954","messageId":"81b0412b0703010212w5367c8cek51f22e9098f8e22f@mail.gmail.com","threadId":"7018","inReplyTo":"45E69EEE.8070905@lu.unisi.ch","subject":"Re: [PATCH] defaults for where to merge from (take 3)","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-01T10:12:00Z","receivedAt":"2007-03-01T10:12:00Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/1/07, Paolo Bonzini <paolo.bonzini@gmail.com> wrote:\n> > Actually, how about making the default configurable _AND_ have\n> > the --no-track option (for scripting)?\n>\n> Fine by me.  And also --track in case you want to try it out.  ;-)\n>\n\nAck. Thanks!\n\n> Patch attached.  --remove-section will go in a separate patch.\n\nStill think it is a very dangerous operation.\n"},{"id":"35955","messageId":"45E6A838.60605@lu.unisi.ch","threadId":"7018","inReplyTo":"81b0412b0703010212w5367c8cek51f22e9098f8e22f@mail.gmail.com","subject":"Re: [PATCH] defaults for where to merge from (take 3)","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-01T10:17:28Z","receivedAt":"2007-03-01T10:17:28Z","isPatch":true,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"\n>> Patch attached.  --remove-section will go in a separate patch.\n> \n> Still think it is a very dangerous operation.\n\nAgreed, that's why I put it in git-config.\n\nPaolo\n"},{"id":"35956","messageId":"7vvehls1h9.fsf@assigned-by-dhcp.cox.net","threadId":"7018","inReplyTo":"81b0412b0703010212w5367c8cek51f22e9098f8e22f@mail.gmail.com","subject":"Re: [PATCH] defaults for where to merge from (take 3)","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-01T10:27:14Z","receivedAt":"2007-03-01T10:27:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Alex Riesen\" <raa.lkml@gmail.com> writes:\n\n> On 3/1/07, Paolo Bonzini <paolo.bonzini@gmail.com> wrote:\n>> > Actually, how about making the default configurable _AND_ have\n>> > the --no-track option (for scripting)?\n>>\n>> Fine by me.  And also --track in case you want to try it out.  ;-)\n>\n> Ack. Thanks!\n\nHaving both --track and --no-track options is a nice touch to\ngive scripts dependable behaviour.  Well done.\n\n>> Patch attached.  --remove-section will go in a separate patch.\n>\n> Still think it is a very dangerous operation.\n\nI am going to bed now, but I would appreciate if the list could\nhelp Paolo:\n\n (1) with styles.  I have only given a cursory look at the\n     patch, but I think people already know what I like and not\n     like.\n\n (2) by reviewing the changes to the .config writer.  That\n     traditionally has been one of the more fragile parts of the\n     system, and I am reluctant to look at it.\n\n (3) come up with a version that is easier-to-apply (including\n     sending an in-line patch).\n\nI would just feel better to see a patch like this, which is a\nsignificant improvement to the system, to be properly signed-off\nby the submitter.\n\nAlso it would be nice if you guys can fight it out about the\ndefault value for 'tracked'.  I do not think _I_ can defend the\nposition to create these tracking configurations by default to\nold timers (especially the ones that do not follow the git\nmailing list), as I am not convinced (not yet, anyway).\n"},{"id":"35959","messageId":"81b0412b0703010242t36cea2fdr676c1adb799c8077@mail.gmail.com","threadId":"7018","inReplyTo":"7vvehls1h9.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] defaults for where to merge from (take 3)","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-01T10:42:16Z","receivedAt":"2007-03-01T10:42:16Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/1/07, Junio C Hamano <junkio@cox.net> wrote:\n> Also it would be nice if you guys can fight it out about the\n> default value for 'tracked'.  I do not think _I_ can defend the\n> position to create these tracking configurations by default to\n> old timers (especially the ones that do not follow the git\n> mailing list), as I am not convinced (not yet, anyway).\n\nI agree with Dscho wrt the default, partly because I don't\ncare as long as I can change it, partly because the learning\ncurve curve can never be shallow enough and the less\nsurprises the better.\nThe oldtimers will have no problems changing the default,\nand the option is properly documented in the patch.\n"},{"id":"35960","messageId":"81b0412b0703010247l14fe2027u76903ac1b9d32645@mail.gmail.com","threadId":"7018","inReplyTo":"7vvehls1h9.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] defaults for where to merge from (take 3)","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-01T10:47:44Z","receivedAt":"2007-03-01T10:47:44Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/1/07, Junio C Hamano <junkio@cox.net> wrote:\n> Also it would be nice if you guys can fight it out about the\n> default value for 'tracked'.  I do not think _I_ can defend the\n> position to create these tracking configurations by default to\n> old timers (especially the ones that do not follow the git\n> mailing list), as I am not convinced (not yet, anyway).\n\nBTW, how about printing a message that the newly created\nbranch is a tracker of that remote branch?\n\n  $ git branch abc origin/master\n  Branch \"abc\" tracks \"remotes/origin/master\"\n  $ _\n"},{"id":"35984","messageId":"45E70041.1030705@lu.unisi.ch","threadId":"7018","inReplyTo":"7vvehls1h9.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] defaults for where to merge from (take 3, inline)","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-01T16:33:05Z","receivedAt":"2007-03-01T16:33:05Z","isPatch":true,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":">  (2) by reviewing the changes to the .config writer.  That\n>      traditionally has been one of the more fragile parts of the\n>      system, and I am reluctant to look at it.\n\nJust FYI, this was broken into a separate patch.\n\n> I would just feel better to see a patch like this, which is a\n> significant improvement to the system, to be properly signed-off\n> by the submitter.\n\nI hope this is better, I tried to follow the steps in\nSubmittingPatches properly.  The code is actually the same\nas take 3.\n\n\n* git-branch: register where to merge from, when branching off a remote branch.\n\nA rather standard (in 1.5) procedure for branching off a remote archive is:\n\n  git checkout -b branchname remote/upstreambranch\n  git config --add branch.branchname.remote remote\n  git config --add branch.branchname.merge refs/heads/upstreambranch\n\nIn this case, we can save the user some effort if \"git branch\" (and\n\"git checkout -b\") automatically do the two \"git-config --add\"s when the\nsource branch is remote.  There is a good chance that some user wants\nto merge something different, but in that case they have to specify what\nto merge _anyway_.\n\nThe behavior is controlled by core.trackremotebranches, and can be\nfine-grained to a specific invocation of \"git branch\" using the new\n--track and --no-track options.\n\nSigned-off-by: Paolo Bonzini  <bonzini@gnu.org>\n---\n Documentation/git-branch.txt |    8 +++++\n builtin-branch.c             |   58 +++++++++++++++++++++++++++++++++++++------\n cache.h                      |    1 \n config.c                     |    5 +++\n environment.c                |    1 \n 5 files changed, 64 insertions(+), 9 deletions(-)\n\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex aa1fdd4..14dc07d 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git-branch' [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\n-'git-branch' [-l] [-f] <branchname> [<start-point>]\n+'git-branch' [--track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git-branch' (-m | -M) [<oldbranch>] <newbranch>\n 'git-branch' (-d | -D) [-r] <branchname>...\n \n@@ -25,6 +25,12 @@ It will start out with a head equal to the one given as <start-point>.\n If no <start-point> is given, the branch will be created with a head\n equal to that of the currently checked out branch.\n \n+When a local branch is started off a remote branch, git will setup\n+the branch so that gitlink:git-pull[1] will appropriately merge from\n+that remote branch.  If this behavior is undesired, it is possible\n+to change it using the `core.trackremotebranches` option, or the\n+`--track` and `--no-track` options.\n+\n With a '-m' or '-M' option, <oldbranch> will be renamed to <newbranch>.\n If <oldbranch> had a corresponding reflog, it is renamed to match\n <newbranch>, and a reflog entry is created to remember the branch\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex d0179b0..20de049 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -12,7 +12,7 @@\n #include \"builtin.h\"\n \n static const char builtin_branch_usage[] =\n-  \"git-branch [-r] (-d | -D) <branchname> | [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\";\n+  \"git-branch [-r] (-d | -D) <branchname> | [--track | --no-track] [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\";\n \n #define REF_UNKNOWN_TYPE    0x00\n #define REF_LOCAL_BRANCH    0x01\n@@ -308,15 +307,36 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)\n \tfree_ref_list(&ref_list);\n }\n \n+static void register_branch_pull (const char *name, const char *remote_name)\n+{\n+\tchar *slash = strchr(remote_name, '/');\n+\n+\tchar *config_key = xmalloc(strlen(name) + 15);\n+\tchar *merge_value = xmalloc(strlen(remote_name) + 10);\n+\n+\tchar *remote_value = xstrdup(remote_name);\n+\tremote_value[slash - remote_name] = 0;\n+\tsprintf(config_key, \"branch.%s.remote\", name);\n+\tgit_config_set(config_key, remote_value);\n+\n+\tsprintf(merge_value, \"refs/heads/%s\", slash + 1);\n+\tsprintf(config_key, \"branch.%s.merge\", name);\n+\tgit_config_set(config_key, merge_value);\n+\n+\tfree (config_key);\n+\tfree (remote_value);\n+\tfree (merge_value);\n+}\n+\n static void create_branch(const char *name, const char *start_name,\n \t\t\t  unsigned char *start_sha1,\n-\t\t\t  int force, int reflog)\n+\t\t\t  int force, int reflog, int track)\n {\n \tstruct ref_lock *lock;\n \tstruct commit *commit;\n \tunsigned char sha1[20];\n-\tchar ref[PATH_MAX], msg[PATH_MAX + 20];\n-\tint forcing = 0;\n+\tchar *real_ref = NULL, ref[PATH_MAX], msg[PATH_MAX + 20];\n+\tint forcing = 0, remote = 0;\n \n \tsnprintf(ref, sizeof ref, \"refs/heads/%s\", name);\n \tif (check_ref_format(ref))\n@@ -333,7 +353,9 @@ static void create_branch(const char *name, const char *start_name,\n \tif (start_sha1)\n \t\t/* detached HEAD */\n \t\thashcpy(sha1, start_sha1);\n-\telse if (get_sha1(start_name, sha1))\n+\telse if (dwim_ref(start_name, strlen (start_name), sha1, &real_ref))\n+\t\tremote = !prefixcmp(real_ref, \"refs/remotes/\");\n+\telse\n \t\tdie(\"Not a valid object name: '%s'.\", start_name);\n \n \tif ((commit = lookup_commit_reference(sha1)) == NULL)\n@@ -354,8 +376,16 @@ static void create_branch(const char *name, const char *start_name,\n \t\tsnprintf(msg, sizeof msg, \"branch: Created from %s\",\n \t\t\t start_name);\n \n+\t/* When branching off a remote branch, set up so that git-pull\n+\t   automatically merges from there.  */\n+\tif (remote && track)\n+\t\tregister_branch_pull (name, real_ref + 13);\n+\n \tif (write_ref_sha1(lock, sha1, msg) < 0)\n \t\tdie(\"Failed to write ref: %s.\", strerror(errno));\n+\n+\tif (real_ref)\n+\t\tfree (real_ref);\n }\n \n static void rename_branch(const char *oldname, const char *newname, int force)\n@@ -397,11 +427,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tint delete = 0, force_delete = 0, force_create = 0;\n \tint rename = 0, force_rename = 0;\n \tint verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;\n-\tint reflog = 0;\n+\tint reflog = 0, track;\n \tint kinds = REF_LOCAL_BRANCH;\n \tint i;\n \n \tgit_config(git_branch_config);\n+\ttrack = track_remote_branches;\n \n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n@@ -412,6 +443,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\t\ti++;\n \t\t\tbreak;\n \t\t}\n+\t\tif (!strcmp(arg, \"--track\")) {\n+\t\t\ttrack = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"--no-track\")) {\n+\t\t\ttrack = 0;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (!strcmp(arg, \"-d\")) {\n \t\t\tdelete = 1;\n \t\t\tcontinue;\n@@ -490,9 +529,11 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \telse if (rename && (i == argc - 2))\n \t\trename_branch(argv[i], argv[i + 1], force_rename);\n \telse if (i == argc - 1)\n-\t\tcreate_branch(argv[i], head, head_sha1, force_create, reflog);\n+\t\tcreate_branch(argv[i], head, head_sha1, force_create, reflog,\n+\t\t\t      track);\n \telse if (i == argc - 2)\n-\t\tcreate_branch(argv[i], argv[i+1], NULL, force_create, reflog);\n+\t\tcreate_branch(argv[i], argv[i+1], NULL, force_create, reflog,\n+\t\t\t      track);\n \telse\n \t\tusage(builtin_branch_usage);\n \ndiff --git a/cache.h b/cache.h\nindex 8bbc142..585a9b4 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -205,6 +205,7 @@ extern int trust_executable_bit;\n extern int assume_unchanged;\n extern int prefer_symlink_refs;\n extern int log_all_ref_updates;\n+extern int track_remote_branches;\n extern int warn_ambiguous_refs;\n extern int shared_repository;\n extern const char *apply_default_whitespace;\ndiff --git a/config.c b/config.c\nindex 0ff413b..49df7bd 100644\n--- a/config.c\n+++ b/config.c\n@@ -294,6 +294,11 @@ int git_default_config(const char *var, const char *value)\n \t\treturn 0;\n \t}\n \n+\tif (!strcmp(var, \"core.trackremotebranches\")) {\n+\t\ttrack_remote_branches = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n+\n \tif (!strcmp(var, \"core.legacyheaders\")) {\n \t\tuse_legacy_headers = git_config_bool(var, value);\n \t\treturn 0;\ndiff --git a/environment.c b/environment.c\nindex 570e32a..e440d05 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -17,6 +17,7 @@ int assume_unchanged;\n int prefer_symlink_refs;\n int is_bare_repository_cfg = -1; /* unspecified */\n int log_all_ref_updates = -1; /* unspecified */\n+int track_remote_branches = 1;\n int warn_ambiguous_refs = 1;\n int repository_format_version;\n char *git_commit_encoding;\n"},{"id":"36015","messageId":"Pine.LNX.4.63.0703012240210.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7018","inReplyTo":"45E70041.1030705@lu.unisi.ch","subject":"Re: [PATCH] defaults for where to merge from (take 3, inline)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-01T22:01:14Z","receivedAt":"2007-03-01T22:01:14Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nplease don't take my comments as insults or even strict rules. It is \npurely for your consideration. (I say this because I haven't seen you so \noften on this list, so you might not know that discussions about patches \nare sometimes, erm, lively...)\n\nOn Thu, 1 Mar 2007, Paolo Bonzini wrote:\n\n> >  (2) by reviewing the changes to the .config writer.  That\n> >      traditionally has been one of the more fragile parts of the\n> >      system, and I am reluctant to look at it.\n> \n> Just FYI, this was broken into a separate patch.\n> \n> > I would just feel better to see a patch like this, which is a\n> > significant improvement to the system, to be properly signed-off\n> > by the submitter.\n> \n> I hope this is better, I tried to follow the steps in\n> SubmittingPatches properly.  The code is actually the same\n> as take 3.\n\nAccording to SubmittingPatches, this is a cover letter.\n\n\tYou often want to add additional explanation about the patch, \n\tother than the commit message itself.  Place such \"cover letter\" \n\tmaterial between the three dash lines and the diffstat.\n\nSo, please put it after the three dashes and the diffstat next time.\n\n> * git-branch: register where to merge from, when branching off a remote branch.\n\nThis is the oneline description, which should have been the Subject of the \nmail, preferably prefixed by \"[PATCH]\" to make it obvious that it is not \nyet another reply in a medium-sized thread, but actually a code \ncontribution. SubmittingPatches is not clear about this: you can write \n_anything_ in brackets, and it will be stripped from the commit message \nautomatically. In your case, I would have preferred \"[PATCH, 3rd \nversion]\".\n\n> A rather standard (in 1.5) procedure for branching off a remote archive is:\n\nSince this will go into the commit message, which is usually shown in the \noutput of \"git log\", indented, it would be nice to break lines early.\n\nAgain, I think that SubmittingPatches is not totally clear about this: I \ntry to maintain a maximum width of 76 characters (which seems to be the \ndefault with pine -- my mail program -- anyway).\n\n> The behavior is controlled by core.trackremotebranches,\n\nI'd make it obvious here that it is on by default -- even if you state \nthat earlier, too.\n\n[I leave comments on documentation to others, since I cannot write them \nmyself.]\n\n> diff --git a/builtin-branch.c b/builtin-branch.c\n> index d0179b0..20de049 100644\n> --- a/builtin-branch.c\n> +++ b/builtin-branch.c\n> @@ -12,7 +12,7 @@\n>  #include \"builtin.h\"\n>  \n>  static const char builtin_branch_usage[] =\n> -  \"git-branch [-r] (-d | -D) <branchname> | [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\";\n> +  \"git-branch [-r] (-d | -D) <branchname> | [--track | --no-track] [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\";\n>  \n>  #define REF_UNKNOWN_TYPE    0x00\n>  #define REF_LOCAL_BRANCH    0x01\n> @@ -308,15 +307,36 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)\n>  \tfree_ref_list(&ref_list);\n>  }\n>  \n> +static void register_branch_pull (const char *name, const char *remote_name)\n\nIt is not yet remote_name, right? it is branch_name. You extract the \nremote_name by finding the first slash.\n\n> +{\n> +\tchar *slash = strchr(remote_name, '/');\n> +\n> +\tchar *config_key = xmalloc(strlen(name) + 15);\n> +\tchar *merge_value = xmalloc(strlen(remote_name) + 10);\n> +\n> +\tchar *remote_value = xstrdup(remote_name);\n\nI'd use \"char key[1024], value[1024]\" instead, erroring out if one of the \nbuffers are too small. It's not like you have to be memory efficient, and \nit is easier to read.\n\n> +\tremote_value[slash - remote_name] = 0;\n\nYou should check if slash == NULL and error out before using it.\n\n> +\tsprintf(config_key, \"branch.%s.remote\", name);\n\nThis would be a snprintf(key, sizeof(key), \"branch.%s.remote\", name); and \nsnprintf(value, sizeof(value), \"%.*s\", slash - branch_name, branch_name);\n\n> +\tgit_config_set(config_key, remote_value);\n> +\n> +\tsprintf(merge_value, \"refs/heads/%s\", slash + 1);\n> +\tsprintf(config_key, \"branch.%s.merge\", name);\n> +\tgit_config_set(config_key, merge_value);\n> +\n> +\tfree (config_key);\n> +\tfree (remote_value);\n> +\tfree (merge_value);\n> +}\n> +\n>  static void create_branch(const char *name, const char *start_name,\n>  \t\t\t  unsigned char *start_sha1,\n> -\t\t\t  int force, int reflog)\n> +\t\t\t  int force, int reflog, int track)\n>  {\n>  \tstruct ref_lock *lock;\n>  \tstruct commit *commit;\n>  \tunsigned char sha1[20];\n> -\tchar ref[PATH_MAX], msg[PATH_MAX + 20];\n> -\tint forcing = 0;\n> +\tchar *real_ref = NULL, ref[PATH_MAX], msg[PATH_MAX + 20];\n> +\tint forcing = 0, remote = 0;\n>  \n>  \tsnprintf(ref, sizeof ref, \"refs/heads/%s\", name);\n>  \tif (check_ref_format(ref))\n> @@ -333,7 +353,9 @@ static void create_branch(const char *name, const char *start_name,\n>  \tif (start_sha1)\n>  \t\t/* detached HEAD */\n>  \t\thashcpy(sha1, start_sha1);\n> -\telse if (get_sha1(start_name, sha1))\n> +\telse if (dwim_ref(start_name, strlen (start_name), sha1, &real_ref))\n> +\t\tremote = !prefixcmp(real_ref, \"refs/remotes/\");\n> +\telse\n>  \t\tdie(\"Not a valid object name: '%s'.\", start_name);\n\nYes, that is how I imagined it. The rest of your patch looks perfect to \nme.\n\nCiao,\nDscho\n"},{"id":"36039","messageId":"7vlkigmeqh.fsf@assigned-by-dhcp.cox.net","threadId":"7018","inReplyTo":"81b0412b0703010242t36cea2fdr676c1adb799c8077@mail.gmail.com","subject":"Re: [PATCH] defaults for where to merge from (take 3)","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-02T04:49:42Z","receivedAt":"2007-03-02T04:49:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Alex Riesen\" <raa.lkml@gmail.com> writes:\n\n> The oldtimers will have no problems changing the default,\n> and the option is properly documented in the patch.\n\n\"Old-timers will have no problems\" is not a good enough\njustification to change the default.  You need to justify _why_\nit is _they_ who needs to do the extra configuration.\n"},{"id":"36043","messageId":"45E7DC04.5010701@lu.unisi.ch","threadId":"7018","inReplyTo":"Pine.LNX.4.63.0703012240210.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] defaults for where to merge from (take 3, inline)","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-02T08:10:44Z","receivedAt":"2007-03-02T08:10:44Z","isPatch":true,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"\n> please don't take my comments as insults or even strict rules. It is \n> purely for your consideration. (I say this because I haven't seen you so \n> often on this list, so you might not know that discussions about patches \n> are sometimes, erm, lively...)\n\nI absolutely haven't taken any of these comments in the thread as insults (the only thing I found a little dubious, was some usage of uppercase), and I got a lot of constructive criticism that outweighed the \"lively\" tone.  And as a mistake on my part, I probably should have lurked a bit longer than I did.\n\n>> +static void register_branch_pull (const char *name, const char *remote_name)\n> \n> It is not yet remote_name, right? it is branch_name. You extract the \n> remote_name by finding the first slash.\n\nYeah, it's a remote_branch_name in fact.\n\n> I'd use \"char key[1024], value[1024]\" instead, erroring out if one of the \n> buffers are too small. It's not like you have to be memory efficient, and \n> it is easier to read.\n\nOk.\n\n>> +\tremote_value[slash - remote_name] = 0;\n> \n> You should check if slash == NULL and error out before using it.\n\nremote_name is of the form \"REMOTE/BRANCH\", because it comes from dwim_ref's output after stripping \"refs/remotes/\" from the beginning.\n\n> Yes, that is how I imagined it. The rest of your patch looks perfect to \n> me.\n\nI will submit again with the requested changes.  I guess the body of this message is too long to become a \"cover letter\".\n\nPaolo\n"},{"id":"36049","messageId":"45E7E53E.5020704@gnu.org","threadId":"7018","inReplyTo":"45E7DC04.5010701@lu.unisi.ch","subject":"[PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-02T08:50:06Z","receivedAt":"2007-03-02T08:50:06Z","isPatch":true,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"A rather standard (in 1.5) procedure for branching off a remote archive\nis:\n\n  git checkout -b branchname remote/upstreambranch\n  git config --add branch.branchname.remote remote\n  git config --add branch.branchname.merge refs/heads/upstreambranch\n\nIn this case, we can save the user some effort if \"git branch\" (and\n\"git checkout -b\") automatically do the two \"git-config --add\"s when the\nsource branch is remote.  There is a good chance that some user wants\nto merge something different, but in that case they have to specify what\nto merge _anyway_.\n\nThe behavior is controlled by core.trackremotebranches (off by default;\nsubject to review later), and can be fine-grained to a specific invocation\nof \"git branch\" using the new --track and --no-track options.\n\nSigned-off-by: Paolo Bonzini  <bonzini@gnu.org>\n---\n Documentation/git-branch.txt |    9 ++++++\n builtin-branch.c             |   56 ++++++++++++++++++++++++++++++++++++-------\n cache.h                      |    1 \n config.c                     |    5 +++\n environment.c                |    1 \n 5 files changed, 63 insertions(+), 9 deletions(-)\n\n\tIncludes comments by Johannes Schindelin on not using xmalloc for\n\tbuffers, and better variable names.  Default is \"false\" in this\n\tversion, unlike previous versions.\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex aa1fdd4..4ccbb3c 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git-branch' [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\n-'git-branch' [-l] [-f] <branchname> [<start-point>]\n+'git-branch' [--track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git-branch' (-m | -M) [<oldbranch>] <newbranch>\n 'git-branch' (-d | -D) [-r] <branchname>...\n \n@@ -25,6 +25,13 @@ It will start out with a head equal to the one given as <start-point>.\n If no <start-point> is given, the branch will be created with a head\n equal to that of the currently checked out branch.\n \n+When a local branch is started off a remote branch, git can setup\n+the branch so that gitlink:git-pull[1] will appropriately merge from\n+that remote branch.  If this behavior is desired, it is possible\n+to make it the default using the `core.trackremotebranches` option.\n+Otherwise, it can be chosen per-branch using the `--track` and\n+`--no-track` options.\n+\n With a '-m' or '-M' option, <oldbranch> will be renamed to <newbranch>.\n If <oldbranch> had a corresponding reflog, it is renamed to match\n <newbranch>, and a reflog entry is created to remember the branch\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex d0179b0..96658ff 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -12,7 +12,7 @@\n #include \"builtin.h\"\n \n static const char builtin_branch_usage[] =\n-  \"git-branch [-r] (-d | -D) <branchname> | [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\";\n+  \"git-branch [-r] (-d | -D) <branchname> | [--track | --no-track] [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]\";\n \n #define REF_UNKNOWN_TYPE    0x00\n #define REF_LOCAL_BRANCH    0x01\n@@ -308,15 +308,34 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)\n \tfree_ref_list(&ref_list);\n }\n \n+static void register_pull (const char *name, const char *remote_branch_name)\n+{\n+\tchar *slash = strchr(remote_branch_name, '/');\n+\tchar key[1024], value[1024];\n+\n+\tif (strlen(remote_branch_name) >= 1024 - 11\n+\t    || strlen(name) >= 1024 - 15)\n+\t\tdie (\"what a long branch name you have!\");\n+\n+\tsnprintf(key, sizeof(key), \"branch.%s.remote\", name);\n+\tsnprintf(value, sizeof(value), \"%.*s\", slash - remote_branch_name,\n+\t\t remote_branch_name);\n+\tgit_config_set(key, value);\n+\n+\tsnprintf(key, sizeof(key), \"branch.%s.merge\", name);\n+\tsnprintf(value, sizeof(value), \"refs/heads/%s\", slash + 1);\n+\tgit_config_set(key, value);\n+}\n+\n static void create_branch(const char *name, const char *start_name,\n \t\t\t  unsigned char *start_sha1,\n-\t\t\t  int force, int reflog)\n+\t\t\t  int force, int reflog, int track)\n {\n \tstruct ref_lock *lock;\n \tstruct commit *commit;\n \tunsigned char sha1[20];\n-\tchar ref[PATH_MAX], msg[PATH_MAX + 20];\n-\tint forcing = 0;\n+\tchar *real_ref = NULL, ref[PATH_MAX], msg[PATH_MAX + 20];\n+\tint forcing = 0, remote = 0;\n \n \tsnprintf(ref, sizeof ref, \"refs/heads/%s\", name);\n \tif (check_ref_format(ref))\n@@ -333,7 +354,9 @@ static void create_branch(const char *name, const char *start_name,\n \tif (start_sha1)\n \t\t/* detached HEAD */\n \t\thashcpy(sha1, start_sha1);\n-\telse if (get_sha1(start_name, sha1))\n+\telse if (dwim_ref(start_name, strlen (start_name), sha1, &real_ref))\n+\t\tremote = !prefixcmp(real_ref, \"refs/remotes/\");\n+\telse\n \t\tdie(\"Not a valid object name: '%s'.\", start_name);\n \n \tif ((commit = lookup_commit_reference(sha1)) == NULL)\n@@ -354,8 +377,16 @@ static void create_branch(const char *name, const char *start_name,\n \t\tsnprintf(msg, sizeof msg, \"branch: Created from %s\",\n \t\t\t start_name);\n \n+\t/* When branching off a remote branch, set up so that git-pull\n+\t   automatically merges from there.  */\n+\tif (remote && track)\n+\t\tregister_pull (name, real_ref + 13);\n+\n \tif (write_ref_sha1(lock, sha1, msg) < 0)\n \t\tdie(\"Failed to write ref: %s.\", strerror(errno));\n+\n+\tif (real_ref)\n+\t\tfree (real_ref);\n }\n \n static void rename_branch(const char *oldname, const char *newname, int force)\n@@ -397,11 +428,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tint delete = 0, force_delete = 0, force_create = 0;\n \tint rename = 0, force_rename = 0;\n \tint verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;\n-\tint reflog = 0;\n+\tint reflog = 0, track;\n \tint kinds = REF_LOCAL_BRANCH;\n \tint i;\n \n \tgit_config(git_branch_config);\n+\ttrack = track_remote_branches;\n \n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n@@ -412,6 +444,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\t\ti++;\n \t\t\tbreak;\n \t\t}\n+\t\tif (!strcmp(arg, \"--track\")) {\n+\t\t\ttrack = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"--no-track\")) {\n+\t\t\ttrack = 0;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (!strcmp(arg, \"-d\")) {\n \t\t\tdelete = 1;\n \t\t\tcontinue;\n@@ -490,9 +530,11 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \telse if (rename && (i == argc - 2))\n \t\trename_branch(argv[i], argv[i + 1], force_rename);\n \telse if (i == argc - 1)\n-\t\tcreate_branch(argv[i], head, head_sha1, force_create, reflog);\n+\t\tcreate_branch(argv[i], head, head_sha1, force_create, reflog,\n+\t\t\t      track);\n \telse if (i == argc - 2)\n-\t\tcreate_branch(argv[i], argv[i+1], NULL, force_create, reflog);\n+\t\tcreate_branch(argv[i], argv[i+1], NULL, force_create, reflog,\n+\t\t\t      track);\n \telse\n \t\tusage(builtin_branch_usage);\n \ndiff --git a/cache.h b/cache.h\nindex 8bbc142..585a9b4 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -205,6 +205,7 @@ extern int trust_executable_bit;\n extern int assume_unchanged;\n extern int prefer_symlink_refs;\n extern int log_all_ref_updates;\n+extern int track_remote_branches;\n extern int warn_ambiguous_refs;\n extern int shared_repository;\n extern const char *apply_default_whitespace;\ndiff --git a/config.c b/config.c\nindex 0ff413b..49df7bd 100644\n--- a/config.c\n+++ b/config.c\n@@ -294,6 +294,11 @@ int git_default_config(const char *var, const char *value)\n \t\treturn 0;\n \t}\n \n+\tif (!strcmp(var, \"core.trackremotebranches\")) {\n+\t\ttrack_remote_branches = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n+\n \tif (!strcmp(var, \"core.legacyheaders\")) {\n \t\tuse_legacy_headers = git_config_bool(var, value);\n \t\treturn 0;\ndiff --git a/environment.c b/environment.c\nindex 570e32a..e440d05 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -17,6 +17,7 @@ int assume_unchanged;\n int prefer_symlink_refs;\n int is_bare_repository_cfg = -1; /* unspecified */\n int log_all_ref_updates = -1; /* unspecified */\n+int track_remote_branches = 0;\n int warn_ambiguous_refs = 1;\n int repository_format_version;\n char *git_commit_encoding;\n"},{"id":"36051","messageId":"81b0412b0703020105o128fc3adq2912e43d5af74dca@mail.gmail.com","threadId":"7018","inReplyTo":"7vlkigmeqh.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] defaults for where to merge from (take 3)","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-03-02T09:05:00Z","receivedAt":"2007-03-02T09:05:00Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 3/2/07, Junio C Hamano <junkio@cox.net> wrote:\n> \"Alex Riesen\" <raa.lkml@gmail.com> writes:\n>\n> > The oldtimers will have no problems changing the default,\n> > and the option is properly documented in the patch.\n>\n> \"Old-timers will have no problems\" is not a good enough\n> justification to change the default.  You need to justify _why_\n> it is _they_ who needs to do the extra configuration.\n>\n\nI don't know. I wont have any trouble, I think.\n\nI don't even care either way (it is documented, it has\nconfigurable default and it can be switched on or off\nin deterministic manner), and will be only slightly\npleased if creation of a tracked branch is more\nnoticeable (see the mail regarding message on\nbranch creation).\n"},{"id":"36055","messageId":"7vtzx4ezvm.fsf@assigned-by-dhcp.cox.net","threadId":"7018","inReplyTo":"45E7E53E.5020704@gnu.org","subject":"Re: [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-02T09:52:29Z","receivedAt":"2007-03-02T09:52:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Paolo Bonzini <paolo.bonzini@gmail.com> writes:\n\n> A rather standard (in 1.5) procedure for branching off a remote archive\n> is:\n\nMuch easier to read, thanks.\n\nAlthough I'll still nitpick a few points...\n\n>\n>   git checkout -b branchname remote/upstreambranch\n>   git config --add branch.branchname.remote remote\n>   git config --add branch.branchname.merge refs/heads/upstreambranch\n\nProbably a rather standard procedure would be to fork from\nremote tracking branch of where you cloned from, i.e. under\n'remotes/origin'.  I think the above examples are a bit easier\nto read if you said:\n\n    In order to track and build on top of a branch 'topic' you\n    track from your upstream repository, you often would end up\n    doing this sequence:\n\n    $ git checkout -b topic origin/topic\n    $ git config --add branch.branchname.remote origin\n    $ git config --add branch.branchname.merge refs/heads/topic\n\n    to fork your own 'topic' branch from the corresponding\n    branch you track from the 'origin' repository, and set up\n    two configuration variables so that 'git pull' without\n    parameters does the right thing while you are on your own\n    'topic' branch.\n\n    This commit teaches --track option to git-branch, so that\n    \"git branch --track topic origin/topic\" performs the latter\n    two actions when creating your 'topic' branch.  By setting\n    configuration variable 'branch.trackremotebranches' to true,\n    you do not have to pass --track option explicitly (the\n    configuration variable is off by default, and there is a\n    --no-track option to countermand it even if the variable is\n    set).\n\n    Signed-off-by: ...\n\nI do not think a porcelain level command 'branch' should\nintroduce core.* configuration variables.\n\nI have a feeling that \"git checkout -b\" and \"git checkout -B\"\nshould be taught to explicitly use \"git branch --no-track\" and\n\"git branch --track\" to create a new branch (currently it does\nnot even use \"git branch\" as far as I can tell).  With your\npatch, I suspect that you have to say \"git branch topic\norigin/topic\" and then \"git checkout topic\", which means you\nmade the three-step process into two steps, but you could have\nmade it into one step.  I'll send out an untested patch to\ngit-checkout so that you can try it out in a separate message.\n\n> diff --git a/builtin-branch.c b/builtin-branch.c\n> index d0179b0..96658ff 100644\n> --- a/builtin-branch.c\n> +++ b/builtin-branch.c\n> @@ -308,15 +308,34 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)\n>  \tfree_ref_list(&ref_list);\n>  }\n>  \n> +static void register_pull (const char *name, const char *remote_branch_name)\n> +{\n> +\tchar *slash = strchr(remote_branch_name, '/');\n> +\tchar key[1024], value[1024];\n> +\n> +\tif (strlen(remote_branch_name) >= 1024 - 11\n> +\t    || strlen(name) >= 1024 - 15)\n> +\t\tdie (\"what a long branch name you have!\");\n> +\n> +\tsnprintf(key, sizeof(key), \"branch.%s.remote\", name);\n> +\tsnprintf(value, sizeof(value), \"%.*s\", slash - remote_branch_name,\n> +\t\t remote_branch_name);\n> +\tgit_config_set(key, value);\n> +\n> +\tsnprintf(key, sizeof(key), \"branch.%s.merge\", name);\n> +\tsnprintf(value, sizeof(value), \"refs/heads/%s\", slash + 1);\n> +\tgit_config_set(key, value);\n> +}\n> +\n\n - (minor style) No SP between \"register_pull\" and \"(\".  Found\n   elsewhere as well.\n\n - (minor style) I tend to prefer pure declarations before decls\n   with initializer.  I.e. \"char key[], value[]\" first then\n   \"char *slash\".\n\n - (discipline) Not 1024 in the comparison.  sizeof(key) or\n   sizeof(value).\n\n - (micronit) Is it true that both strlen() tests are about long\n   *branch* names?\n\n - (style and discipline) If you use snprintf(), it is usually\n   easier to check its return value to see if you would have\n   overflowed, without having the if() statement to check the\n   length upfront.  As the code gets updated, you may need to\n   change the snprintf() format strings later, and you can\n   forget making a matching change to the condition in if()\n   statement with the patch above.\n\n - (moderately serious) The code blindly trusts that\n   \"refs/remotes/foo/bar\" tracks \"refs/heads/bar\" from remote\n   named \"foo\", which is a bit disturbing.  With the default\n   configuration git-clone and git-remote creates, it always is\n   the case, but I suspect you might want to at least verify\n   that assumption (the user can have different settings in the\n   config), if not figuring them out by reading the existing\n   configuration yourself.\n\n> @@ -333,7 +354,9 @@ static void create_branch(const char *name, const char *start_name,\n>  \tif (start_sha1)\n>  \t\t/* detached HEAD */\n>  \t\thashcpy(sha1, start_sha1);\n> -\telse if (get_sha1(start_name, sha1))\n> +\telse if (dwim_ref(start_name, strlen(start_name), sha1, &real_ref))\n> +\t\tremote = !prefixcmp(real_ref, \"refs/remotes/\");\n> +\telse\n>  \t\tdie(\"Not a valid object name: '%s'.\", start_name);\n>  \n>  \tif ((commit = lookup_commit_reference(sha1)) == NULL)\n\n - (pure question) What happens if dwim_ref() returns more than one?\n\n> diff --git a/config.c b/config.c\n> index 0ff413b..49df7bd 100644\n> --- a/config.c\n> +++ b/config.c\n> @@ -294,6 +294,11 @@ int git_default_config(const char *var, const char *value)\n>  \t\treturn 0;\n>  \t}\n>  \n> +\tif (!strcmp(var, \"core.trackremotebranches\")) {\n> +\t\ttrack_remote_branches = git_config_bool(var, value);\n> +\t\treturn 0;\n> +\t}\n> +\n>  \tif (!strcmp(var, \"core.legacyheaders\")) {\n>  \t\tuse_legacy_headers = git_config_bool(var, value);\n>  \t\treturn 0;\n\n - (mild objection) Does this belong to git_default_config()?  I\n   would have expected this to appear in git_branch_config().\n\n> diff --git a/environment.c b/environment.c\n> index 570e32a..e440d05 100644\n> --- a/environment.c\n> +++ b/environment.c\n> @@ -17,6 +17,7 @@ int assume_unchanged;\n>  int prefer_symlink_refs;\n>  int is_bare_repository_cfg = -1; /* unspecified */\n>  int log_all_ref_updates = -1; /* unspecified */\n> +int track_remote_branches = 0;\n>  int warn_ambiguous_refs = 1;\n>  int repository_format_version;\n>  char *git_commit_encoding;\n\n - (style and discipline) No need to initialize global int to\n   0.  BSS would take care of it.\n"},{"id":"36056","messageId":"7vmz2wezqq.fsf@assigned-by-dhcp.cox.net","threadId":"7018","inReplyTo":"7vtzx4ezvm.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-02T09:55:25Z","receivedAt":"2007-03-02T09:55:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> I have a feeling that \"git checkout -b\" and \"git checkout -B\"\n> should be taught to explicitly use \"git branch --no-track\" and\n> \"git branch --track\" to create a new branch (currently it does\n> not even use \"git branch\" as far as I can tell).  With your\n> patch, I suspect that you have to say \"git branch topic\n> origin/topic\" and then \"git checkout topic\", which means you\n> made the three-step process into two steps, but you could have\n> made it into one step.  I'll send out an untested patch to\n> git-checkout so that you can try it out in a separate message.\n\nThis does not add -B because I haven't applied your patch to my\ntree yet, but it should be obvious where to add --track/--no-track.\n\nOh, as usual, I only have tested it once, so it may or may not\nwork.\n\n\ndiff --git a/git-checkout.sh b/git-checkout.sh\nindex 14835a4..bdf5cdf 100755\n--- a/git-checkout.sh\n+++ b/git-checkout.sh\n@@ -33,7 +33,7 @@ while [ \"$#\" != \"0\" ]; do\n \t\t\tdie \"git checkout: we do not like '$newbranch' as a branch name.\"\n \t\t;;\n \t\"-l\")\n-\t\tnewbranch_log=1\n+\t\tnewbranch_log=-l\n \t\t;;\n \t\"-f\")\n \t\tforce=1\n@@ -235,11 +235,7 @@ fi\n #\n if [ \"$?\" -eq 0 ]; then\n \tif [ \"$newbranch\" ]; then\n-\t\tif [ \"$newbranch_log\" ]; then\n-\t\t\tmkdir -p $(dirname \"$GIT_DIR/logs/refs/heads/$newbranch\")\n-\t\t\ttouch \"$GIT_DIR/logs/refs/heads/$newbranch\"\n-\t\tfi\n-\t\tgit-update-ref -m \"checkout: Created from $new_name\" \"refs/heads/$newbranch\" $new || exit\n+\t\tgit branch $newbranch_log \"$newbranch\" \"$new_name\" || exit\n \t\tbranch=\"$newbranch\"\n \tfi\n \tif test -n \"$branch\"\n"},{"id":"36057","messageId":"7virdkezms.fsf@assigned-by-dhcp.cox.net","threadId":"7018","inReplyTo":"81b0412b0703020105o128fc3adq2912e43d5af74dca@mail.gmail.com","subject":"Re: [PATCH] defaults for where to merge from (take 3)","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-02T09:57:47Z","receivedAt":"2007-03-02T09:57:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Alex Riesen\" <raa.lkml@gmail.com> writes:\n\n> ..., and will be only slightly\n> pleased if creation of a tracked branch is more\n> noticeable (see the mail regarding message on\n> branch creation).\n\nI would very much agree on this part, regardless of what the\ndefault would end up to be.\n"},{"id":"36066","messageId":"20070302103240.GA13217@coredump.intra.peff.net","threadId":"7018","inReplyTo":"7vtzx4ezvm.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-03-02T10:32:40Z","receivedAt":"2007-03-02T10:32:40Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Mar 02, 2007 at 01:52:29AM -0800, Junio C Hamano wrote:\n\n>  - (moderately serious) The code blindly trusts that\n>    \"refs/remotes/foo/bar\" tracks \"refs/heads/bar\" from remote\n>    named \"foo\", which is a bit disturbing.  With the default\n>    configuration git-clone and git-remote creates, it always is\n>    the case, but I suspect you might want to at least verify\n>    that assumption (the user can have different settings in the\n>    config), if not figuring them out by reading the existing\n>    configuration yourself.\n\nSorry to come into this conversation a bit late, but I am catching up on\ngit reading. I agree that this assumption seems a bit suspect; this is\nthe exact sort of thing I was envisioning a 'mergeLocal' or similar\nconfig option for; it avoids the need to make the reverse mapping.\n\nIn fact, the way I thought about it was that branching might set the\nbranch.*.branched_from variable. Then any porcelain which wanted\nto have a sane default for various operations (merge, rebase, etc) could\nuse their regular, user-specified config (e.g., merge checks\nbranch.*.merge; if not set, it defaults to branch.*.branched_from; if\nnot set, barf).\n\nThus you are compatible with the config features we have now, but in the\ncase where we would currently die, this gives another option. It is\nsafer to remove this variable on branch deletion (I know some people\nraised concerns about automatically removing parts of the config file)\nbecause the user would never set 'branched_from'; they would set\n'merge'.\n\nIOW, my point is that branching should write the information it _knows_\ninto the config: branch X was branched from branch Y. It should be up to\nthe programs to _use_ that information in a reasonable way. As it is\nnow, this patch makes the decision about how to use the information at\nthe time of branching, which seems to be the source of a lot of objects.\n\nMy 2 cents,\n-Peff\n"},{"id":"36070","messageId":"45E8072A.2020303@lu.unisi.ch","threadId":"7018","inReplyTo":"7vtzx4ezvm.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-02T11:14:50Z","receivedAt":"2007-03-02T11:14:50Z","isPatch":true,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"> I have a feeling that \"git checkout -b\" and \"git checkout -B\"\n> should be taught to explicitly use \"git branch --no-track\" and\n> \"git branch --track\" to create a new branch (currently it does\n> not even use \"git branch\" as far as I can tell).  With your\n> patch, I suspect that you have to say \"git branch topic\n> origin/topic\" and then \"git checkout topic\", which means you\n> made the three-step process into two steps, but you could have\n> made it into one step.\n\nWell, yes, the next part would have been to patch git-checkout.  But this one is already proving to be complicated enough.  :-)\n\n> I'll send out an untested patch to\n> git-checkout so that you can try it out in a separate message.\n\nI saw it.  I tested your patch and it seems to work.\n \n>  - (micronit) Is it true that both strlen() tests are about long\n>    *branch* names?\n\nIf you consider something like \"origin/next\" to be a branch name, yes.\n\n>  - (moderately serious) The code blindly trusts that\n>    \"refs/remotes/foo/bar\" tracks \"refs/heads/bar\" from remote\n>    named \"foo\", which is a bit disturbing.  With the default\n>    configuration git-clone and git-remote creates, it always is\n>    the case, but I suspect you might want to at least verify\n>    that assumption (the user can have different settings in the\n>    config), if not figuring them out by reading the existing\n>    configuration yourself.\n\nOuch.  Absolutely right, but this means I will prepare the patch later then.\n\n>> +\telse if (dwim_ref(start_name, strlen(start_name), sha1, &real_ref))\n>> +\t\tremote = !prefixcmp(real_ref, \"refs/remotes/\");\n> \n>  - (pure question) What happens if dwim_ref() returns more than one?\n\nThen, real_ref is the one matching sha1.\n\nConsidering your other objection about the naming of the variable, what about enabling/disabling the tracking using remote.REMOTENAME.tracklocalsubbranches?\n\nPaolo\n"},{"id":"36071","messageId":"45E8076F.1050606@lu.unisi.ch","threadId":"7018","inReplyTo":"20070302103240.GA13217@coredump.intra.peff.net","subject":"Re: [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@gmail.com","sentAt":"2007-03-02T11:15:59Z","receivedAt":"2007-03-02T11:15:59Z","isPatch":true,"sender":{"key":"paolo.bonzini@gmail.com","avatar":"https://gravatar.com/avatar/7817ef2e168b4ef0570c5bb5bdc1d4b44f34d3075fe32b871710dd942d0a89f5?d=mp&s=160"},"body":"\n> IOW, my point is that branching should write the information it _knows_\n> into the config: branch X was branched from branch Y. It should be up to\n> the programs to _use_ that information in a reasonable way. As it is\n> now, this patch makes the decision about how to use the information at\n> the time of branching, which seems to be the source of a lot of objects.\n\nThe problem is that this will pollute the configuration file a lot.  I'm starting to wonder if all this branch information really belongs in .git/config at all.\n\nPaolo\n"},{"id":"36072","messageId":"Pine.LNX.4.63.0703021202080.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7018","inReplyTo":"45E7DC04.5010701@lu.unisi.ch","subject":"Re: [PATCH] defaults for where to merge from (take 3, inline)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-02T11:19:32Z","receivedAt":"2007-03-02T11:19:32Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 2 Mar 2007, Paolo Bonzini wrote:\n\n> >> +\tremote_value[slash - remote_name] = 0;\n> > \n> > You should check if slash == NULL and error out before using it.\n> \n> remote_name is of the form \"REMOTE/BRANCH\", because it comes from \n> dwim_ref's output after stripping \"refs/remotes/\" from the beginning.\n\nYou can create a new \"remote\" branch anytime by\n\n\t$ git update-ref refs/remotes/lirumlarum HEAD\n\nYour code would realize that it is a remote ref, strip \"refs/remotes/\", \nand then call strchr(\"lirumlarum\", '/'), which returns NULL.\n\nOn a related note, it _might_ make sense to check that the remote \ninformation is set as expected:\n\n\tstatic const char *remote_name;\n\tstatic int found_remote, remote_name_len;\n\n\tstatic int find_remote(const char *key, const char *value) {\n\t\t/*\n\t\t * This checks if\n\t\t * remote.<bla>.fetch == refs/heads/*:refs/heads/<bla>/*\n\t\t * where <bla> is the remote_name.\n\t\t */\n\t\tif (!prefixcmp(key, \"remote.\") &&\n\t\t\t\t!prefixcmp(key + 7, remote_name) && \n\t\t\t\t!strcmp(key + 7 + remote_name_len,\n\t\t\t\t\t \".fetch\") &&\n\t\t\t\tvalue &&\n\t\t\t\t!prefixcmp(value, \n\t\t\t\t\t\"refs/heads/*:refs/remotes/\") &&\n\t\t\t\t!prefixcmp(value + 26, remote_name) &&\n\t\t\t\t!strcmp(value + 26 + remote_name, \"/*\")) {\n\t\t\tfound_remote = 1;\n\t\t\treturn -1; /* stop parsing config */\n\t\t}\n\t\treturn 0;\n\t}\n\nand then in remote_pull():\n\n\tfound_remote = 0;\n\tremote_name = branch_name;\n\tremote_name_len = slash - branch_name;\n\tgit_config(find_remote);\n\tif (!found_remote) {\n\t\twarn(\"Remote %s was not created with git-remote; \"\n\t\t\t\"will not add it as default merge source to %s\",\n\t\t\tbranch_name, name);\n\t\treturn;\n\t}\n\nWe could rely on new git users not to fiddle with the remote information \nin the config, and old-timers still using .git/remotes/ or .git/branches \nwould be told why the default merge information was not set up.\n\nCiao,\nDscho\n"},{"id":"36073","messageId":"20070302112152.GA14377@coredump.intra.peff.net","threadId":"7018","inReplyTo":"45E8076F.1050606@lu.unisi.ch","subject":"Re: [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-03-02T11:21:52Z","receivedAt":"2007-03-02T11:21:52Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Mar 02, 2007 at 12:15:59PM +0100, Paolo Bonzini wrote:\n\n> > the time of branching, which seems to be the source of a lot of objects.\n\nErr, this should be \"the source of a lot of objections\" of course.\n\n> The problem is that this will pollute the configuration file a lot.\n> I'm starting to wonder if all this branch information really belongs\n> in .git/config at all.\n\nI'm not sure how this pollutes any more than the existing proposal. But\nI have always been a bit uncomfortable with automatic editing of the\nuser config (having used such programs in the past, it always seems to\ncause subtle annoyances -- however, I find I don't even use the per-repo\nconfig in most cases, but just the ~/.gitconfig).\n\nPerhaps if we had an inclusion mechanism, all automatically written\nconfiguration could go into $GIT_DIR/auto_config with a big warning at\nthe top, and the .git/config could include it.\n\nOr are you concerned with just polluting the config namespace? Obviously\nwe could store per-branch metadata somewhere else, but I think there has\nbeen a push to put it _into_ the config over the past several months,\ninstead of in a separate file.\n\n-Peff\n"},{"id":"36087","messageId":"es9b3k$9u1$1@sea.gmane.org","threadId":"7018","inReplyTo":"Pine.LNX.4.63.0703012240210.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] defaults for where to merge from (take 3, inline)","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-03-02T14:10:09Z","receivedAt":"2007-03-02T14:10:09Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Johannes Schindelin wrote:\n>On Thu, 1 Mar 2007, Paolo Bonzini wrote:\n\n>>  \n>> +static void register_branch_pull (const char *name, const char\n*remote_name)\n> \n> It is not yet remote_name, right? it is branch_name. You extract the \n> remote_name by finding the first slash.\n\nI'm bit reluctant about this, as it is not required that remote\nnames cannot contain slashes. But remotes with slashes would make\nseparation into remote and tracking branch part more difficult.\n\n>> +{\n>> +     char *slash = strchr(remote_name, '/');\n>> +\n>> +     char *config_key = xmalloc(strlen(name) + 15);\n>> +     char *merge_value = xmalloc(strlen(remote_name) + 10);\n>> +\n>> +     char *remote_value = xstrdup(remote_name);\n> \n> I'd use \"char key[1024], value[1024]\" instead, erroring out if one of the \n> buffers are too small. It's not like you have to be memory efficient, and \n> it is easier to read.\n\nThe config parser has lengths limits on fully qualified key name (with\nsection name and subsection name) _and_ on value name. Use them, please,\ninstead of dynamic allocation and troubles with those.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"36102","messageId":"20070302155348.GB24547@fieldses.org","threadId":"7018","inReplyTo":"7vejo9xtot.fsf@assigned-by-dhcp.cox.net","subject":"Re: defaults for where to merge from","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-03-02T15:53:48Z","receivedAt":"2007-03-02T15:53:48Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Thu, Mar 01, 2007 at 12:18:58AM -0800, Junio C Hamano wrote:\n> \"Alex Riesen\" <raa.lkml@gmail.com> writes:\n> \n> >> If everyone hated the old behavior, old users should already be careful\n> >> about not git-pull'ing (without options) from any branch but master.  So\n> >> they won't see any difference.\n> >\n> > except for .git/config growing uncontrollably\n> \n> I think this should be a new option, not the _modified default_.\n> Otherwise it would be harder to sell to olde timers.\n> \n> \t$ git checkout -B <newbranch> remotes/<blah>\n>         $ git branch --track <newbranch> remotes/<blah>\n> \n> might be a good compromise.\n\nPersonally I usually use <blah> as <newbranch>.  I might have gone for\nsomething like\n\n\tgit remote checkout [remote] blah [-b newbranch]\n\nwith defaulted to newbranch = blah.\n\n--b.\n"},{"id":"36103","messageId":"Pine.LNX.4.63.0703021647560.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7018","inReplyTo":"45E8072A.2020303@lu.unisi.ch","subject":"Re: [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-02T15:54:31Z","receivedAt":"2007-03-02T15:54:31Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 2 Mar 2007, Paolo Bonzini wrote:\n\n> >  - (micronit) Is it true that both strlen() tests are about long\n> >    *branch* names?\n\nYes. \"name\" refers to the _new_ branch, and \"remote_branch_name\" refers to \nthe remote branch.\n\n> >  - (moderately serious) The code blindly trusts that\n> >    \"refs/remotes/foo/bar\" tracks \"refs/heads/bar\" from remote\n> >    named \"foo\", which is a bit disturbing.  With the default\n> >    configuration git-clone and git-remote creates, it always is\n> >    the case, but I suspect you might want to at least verify\n> >    that assumption (the user can have different settings in the\n> >    config), if not figuring them out by reading the existing\n> >    configuration yourself.\n> \n> Ouch.  Absolutely right, but this means I will prepare the patch later \n> then.\n\nI really recommend doing what I said in another reply: check that \nthe remote information in the config for that remote meets our \nexpectations. And do nothing at all if it does not (maybe warn that no \nbranch.<foo> voodoo was done).\n\n> >> +\telse if (dwim_ref(start_name, strlen(start_name), sha1, &real_ref))\n> >> +\t\tremote = !prefixcmp(real_ref, \"refs/remotes/\");\n> > \n> >  - (pure question) What happens if dwim_ref() returns more than one?\n> \n> Then, real_ref is the one matching sha1.\n\nWhich one ;-)\n\nWhat Junio tried to get at: if you have \"refs/heads/my\" and \n\"refs/remotes/origin/my\", dwim_ref(\"my\", ...) returns 2 (or even more, if \nyou have other refs ending in \"/my\").\n\nPlease test if the return value is exactly 1, and if it is not, do \nnothing.\n\nCiao,\nDscho\n"},{"id":"36107","messageId":"45E851F2.6010405@lu.unisi.ch","threadId":"7018","inReplyTo":"Pine.LNX.4.63.0703021647560.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch","fromName":"Paolo Bonzini","fromEmail":"paolo.bonzini@lu.unisi.ch","sentAt":"2007-03-02T16:33:54Z","receivedAt":"2007-03-02T16:33:54Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"\n>>>> +\telse if (dwim_ref(start_name, strlen(start_name), sha1, &real_ref))\n>>>> +\t\tremote = !prefixcmp(real_ref, \"refs/remotes/\");\n>>>  - (pure question) What happens if dwim_ref() returns more than one?\n>> Then, real_ref is the one matching sha1.\n> \n> Which one ;-)\n\nMatching \"the variable named\" sha1. :-)\n\n> What Junio tried to get at: if you have \"refs/heads/my\" and \n> \"refs/remotes/origin/my\", dwim_ref(\"my\", ...) returns 2 (or even more, if \n> you have other refs ending in \"/my\").\n\nBut the sha1 and the real_ref are always consistent.  If I get refs/heads/my (and a non-remote will always override the remote), the sha1 is non remote.  If I get refs/remotes/origin/my (which triggers the magic), the sha1 is remote.\n\nStill, let's put this patch on hold, I have to understand more about git before proposing something that is clearly beyond my knowledge (as the criticism shows).\n\nPaolo\n"},{"id":"36114","messageId":"Pine.LNX.4.63.0703022005080.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7018","inReplyTo":"45E851F2.6010405@lu.unisi.ch","subject":"Re: [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-02T19:06:44Z","receivedAt":"2007-03-02T19:06:44Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 2 Mar 2007, Paolo Bonzini wrote:\n\n> >>>> +\telse if (dwim_ref(start_name, strlen(start_name), sha1, &real_ref))\n> >>>> +\t\tremote = !prefixcmp(real_ref, \"refs/remotes/\");\n> >>>  - (pure question) What happens if dwim_ref() returns more than one?\n> >> Then, real_ref is the one matching sha1.\n> > \n> > Which one ;-)\n> \n> Matching \"the variable named\" sha1. :-)\n> \n> > What Junio tried to get at: if you have \"refs/heads/my\" and \n> > \"refs/remotes/origin/my\", dwim_ref(\"my\", ...) returns 2 (or even more, \n> > if you have other refs ending in \"/my\").\n> \n> But the sha1 and the real_ref are always consistent.  If I get \n> refs/heads/my (and a non-remote will always override the remote), the \n> sha1 is non remote.  If I get refs/remotes/origin/my (which triggers the \n> magic), the sha1 is remote.\n\nOkay, but you can have \"refs/remotes/origin/my\" and \n\"refs/remotes/paolo/my\".\n\n> Still, let's put this patch on hold, I have to understand more about git \n> before proposing something that is clearly beyond my knowledge (as the \n> criticism shows).\n\nI think you are doing fine. Since there is a lot of discussion about this \nfeature, it does clearly not fail the mark. A little bit more work, and it \nis ready for inclusion IMHO.\n\nCiao,\nDscho\n"}]}