Git中的HEAD和ORIG_HEAD


252

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

(我在官方文档中找不到任何解释)


4
注意:HEAD现在(即将到来的git1.8.4)' @'!请参阅下面我编辑的答案
VonC

注之二:' @(用于HEAD)仍在,但对于1.8.4 答案已编辑和修改的不是。
VonC

1
注意三:' @'for HEAD返回git 1.8.5 / 1.9。答案再次编辑
VonC

21
HEADORIG_HEAD在Git的像$PWD$OLDPWD在猛砸。:)
musiphil 2014年

Answers:


325

HEAD是(直接或间接,即符号)对当前提交的引用。这是您已在工作目录中签入的提交(除非您进行了一些更改或等效更改),并且它是一个提交,在此提交之前,“ git commit”将做出一个新的提交。通常HEAD是对其他命名分支的符号引用;该分支当前是检出分支,即当前分支。HEAD也可以直接指向提交;此状态称为“分离的HEAD”,可以理解为处于未命名的匿名分支上。

@单是一个捷径HEAD,因为Git的1.8.5

ORIG_HEAD是的先前状态HEAD,由可能具有危险行为的命令设置,以便于将其还原。现在,Git具有reflog不再有用:HEAD@{1}大致等于ORIG_HEADHEAD@{1}始终是的最后一个值HEADORIG_HEAD是的最后一个值HEAD危险操作之前的。

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


2
嗨,雅各布。+1为解释。您能否详细说明HEAD @ {1}的“大致等效”部分?我在对线程thread.gmane.org/gmane.comp.version-control.git/38379的答复中提到了(您早在2007年2月就在其中),但我不完全理解你们围绕的讨论。 @ {...}语法。
VonC

19
(我认为)ORIG_HEAD仅由“危险”命令设置,该命令将HEAD移入多个提交。因此,并非始终设置ORIG_HEAD,而始终设置HEAD @ {1}。@ {1}是$(git symbolic-ref HEAD)@ {1},即它对当前分支使用reflog,而不是HEAD reflog。
2009年

Riiight ...我现在明白了:)谢谢您的澄清。对于它的价值,我也支持您的评论!
VonC

1
“并且HEAD是一个提交,在它上面的“ git commit”将产生一个新的提交。“-谨记,谢谢!同样来自@VonC,“这是基于“ git commit”的提交,与“ git diff --cached”和“ git status”进行比较。”
潘敏琦2012年

1
git help修订版调出了git-scm.com/docs/gitrevisions,它描述了引用提交的所有方法(包括HEADORIG_HEAD)。
dahlbyk 2013年

104

git reset

“ pull”或“ merge”始终将当前分支的原始尖端留在中ORIG_HEAD

git reset --hard ORIG_HEAD

对其进行艰难的重置会使索引文件和工作树回到该状态,并将分支的尖端重置为该提交。

git reset --merge ORIG_HEAD

检查合并的结果后,您可能会发现另一个分支中的更改不令人满意。运行“ git reset --hard ORIG_HEAD”将使您返回到原来的位置,但是会丢弃您不需要的本地更改。“ git reset --merge”保留您的本地更改。


在应用任何补丁之前,将ORIG_HEAD设置为当前分支的尖端。
如果您在执行多个提交时遇到问题,例如运行“git am在错误的分支上 '或通过更改邮箱更容易解决的提交错误(例如,“ From:”行中的+ errors),则。

此外,合并总是将' .git/ORIG_HEAD' 设置为HEAD的原始状态,因此可以使用' git reset ORIG_HEAD' 删除有问题的合并。


注意:从这里

HEAD是移动的指针。有时它表示当前分支,有时则不是。

因此,HEAD 到处都不是“当前分支”的同义词。

HEAD 处处表示“当前”在git的,但不一定表示“当前分支”(即,分离的HEAD)。

但这几乎总是意味着“当前提交”。
这是提交“ git commit”基础上的顶部,“ git diff --cached”和“ git status”比较反对。
这意味着当前分支仅在非常有限的上下文中(恰好在我们希望分支名称可以通过--commit / rebase / etc重置和增长分支提示的情况下使用)。

Reflog是一种时光倒流的工具,时间机器与“当前”的概念有着有趣的互动。

HEAD@{5.minutes.ago}可能意味着“取消HEAD symref来找出我们现在在哪个分支上,然后找出该分支的尖端在5分钟前所在的位置”。
或者,它的意思可能是“ 5分钟前我将其称为HEAD的提交是什么,例如,如果我当时做了“ git show HEAD”。


git1.8.4(2013年7月) 介绍 引入了新的符号!
(实际上,它适用于2013年第4季度1.8.5或1.9:通过commit 9ba89f4重新引入)

不用输入四个大写字母“ HEAD”,您@现在可以说“ ”,
例如“ git log @”。

查看commit cdfd948

键入“ HEAD”很繁琐,尤其是当我们可以使用“ @”代替时。

选择' @' 的原因是它自然地遵循了ref@op语法(例如HEAD@{u}),除了我们没有ref和没有操作,而且当我们没有ref和操作时,假设'HEAD '。

因此,现在我们可以使用“ git show @~1”以及所有其他优点。

到目前为止,“ @”是一个有效名称,但是与该想法冲突,因此让我们使其无效。使用此名称的人可能很少(如果有的话)。


1.8.4-rc3期间(2013年8月14日)的博客文章宣布,此功能已还原和延迟(感谢Cupcake for heads-up)。
再次,它在提交9ba89f4中再次引入 (2013年9月)。

参见commit 2c2b664

还原“为添加新的@快捷方式HEAD

这将还原提交cdfd948,因为它不仅适用于“ @”(以及带有类似修饰符的形式@{u}),而且还会影响“ refs/heads/@/foo”,但不应这样做。

简写的基本想法可能很好,可以稍后重试该主题,但是让我们恢复以避免对即将发布的版本暂时影响现有用例。


运行git后,重置ORIG_HEAD并提交。ORIG_HEAD仍在HEAD旁的References下。为什么没有将其从视图中删除?
powder366 2013年

@ powder366但a git reset会生成一个ORIG_HEAD。因此,您需要rm手动进行操作。例如,请参阅stackoverflow.com/a/12418078/6309
VonC

1
@VonC Git 1.8.4版本@别名HEAD将被还原(临时?)!今天才宣布!

享受“平视”评论!
罗宾诺

2

我的理解是,HEAD指向当前分支,而ORIG_HEAD用于在执行“危险”操作之前存储先前的HEAD。

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


4
HEAD并不总是指向当前分支(可以分离)
VonC

1
那么,当HEAD被“分离”时,“当前分支”是什么?
cjs

@ CurtJ.Sampson那是“无分支”。这就是为什么当您处于分离状态时,您git branch foo -b为了“创建”该孤儿提交的分支而这么做的原因。
罗伊·纳米尔

1

来自man 7 gitrevisions

HEAD命名工作树中所做更改的基础提交。FETCH_HEAD记录您最近一次git fetch调用从远程存储库获取的分支。ORIG_HEAD是由命令创建的,这些命令以剧烈的方式移动HEAD,以在操作之前记录HEAD的位置,以便您可以在运行它们之前轻松地将分支的尖端更改回状态。MERGE_HEAD记录运行git merge时要合并到分支中的提交。CHERRY_PICK_HEAD记录您在运行git cherry-pick时正在选择的提交。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.