git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re* Inconsistent behavior of the path disambiguator

From
Junio C Hamano <gitster@pobox.com>
Date
Oct 29, 2010, 20:19 UTC
Message-ID
<7vwrp069aq.fsf_-_@alter.siamese.dyndns.org>
In-Reply-To
<AANLkTikc+pBe31j9tA88HwGz2kBouW_0S9oU6PtSQEzj@mail.gmail.com>
Dun Peal <dunpealer@gmail.com> writes:
> It makes no sense IMHO for the disambiguating syntax to break that
> behavior,...
Ahh, Ok, and sorry, I think I misread your original.

I agree that there shouldn't be any difference between "git co foo" and "git co foo --" when you do not have local "foo" (i.e. immediately after cloning from somebody who has "foo").

Perhaps something like this...
 builtin/checkout.c |   52 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 9240faf..ceaf479 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -804,17 +804,30 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		arg = argv[0];
 		has_dash_dash = (argc > 1) && !strcmp(argv[1], "--");
 
+		if (has_dash_dash) {
+			argv++;
+			argc--;
+			/*
+			 * Copy arg so that argv[] ends up being all
+			 * paths if arg turns out to be a non-ref.
+			 */
+			argv[0] = arg;
+		}
+
+		/*
+		 * arg may be a ref; or it may be the first of the
+		 * paths, if we did not see dash-dash.
+		 */
 		if (!strcmp(arg, "-"))
 			arg = "@{-1}";
 
 		if (get_sha1_mb(arg, rev)) {
-			if (has_dash_dash)          /* case (1) */
-				die("invalid reference: %s", arg);
+			/* Not a ref */
 			if (!patch_mode &&
 			    dwim_new_local_branch &&
 			    opts.track == BRANCH_TRACK_UNSPECIFIED &&
 			    !opts.new_branch &&
-			    !check_filename(NULL, arg) &&
+			    (has_dash_dash || !check_filename(NULL, arg)) &&
 			    argc == 1) {
 				const char *remote = unique_tracking_name(arg);
 				if (!remote || get_sha1(remote, rev))
@@ -823,11 +836,26 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 				arg = remote;
 				/* DWIMmed to create local branch */
 			}
-			else
+			else {
 				goto no_reference;
+			}
+		} else if (!has_dash_dash && argc > 1) {
+			/*
+			 * We saw "checkout foo bar" without dashdash,
+			 * and "foo" can name an object.  It shouldn't
+			 * be a filename. Note that by checking argc,
+			 * we do not complain in the most common case
+			 *	git checkout branch
+			 * even if there happen to be a file called 'branch';
+			 * it would be extremely annoying.
+			 */
+			verify_non_filename(NULL, arg);
 		}
 
-		/* we can't end up being in (2) anymore, eat the argument */
+		/*
+		 * It turns out that we had a ref, so argv[1:] are the
+		 * paths (we stripped dash-dash already).
+		 */
 		argv++;
 		argc--;
 
@@ -847,20 +875,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 
 		if (!source_tree)                   /* case (1): want a tree */
 			die("reference is not a tree: %s", arg);
-		if (!has_dash_dash) {/* case (3 -> 1) */
-			/*
-			 * Do not complain the most common case
-			 *	git checkout branch
-			 * even if there happen to be a file called 'branch';
-			 * it would be extremely annoying.
-			 */
-			if (argc)
-				verify_non_filename(NULL, arg);
-		}
-		else {
-			argv++;
-			argc--;
-		}
 	}
 
 no_reference:
Previous: Dun PealNext: Jonathan Nieder
Message 4 of 10 in “Inconsistent behavior of the path disambiguator”
  1. Dun PealOct 29, 2010
  2. Junio C HamanoOct 29, 2010
  3. Dun PealOct 29, 2010
  4. Re* Inconsistent behavior of the path disambiguatorJunio C Hamano, Oct 29, 2010
  5. Jonathan NiederOct 29, 2010
  6. Junio C HamanoOct 29, 2010
  7. checkout: apply Dscho's dwim even with "--" presentJonathan Nieder, Oct 29, 2010
  8. Jonathan NiederOct 29, 2010
  9. Jonathan NiederOct 30, 2010
  10. Junio C HamanoOct 31, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.