Re* Inconsistent behavior of the path disambiguator

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dun Peal <dunpealer@xxxxxxxxx> 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:
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]