The HEAD in Git is the pointer to the current branch reference, which is in turn a pointer to the last commit you made or the last commit that was checked out into your working directory. That also means it will be the parent of the next commit you do.
The ~(tilde) and ^(caret) symbols are used to point to a position relative to a specific commit. The symbols are used together with a commit reference, typically HEAD or a commit hash.
The caret refers to the parent of a particular commit. E.g. HEAD^ refers to the parent of the current HEAD commmit.
By using the -a flag when committing you are telling Git to add all files that have been modified and then commit them. This runs into issues with new files, though. Since the -a flag only adds modified files it will not add new files or deleted files.
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.
While it is true that @
means HEAD
since Git 1.8.5 (Q3 2013), it... does not always work, not before Git 2.30 (Q1 2021),
"@
" sometimes worked (e.g. "git push origin @:there
as a part of a refspec element, but "git push origin @
" did not work, which has been corrected.
See commit 374fbae, commit e7f80ea, commit 12a30a3 (25 Nov 2020) by Felipe Contreras (felipec
).
(Merged by Junio C Hamano -- gitster
-- in commit c59b73b, 14 Dec 2020)
refspec
: make@
a synonym ofHEAD
Signed-off-by: Felipe Contreras
Since commit 9ba89f484e Git learned how to push to a remote branch using the source
@
, for example:git push origin @:master
However, if the right-hand side is missing, the push fails:
git push origin @
It is obvious what is the desired behavior, and allowing the push makes things more consistent.
Additionally,
@:master
now has the same semantics asHEAD:master
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With