What do these symbols refer to and what do they mean?
(I can't find any explanation in official documentation)
What do these symbols refer to and what do they mean?
(I can't find any explanation in official documentation)
HEAD
is (direct or indirect, i.e. symbolic) reference to the current commit. It is a commit that you have checked in the working directory (unless you made some changes, or equivalent), and it is a commit on top of which "git commit" would make a new one. Usually HEAD
is symbolic reference to some other named branch; this branch is currently checked out branch, or current branch. HEAD
can also point directly to a commit; this state is called "detached HEAD", and can be understood as being on unnamed, anonymous branch.
And @
alone is a shortcut for HEAD
, since Git 1.8.5
ORIG_HEAD
is previous state of HEAD
, set by commands that have possibly dangerous behavior, to be easy to revert them. It is less useful now that Git has reflog: HEAD@{1}
is roughly equivalent to ORIG_HEAD
(HEAD@{1}
is always last value of HEAD
, ORIG_HEAD
is last value of HEAD
before dangerous operation).
For more information read git(1) manpage / [gitrevisions(7) manpage][git-revisions], Git User's Manual, the Git Community Book and Git Glossary
HEAD
and ORIG_HEAD
). –
Stellular git show ORIG_HEAD
is a good sanity check before using that revision in a command –
Settee HEAD
is not identical to @
. Here are a bunch of screenshots. –
Breadboard @
, which probably shouldn't be allowed. git-scm.com/docs/gitrevisions says explicitly "@ alone is a shortcut for HEAD" –
Faliscan HEAD
of the last fetch from the origin
remote… :) –
Calais ORIG_HEAD
From git reset
"pull" or "merge" always leaves the original tip of the current branch in
ORIG_HEAD
.git reset --hard ORIG_HEAD
Resetting hard to it brings your index file and the working tree back to that state, and resets the tip of the branch to that commit.
git reset --merge ORIG_HEAD
After inspecting the result of the merge, you may find that the change in the other branch is unsatisfactory. Running "
git reset --hard ORIG_HEAD
" will let you go back to where you were, but it will discard your local changes, which you do not want. "git reset --merge
" keeps your local changes.
Before any patches are applied, ORIG_HEAD is set to the tip of the current branch.
This is useful if you have problems with multiple commits, like running 'git am
' on the wrong branch or an error in the commits that is more easily fixed by changing the mailbox (e.g. +errors in the "From:" lines).In addition, merge always sets '
.git/ORIG_HEAD
' to the original state of HEAD so a problematic merge can be removed by using 'git reset ORIG_HEAD
'.
Git 2.40 (Q1 2023) documents ORIG_HEAD
a bit more:
See commit f1c9243, commit c6eec9c, commit 0c514d5, commit d03c773, commit e29678b (10 Jan 2023) by Philippe Blain (phil-blain
).
(Merged by Junio C Hamano -- gitster
-- in commit 9c2003a, 21 Jan 2023)
git-rebase.txt
: add a note about 'ORIG_HEAD
' being overwrittenReported-by: Erik Cervin Edin
Signed-off-by: Philippe Blain
Acked-by: Phillip Wood
'
ORIG_HEAD
' is written at the start of the rebase, but is not guaranteed to still point to the original branch tip at the end of the rebase.Indeed, using other commands that write '
ORIG_HEAD
' during the rebase, like splitting a commit using 'git reset
'(man) HEAD^', will lead to 'ORIG_HEAD
' being overwritten.
This causes confusion for some users.Add a note about that in the 'Description' section, and mention the more robust alternative of using the branch's reflog.
git rebase
now includes in its man page:
[NOTE]
:
ORIG_HEAD
is not guaranteed to still point to the previous branch tip at the end of the rebase if other commands that write that pseudo-ref (e.g.git reset
) are used during the rebase.
The previous branch tip, however, is accessible using the reflog of the current branch (i.e.@{1}
).
And:
revisions.txt
: be explicit about commands writing 'ORIG_HEAD
'Signed-off-by: Philippe Blain
Acked-by: Phillip Wood
When mentioning '
ORIG_HEAD
', be explicit about which command write that pseudo-ref, namely 'git am
'(man), 'git merge
'(man), 'git rebase
'(man) and 'git reset
'(man).
revisions
now includes in its man page:
ORIG_HEAD
is created by commands that move yourHEAD
in a drastic way (git am
,git merge
,git rebase
,git reset
), to record the position of theHEAD
before their operation, so that you can easily change the tip of the branch back to the state before you ran them.
HEAD
Note: from here
HEAD is a moving pointer. Sometimes it means the current branch, sometimes it doesn't.
So HEAD is NOT a synonym for "current branch" everywhere already.
HEAD means "current" everywhere in git, but it does not necessarily mean "current branch" (i.e. detached HEAD).
But it almost always means the "current commit".
It is the commit "git commit
" builds on top of, and "git diff --cached
" and "git status
" compare against.
It means the current branch only in very limited contexts (exactly when we want a branch name to operate on --- resetting and growing the branch tip via commit/rebase/etc.).Reflog is a vehicle to go back in time and time machines have interesting interaction with the notion of "current".
HEAD@{5.minutes.ago}
could mean "dereference HEAD symref to find out what branch we are on RIGHT NOW, and then find out where the tip of that branch was 5 minutes ago".
Alternatively it could mean "what is the commit I would have referred to as HEAD 5 minutes ago, e.g. if I did "git show HEAD" back then".
git1.8.4 (July 2013) introduces introduced a new notation!
(Actually, it will be for 1.8.5, Q4 2013: reintroduced with commit 9ba89f4), by Felipe Contreras.
Instead of typing four capital letters "
HEAD
", you can say "@
" now,
e.g. "git log @
".
See commit cdfd948
Typing '
HEAD
' is tedious, especially when we can use '@
' instead.The reason for choosing '
@
' is that it follows naturally from theref@op
syntax (e.g.HEAD@{u}
), except we have no ref, and no operation, and when we don't have those, it makes sens to assume 'HEAD
'.So now we can use '
git show @~1
', and all that goody goodness.Until now '
@
' was a valid name, but it conflicts with this idea, so let's make it invalid. Probably very few people, if any, used this name.
git reset
will generate a ORIG_HEAD
. So you need to rm
it manually. See https://mcmap.net/q/11622/-how-to-delete-an-orig_head-branch-in-git for instance. –
Redfish @
alias for HEAD
is being reverted (temporarily?) for the Git 1.8.4 release! It was just announced today! –
Ettie @ alone is a shortcut for HEAD
dates from Git 1.8.5 and commit 9ba89f4, Q3 2013. –
Redfish From man 7 gitrevisions
:
HEAD names the commit on which you based the changes in the working tree. FETCH_HEAD records the branch which you fetched from a remote repository with your last git fetch invocation. ORIG_HEAD is created by commands that move your HEAD in a drastic way, to record the position of the HEAD before their operation, so that you can easily change the tip of the branch back to the state before you ran them. MERGE_HEAD records the commit(s) which you are merging into your branch when you run git merge. CHERRY_PICK_HEAD records the commit which you are cherry-picking when you run git cherry-pick.
My understanding is that HEAD points the current branch, while ORIG_HEAD is used to store the previous HEAD before doing "dangerous" operations.
For example git-rebase and git-am record the original tip of branch before they apply any changes.
git branch foo -b
in order to "create" a branch for that orphans commits. –
Gallows © 2022 - 2024 — McMap. All rights reserved.
HEAD
is now (upcoming git1.8.4) '@
'! See my edited answer below – Redfish@
' (forHEAD
) is still coming, but not for 1.8.4 answer edited and amended. – Redfish@
' forHEAD
is back for git 1.8.5/1.9. answer edited again. – RedfishHEAD
andORIG_HEAD
in Git are like$PWD
and$OLDPWD
in Bash. :) – ChoricHEAD
is not identical to@
when runninggit checkout
. In addition, I also find thatHEAD
is not identical toHEAD~0
when runninggit checkout
. In fact,@
is identical toHEAD~0
. The following screenshots are as follows:@
vsHEAD
andHEAD
vsHEAD~0
– Breadboard