Junio C Hamano wrote: > I can see why this is confusing, though. > > Dun Peal <dunpealer@xxxxxxxxx> writes: >> $ git checkout foo -- >> fatal: invalid reference: foo > > Immediately 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 <dunpealer@xxxxxxxxx> Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx> --- 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 */ -- 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