Re: Inconsistent behavior of the path disambiguator
From: Jonathan Nieder <hidden>
Date: 2016-06-15 22:49:56
Subsystem:
the rest · Maintainer:
Linus Torvalds
Possibly related (same subject, not in this thread)
- 2016-06-15 · Inconsistent behavior of the path disambiguator · Dun Peal <hidden>
- 2016-06-15 · Re: Inconsistent behavior of the path disambiguator · Junio C Hamano <hidden>
Junio C Hamano wrote:
I can see why this is confusing, though. Dun Peal [off-list ref] writes:quoted
$ git checkout foo -- fatal: invalid reference: fooImmediately after a clone you would have refs/heads/master refs/HEAD -> refs/heads/master refs/remotes/origin/foo refs/remotes/origin/whatever-else-you-have ... and there is no commit that you can name with "foo" when asking git to check out some paths out of, nor there is no branch that you can name with "foo" when asking git to check out to work on it.
How about something like this? -- 8< -- Subject: checkout: apply Dscho's dwim even with "--" present git reset and similar commands use -- to disambiguate between revisions and paths on the command line. The same syntax is not necessary to specify a revision to git checkout (for convenience and historical reasons, revisions are preferred over paths), but for consistency it is accepted: git checkout master --; # check out master branch, not "master" file. The autovivification of branches introduced by 70c9ac2f1 (DWIM "git checkout frotz" to "git checkout -b frotz origin/frotz", 2009-10-18) is currently disabled by that syntax, for no good reason. Paranoid scripts can still use git checkout --no-guess master or even better, old=$(git rev-parse --verify HEAD) new=$(git rev-parse --verify refs/heads/master^0) git read-tree -m -u --exclude-standard $old $new git symbolic-ref -m "$me: switching branches" HEAD refs/heads/master Requested-by: Dun Peal [off-list ref] Signed-off-by: Jonathan Nieder <redacted> ---
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 9240faf..1dc3640 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c@@ -771,6 +771,12 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) * <ref> must be a valid tree, everything after the '--' must be * a path. * + * Except: with no paths, if <something> does not resolve as + * an object, no -t nor -b was given, and there is a tracking + * branch whose name is <something> in one and only one remote, + * then this is a short-hand to fork local <something> from + * that remote-tracking branch. + * * case 2: git checkout -- [<paths>] * * everything after the '--' must be paths.
@@ -808,13 +814,11 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) arg = "@{-1}"; if (get_sha1_mb(arg, rev)) { - if (has_dash_dash) /* case (1) */ - die("invalid reference: %s", arg); 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))
@@ -822,9 +826,11 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) opts.new_branch = arg; arg = remote; /* DWIMmed to create local branch */ - } - else + } else if (has_dash_dash) { /* case (1) */ + die("invalid reference: %s", arg); + } else { goto no_reference; + } } /* we can't end up being in (2) anymore, eat the argument */