头和orig_头在git中


HEAD and ORIG_HEAD in Git

这些符号是指什么?它们是什么意思?

(官方文件中找不到任何解释)


HEAD是(直接或间接,即符号)对当前提交的引用。这是一个您已经签入工作目录的提交(除非您做了一些更改或等效更改),它是一个提交,在此基础上,"git commit"将生成一个新的提交。通常,HEAD是对其他某个命名分支的符号引用;此分支当前已签出分支或当前分支。HEAD还可以直接指向提交;这种状态称为"分离的头",可以理解为在未命名的匿名分支上。

单是@HEAD的捷径,因为git 1.8.5

ORIG_HEADHEAD的先前状态,由具有可能危险行为的命令设置,以便于恢复。现在git有了reflog就没那么有用了:HEAD@{1}大致相当于ORIG_HEAD(HEAD@{1}总是HEAD的最后一个值,ORIG_HEAD是危险操作前HEAD的最后一个值)。

有关更多信息,请阅读Git(1)手册、Git用户手册、Git社区手册和Git词汇表。


从Git复位

"pull" or"merge" always leaves the original tip of the current branch in ORIG_HEAD.

1
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.

1
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'.

注:从这里开始

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(2013年7月)investmentsintroduced a new notation!(实际上,这将是2013年第4季度的1.8.5或1.9:重新引入commit 9ba89f4)

Instead of typing four capital letters"HEAD", you can say"@" now,
e.g."git log @".

参见提交CDFD948

Typing 'HEAD' is tedious, especially when we can use '@' instead.

The reason for choosing '@' is that it follows naturally from the ref@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.

在1.8.4-rc3期间(2013年8月14日)的一篇博客文章中宣布,这项功能已被恢复并延迟(感谢您的提示)。再次,它通过commit 9ba89f4(2013年9月)再次引入。

见提交2c2b664:

Revert"添加新的@HEAD快捷方式"

This reverts commit cdfd948, as it does not just apply to"@" (and forms with modifiers like @{u} applied to it), but also affects e.g."refs/heads/@/foo", which it shouldn't.

The basic idea of giving a short-hand might be good, and the topic can be retried later, but let's revert to avoid affecting existing use cases for now for the upcoming release.


我的理解是,头指向当前的分支,而orig_头用于存储前一个头,然后再执行"危险"操作。

例如,git-rebase和git-am在应用任何更改之前记录分支的原始尖端。