The at-sign @
is often used in git to specify revisions in different
ways. For example,
<ref>@{<date>}
specifies the reference at its state on <date>
.
Example: git diff master@{yesterday} master
.
<ref>@{<n>}
specific the reference at its nth prior state.
Example: git diff master@{1} master
.
@{-<n>}
specifies the nth previously checked-out branch before
the current one.
Example: git checkout @{-5}
.
<ref>@{upstream}
specifies the upstream branch for the reference.
Example: git diff master@{upstream} master
.
However, the @
is being used in other ways in git commands too, like
git rebase -i @~4
git log @^^..@
What does the at-sign @
mean in those examples?
As of Git version 1.8.5, the at-sign @
, without a leading branch/reference name and ordinal {n}
suffix like HEAD@{1}
and master@{1}
, is just a synonym/alias/shortcut for the special Git reference HEAD
:
Instead of typing four capital letters "HEAD", you can say "@" now, e.g. "git log @".
So for these commands
git rebase -i @~4
git log @^^..@
you can simply substitute the first occurrence of @
with HEAD
(or head
if using Windows or OS X)
git rebase -i HEAD~4
git log HEAD^^..HEAD
So what does HEAD
mean? As explained by the official Linux Kernel Git documentation for specifying Git revisions, HEAD
is a special shortcut reference for the commit that you currently have checked-out as your working copy (or in Git terms, your "working tree"):
HEAD names the commit on which you based the changes in the working tree.
You can also read these other Stack Overflow questions on what the special reference HEAD
means:
VonC also found interesting information about why @
was chosen as a shortcut for head
in this Stack Overflow answer (the last section at the bottom).
Note that like it often happens with Git, while @
is a convenient shortcut, it isn't always a valid replacement for HEAD
. Example:
$ git bundle create temp.bundle @
Enumerating objects: 25, done.
Counting objects: 100% (25/25), done.
Compressing objects: 100% (20/20), done.
Total 25 (delta 3), reused 0 (delta 0), pack-reused 0
$ git bundle list-heads temp.bundle
c006e049da432677d1a27f0eba661671e0524710 refs/heads/master
$ git bundle create temp.bundle HEAD
Enumerating objects: 25, done.
Counting objects: 100% (25/25), done.
Compressing objects: 100% (20/20), done.
Total 25 (delta 3), reused 0 (delta 0), pack-reused 0
$ git bundle list-heads temp.bundle
c006e049da432677d1a27f0eba661671e0524710 HEAD
In this case, using @
is more like a replacement for master
(the branch that HEAD
happened to be pointing to) rather than for HEAD
. If you try to fetch from the resulting bundle later, you'll have to specify the ref you want to fetch (master
) if you used @
, and you won't have to to it if you specified HEAD
explicitly.