What is the meaning of - (single dash) in "git checkout - ..."?

Viewed 2849

In my repository, I had some changes (let's say that all the edited files' paths started with abc_) that I wanted to discard, with the command:

git checkout -- abc_*

However, I made a typo and instead of two dashes I used only one:

git checkout - abc_*

Looks like instead of discarding the changes, the command added even more changes to be committed - in fact, it added a few hundred files whose names started with abc_ (but not all of them in the project!).

My question is: What have I just done? Or, more precisely: what does the dash stand for?

All the answers that I was able to find explained what two dashes (--) do, but I understand this. I also believe I understand how git checkout works, both with the branch/tree-ish argument or with file paths. I cannot find any information on the single dash meaning, however - dashes are also used to designate parameters (e.g. git checkout -b ...), and it makes searching for this command problematic.

3 Answers

The single dash here means the previous active branch or detached HEAD.

Case 1:

git checkout master
git checkout dev

# here - means master
git checkout -

# here - means dev
git checkout -

Case 2:

# detached HEAD
git checkout refs/heads/master
# back to master
git checkout master

# detached HEAD again
git checkout -

# master again
git checkout -

So git checkout - abc_* means to overwrite paths (abc_*) in the working tree by replacing with the contents in the previous active branch or detached HEAD. See git checkout

-- is a special argument that tells Git that the arguments that follow it are paths; those before it are something else (command options, remote names, branch names, tag names etc.)

- in git checkout - is the branch name. - is a alias of "@{-1}" which represents the name of the previous current branch (the branch that was the current branch before the last git checkout command that was used to change the branch).

As others already answered, git checkout - checkouts the last branch. Check the release notes:

@{-1} is a way to refer to the last branch you were on.
This is accepted not only where an object name is expected, but anywhere a branch name is expected and acts as if you typed the branch name. E.g. "git branch --track mybranch @{-1}", "git merge @{-1}", and "git rev-parse --symbolic-full-name @{-1}" would work as expected.

In order to demonstrate what happened, let's try this example:

$ (master) echo 'Hello from master' > test
$ (master) git commit -am 'Hello from master'

Now let's create another branch, branch_1 and modify the "test" file:

$ (master) git checkout branch_1
$ (branch_1) echo 'Hello from branch_1' > test
$ (branch_1) git commit -am 'Hello from branch_1'

If you now run git checkout -, you'll get back to master:

$ (branch_1) git checkout -
$ (master)

Finally, running git checkout - test will checkout the test file from the branch_1 branch:

$ (master) git checkout - test
Updated 1 path from e2bcb78
$ git diff --cached
@@ -1 +1 @@
-Hello from master
+Hello from branch_1
Related