今天学了两个命令非常有意思:一个是git checkout
,一个是git branch -f
。我们可以认为在提交树上,任何一个节点代表着一次提交。并且,git commit
将会在
H
E
A
D
HEAD
HEAD指针指向的节点上进行进一步提交。将每一个分支名视为标记当前分支最新情况的节点名字。首先,先明确以下基本概念
git checkout
我们可以认为git checkout
是在变动 H E A D HEAD HEAD指针,比如git checkout main
是把 H E A D HEAD HEAD指针变到 m a i n main main指向的节点上面。如果单独使用git checkout [log-hash]
,我们甚至可以在 l o g log log树上面随意切换 H E A D HEAD HEAD,而git commit
就是在 H E A D HEAD HEAD的基础上进行提交的。
验证上述理论:
-
git checkout [log-hash]
-
git checkout main
-
git commit
提交
-
git checkout HEAD^
有几个^
就是向上移动几级
git checkout main~3
在main
的基础上向上移动3级
git branch -f [branchName] [log hash]
移动分支标记节点
明确了上述概念,可以进行学习 git rebase
了。这个命令常常会令人十分迷惑,在八股文中会拿这个命令和 git merge
进行比较。最后得出的结论就是 git rebase
一般用在本地分支整理,不会用在远程上。 git merge
一般用在合并远程分支和本地分支的差异。
那么先给出 git rebase
的定义,然后再进行验证。假设你现在在main
分支上,那么git rebase master
就是要将当前面分支变基到 master
分支上。步骤可以分成以下三个:
- 先找到两个分支标记节点的最近公共父节点 A A A
- 将
main
到 A A A路径上的节点与master
到 A A A路径上的节点进行去重。 - 将去重后的节点复制到
master
节点下(注意是复制,原来的节点并未删除)。如果master
节点已经有子节点了,那么这些节点作为新建路径复制到master
节点下面。
验证:
- 初阶-- 将
m
a
i
n
main
main变基到
y
h
yh
yh上
执行命令:
git checkout main
git rebase yh
得到下面的树:
最近公共父节点为 c 4 ′ c4' c4′, m a i n main main到父节点的路径是 c 11 c11 c11和 c 10 c10 c10,直接复制到 y h yh yh下面变成 c 11 ‘ c11‘ c11‘和 c 10 ’ c10’ c10’,这时 y h yh yh是没有子节点的。 c 11 c11 c11和 c 10 c10 c10还是在的,截屏的时候没截下来,蚌。
-
进阶–从 z t zt zt向 y h yh yh变基
这时的 y h yh yh是有子节点的,所以会新建路径。将 c 12 c12 c12~ c 14 c14 c14会一起复制到 y h yh yh下面
-
高阶–从 z t zt zt向 b u g F i x bugFix bugFix变基,路径上的 c 12 c12 c12是重复的,所以会去重。
-
综合–验证去重的正确性,在 z t zt zt的上面 c 1 3 ′ ′ c13'' c13′′位置新开个分支 m q mq mq
将
m
a
i
n
main
main变基到
m
q
mq
mq上,路径上的
c
4
′
c4'
c4′和
c
7
c7
c7和
c
8
c8
c8都是重复的。放个结果,验证成功!
我还录了个视频,但是没录好,还是放上来,大家看一下吧~
附练习网站链接:https://learngitbranching.js.org/
谢谢您看到这里!您的点赞和收藏是我创作的不竭动力~感谢您的支持