{"thread":{"id":"14905","subject":"[PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","startedAt":"2008-08-09T14:00:12Z","lastAt":"2008-08-11T18:54:08Z","messageCount":10,"participants":["Johannes Schindelin","Junio C Hamano","Tarmigan","Pieter de Bie"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"86600","messageId":"alpine.DEB.1.00.0808091559460.24820@pacific.mpi-cbg.de.mpi-cbg.de","threadId":"14905","inReplyTo":null,"subject":"[PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-08-09T14:00:12Z","receivedAt":"2008-08-09T14:00:12Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nWhat does the user most likely want with this command?\n\n\t$ git checkout --track origin/next\n\nExactly.  A branch called 'next', that tracks origin's branch 'next'.\nMake it so.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tThis comes in the wake for Shawn's call for more user-friendliness.\n\n Documentation/git-checkout.txt |   10 +++++++++-\n builtin-checkout.c             |   21 ++++++++++++++++++---\n t/t7201-co.sh                  |   11 +++++++++++\n 3 files changed, 38 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex 5aa69c0..43d4502 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -8,7 +8,7 @@ git-checkout - Checkout a branch or paths to the working tree\n SYNOPSIS\n --------\n [verse]\n-'git checkout' [-q] [-f] [[--track | --no-track] -b <new_branch> [-l]] [-m] [<branch>]\n+'git checkout' [-q] [-f] [--track | --no-track] [-b <new_branch> [-l]] [-m] [<branch>]\n 'git checkout' [<tree-ish>] [--] <paths>...\n \n DESCRIPTION\n@@ -21,6 +21,10 @@ specified, <new_branch>.  Using -b will cause <new_branch> to\n be created; in this case you can use the --track or --no-track\n options, which will be passed to `git branch`.\n \n+As a convenience, --track will default to create a branch whose\n+name is constructed from the specified branch name by stripping\n+the first namespace level.\n+\n When <paths> are given, this command does *not* switch\n branches.  It updates the named paths in the working tree from\n the index file (i.e. it runs `git checkout-index -f -u`), or\n@@ -59,6 +63,10 @@ OPTIONS\n \t'git-checkout' and 'git-branch' to always behave as if '--no-track' were\n \tgiven. Set it to `always` if you want this behavior when the\n \tstart-point is either a local or remote branch.\n++\n+If no '-b' option was given, a name will be made up for you, by stripping\n+the part up to the first slash of the tracked branch.  For example, if you\n+called 'git checkout --track origin/next', the branch name will be 'next'.\n \n --no-track::\n \tIgnore the branch.autosetupmerge configuration variable.\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 411cc51..e95eab9 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -437,13 +437,28 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_default_config, NULL);\n \n-\topts.track = git_branch_track;\n+\topts.track = -1;\n \n \targc = parse_options(argc, argv, options, checkout_usage,\n \t\t\t     PARSE_OPT_KEEP_DASHDASH);\n \n-\tif (!opts.new_branch && (opts.track != git_branch_track))\n-\t\tdie(\"git checkout: --track and --no-track require -b\");\n+\t/* --track without -b should DWIM */\n+\tif (opts.track && opts.track != -1 && !opts.new_branch) {\n+\t\tchar *slash;\n+\t\tif (!argc || !strcmp(argv[0], \"--\"))\n+\t\t\tdie (\"--track needs a branch name\");\n+\t\tslash = strchr(argv[0], '/');\n+\t\tif (slash && !prefixcmp(argv[0], \"refs/\"))\n+\t\t\tslash = strchr(slash + 1, '/');\n+\t\tif (slash && !prefixcmp(argv[0], \"remotes/\"))\n+\t\t\tslash = strchr(slash + 1, '/');\n+\t\tif (!slash || !slash[1])\n+\t\t\tdie (\"Missing branch name; try -b\");\n+\t\topts.new_branch = slash + 1;\n+\t}\n+\n+\tif (opts.track == -1)\n+\t\topts.track = git_branch_track;\n \n \tif (opts.force && opts.merge)\n \t\tdie(\"git checkout: -f and -m are incompatible\");\ndiff --git a/t/t7201-co.sh b/t/t7201-co.sh\nindex 9ad5d63..943dd57 100755\n--- a/t/t7201-co.sh\n+++ b/t/t7201-co.sh\n@@ -337,4 +337,15 @@ test_expect_success \\\n     test refs/heads/delete-me = \"$(git symbolic-ref HEAD)\" &&\n     test_must_fail git checkout --track -b track'\n \n+test_expect_success \\\n+    'checkout with --track fakes a sensible -b <name>' '\n+    git update-ref refs/remotes/origin/koala/bear renamer &&\n+    git checkout --track origin/koala/bear &&\n+    test \"refs/heads/koala/bear\" = \"$(git symbolic-ref HEAD)\" &&\n+    test \"$(git rev-parse HEAD)\" = \"$(git rev-parse renamer)\"'\n+\n+test_expect_success \\\n+    'checkout with --track, but without -b, fails with too short tracked name' '\n+    test_must_fail git checkout --track renamer'\n+\n test_done\n-- \n1.6.0.rc2.26.g0d7ea\n"},{"id":"86603","messageId":"7vtzdu6nb7.fsf@gitster.siamese.dyndns.org","threadId":"14905","inReplyTo":"alpine.DEB.1.00.0808091559460.24820@pacific.mpi-cbg.de.mpi-cbg.de","subject":"Re: [PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-09T18:44:12Z","receivedAt":"2008-08-09T18:44:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> What does the user most likely want with this command?\n>\n> \t$ git checkout --track origin/next\n>\n> Exactly.  A branch called 'next', that tracks origin's branch 'next'.\n\nI like this.\n\nAn explicit --track request from the command line (as opposed to happening\nto have \"branch.autosetupmerge\" configuration) is a very good cue that\nwhat the user wants to do is not to take a peek on a detached HEAD but a\nmore permanent playpen created.\n"},{"id":"86609","messageId":"7vvdya55ur.fsf@gitster.siamese.dyndns.org","threadId":"14905","inReplyTo":"7vtzdu6nb7.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-09T19:46:36Z","receivedAt":"2008-08-09T19:46:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>\n>> What does the user most likely want with this command?\n>>\n>> \t$ git checkout --track origin/next\n>>\n>> Exactly.  A branch called 'next', that tracks origin's branch 'next'.\n>\n> I like this.\n>\n> An explicit --track request from the command line (as opposed to happening\n> to have \"branch.autosetupmerge\" configuration) is a very good cue that\n> what the user wants to do is not to take a peek on a detached HEAD but a\n> more permanent playpen created.\n\nA couple more thoughts.\n\n(1) You may not necessarily are used to --track, but may still want this\n    done.  It might not be a bad idea to associate this \"local dwimming\"\n    to creation of a new branch.  In other words, all of these:\n\n    $ git checkout -b origin/next\n    $ git checkout -b --track origin/next\n    $ git checkout --track origin/next\n\n    may merit the same dwimming.\n\n(2) If you work with somebody else, you might not want to have the name\n    mapping to be \"s|^[^/]*/||\" (i.e. drop \"origin/\"):\n\n    $ git remote add -f jeff $url_to_his_repository\n    $ git checkout -b [--track] jeff-next jeff/next\n    $ git checkout -b [--track] origin-next origin/next\n"},{"id":"86613","messageId":"alpine.DEB.1.00.0808092302520.24820@pacific.mpi-cbg.de.mpi-cbg.de","threadId":"14905","inReplyTo":"7vvdya55ur.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-08-09T21:08:04Z","receivedAt":"2008-08-09T21:08:04Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 9 Aug 2008, Junio C Hamano wrote:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n> > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> >\n> >> What does the user most likely want with this command?\n> >>\n> >> \t$ git checkout --track origin/next\n> >>\n> >> Exactly.  A branch called 'next', that tracks origin's branch 'next'.\n> >\n> > I like this.\n> >\n> > An explicit --track request from the command line (as opposed to \n> > happening to have \"branch.autosetupmerge\" configuration) is a very \n> > good cue that what the user wants to do is not to take a peek on a \n> > detached HEAD but a more permanent playpen created.\n> \n> A couple more thoughts.\n\nAt first, I liked the thoughts, but...\n\n> (1) You may not necessarily are used to --track, but may still want this\n>     done.  It might not be a bad idea to associate this \"local dwimming\"\n>     to creation of a new branch.  In other words, all of these:\n> \n>     $ git checkout -b origin/next\n\nThis cannot be dwimmed, as it literally means \"start a new branch called \n'origin/next' from HEAD\".\n\nSo it would change the current behavior would, breaking people's habits (I \ndo \"git checkout -b bla\" a lot when I realize that I want to have the \ncurrent changes on a new branch).\n\n>     $ git checkout -b --track origin/next\n\nThis is a clear syntax error.  By the same reasoning, we would have to \nallow \"git add remote origin git://...\"\n\nI think allowing this would confuse the syntax, and foster unreasonable \nexpectations.\n\n>     $ git checkout --track origin/next\n\nThat is what my patch does.\n\n> (2) If you work with somebody else, you might not want to have the name\n>     mapping to be \"s|^[^/]*/||\" (i.e. drop \"origin/\"):\n> \n>     $ git remote add -f jeff $url_to_his_repository\n>     $ git checkout -b [--track] jeff-next jeff/next\n>     $ git checkout -b [--track] origin-next origin/next\n\nAs I said, I think you must not allow switching around the options -b and \n--track.\n\nAnd the rest of what you describe is already supported.\n\nCiao,\nDscho\n"},{"id":"86614","messageId":"7vsktd51wg.fsf@gitster.siamese.dyndns.org","threadId":"14905","inReplyTo":"alpine.DEB.1.00.0808092302520.24820@pacific.mpi-cbg.de.mpi-cbg.de","subject":"Re: [PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-09T21:11:59Z","receivedAt":"2008-08-09T21:11:59Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> On Sat, 9 Aug 2008, Junio C Hamano wrote:\n> ...\n> At first, I liked the thoughts, but...\n>\n>> (1) You may not necessarily are used to --track, but may still want this\n>>     done.  It might not be a bad idea to associate this \"local dwimming\"\n>>     to creation of a new branch.  In other words, all of these:\n>> \n>>     $ git checkout -b origin/next\n>\n> This cannot be dwimmed, as it literally means \"start a new branch called \n> 'origin/next' from HEAD\".\n\nRight.  Forget this part.\n\n>> (2) If you work with somebody else, you might not want to have the name\n>>     mapping to be \"s|^[^/]*/||\" (i.e. drop \"origin/\"):\n>> \n>>     $ git remote add -f jeff $url_to_his_repository\n>>     $ git checkout -b [--track] jeff-next jeff/next\n>>     $ git checkout -b [--track] origin-next origin/next\n>\n> As I said, I think you must not allow switching around the options -b and \n> --track.\n\nOh, that was a typo.  \"git checkout [--track] -b\" was what I meant, but\nthe point was that with your patch \"git checkout --track jeff/next\" and\n\"git checkout --track origin/next\" would create 'next' branch which will\nnot be useful for people who work with more than one repository.\n\nYes, you can of course explicitly name what you want to create with -b,\nbut that argument goes directly against the \"usability enhancement\" theme\nof your patch.\n\nDon't mistake this comment as \"I oppose to the patch\".  I was hoping\npeople who care, not necessarily you, might come up with a clean UI and\nmechanism to let users affect how this dwimmery would work depending on\nhow the users want to work, by raising this point as something to ponder\non.\n"},{"id":"86621","messageId":"A6E466C6-C3B5-40EB-940C-516CF4D02ADF@frim.nl","threadId":"14905","inReplyTo":"7vsktd51wg.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","fromName":"Pieter de Bie","fromEmail":"pieter@frim.nl","sentAt":"2008-08-09T21:44:49Z","receivedAt":"2008-08-09T21:44:49Z","isPatch":true,"sender":{"key":"pieter@frim.nl","avatar":null},"body":"\nOn Aug 9, 2008, at 11:11 PM, Junio C Hamano wrote:\n\n>>> (1) You may not necessarily are used to --track, but may still  \n>>> want this\n>>>    done.  It might not be a bad idea to associate this \"local  \n>>> dwimming\"\n>>>    to creation of a new branch.  In other words, all of these:\n>>>\n>>>    $ git checkout -b origin/next\n>>\n>> This cannot be dwimmed, as it literally means \"start a new branch  \n>> called\n>> 'origin/next' from HEAD\".\n>\n> Right.  Forget this part.\n\nThis is too bad. I often see people make mistakes like\n\n\tgit checkout -b origin/master\nor\n\tgit checkout -b origin/master origin/master\n\nwhich should be\n\n\tgit checkout -b origin/master master\n\nI think both forms should at least be an error if the remote branch  \n\"origin/master\" already exists, as then suddenly they aren't reachable  \nanymore by using \"origin/master\".\n\nChanging the behaviour to mean \"git checkout -b origin/master master\"  \nwill change the meaning, but who uses -b with an existing remote  \nbranch anyway? I think the current behaviour leads to more confusion  \nin every case and should at least error out (\"Error: creating a local  \nrepository with the same name as the remote is not allowed\") or do  \nwhat it's meant to do, which is create a local repository with the  \ntrailing part.\n\nJust my .02,\n\n- Pieter\n"},{"id":"86618","messageId":"905315640808091456q63c20dcfp9ab3b93387688693@mail.gmail.com","threadId":"14905","inReplyTo":"alpine.DEB.1.00.0808092302520.24820@pacific.mpi-cbg.de.mpi-cbg.de","subject":"Re: [PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","fromName":"Tarmigan","fromEmail":"tarmigan+git@gmail.com","sentAt":"2008-08-09T21:56:19Z","receivedAt":"2008-08-09T21:56:19Z","isPatch":true,"sender":{"key":"tarmigan+git@gmail.com","avatar":null},"body":"On Sat, Aug 9, 2008 at 2:08 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> On Sat, 9 Aug 2008, Junio C Hamano wrote:\n>\n>> Junio C Hamano <gitster@pobox.com> writes:\n>>\n>> > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>> >\n>> >> What does the user most likely want with this command?\n>> >>\n>> >>    $ git checkout --track origin/next\n>> >>\n>> >> Exactly.  A branch called 'next', that tracks origin's branch 'next'.\n>> >\n>> > I like this.\n>> >\n>> > An explicit --track request from the command line (as opposed to\n>> > happening to have \"branch.autosetupmerge\" configuration) is a very\n>> > good cue that what the user wants to do is not to take a peek on a\n>> > detached HEAD but a more permanent playpen created.\n>>\n>> A couple more thoughts.\n>\n> At first, I liked the thoughts, but...\n>\n>> (1) You may not necessarily are used to --track, but may still want this\n>>     done.  It might not be a bad idea to associate this \"local dwimming\"\n>>     to creation of a new branch.  In other words, all of these:\n>>\n>>     $ git checkout -b origin/next\n>\n> This cannot be dwimmed, as it literally means \"start a new branch called\n> 'origin/next' from HEAD\".\n\nCould we check whether there is already a remote called \"origin\" with\na branch called \"next\"?  If refs/remotes/origin/next exists it could\nbe confusing to create refs/heads/origin/next anyway, so it this dwim\nmight eliminate a problem as well as be nicer.  In fact, git soon\ncomplains (rightly) about ambigiuos references in this case.\n\n> So it would change the current behavior would, breaking people's habits (I\n> do \"git checkout -b bla\" a lot when I realize that I want to have the\n> current changes on a new branch).\n\nIf we did this dwim only for remotes, your desired behavior could\nstill work, right?.  The default is to --track for branches created\nfrom remotes anyway, right?\n\nThanks,\nTarmigan\n"},{"id":"86729","messageId":"alpine.DEB.1.00.0808110058360.24820@pacific.mpi-cbg.de.mpi-cbg.de","threadId":"14905","inReplyTo":"A6E466C6-C3B5-40EB-940C-516CF4D02ADF@frim.nl","subject":"Re: [PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-08-10T23:02:33Z","receivedAt":"2008-08-10T23:02:33Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 9 Aug 2008, Pieter de Bie wrote:\n\n> Changing the behaviour to mean \"git checkout -b origin/master master\" \n> will change the meaning, but who uses -b with an existing remote branch \n> anyway?\n\nFWIW I am totally opposed to this kind of reasoning.  I consider it sloppy \nto make assumptions that might or might not be true, and to force \na change that might be convenient to you, but is likely to hurt others.\n\nBesides, your suggestion completely breaks consistency.  If somebody asks \nto name a new branch \"origin/master\" (and \"-b origin/master\" is _just_ \n_that_), then it is not Git's job to fix the user's mistake.  Just like it \nis not Git's job to fix when somebody said \"git commit\", but meant \"git \npush\".\n\nAfter all, I might _want_ to create a local branch \"origin/master\", and \nyou would just break the valid assumption that \"-b origin/master\" would do \nthat for me.\n\nHth,\nDscho\n"},{"id":"86764","messageId":"alpine.DEB.1.00.0808111256260.24820@pacific.mpi-cbg.de.mpi-cbg.de","threadId":"14905","inReplyTo":"7vsktd51wg.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-08-11T11:01:40Z","receivedAt":"2008-08-11T11:01:40Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 9 Aug 2008, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > On Sat, 9 Aug 2008, Junio C Hamano wrote:\n> > ...\n> >> (2) If you work with somebody else, you might not want to have the name\n> >>     mapping to be \"s|^[^/]*/||\" (i.e. drop \"origin/\"):\n> >> \n> >>     $ git remote add -f jeff $url_to_his_repository\n> >>     $ git checkout -b [--track] jeff-next jeff/next\n> >>     $ git checkout -b [--track] origin-next origin/next\n> >\n> > As I said, I think you must not allow switching around the options -b \n> > and --track.\n> \n> Oh, that was a typo.  \"git checkout [--track] -b\" was what I meant, but \n> the point was that with your patch \"git checkout --track jeff/next\" and \n> \"git checkout --track origin/next\" would create 'next' branch which will \n> not be useful for people who work with more than one repository.\n> \n> Yes, you can of course explicitly name what you want to create with -b, \n> but that argument goes directly against the \"usability enhancement\" \n> theme of your patch.\n\nNot necessarily:\n\n$ git checkout --track jeff/next\nSwitched to a new branch \"next\"\n\n[do a lot of work, even on that 'next' branch]\n\n[weeks, months or centuries later, decide to do something on origin/next]\n\n$ git checkout --track origin/next\nfatal: A branch named 'next' already exists.\n\n[Ah! Slap your head, remembering that 'next' tracks jeff's 'next']\n$ git branch -m next jeff-next\nBranch: next renamed to jeff-next\n$ git checkout --track -b origin-next origin/next\n\n\nConcluding, I do not see how the DWIMing of the normal case impacts the \nnon-normal case negatively.\n\nDon't get me wrong.  I do not need that patch in git.git desperately.  \nBut if it is rejected, I want it to be rejected for reasons I understand.\n\nCiao,\nDscho\n"},{"id":"86805","messageId":"7vbpzzxu0f.fsf@gitster.siamese.dyndns.org","threadId":"14905","inReplyTo":"alpine.DEB.1.00.0808111256260.24820@pacific.mpi-cbg.de.mpi-cbg.de","subject":"Re: [PATCH] checkout --track: make up a sensible branch name if '-b' was omitted","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-11T18:54:08Z","receivedAt":"2008-08-11T18:54:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Don't get me wrong.  I do not need that patch in git.git desperately.  \n> But if it is rejected, I want it to be rejected for reasons I understand.\n\nYou are the second person in the past few days to talk about rejection\nafter my comments.  I'll try to do better in the future, but if it was not\nclear, I thought the original is good enough for inclusion as-is.\n\nMy comments were about potential improvements on top of what was\npresented, and I say \"potential\" not in the sense that yours is inferior\nthan the ideal because it lacks such improvements, but in the sense that\nthe suggested line of thought might not be even an improvement (iow, I do\nnot mean \"the code your patch brings is has potential to improve and not\ngood enough as it stands\", but \"I think we might also want to do these on\ntop of it, but I may well have overlooked downsides in my suggestion hence\nI am bringing it up for discussion\").\n"}]}