Reputation: 4490
What is the meaning of the double dashes before the file name in this git command?
git checkout --ours -- path/to/file.txt
git checkout --theirs -- path/to/file.txt
Are they mandatory? Is it equivalent to
git checkout --ours path/to/file.txt
git checkout --theirs path/to/file.txt
Upvotes: 334
Views: 51896
Reputation: 1324505
Note that you would not need, since Git 2.5 (Q2 2015) a '--
' if your argument includes wildcard (*
)
An heuristic to help the "git <cmd> <revs> <pathspec>
" command line convention to catch mistyped paths is to make sure all the non-rev parameters in the later part of the command line are names of the files in the working tree, but that means "git grep $str -- \*.c
" must always be disambiguated with "--
", because nobody sane will create a file whose name literally is asterisk-dot-see.
Git 2.5 looses the heuristic to declare that with a wildcard string the user likely meant to give us a pathspec.
git checkout 'a*'
# same as
git checkout -- 'a*'
See commit 28fcc0b (02 May 2015) by Duy Nguyen (nguyenlocduy
).
(Merged by Junio C Hamano -- gitster
-- in commit 949d167, 19 May 2015)
pathspec
: avoid the need of "--
" when wildcard is usedWhen "
--
" is lacking from the command line and a command can take both revs and paths, the idea is if an argument can be seen as both an extended SHA-1 and a path, then "--
" is required or git refuses to continue.
It's currently implemented as:
- (1) if an argument is rev, then it must not exist in worktree
- (2) else, it must exist in worktree
- (3) else, "
--
" is required.These rules work for literal paths, but when non-literal pathspec is involved, it almost always requires the user to add "
--
" because it fails (2) and (1) is really rarely met (take "*.c
" for example, (1) is met if there is a ref named "*.c
").This patch modifies the rules a bit by considering any valid (
*
) wildcard pathspec "exist in worktree".
The rules become:
- (1) if an arg is a rev, then it must either exist in worktree or not be a valid wildcard pathspec.
- (2) else, it either exists in worktree or is a wildcard pathspec
- (3) else, "
--
" is required.With the new rules, "
--
" is not needed most of the time when wildcard pathspec is involved.
With Git 2.26 (Q1 2020), the disambiguation logic to tell revisions and pathspec apart has been tweaked so that backslash-escaped glob special characters do not count in the "wildcards are pathspec" rule.
See commit 39e21c6 (25 Jan 2020) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
-- in commit 341f8a6, 12 Feb 2020)
verify_filename()
: handle backslashes in "wildcards are pathspecs" ruleReported-by: David Burström
Signed-off-by: Jeff KingCommit 28fcc0b71a (
pathspec
: avoid the need of "--
" when wildcard is used, 2015-05-02) allowed:git rev-parse '*.c'
without the double-dash.
But the rule it uses to check for wildcards actually looks for any glob special.
This is overly liberal, as it means that a pattern that doesn't actually do any wildcard matching, like "a\b
", will be considered a pathspec.If you do have such a file on disk, that's presumably what you wanted.
But if you don't, the results are confusing: rather than say "there's no such path a\b
", we'll quietly accept it as a pathspec which very likely matches nothing (or at least not what you intended).
Likewise, looking for path "a\*b
" doesn't expand the search at all; it would only find a single entry, "a*b
".This commit switches the rule to trigger only when glob metacharacters would expand the search, meaning both of those cases will now report an error (you can still disambiguate using "
--
", of course; we're just tightening the DWIM heuristic).
Note that we didn't test the original feature in 28fcc0b71a at all.
So this patch not only tests for these corner cases, but also adds a regression test for the existing behavior.
Upvotes: 1
Reputation: 213338
Suppose I have a file named path/to/file.txt
in my Git repository, and I want to revert changes on it.
git checkout path/to/file.txt
Now suppose that the file is named master
...
git checkout master
Whoops! That changed branches instead. The --
separates the tree you want to check out from the files you want to check out.
git checkout -- master
It also helps us if some freako added a file named -f
to our repository:
git checkout -f # wrong
git checkout -- -f # right
This is documented in git-checkout: Argument Disambiguation.
Upvotes: 464
Reputation: 1879
The double dash "--" means "end of command line flags" i.e. it tells the preceding command not to try to parse what comes after command line options.
Upvotes: 132