Difference between "git checkout <filename>" and "git checkout -​- <filename>"
Asked Answered
L

4

141

http://norbauer.com/notebooks/code/notes/git-revert-reset-a-single-file

I have found a post.

But still don't know what is the difference between

  1. git checkout <filename>

  2. git checkout -- <filename>

In what situation I should use first one and second one respectively?

Lazor answered 3/7, 2011 at 4:45 Comment(1)
See also Meaning of Git checkout double dashes.World
B
269

The special "option" -- means "treat every argument after this point as a file name, no matter what it looks like." This is not Git-specific, it's a general Unix command line convention. Normally you use it to clarify that an argument is a file name rather than an option, e.g.

rm -f      # does nothing
rm -- -f   # deletes a file named "-f"

git checkout1 also takes -- to mean that subsequent arguments are not its optional "treeish" parameter specifying which commit you want.

So in this context it's safe to use -- always, but you need it when the file you want to revert has a name that begins with -, or is the same as the name of a branch. Some examples for branch/file disambiguation:

git checkout README     # would normally discard uncommitted changes
                        # to the _file_ "README"

git checkout master     # would normally switch the working copy to
                        # the _branch_ "master"

git checkout -- master  # discard uncommitted changes to the _file_ "master"

and option/file disambiguation:

git checkout -p -- README  # interactively discard uncommitted changes
                           # to the file "README"

git checkout -- -p README  # unconditionally discard all uncommitted
                           # changes to the files "-p" and "README"

I'm not sure what you do if you have a branch whose name begins with -. Perhaps don't do that in the first place.


1 in this mode; "checkout" can do several other things as well. I have never understood why git chose to implement "discard uncommitted changes" as a mode of the "checkout" subcommand, rather than "revert" like most other VCSes, or "reset" which I think might make more sense in git's own terms.

Benjamin answered 3/7, 2011 at 4:51 Comment(6)
git checkout <name> checks out the branch <name>. git checkout -- <name> checks out the index version of the file <name>.Elboa
Thanks, unfortunately the git documentation doesn't really explain thisBotchy
Regarding "Unix convention": indeed -- as a separator between options and arguments is widely implemented. It works for any program/utility that uses POSIX getopt(3) to handle its command line options, (see man 3 getopt), shell-scripts which use getopt(1), and some programs which implement it themselves, but is not universally guaranteed to work.Friesen
Hah! I simply read an example way back when of how to discard working changes, having forgotten seeing this convention in other command-line programs, assumed that -- meant 'negate changes' a la C/C++ - and have been thinking that ever since. Mind blown!Kerwon
For people like me: don't get confused by name master, he means file named master and not the branch.Calices
@Calices What part of the answer did you find confusing? I would like to clarify it.Benjamin
U
12

Anything following the -- is treated as a filename (not as a program argument). This is important if, for example, you have filenames which start with dashes.

Underling answered 3/7, 2011 at 4:52 Comment(1)
This is the best answer. It is short and clear.Prostration
B
0
git checkout -- filename

will replace the version of the file you have in working directory with the one you have in index(staging area).

git checkout filename

will try to checkout the branch with the same name, if it doesn't exist then it will perform same operation as git checkout -- <filename>

Brat answered 30/1, 2023 at 4:33 Comment(0)
T
0

The difference between git checkout <filename> and git checkout -- <filename> lies in the handling of unmerged changes.

git checkout <filename> discards the changes in the current branch and replaces the file with the version from the specified branch or commit. If you have unmerged changes in the file, this command will fail and you'll get an error message.

git checkout -- <filename> discards all changes in the file, including any unmerged changes. This is useful when you want to completely discard your local changes and start over with the version from the specified branch or commit.

In summary, git checkout <filename> is used to switch to a specific version of a file while preserving the changes that have been merged into the current branch, while git checkout -- <filename> discards all changes in a file, including unmerged changes.

Trout answered 30/1, 2023 at 7:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.