git-HEAD

发布时间 2023-07-13 15:24:21作者: lxd670

1.HEAD概念

HEAD是一个指针,指向当前分支最新的commit,而branch指向一个commit

1-1.当前HEAD

HEAD文件指向当前分支

cat .git/HEAD
ref: refs/heads/master

1-2.查看HEAD执行的文件

文件指向了一个hash值

cat .git/refs/heads/master
7cc0ac8e656a95fe8f65ccbcbd7e9c0c8791e74a

1-3.查看hash值

git cat-file -t 7cc0ac8e656a95fe8f65ccbcbd7e9c0c8791e74a
commit

1-4.查看commit对象信息

git cat-file -p 7cc0ac8e656a95fe8f65ccbcbd7e9c0c8791e74a
tree 22f476fceb74f3f1e3547311f7d5e1271021229f
parent b9410841d7fa4cc8f8f29aab780b661d0f8dcf4f
author user-name <xxxxx@xxx.com> 1677307290 +0800
committer user-name <xxxxx@xxx.com> 1677307290 +0800

add c3.txt

1-5.查看日志

git log -1
commit 7cc0ac8e656a95fe8f65ccbcbd7e9c0c8791e74a (HEAD -> master)
Author: user_name <user_name@xxx.com>
Date:   Sat Feb 25 14:41:30 2023 +0800

    add c3.txt

2.HEAD~

HEAD~{n}是用来在当前提交路径上回溯的修饰符

HEAD~{n} 表示当前所在的提交路径上的前 n 个提交(n >= 0):
HEAD = HEAD~0					# 当前的commit-id
HEAD~ = HEAD~1				# 前一个的commit-id
HEAD~~ = HEAD~2				# 前两个的commit-id
HEAD{n个~} = HEAD~n	 # 前N个的commit-id

3.HEAD^

3-1.说明

^ 是用来切换父级提交路径的修饰符。

<rev>^<n> 用来表示一个提交<rev>第 n 个父提交,如果不指定 n,那么默认为 1。

比如,在一个提交引用C是由B合并到A中并产生的一个新提交(git merge B)

C
|\
A B
此时认为A是C的第一个父祖先提交B是C的第二个父祖先提交,因此通过提交引用C来获取B的表达式为:C^2。

注意:HEAD^^^ 并不等价于 HEAD^3,而是等价与 HEAD^1^1^1。

3-3.两级

以当前HEAD(a422bf9)开始计算,master分支最后合并了fix,所以只有两级

image-20230705130412733 image-20230705112725440

3-3-1.查看日志关系图

git log --oneline --graph --all
*   a422bf9 (HEAD -> master) Merge branch 'fix'
|\  
| * 3f2cb47 (fix) add fix
* |   080c24b Merge branch 'dev'
|\ \  
| * | 0df0755 (dev) add dev_b.txt
| * | 1b60089 add dev_a.txt
* | | cc115c7 add d.txt
| |/  
|/|   
* | aa754c8 add c.txt
|/  
* f8efdee add b.txt
* 40ee907 add a.txt

3-3-2.HEAD 的 第一个父级

a422bf9第一个父级是080c24b

git rev-parse HEAD^1
080c24bad3d95048f7e374ce576558f4eb94aac8

3-3-3.HEAD 的 第二个父级

a422bf9第一个父级是3f2cb47

git rev-parse HEAD^2
3f2cb4783ad0665c4d9992208b0e836e2dc6a302

3-4.三级

以当前HEAD(bd9f951)开始计算,master一起合并了devfix,所以有三级

image-20230705130412733 image-20230705130622720

3-4-1.查看日志关系图

git log --graph --oneline --all
*-.   bd9f951 (HEAD -> master) merge dev fix
|\ \  
| | * 3f2cb47 (fix) add fix
| * | 0df0755 (dev) add dev_b.txt
| * | 1b60089 add dev_a.txt
* | | cc115c7 add d.txt
| |/  
|/|   
* | aa754c8 add c.txt
|/  
* f8efdee add b.txt
* 40ee907 add a.txt

3-4-2.HEAD 的 第一个父级

cc115c7 add d.txt

git rev-parse HEAD^1
cc115c71947e4f3ea8c0f57db8cdfc415516dfd0

3-4-3.HEAD 的 第二个父级

0df0755 (dev) add dev_b.txt

git rev-parse HEAD^2
0df0755e32564efff21149e6c5a7dd46f3f8ff14

3-4-4.HEAD 的 第三个父级

3f2cb47 (fix) add fix

git rev-parse HEAD^3 
3f2cb4783ad0665c4d9992208b0e836e2dc6a302

4.换算

# 当前提交
HEAD = HEAD~0 = HEAD^0

# 主线回溯
HEAD~1 = HEAD^ 主线的上一次提交
HEAD~2 = HEAD^^ 主线的上二次提交
HEAD~3 = HEAD^^^ 主线的上三次提交

# 如果某个节点有其他分支并入
HEAD^1 主线提交(第一个父提交)
HEAD^2 切换到了第2个并入的分支并得到最近一次的提交
HEAD^2~3 切换到了第2个并入的分支并得到最近第 4 次的提交
HEAD^3~2 切换到了第3个并入的分支并得到最近第 3 次的提交

# ^{n} 和 ^ 重复 n 次的区别 
HEAD~1 = HEAD^
HEAD~2 = HEAD^^
HEAD~3 = HEAD^^^

# 切换父级
HEAD^1~3 = HEAD~4 
HEAD^2~3 = HEAD^2^^^
HEAD^3~3 = HEAD^3^^^

5.两者关系

  • ~ 获取第一个祖先提交,^ 可以获取第一个父提交。
  • 其实第一个祖先提交就是第一个父提交,反之亦然。
  • 因此,当 n 为 1 时,~^其实是等价的。 譬如:HEAD~~~HEAD^^^ 是等价的