134

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?

Paul Roub
  • 35,848
  • 27
  • 79
  • 88
TheOneTeam
  • 24,336
  • 44
  • 110
  • 154
  • 1
    See also [Meaning of Git checkout double dashes](http://stackoverflow.com/q/13321458/456814). –  May 23 '14 at 20:37

2 Answers2

250

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.

zwol
  • 129,170
  • 35
  • 235
  • 347
  • 14
    git checkout checks out the branch . git checkout -- checks out the index version of the file . – dunni Jul 03 '11 at 09:33
  • 3
    Thanks, unfortunately the git documentation doesn't really explain this – Carlton Dec 13 '13 at 10:57
  • 1
    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. – arielf Mar 22 '16 at 17:56
  • 1
    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! – underscore_d Jul 19 '16 at 13:38
  • For people like me: don't get confused by name master, he means file named master and not the branch. – HarsH Aug 14 '19 at 23:54
  • @HarsH What part of the answer did you find confusing? I would like to clarify it. – zwol Aug 15 '19 at 16:13
11

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.

jtbandes
  • 110,948
  • 34
  • 232
  • 256