{"thread":{"id":"14608","subject":"[PATCH] git-checkout: fix argument parsing to detect ambiguous arguments.","startedAt":"2008-07-23T01:02:20Z","lastAt":"2008-07-25T20:34:10Z","messageCount":16,"participants":["Pierre Habouzit","Johannes Schindelin","SZEDER Gábor","Junio C Hamano","Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"84421","messageId":"1216774940-4955-1-git-send-email-madcoder@debian.org","threadId":"14608","inReplyTo":null,"subject":"[PATCH] git-checkout: fix argument parsing to detect ambiguous arguments.","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-23T01:02:20Z","receivedAt":"2008-07-23T01:02:20Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"Note that it also fix a bug, git checkout -- <path> would be badly\nunderstood as git checkout <branch> if <path> is ambiguous with a branch.\n\nTestcases included.\n\nSigned-off-by: Pierre Habouzit <madcoder@debian.org>\n---\n\n  A user on #git happened to have issues that made me realize that\n  builtin-checkout is badly broken wrt argument parseing.\n\n  This clearly needs to be applied to master, probably to maint too.\n\n  The patch is against next though, but should probably apply to other\n  branches just fine.\n\n\n builtin-checkout.c            |    9 +++++++--\n t/t2010-checkout-ambiguous.sh |   27 +++++++++++++++++++++++++++\n 2 files changed, 34 insertions(+), 2 deletions(-)\n create mode 100755 t/t2010-checkout-ambiguous.sh\n\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex fbd5105..1490e8e 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -438,9 +438,14 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \n \topts.track = git_branch_track;\n \n-\targc = parse_options(argc, argv, options, checkout_usage, 0);\n-\tif (argc) {\n+\targc = parse_options(argc, argv, options, checkout_usage,\n+\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n+\n+\tif (argc && strcmp(argv[0], \"--\")) {\n \t\targ = argv[0];\n+\n+\t\tif (argc == 1 || strcmp(argv[1], \"--\"))\n+\t\t\tverify_non_filename(NULL, arg);\n \t\tif (get_sha1(arg, rev))\n \t\t\t;\n \t\telse if ((new.commit = lookup_commit_reference_gently(rev, 1))) {\ndiff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh\nnew file mode 100755\nindex 0000000..c1a86a2\n--- /dev/null\n+++ b/t/t2010-checkout-ambiguous.sh\n@@ -0,0 +1,26 @@\n+#!/bin/sh\n+\n+test_description='checkout and pathspecs/refspecs ambiguities'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'setup' '\n+\techo hello >world &&\n+\tgit add world &&\n+\tgit commit -m initial &&\n+\tgit branch world\n+'\n+\n+test_expect_success 'branch switching' '\n+\tgit checkout world --\n+'\n+\n+test_expect_success 'checkout world from the index' '\n+\tgit checkout -- world\n+'\n+\n+test_expect_success 'ambiguous call' '\n+\ttest_must_fail git checkout world\n+'\n+\n+test_done\n-- \n1.6.0.rc0.154.g60644\n"},{"id":"84424","messageId":"20080723011322.GH11831@artemis.madism.org","threadId":"14608","inReplyTo":"1216774940-4955-1-git-send-email-madcoder@debian.org","subject":"Re: [PATCH] git-checkout: fix argument parsing to detect ambiguous arguments.","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-23T01:13:22Z","receivedAt":"2008-07-23T01:13:22Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"On Wed, Jul 23, 2008 at 01:02:20AM +0000, Pierre Habouzit wrote:\n> Note that it also fix a bug, git checkout -- <path> would be badly\n> understood as git checkout <branch> if <path> is ambiguous with a branch.\n> \n> Testcases included.\n> \n> Signed-off-by: Pierre Habouzit <madcoder@debian.org>\n> ---\n> \n>   A user on #git happened to have issues that made me realize that\n>   builtin-checkout is badly broken wrt argument parseing.\n> \n>   This clearly needs to be applied to master, probably to maint too.\n> \n>   The patch is against next though, but should probably apply to other\n>   branches just fine.\n> \n> \n>  builtin-checkout.c            |    9 +++++++--\n>  t/t2010-checkout-ambiguous.sh |   27 +++++++++++++++++++++++++++\n>  2 files changed, 34 insertions(+), 2 deletions(-)\n>  create mode 100755 t/t2010-checkout-ambiguous.sh\n> \n> diff --git a/builtin-checkout.c b/builtin-checkout.c\n> index fbd5105..1490e8e 100644\n> --- a/builtin-checkout.c\n> +++ b/builtin-checkout.c\n> @@ -438,9 +438,14 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n>  \n>  \topts.track = git_branch_track;\n>  \n> -\targc = parse_options(argc, argv, options, checkout_usage, 0);\n> -\tif (argc) {\n> +\targc = parse_options(argc, argv, options, checkout_usage,\n> +\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n> +\n> +\tif (argc && strcmp(argv[0], \"--\")) {\n>  \t\targ = argv[0];\n> +\n> +\t\tif (argc == 1 || strcmp(argv[1], \"--\"))\n> +\t\t\tverify_non_filename(NULL, arg);\n>  \t\tif (get_sha1(arg, rev))\n>  \t\t\t;\n>  \t\telse if ((new.commit = lookup_commit_reference_gently(rev, 1))) {\n> diff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh\n> new file mode 100755\n> index 0000000..c1a86a2\n> --- /dev/null\n> +++ b/t/t2010-checkout-ambiguous.sh\n> @@ -0,0 +1,26 @@\n> +#!/bin/sh\n> +\n> +test_description='checkout and pathspecs/refspecs ambiguities'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success 'setup' '\n> +\techo hello >world &&\n> +\tgit add world &&\n> +\tgit commit -m initial &&\n> +\tgit branch world\n> +'\n> +\n> +test_expect_success 'branch switching' '\n> +\tgit checkout world --\n> +'\n> +\n> +test_expect_success 'checkout world from the index' '\n> +\tgit checkout -- world\n> +'\n\n  Okay those two tests are stupid in the sense that they don't check\ngit-checkout does what it's supposed to do. One should check the first\none outputs 'Switched to branch \"world\"'\n\n  and the second should rather be:\n\n'\n  echo \"bye bye\" > world &&\n  git checkout -- world &&\n  git diff --quiet --exit-code\n'\n\n"},{"id":"84426","messageId":"alpine.DEB.1.00.0807230215480.8986@racer","threadId":"14608","inReplyTo":"1216774940-4955-1-git-send-email-madcoder@debian.org","subject":"Re: [PATCH] git-checkout: fix argument parsing to detect ambiguous arguments.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-07-23T01:17:52Z","receivedAt":"2008-07-23T01:17:52Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 23 Jul 2008, Pierre Habouzit wrote:\n\n> diff --git a/builtin-checkout.c b/builtin-checkout.c\n> index fbd5105..1490e8e 100644\n> --- a/builtin-checkout.c\n> +++ b/builtin-checkout.c\n> @@ -438,9 +438,14 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n>  \n>  \topts.track = git_branch_track;\n>  \n> -\targc = parse_options(argc, argv, options, checkout_usage, 0);\n> -\tif (argc) {\n> +\targc = parse_options(argc, argv, options, checkout_usage,\n> +\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n> +\n> +\tif (argc && strcmp(argv[0], \"--\")) {\n>  \t\targ = argv[0];\n> +\n> +\t\tif (argc == 1 || strcmp(argv[1], \"--\"))\n> +\t\t\tverify_non_filename(NULL, arg);\n\nWhy \"argc == 1\"?  Should \"git checkout <path>\" really fail?  That would be \na change in behavior that _would_ hit me.\n\nHowever, you may want to verify_non_filename() when argc == 1 _and_ \nget_sha1() succeeded.  Because then, <path> is ambiguous.\n\nCiao,\nDscho\n"},{"id":"84429","messageId":"20080723012751.GI11831@artemis.madism.org","threadId":"14608","inReplyTo":"1216774940-4955-1-git-send-email-madcoder@debian.org","subject":"[RESEND PATCH] git-checkout: fix argument parsing to detect ambiguous arguments.","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-23T01:27:51Z","receivedAt":"2008-07-23T01:27:51Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"Note that it also fix a bug, git checkout -- <path> would be badly\nunderstood as git checkout <branch> if <path> is ambiguous with a branch.\n\nTestcases included.\n\nSigned-off-by: Pierre Habouzit <madcoder@debian.org>\n---\n\n  This is a resend with proper patches that made me realize that my\nprevious patch had silly mistakes and wasn't testing thigns properly.\n\n builtin-checkout.c            |   23 +++++++++++++++++------\n t/t2010-checkout-ambiguous.sh |   35 +++++++++++++++++++++++++++++++++++\n 2 files changed, 52 insertions(+), 6 deletions(-)\n create mode 100755 t/t2010-checkout-ambiguous.sh\n\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex fbd5105..97321e6 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -438,12 +438,17 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \n \topts.track = git_branch_track;\n \n-\targc = parse_options(argc, argv, options, checkout_usage, 0);\n-\tif (argc) {\n+\targc = parse_options(argc, argv, options, checkout_usage,\n+\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n+\n+\tif (argc && strcmp(argv[0], \"--\")) {\n+\t\tint may_be_ambiguous = argc == 1 || strcmp(argv[1], \"--\");\n+\n \t\targ = argv[0];\n-\t\tif (get_sha1(arg, rev))\n-\t\t\t;\n-\t\telse if ((new.commit = lookup_commit_reference_gently(rev, 1))) {\n+\t\tif (get_sha1(arg, rev)) {\n+\t\t\tif (may_be_ambiguous)\n+\t\t\t\tverify_filename(NULL, arg);\n+\t\t} else if ((new.commit = lookup_commit_reference_gently(rev, 1))) {\n \t\t\tnew.name = arg;\n \t\t\tsetup_branch_path(&new);\n \t\t\tif (resolve_ref(new.path, rev, 1, NULL))\n@@ -454,10 +459,16 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\t\tsource_tree = new.commit->tree;\n \t\t\targv++;\n \t\t\targc--;\n+\t\t\tif (may_be_ambiguous)\n+\t\t\t\tverify_non_filename(NULL, arg);\n \t\t} else if ((source_tree = parse_tree_indirect(rev))) {\n \t\t\targv++;\n \t\t\targc--;\n-\t\t}\n+\t\t\tif (may_be_ambiguous)\n+\t\t\t\tverify_non_filename(NULL, arg);\n+\t\t} else\n+\t\t\tif (may_be_ambiguous)\n+\t\t\t\tverify_filename(NULL, arg);\n \t}\n \n \tif (argc && !strcmp(argv[0], \"--\")) {\ndiff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh\nnew file mode 100755\nindex 0000000..389ba8c\n--- /dev/null\n+++ b/t/t2010-checkout-ambiguous.sh\n@@ -0,0 +1,35 @@\n+#!/bin/sh\n+\n+test_description='checkout and pathspecs/refspecs ambiguities'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'setup' '\n+\techo hello >world &&\n+\techo hello >all &&\n+\tgit add all world &&\n+\tgit commit -m initial &&\n+\tgit branch world\n+'\n+\n+test_expect_success 'branch switching' '\n+\ttest \"refs/heads/master\" = \"$(git symbolic-ref HEAD)\" &&\n+\tgit checkout world -- &&\n+\ttest \"refs/heads/world\" = \"$(git symbolic-ref HEAD)\"\n+'\n+\n+test_expect_success 'checkout world from the index' '\n+\techo bye > world &&\n+\tgit checkout -- world &&\n+\tgit diff --exit-code --quiet\n+'\n+\n+test_expect_success 'non ambiguous call' '\n+\tgit checkout all\n+'\n+\n+test_expect_success 'ambiguous call' '\n+\ttest_must_fail git checkout world\n+'\n+\n+test_done\n-- \n1.6.0.rc0.154.ge2a39.dirty\n\n"},{"id":"84431","messageId":"20080723013203.GJ11831@artemis.madism.org","threadId":"14608","inReplyTo":"alpine.DEB.1.00.0807230215480.8986@racer","subject":"Re: [PATCH] git-checkout: fix argument parsing to detect ambiguous arguments.","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-23T01:32:03Z","receivedAt":"2008-07-23T01:32:03Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"On Wed, Jul 23, 2008 at 01:17:52AM +0000, Johannes Schindelin wrote:\n> Hi,\n> \n> On Wed, 23 Jul 2008, Pierre Habouzit wrote:\n> \n> > diff --git a/builtin-checkout.c b/builtin-checkout.c\n> > index fbd5105..1490e8e 100644\n> > --- a/builtin-checkout.c\n> > +++ b/builtin-checkout.c\n> > @@ -438,9 +438,14 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n> >  \n> >  \topts.track = git_branch_track;\n> >  \n> > -\targc = parse_options(argc, argv, options, checkout_usage, 0);\n> > -\tif (argc) {\n> > +\targc = parse_options(argc, argv, options, checkout_usage,\n> > +\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n> > +\n> > +\tif (argc && strcmp(argv[0], \"--\")) {\n> >  \t\targ = argv[0];\n> > +\n> > +\t\tif (argc == 1 || strcmp(argv[1], \"--\"))\n> > +\t\t\tverify_non_filename(NULL, arg);\n> \n> Why \"argc == 1\"?  Should \"git checkout <path>\" really fail?  That would be \n> a change in behavior that _would_ hit me.\n\n  No I was mistaken about what verify_non_filename did, actually I\nshould not code when I'm so obviously tired, and I wanted\nverify_non_filename to do what I meant instead of checking what it does\n;P\n\n  I believe my resent patch is better.\n\n> However, you may want to verify_non_filename() when argc == 1 _and_ \n> get_sha1() succeeded.  Because then, <path> is ambiguous.\n\n  Yes and the reverse when we have sucessfully parsed something that\nlooks like a path as a path. Anyways, someone should carefully proofread\nmy resent patch, it's likely that errors slipped through given my sleep\ndeprivation atm.\n"},{"id":"84432","messageId":"20080723013946.GK11831@artemis.madism.org","threadId":"14608","inReplyTo":"20080723012751.GI11831@artemis.madism.org","subject":"Re: [RESEND PATCH] git-checkout: fix argument parsing to detect ambiguous arguments.","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-23T01:39:46Z","receivedAt":"2008-07-23T01:39:46Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"On Wed, Jul 23, 2008 at 01:27:51AM +0000, Pierre Habouzit wrote:\n> Note that it also fix a bug, git checkout -- <path> would be badly\n> understood as git checkout <branch> if <path> is ambiguous with a branch.\n> \n> Testcases included.\n> \n> Signed-off-by: Pierre Habouzit <madcoder@debian.org>\n> ---\n> \n>   This is a resend with proper patches that made me realize that my\n> previous patch had silly mistakes and wasn't testing thigns properly.\n> \n>  builtin-checkout.c            |   23 +++++++++++++++++------\n>  t/t2010-checkout-ambiguous.sh |   35 +++++++++++++++++++++++++++++++++++\n>  2 files changed, 52 insertions(+), 6 deletions(-)\n>  create mode 100755 t/t2010-checkout-ambiguous.sh\n> \n> diff --git a/builtin-checkout.c b/builtin-checkout.c\n> index fbd5105..97321e6 100644\n> --- a/builtin-checkout.c\n> +++ b/builtin-checkout.c\n> @@ -438,12 +438,17 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n>  \n>  \topts.track = git_branch_track;\n>  \n> -\targc = parse_options(argc, argv, options, checkout_usage, 0);\n> -\tif (argc) {\n> +\targc = parse_options(argc, argv, options, checkout_usage,\n> +\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n> +\n> +\tif (argc && strcmp(argv[0], \"--\")) {\n> +\t\tint may_be_ambiguous = argc == 1 || strcmp(argv[1], \"--\");\n> +\n>  \t\targ = argv[0];\n> -\t\tif (get_sha1(arg, rev))\n> -\t\t\t;\n> -\t\telse if ((new.commit = lookup_commit_reference_gently(rev, 1))) {\n> +\t\tif (get_sha1(arg, rev)) {\n> +\t\t\tif (may_be_ambiguous)\n> +\t\t\t\tverify_filename(NULL, arg);\n\n  Dscho mentionned on irc that this bit is superfluous, we already know\nthat 'arg' cannot be a refspec here, so in the worse case, if it's not a\nfile at all, this will generate a curious error message about\n\"ambiguous\" arguments, whereas it should fail with an \"unknown file\"\nerror or sth similar. This two lines should probably remain ';' like it\npreviously was.\n\n  The rest looks correct to me, but it's late...\n\n> +\t\t} else if ((new.commit = lookup_commit_reference_gently(rev, 1))) {\n>  \t\t\tnew.name = arg;\n>  \t\t\tsetup_branch_path(&new);\n>  \t\t\tif (resolve_ref(new.path, rev, 1, NULL))\n> @@ -454,10 +459,16 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n>  \t\t\tsource_tree = new.commit->tree;\n>  \t\t\targv++;\n>  \t\t\targc--;\n> +\t\t\tif (may_be_ambiguous)\n> +\t\t\t\tverify_non_filename(NULL, arg);\n>  \t\t} else if ((source_tree = parse_tree_indirect(rev))) {\n>  \t\t\targv++;\n>  \t\t\targc--;\n> -\t\t}\n> +\t\t\tif (may_be_ambiguous)\n> +\t\t\t\tverify_non_filename(NULL, arg);\n> +\t\t} else\n> +\t\t\tif (may_be_ambiguous)\n> +\t\t\t\tverify_filename(NULL, arg);\n>  \t}\n>  \n>  \tif (argc && !strcmp(argv[0], \"--\")) {\n> diff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh\n> new file mode 100755\n> index 0000000..389ba8c\n> --- /dev/null\n> +++ b/t/t2010-checkout-ambiguous.sh\n> @@ -0,0 +1,35 @@\n> +#!/bin/sh\n> +\n> +test_description='checkout and pathspecs/refspecs ambiguities'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success 'setup' '\n> +\techo hello >world &&\n> +\techo hello >all &&\n> +\tgit add all world &&\n> +\tgit commit -m initial &&\n> +\tgit branch world\n> +'\n> +\n> +test_expect_success 'branch switching' '\n> +\ttest \"refs/heads/master\" = \"$(git symbolic-ref HEAD)\" &&\n> +\tgit checkout world -- &&\n> +\ttest \"refs/heads/world\" = \"$(git symbolic-ref HEAD)\"\n> +'\n> +\n> +test_expect_success 'checkout world from the index' '\n> +\techo bye > world &&\n> +\tgit checkout -- world &&\n> +\tgit diff --exit-code --quiet\n> +'\n> +\n> +test_expect_success 'non ambiguous call' '\n> +\tgit checkout all\n> +'\n> +\n> +test_expect_success 'ambiguous call' '\n> +\ttest_must_fail git checkout world\n> +'\n> +\n> +test_done\n> -- \n> 1.6.0.rc0.154.ge2a39.dirty\n> \n\n\n"},{"id":"84455","messageId":"alpine.DEB.1.00.0807231158390.2830@eeepc-johanness","threadId":"14608","inReplyTo":"20080723012751.GI11831@artemis.madism.org","subject":"Re: [RESEND PATCH] git-checkout: fix argument parsing to detect ambiguous arguments.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-07-23T10:10:03Z","receivedAt":"2008-07-23T10:10:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 23 Jul 2008, Pierre Habouzit wrote:\n\n> Note that it also fix a bug, git checkout -- <path> would be badly\n\ns/fix/fixes/\n\n> understood as git checkout <branch> if <path> is ambiguous with a branch.\n> \n> Testcases included.\n> \n> Signed-off-by: Pierre Habouzit <madcoder@debian.org>\n\nInstead of the \"Testcases included\", I would have expected something like\n\n\tWhen calling \"git checkout <name>\" and <name> is both a path and a \n\tbranch, Git would silently assume that you meant the branch.  \n\tWorse, \"git checkout -- <name>\" would behave the same.\n\nprobably even as first paragraph.\n\n>   This is a resend with proper patches that made me realize that my\n\ns/patches/tests/\n\n> previous patch had silly mistakes and wasn't testing thigns properly.\n> \n>  builtin-checkout.c            |   23 +++++++++++++++++------\n>  t/t2010-checkout-ambiguous.sh |   35 +++++++++++++++++++++++++++++++++++\n>  2 files changed, 52 insertions(+), 6 deletions(-)\n>  create mode 100755 t/t2010-checkout-ambiguous.sh\n> \n> diff --git a/builtin-checkout.c b/builtin-checkout.c\n> index fbd5105..97321e6 100644\n> --- a/builtin-checkout.c\n> +++ b/builtin-checkout.c\n> @@ -438,12 +438,17 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n>  \n>  \topts.track = git_branch_track;\n>  \n> -\targc = parse_options(argc, argv, options, checkout_usage, 0);\n> -\tif (argc) {\n> +\targc = parse_options(argc, argv, options, checkout_usage,\n> +\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n> +\n> +\tif (argc && strcmp(argv[0], \"--\")) {\n> +\t\tint may_be_ambiguous = argc == 1 || strcmp(argv[1], \"--\");\n> +\n>  \t\targ = argv[0];\n> -\t\tif (get_sha1(arg, rev))\n> -\t\t\t;\n> -\t\telse if ((new.commit = lookup_commit_reference_gently(rev, 1))) {\n> +\t\tif (get_sha1(arg, rev)) {\n> +\t\t\tif (may_be_ambiguous)\n> +\t\t\t\tverify_filename(NULL, arg);\n\nStill you allow \"git checkout <path> --\" to succeed, right?  It should \nnot.\n\nIMHO you need \"must_be_branch\" and \"must_not_be_path\" instead of \n\"may_be_ambiguous\".\n\nI.e. something like\n\n\t\tint must_be_branch = argc > 1 && !strcmp(argv[1], \"--\");\n\t\tint must_not_be_path = argc > 1 && strcmp(argv[1], \"--\");\n\n\t\targ = argv[0];\n\t\tif (get_sha1(arg, rev)) {\n\t\t\tif (must_be_branch)\n\t\t\t\tdie (\"Not a branch: '%s'\", arg);\n\t\t}\n\t\telse {\n\t\t\tif (must_not_be_path)\n\t\t\t\tverify_non_filename(NULL, arg);\n\t\t\tif ((new.commit = lookup_commit_reference_gently(rev, 1))) {\n\t\t\t\t[...]\n\nAnd maybe you want to add a test for \"git checkout <path> --\" to fail, \ntoo.\n\nCiao,\nDscho\n"},{"id":"84459","messageId":"1216808133-31919-1-git-send-email-madcoder@debian.org","threadId":"14608","inReplyTo":"1216774940-4955-1-git-send-email-madcoder@debian.org","subject":"Resubmit after a night of sleep","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-23T10:15:31Z","receivedAt":"2008-07-23T10:15:31Z","isPatch":false,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"Okay, so after a (too short) night sleep, here is a way better series.\nThe first patch corrects a real bug, and should be applied to maint.\nIt's a one liner, the comment is self explanatory.\n\nThe second one is a twofold UI improvement wrt error messages that\ngit-checkout (if we abstract the issues from patch 1) already caught as\nerrors but with dreadful errors. And with respect to the case where\nthere is no '--' and that there is an ambiguity. We used to always favor\nthe interpretation where the first argument is understood as a\npath (which is really horrible because it's the destructive choice: at\nleast if we favored the reference, user would never loose local\nmodifications), it now barfs.\n\nI reckon I've not checked what git-checkout did when it wasn't a\nbuiltin, so I don't know if the second part of this UI improvement comes\nas fixing a regression (in which case the patch could be considered for\nmaint) or if it's an ambiguity that was here like forever, in which case\nit's less urgent, but should IMHO be addressed because git-checkout is\nporcelain: see http://gist.github.com/1402 for the user issue that made\nme discover that, you'll see we want a desambiguation one way or the\nother.\n"},{"id":"84457","messageId":"1216808133-31919-2-git-send-email-madcoder@debian.org","threadId":"14608","inReplyTo":"1216808133-31919-1-git-send-email-madcoder@debian.org","subject":"[PATCH 1/2] git-checkout: fix command line parsing.","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-23T10:15:32Z","receivedAt":"2008-07-23T10:15:32Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"This fixes an issue when you use:\n\n    $ git checkout -- <path1> [<paths>...]\n\nand that <path1> can also be understood as a reference. git-checkout\nmistakenly understands this as the same as:\n\n    $ git checkout <path1> -- [<paths>...]\n\nbecause parse-options was eating the '--' and the argument parser thought\nhe was parsing:\n\n    $ git checkout <path1> [<paths>...]\n\nWhere there indeed is an ambiguity\n\nSigned-off-by: Pierre Habouzit <madcoder@debian.org>\n---\n builtin-checkout.c |    3 ++-\n 1 files changed, 2 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex fbd5105..9cadf9c 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -438,7 +438,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \n \topts.track = git_branch_track;\n \n-\targc = parse_options(argc, argv, options, checkout_usage, 0);\n+\targc = parse_options(argc, argv, options, checkout_usage,\n+\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n \tif (argc) {\n \t\targ = argv[0];\n \t\tif (get_sha1(arg, rev))\n-- \n1.6.0.rc0.155.g8e50b\n"},{"id":"84458","messageId":"1216808133-31919-3-git-send-email-madcoder@debian.org","threadId":"14608","inReplyTo":"1216808133-31919-2-git-send-email-madcoder@debian.org","subject":"[PATCH 2/2] git-checkout: improve error messages, detect ambiguities.","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-23T10:15:33Z","receivedAt":"2008-07-23T10:15:33Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"The patch is twofold: it moves the option consistency checks just under\nthe parse_options call so that it doesn't get in the way of the tree\nreference vs. pathspecs desambiguation.\n\nThe other part rewrites the way to understand arguments so that when\ngit-checkout fails it does with an understandable message. Compared to the\nprevious behavior we now have:\n\n  - a better error message when doing:\n        git checkout <blob reference> --\n    now complains about the reference not pointing to a tree, instead of\n    things like:\n        error: pathspec <blob reference> did not match any file(s) known to git.\n        error: pathspec '--' did not match any file(s) known to git.\n\n    you what it spitted before.\n\n  - a better error message when doing:\n        git checkout <path> --\n    It now complains about <path> not being a reference instead of the\n    completely obscure:\n        error: pathspec '--' did not match any file(s) known to git.\n\n  - an error when -- wasn't used and the first argument is ambiguous.\n\nSigned-off-by: Pierre Habouzit <madcoder@debian.org>\n---\n builtin-checkout.c            |   71 +++++++++++++++++++++++++++++++----------\n t/t2010-checkout-ambiguous.sh |   39 ++++++++++++++++++++++\n 2 files changed, 93 insertions(+), 17 deletions(-)\n create mode 100755 t/t2010-checkout-ambiguous.sh\n\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 9cadf9c..e9ae834 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -430,6 +430,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOLEAN('m', NULL, &opts.merge, \"merge\"),\n \t\tOPT_END(),\n \t};\n+\tint has_dash_dash;\n \n \tmemset(&opts, 0, sizeof(opts));\n \tmemset(&new, 0, sizeof(new));\n@@ -440,11 +441,52 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\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+\n+\tif (opts.force && opts.merge)\n+\t\tdie(\"git checkout: -f and -m are incompatible\");\n+\n+\t/*\n+\t * case 1: git checkout <ref> -- [<paths>]\n+\t *\n+\t *   <ref> must be a valid tree, everything after the '--' must be\n+\t *   a path.\n+\t *\n+\t * case 2: git checkout -- [<paths>]\n+\t *\n+\t *   everything after the '--' must be paths.\n+\t *\n+\t * case 3: git checkout <something> [<paths>]\n+\t *\n+\t *   <something> shall not be ambiguous.\n+\t *   - If it's *only* a reference, treat it like case (1).\n+\t *   - If it's only a path, treat it like case (2).\n+\t *   - else: fail.\n+\t *\n+\t */\n \tif (argc) {\n+\t\tif (!strcmp(argv[0], \"--\")) {       /* case (2) */\n+\t\t\targv++;\n+\t\t\targc--;\n+\t\t\tgoto no_reference;\n+\t\t}\n+\t\t\n \t\targ = argv[0];\n-\t\tif (get_sha1(arg, rev))\n-\t\t\t;\n-\t\telse if ((new.commit = lookup_commit_reference_gently(rev, 1))) {\n+\t\thas_dash_dash = argc > 1 && !strcmp(argv[1], \"--\");\n+\n+\t\tif (get_sha1(arg, rev)) {\n+\t\t\tif (has_dash_dash)          /* case (1) */\n+\t\t\t\tdie(\"invalid reference: %s\", arg);\n+\t\t\tgoto no_reference;          /* case (3 -> 2) */\n+\t\t}\n+\n+\t\t/* we can't end up being in (2) anymore, eat the argument */\n+\t\targv++;\n+\t\targc--;\n+\n+\t\tif ((new.commit = lookup_commit_reference_gently(rev, 1))) {\n \t\t\tnew.name = arg;\n \t\t\tsetup_branch_path(&new);\n \t\t\tif (resolve_ref(new.path, rev, 1, NULL))\n@@ -453,25 +495,20 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\t\t\tnew.path = NULL;\n \t\t\tparse_commit(new.commit);\n \t\t\tsource_tree = new.commit->tree;\n-\t\t\targv++;\n-\t\t\targc--;\n-\t\t} else if ((source_tree = parse_tree_indirect(rev))) {\n+\t\t} else\n+\t\t\tsource_tree = parse_tree_indirect(rev);\n+\n+\t\tif (!source_tree)                   /* case (1): want a tree */\n+\t\t\tdie(\"reference is not a tree: %s\", arg);\n+\t\tif (!has_dash_dash)                 /* case (3 -> 1) */\n+\t\t\tverify_non_filename(NULL, arg);\n+\t\telse {\n \t\t\targv++;\n \t\t\targc--;\n \t\t}\n \t}\n \n-\tif (argc && !strcmp(argv[0], \"--\")) {\n-\t\targv++;\n-\t\targc--;\n-\t}\n-\n-\tif (!opts.new_branch && (opts.track != git_branch_track))\n-\t\tdie(\"git checkout: --track and --no-track require -b\");\n-\n-\tif (opts.force && opts.merge)\n-\t\tdie(\"git checkout: -f and -m are incompatible\");\n-\n+no_reference:\n \tif (argc) {\n \t\tconst char **pathspec = get_pathspec(prefix, argv);\n \ndiff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh\nnew file mode 100755\nindex 0000000..50d1f43\n--- /dev/null\n+++ b/t/t2010-checkout-ambiguous.sh\n@@ -0,0 +1,39 @@\n+#!/bin/sh\n+\n+test_description='checkout and pathspecs/refspecs ambiguities'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'setup' '\n+\techo hello >world &&\n+\techo hello >all &&\n+\tgit add all world &&\n+\tgit commit -m initial &&\n+\tgit branch world\n+'\n+\n+test_expect_success 'reference must be a tree' '\n+\ttest_must_fail git checkout $(git hash-object ./all) --\n+'\n+\n+test_expect_success 'branch switching' '\n+\ttest \"refs/heads/master\" = \"$(git symbolic-ref HEAD)\" &&\n+\tgit checkout world -- &&\n+\ttest \"refs/heads/world\" = \"$(git symbolic-ref HEAD)\"\n+'\n+\n+test_expect_success 'checkout world from the index' '\n+\techo bye > world &&\n+\tgit checkout -- world &&\n+\tgit diff --exit-code --quiet\n+'\n+\n+test_expect_success 'non ambiguous call' '\n+\tgit checkout all\n+'\n+\n+test_expect_success 'ambiguous call' '\n+\ttest_must_fail git checkout world\n+'\n+\n+test_done\n-- \n1.6.0.rc0.155.g8e50b\n"},{"id":"84470","messageId":"1216813762-23511-1-git-send-email-szeder@ira.uka.de","threadId":"14608","inReplyTo":"1216808133-31919-2-git-send-email-madcoder@debian.org","subject":"[PATCH] checkout: mention '--' in the docs","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2008-07-23T11:49:21Z","receivedAt":"2008-07-23T11:49:21Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"'git checkout' uses '--' to separate options from paths, but it was not\nmentioned in the documentation\n\nSigned-off-by: SZEDER Gábor <szeder@ira.uka.de>\n---\nAnd here are two small changes related to 'git checkout --'.\n\n Documentation/git-checkout.txt |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex 2abfbda..5aa69c0 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git checkout' [-q] [-f] [[--track | --no-track] -b <new_branch> [-l]] [-m] [<branch>]\n-'git checkout' [<tree-ish>] <paths>...\n+'git checkout' [<tree-ish>] [--] <paths>...\n \n DESCRIPTION\n -----------\n-- \n1.6.0.rc0.35.gb83a7\n"},{"id":"84471","messageId":"1216813762-23511-2-git-send-email-szeder@ira.uka.de","threadId":"14608","inReplyTo":"1216813762-23511-1-git-send-email-szeder@ira.uka.de","subject":"[PATCH] bash: offer only paths after '--' for 'git checkout'","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2008-07-23T11:49:22Z","receivedAt":"2008-07-23T11:49:22Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Commit d773c631 (bash: offer only paths after '--', 2008-07-08) did the\nsame for several other git commands, but 'git checkout' went unnoticed.\n\nSigned-off-by: SZEDER Gábor <szeder@ira.uka.de>\n---\n contrib/completion/git-completion.bash |    2 ++\n 1 files changed, 2 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 2edb341..9b51fda 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -626,6 +626,8 @@ _git_bundle ()\n \n _git_checkout ()\n {\n+\t__git_has_doubledash && return\n+\n \t__gitcomp \"$(__git_refs)\"\n }\n \n-- \n1.6.0.rc0.35.gb83a7\n"},{"id":"84635","messageId":"7v7ibc9p93.fsf@gitster.siamese.dyndns.org","threadId":"14608","inReplyTo":"1216808133-31919-3-git-send-email-madcoder@debian.org","subject":"Re: [PATCH 2/2] git-checkout: improve error messages, detect ambiguities.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-07-23T23:04:08Z","receivedAt":"2008-07-23T23:04:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pierre Habouzit <madcoder@debian.org> writes:\n\n> The patch is twofold: it moves the option consistency checks just under\n> the parse_options call so that it doesn't get in the way of the tree\n> reference vs. pathspecs desambiguation.\n\nI think this goes a bit too far.\n\nEven if you have a file called 'master' tracked in your project, when you\nsay:\n\n    $ git checkout master\n\nthat's almost always branch switching.  Forcing \"git checkout master --\"\ndisambiguation for such a common case is simply a wrong thing to do from\nthe usability point of view.\n\nSo how about (obviously we are interested only in the case without\ndisambiguating '--' here):\n\n    (3-1) if there is only one token left and if it is a rev, that's the\n          branch to check out or commit to detach to.\n\n    (3-2) otherwise the user might have mistyped one of the paths, so help\n          avoiding by making sure the first token is unambiguously either\n          a rev or a path (but not both).\n"},{"id":"84663","messageId":"7vljzs6nmd.fsf@gitster.siamese.dyndns.org","threadId":"14608","inReplyTo":"7v7ibc9p93.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] git-checkout: improve error messages, detect ambiguities.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-07-24T02:07:38Z","receivedAt":"2008-07-24T02:07:38Z","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> Pierre Habouzit <madcoder@debian.org> writes:\n>\n>> The patch is twofold: it moves the option consistency checks just under\n>> the parse_options call so that it doesn't get in the way of the tree\n>> reference vs. pathspecs desambiguation.\n>\n> I think this goes a bit too far.\n>\n> Even if you have a file called 'master' tracked in your project, when you\n> say:\n>\n>     $ git checkout master\n>\n> that's almost always branch switching.  Forcing \"git checkout master --\"\n> disambiguation for such a common case is simply a wrong thing to do from\n> the usability point of view.\n\nSo something like this on top of your patch.\n\n builtin-checkout.c            |   19 +++++++++++++++----\n t/t2010-checkout-ambiguous.sh |   15 +++++++++++++--\n 2 files changed, 28 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex d99c1c0..411cc51 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -460,7 +460,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t *\n \t * case 3: git checkout <something> [<paths>]\n \t *\n-\t *   <something> shall not be ambiguous.\n+\t *   With no paths, if <something> is a commit, that is to\n+\t *   switch to the branch or detach HEAD at it.\n+\t *\n+\t *   Otherwise <something> shall not be ambiguous.\n \t *   - If it's *only* a reference, treat it like case (1).\n \t *   - If it's only a path, treat it like case (2).\n \t *   - else: fail.\n@@ -474,7 +477,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\t}\n \n \t\targ = argv[0];\n-\t\thas_dash_dash = argc > 1 && !strcmp(argv[1], \"--\");\n+\t\thas_dash_dash = (argc > 1) && !strcmp(argv[1], \"--\");\n \n \t\tif (get_sha1(arg, rev)) {\n \t\t\tif (has_dash_dash)          /* case (1) */\n@@ -500,8 +503,16 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \n \t\tif (!source_tree)                   /* case (1): want a tree */\n \t\t\tdie(\"reference is not a tree: %s\", arg);\n-\t\tif (!has_dash_dash)                 /* case (3 -> 1) */\n-\t\t\tverify_non_filename(NULL, arg);\n+\t\tif (!has_dash_dash) {/* case (3 -> 1) */\n+\t\t\t/*\n+\t\t\t * Do not complain the most common case\n+\t\t\t *\tgit checkout branch\n+\t\t\t * even if there happen to be a file called 'branch';\n+\t\t\t * it would be extremely annoying.\n+\t\t\t */\n+\t\t\tif (argc)\n+\t\t\t\tverify_non_filename(NULL, arg);\n+\t\t}\n \t\telse {\n \t\t\targv++;\n \t\t\targc--;\ndiff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh\nindex 50d1f43..7cc0a35 100755\n--- a/t/t2010-checkout-ambiguous.sh\n+++ b/t/t2010-checkout-ambiguous.sh\n@@ -32,8 +32,19 @@ test_expect_success 'non ambiguous call' '\n \tgit checkout all\n '\n \n-test_expect_success 'ambiguous call' '\n-\ttest_must_fail git checkout world\n+test_expect_success 'allow the most common case' '\n+\tgit checkout world &&\n+\ttest \"refs/heads/world\" = \"$(git symbolic-ref HEAD)\"\n+'\n+\n+test_expect_success 'check ambiguity' '\n+\ttest_must_fail git checkout world all\n+'\n+\n+test_expect_success 'disambiguate checking out from a tree-ish' '\n+\techo bye > world &&\n+\tgit checkout world -- world &&\n+\tgit diff --exit-code --quiet\n '\n \n test_done\n"},{"id":"84689","messageId":"20080724083322.GB10950@artemis.madism.org","threadId":"14608","inReplyTo":"7v7ibc9p93.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] git-checkout: improve error messages, detect ambiguities.","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-24T08:33:22Z","receivedAt":"2008-07-24T08:33:22Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"On Wed, Jul 23, 2008 at 11:04:08PM +0000, Junio C Hamano wrote:\n> Pierre Habouzit <madcoder@debian.org> writes:\n> \n> > The patch is twofold: it moves the option consistency checks just under\n> > the parse_options call so that it doesn't get in the way of the tree\n> > reference vs. pathspecs desambiguation.\n> \n> I think this goes a bit too far.\n> \n> Even if you have a file called 'master' tracked in your project, when you\n> say:\n> \n>     $ git checkout master\n> \n> that's almost always branch switching.  Forcing \"git checkout master --\"\n> disambiguation for such a common case is simply a wrong thing to do from\n> the usability point of view.\n> \n> So how about (obviously we are interested only in the case without\n> disambiguating '--' here):\n> \n>     (3-1) if there is only one token left and if it is a rev, that's the\n>           branch to check out or commit to detach to.\n> \n>     (3-2) otherwise the user might have mistyped one of the paths, so help\n>           avoiding by making sure the first token is unambiguously either\n>           a rev or a path (but not both).\n\n  It sounds really reasonable, and your patch seems really fine.\n\n-- \n·O·  Pierre Habouzit\n··O                                                madcoder@debian.org\nOOO                                                http://www.madism.org\n"},{"id":"84944","messageId":"20080725203410.GA23202@spearce.org","threadId":"14608","inReplyTo":"1216813762-23511-2-git-send-email-szeder@ira.uka.de","subject":"Re: [PATCH] bash: offer only paths after '--' for 'git checkout'","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-07-25T20:34:10Z","receivedAt":"2008-07-25T20:34:10Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"SZEDER GGGbor <szeder@ira.uka.de> wrote:\n> Commit d773c631 (bash: offer only paths after '--', 2008-07-08) did the\n> same for several other git commands, but 'git checkout' went unnoticed.\n> \n> Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>\n\nAcked-by: Shawn O. Pearce <spearce@spearce.org>\n\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 2edb341..9b51fda 100755\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -626,6 +626,8 @@ _git_bundle ()\n>  \n>  _git_checkout ()\n>  {\n> +\t__git_has_doubledash && return\n> +\n>  \t__gitcomp \"$(__git_refs)\"\n>  }\n>  \n\n-- \nShawn.\n"}]}