Git中HEAD ^和HEAD〜有什么区别?
当我在Git中指定一个祖先提交对象时,我在HEAD^
和HEAD~
之间混淆了。
两者都有一个“编号”的版本,像HEAD^3
和HEAD~2
。
他们对我来说看起来很相似或相同,但在代字和插入符号之间是否有区别?
HEAD^
表示当前分支顶端的第一个父项。
请记住,git提交可以有多个父代。 HEAD^
是HEAD^1
缩写,您也可以根据需要定位HEAD^2
等等。
你可以到任何提交的父母,而不仅仅是HEAD
。 你也可以代代相传:例如, master~2
表示master分支的祖父母,在含糊不清的情况下赞成第一个父母。 这些说明符可以任意链接, 例如 topic~3^2
。
有关完整的详细信息,请参阅git rev-parse
文档中的“指定修订” 。
要有一个可视化的想法表示,让我们引用一部分文档:
这是由Jon Loeliger提供的一个例子。 提交节点B和C都是提交节点A的父节点。父提交按从左到右的顺序排列。
GHIJ \ / \ / DEF \ | / \ \ | / | \|/ | BC \ / \ / A A = = A^0 B = A^ = A^1 = A~1 C = A^2 = A^2 D = A^^ = A^1^1 = A~2 E = B^2 = A^^2 F = B^3 = A^^3 G = A^^^ = A^1^1^1 = A~3 H = D^2 = B^^2 = A^^^2 = A~2^2 I = F^ = B^3^ = A^^3^ J = F^2 = B^3^2 = A^^3^2
HEAD^
和HEAD〜的区别在http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html上的插图(Jon Loeliger)中有详细描述。
这个文档对于初学者来说可能有些模糊,所以我在下面重复了这个插图:
GHIJ \ / \ / DEF \ | / \ \ | / | \|/ | BC \ / \ / A A = = A^0 B = A^ = A^1 = A~1 C = A^2 = A^2 D = A^^ = A^1^1 = A~2 E = B^2 = A^^2 F = B^3 = A^^3 G = A^^^ = A^1^1^1 = A~3 H = D^2 = B^^2 = A^^^2 = A~2^2 I = F^ = B^3^ = A^^3^ J = F^2 = B^3^2 = A^^3^2
^
和^^
都是指提交的父母( ~~
和^^
都指祖父母提交等),但是它们与数字一起使用时意义不同:
-
如果一个提交具有多于一个父代,那么〜2意味着通过第一个父级在层次结构中增加两个级别
-
^2
表示提交具有多个父代的第二个父代(即因为它是合并)
这些可以合并,所以HEAD~2^3
表示HEAD
的祖父母提交的第三个父母提交。
我的两分钱…(好吧,我必须input更多的字符,因为计算器策略。)
^<n>
格式允许您select提交的第n个父代(与合并相关)。 ~<n>
格式允许您select第n个祖先提交,始终在第一个父代之后。 有关示例,请参阅git-rev-parse的文档。
值得注意的是,git也有一个跟踪“from-where-you-come”/“想要回到现在”的语法 – 例如, HEAD@{1}
会引用你跳转的地方到新的提交位置。
基本上, HEAD@{}
variables捕获HEAD移动的历史logging,您可以通过使用git reflog
命令查看git reflog
来决定使用特定的头部。
例:
0aee51f HEAD@{0}: reset: moving to HEAD@{5} 290e035 HEAD@{1}: reset: moving to HEAD@{7} 0aee51f HEAD@{2}: reset: moving to HEAD@{3} 290e035 HEAD@{3}: reset: moving to HEAD@{3} 9e77426 HEAD@{4}: reset: moving to HEAD@{3} 290e035 HEAD@{5}: reset: moving to HEAD@{3} 0aee51f HEAD@{6}: reset: moving to HEAD@{3} 290e035 HEAD@{7}: reset: moving to HEAD@{3} 9e77426 HEAD@{8}: reset: moving to HEAD@{3} 290e035 HEAD@{9}: reset: moving to HEAD@{1} 0aee51f HEAD@{10}: reset: moving to HEAD@{4} 290e035 HEAD@{11}: reset: moving to HEAD^ 9e77426 HEAD@{12}: reset: moving to HEAD^ eb48179 HEAD@{13}: reset: moving to HEAD~ f916d93 HEAD@{14}: reset: moving to HEAD~ 0aee51f HEAD@{15}: reset: moving to HEAD@{5} f19fd9b HEAD@{16}: reset: moving to HEAD~1 290e035 HEAD@{17}: reset: moving to HEAD~2 eb48179 HEAD@{18}: reset: moving to HEAD~2 0aee51f HEAD@{19}: reset: moving to HEAD@{5} eb48179 HEAD@{20}: reset: moving to HEAD~2 0aee51f HEAD@{21}: reset: moving to HEAD@{1} f916d93 HEAD@{22}: reset: moving to HEAD@{1} 0aee51f HEAD@{23}: reset: moving to HEAD@{1} f916d93 HEAD@{24}: reset: moving to HEAD^ 0aee51f HEAD@{25}: commit (amend): 3rd commmit 35a7332 HEAD@{26}: checkout: moving from temp2_new_br to temp2_new_br 35a7332 HEAD@{27}: commit (amend): 3rd commmit 72c0be8 HEAD@{28}: commit (amend): 3rd commmit
一个例子可能是我本地提交a-> b-> c-> d,然后我回去丢弃2提交检查我的代码 – git reset HEAD~2
– 之后,我想要移回我的HEAD到d – git reset HEAD@{1}
。
这是从http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde逐字logging的一个非常好的解释:;
ref~
是ref〜1的简写forms,表示提交的第一个父代。ref~2
表示提交的第一个父代的第一个父代。ref~3
表示提交的第一个父代的第一个父代的第一个父代。 等等。
ref^
是ref^1
缩写,意思是提交的第一个父代。 但是,两者不同的地方在于ref^2
意味着提交的第二个父(记住,提交可以在合并时有两个父母)。
^
和~
运算符可以合并。
HEAD ^^^与HEAD〜3相同,selectHEAD之前的第三个提交
HEAD ^ 2指定合并提交中的第二个头
-
HEAD〜指定“分支”上的第一个父项
-
HEAD ^允许您select提交的特定父级
一个例子:
如果你想跟随一个分支,你必须指定类似的东西
master~209^2~15
简单地说 :
-
~
指定祖先 -
^
指定父母
合并时可以指定一个或多个分支。 然后提交有两个或更多的父母,然后^
是有用的表示父母。
假设你在分支A上,并且你有两个分支: B和C.
在每个分支上,最后的三个提交分别是:
- 答 : A1 , A2 , A3
- B : B1 , B2 , B3
- C : C1 , C3 , C3
如果现在在分支A上执行命令:
git merge BC
那么你正在梳理三个分支(这里你的合并提交有三个父母)
和
~
表示第一个分支的第n个祖先,所以
-
HEAD~
表示A3 -
HEAD~2
表示A2 -
HEAD~3
表示A1
^
表示第n个父母,所以
-
HEAD^
表示A3 -
HEAD^2
表示B3 -
HEAD^3
表示C3
下一个使用~
或^
彼此相邻,在前面的字符指定的提交的上下文中。
注意1 :
-
HEAD~3
总是等于:HEAD~~~
和HEAD^^^
(每个表示A1 ),
一般来说 :
-
HEAD~n
总是等于:HEAD~...~
( n次~
)和:HEAD^...^
( n次^
)。
注意2 :
-
HEAD^3
与HEAD^^^
(第一个表示C3 ,第二个表示A1 ),
一般来说 :
-
HEAD^1
与HEAD^
相同, - 但对于n > 1:
HEAD^n
始终与HEAD^...^
( n次~
) 不相同。
简单地说,对于第一级血统(血统,inheritance,谱系等)HEAD ^和HEAD〜都指向相同的提交,它是(位于)HEAD(提交)之上的一个父级。
此外,HEAD = HEAD = 1 = HEAD = HEAD = 1。 但是HEAD ^^!= HEAD ^ 2!= HEAD〜2。 然而HEAD ^ HEAD〜2。 阅读。
除了第一级亲子关系,事情变得更加棘手,特别是如果工作分支/主分支已经合并(来自其他分支)。 还有一个与脱字符语法相关的问题,HEAD ^^ = HEAD〜2(它们是等价的)但是HEAD ^^!= HEAD ^ 2(它们完全是两个不同的东西)。
每一个插入符号都是指HEAD的第一个父母,这就是为什么在一起串连起来的贴子相当于代字符的expression,因为它们严格地根据连接的插入符号的数字来引用第一个父母(第一父母)的第一个父母等等或者在波浪号之后的数字(无论哪种方式,它们都是指同一事物),即与第一父母留在一起并向上x代。
HEAD〜2(或HEAD ^^)是指在层次结构中当前提交(HEAD)之上/之上的两层血统的提交,即HEAD的祖父提交。
另一方面,HEAD ^ 2不是指第一个父母的第二个父母的提交,而是第二个父母的提交。 这是因为脱字符表示提交的父项,后面的数字表示提及哪个/哪个父提交(第一个父项,在脱字符后面没有跟随一个数字的情况下[因为它是数字的缩写是1,意思是第一个父母])。 与脱字符号不同的是,后面的数字并不意味着另一层次的层次向上,而是意味着在层次结构中横向有多less层次,需要find正确的父代(提交)。 与波浪号expression式中的数字不同,它只是层次结构中的一个父项,而不pipe数字(立即)如何处理。 插入的号码不是向上的,而是横跨整个层级的父母的横向数目(在父母向上的水平上,相当于连续的插入数)。
所以HEAD ^ 3等于HEAD提交的第三个父代(不是曾祖父母,这是HEAD ^^^和HEAD〜3会是…)。