Git 上的插图(Jon Loeliger)很好地描述了HEAD^和HEAD~之间的关系

Git 上的插图(Jon Loeliger)很好地描述了HEAD^和HEAD~之间的关系,git,Git,对于初学者来说,本文档可能有点晦涩难懂,因此我复制了下面的说明: G H I J \ / \ / D E F \ | / \ \ | / | \|/ | B C \ / \ / A A = = A^0 B = A^ = A^1 = A~1 C = A^2 D = A^^ = A^1^1 = A~2 E = B^2 = A^^

对于初学者来说,本文档可能有点晦涩难懂,因此我复制了下面的说明:

G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     \|/    |
      B     C
       \   /
        \ /
         A
A =      = A^0
B = A^   = A^1     = A~1
C = 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

值得注意的是,git还有一个跟踪“从哪里来”/“现在想回去”的语法,例如,
HEAD@{1}
将引用您跳转到新提交位置的位置

基本上,
HEAD@{}
变量捕获头部运动的历史,您可以通过使用命令
git reflog
查看git的reflogs来决定使用特定头部

例如:

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
,然后我想把我的头移回d-
git reset HEAD@{1}

^
都是指提交的父项(
~~
^
都指祖父母提交等),但它们与数字一起使用时含义不同:

  • ~2
    表示如果提交有多个父级,则通过第一个父级在层次结构中向上提升两级

  • ^2
    表示第二个父级,其中提交有多个父级(即,因为它是合并)


这些可以组合在一起,因此
HEAD~2^3
意味着
HEAD的祖父母提交的第三个父母提交的。

我的两分钱


这里有一个很好的解释,逐字逐句地从以下几个方面进行解释:

ref~
ref~1
的缩写,表示提交的第一个父级。
ref~2
表示提交的第一个父级。
ref~3
表示提交的第一个父级的第一个父级。依此类推

ref^
ref^1
的缩写,表示提交的第一个父级。但两者的不同之处在于
ref^2
表示提交的第二个父级(请记住,提交在合并时可以有两个父级)

可以组合使用
^
~
运算符


简单地说

  • ~
    指定祖先
  • ^
    指定父项
合并时可以指定一个或多个分支。然后提交有两个或多个父级,然后
^
用于指示父级

假设您在分支A上,您还有两个分支:B和C

在每个分支上,最后三次提交是:

  • A:A1、A2、A3
  • B:B1、B2、B3
  • C:C1、C3、C3
如果现在在分支A上执行命令:

git merge B C
然后将三个分支组合在一起(这里,合并提交有三个父级)

~
表示第一个分支中的第n个祖先,因此

  • 头部~
    表示A3
  • HEAD~2
    表示A2
  • 头3
    表示A1
^
表示第n个父项,因此

  • HEAD^
    表示A3
  • 头^2
    表示B3
  • 头^3
    表示C3
相邻的
~
^
的下一次使用是在前面字符指定的提交上下文中

注意1

  • HEAD~3
    始终等于:
    HEAD~~~
    和to:
    HEAD^^^
    (每个表示A1)
和一般情况下

  • HEAD~n
    始终等于:
    HEAD~…
    (n次
    ~
    )和to:
    HEAD^ ^ ^
    (n次
    ^
注意2

  • HEAD^3
    HEAD^^^
    不同(第一个表示C3,第二个表示A1)
和一般情况下

  • HEAD^1
    HEAD^
    相同
  • 但是对于n>1:
    HEAD^n
    总是而不是
    HEAD^…^
    (n次
    ~

简单地说,对于第一级亲子关系(祖先、继承、世系等),HEAD^和HEAD~都指向同一个提交,即(位于)头部上方的一个父级(提交)

此外,HEAD^=HEAD^1=HEAD~=HEAD~1。但是HEAD^^!=HEAD^2!=HEAD~2。但是HEAD^^=HEAD~2。请继续阅读

在第一级亲子关系之外,事情变得更加棘手,特别是如果工作分支/主分支(从其他分支)进行了合并的话。还有插入符号的语法问题,HEAD^^^=HEAD~2(它们是等效的),但HEAD^^!=HEAD^2(它们完全是两个不同的东西)

每个/每个插入符号都指头部的第一个父级,这就是为什么将插入符号串在一起相当于波浪形表达式,因为它们指的是第一个父级(第一个父级)的第一个父级等,严格基于连接的插入符号上的数字或波浪形后面的数字(无论哪种方式,它们都表示相同的事情),也就是说,与第一代父母同住,然后再上x代

HEAD~2(或HEAD^^^)指的是在层次结构中当前提交(HEAD)之上/之上的两个祖先级别的提交,即HEAD的祖父母提交

另一方面,头^2不是指第一个父项的第二个父项的提交,而是指第二个父项的提交。这是因为插入符号表示提交的父项,下面的数字表示提交的父项(如果插入符号后面没有数字,则指第一个父项)[因为它是数字为1的简写,意味着第一个父项]。与插入符号不同,后面的数字并不意味着上一级的层次结构
$ git log -1 --format=%f $(git rev-parse A^)
B
$ git log -1 --format=%f $(git rev-parse A~^3~)
I
$ git log -1 --format=%f $(git rev-parse A^2~)
F
commit 89e4fcb0dd01b42e82b8f27f9a575111a26844df
Merge: c670b1f876 649bf3a42f b67d40adbb
Author: Junio C Hamano <gitster@pobox.com>
Date:   Mon Oct 29 10:15:31 2018 +0900

    Merge branches 'bp/reset-quiet' and 'js/mingw-http-ssl' into nd/config-split […]
$ git rev-parse 89e4fcb0dd^1 89e4fcb0dd^2 89e4fcb0dd^3
c670b1f876521c9f7cd40184bf7ed05aad843433
649bf3a42f344e71b1b5a7f562576f911a1f7423
b67d40adbbaf4f5c4898001bf062a9fd67e43368
$ git rev-parse 89e4fcb0dd^4
89e4fcb0dd^4
fatal: ambiguous argument '89e4fcb0dd^4': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
$ git log -1 --pretty=%P 89e4fcb0dd
c670b1f876521c9f7cd40184bf7ed05aad843433 649bf3a42f344e71b1b5a7f562576f911a1f7423 b67d40adbbaf4f5c4898001bf062a9fd67e43368
$ git log -1 --pretty=%p 89e4fcb0dd
c670b1f876 649bf3a42f b67d40adbb
G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     \|/    |
      B     C
       \   /
        \ /
         A
A =      = A^0
B = A^   = A^1     = A~1
C = 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
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
git merge B C