Skip to content

Commit 31b83f3

Browse files
committed
Merge branch 'nd/checkout-disambiguation'
"git checkout <word>" does not follow the usual disambiguation rules when the <word> can be both a rev and a path, to allow checking out a branch 'foo' in a project that happens to have a file 'foo' in the working tree without having to disambiguate. This was poorly documented and the check was incorrect when the command was run from a subdirectory. * nd/checkout-disambiguation: checkout: fix ambiguity check in subdir checkout.txt: document a common case that ignores ambiguation rules checkout: add some spaces between code and comment
2 parents 8969fea + b829b94 commit 31b83f3

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

Documentation/git-checkout.txt

+12
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,18 @@ $ git reflog -2 HEAD # or
419419
$ git log -g -2 HEAD
420420
------------
421421

422+
ARGUMENT DISAMBIGUATION
423+
-----------------------
424+
425+
When there is only one argument given and it is not `--` (e.g. "git
426+
checkout abc"), and when the argument is both a valid `<tree-ish>`
427+
(e.g. a branch "abc" exists) and a valid `<pathspec>` (e.g. a file
428+
or a directory whose name is "abc" exists), Git would usually ask
429+
you to disambiguate. Because checking out a branch is so common an
430+
operation, however, "git checkout abc" takes "abc" as a `<tree-ish>`
431+
in such a situation. Use `git checkout -- <pathspec>` if you want
432+
to checkout these paths out of the index.
433+
422434
EXAMPLES
423435
--------
424436

builtin/checkout.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ static int parse_branchname_arg(int argc, const char **argv,
985985
int recover_with_dwim = dwim_new_local_branch_ok;
986986

987987
if (!has_dash_dash &&
988-
(check_filename(NULL, arg) || !no_wildcard(arg)))
988+
(check_filename(opts->prefix, arg) || !no_wildcard(arg)))
989989
recover_with_dwim = 0;
990990
/*
991991
* Accept "git checkout foo" and "git checkout foo --"
@@ -1038,15 +1038,15 @@ static int parse_branchname_arg(int argc, const char **argv,
10381038

10391039
if (!*source_tree) /* case (1): want a tree */
10401040
die(_("reference is not a tree: %s"), arg);
1041-
if (!has_dash_dash) {/* case (3).(d) -> (1) */
1041+
if (!has_dash_dash) { /* case (3).(d) -> (1) */
10421042
/*
10431043
* Do not complain the most common case
10441044
* git checkout branch
10451045
* even if there happen to be a file called 'branch';
10461046
* it would be extremely annoying.
10471047
*/
10481048
if (argc)
1049-
verify_non_filename(NULL, arg);
1049+
verify_non_filename(opts->prefix, arg);
10501050
} else {
10511051
argcount++;
10521052
argv++;

t/t2010-checkout-ambiguous.sh

+9
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ test_expect_success 'check ambiguity' '
4141
test_must_fail git checkout world all
4242
'
4343

44+
test_expect_success 'check ambiguity in subdir' '
45+
mkdir sub &&
46+
# not ambiguous because sub/world does not exist
47+
git -C sub checkout world ../all &&
48+
echo hello >sub/world &&
49+
# ambiguous because sub/world does exist
50+
test_must_fail git -C sub checkout world ../all
51+
'
52+
4453
test_expect_success 'disambiguate checking out from a tree-ish' '
4554
echo bye > world &&
4655
git checkout world -- world &&

t/t2024-checkout-dwim.sh

+12
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,18 @@ test_expect_success 'checkout of branch with a file having the same name fails'
174174
test_branch master
175175
'
176176

177+
test_expect_success 'checkout of branch with a file in subdir having the same name fails' '
178+
git checkout -B master &&
179+
test_might_fail git branch -D spam &&
180+
181+
>spam &&
182+
mkdir sub &&
183+
mv spam sub/spam &&
184+
test_must_fail git -C sub checkout spam &&
185+
test_must_fail git rev-parse --verify refs/heads/spam &&
186+
test_branch master
187+
'
188+
177189
test_expect_success 'checkout <branch> -- succeeds, even if a file with the same name exists' '
178190
git checkout -B master &&
179191
test_might_fail git branch -D spam &&

0 commit comments

Comments
 (0)