闭门造车姚师傅

Git 中的 rebase, 变基!

字数统计: 899阅读时长: 3 min
2017/08/29 Share

Rebase, what is rebase and what advantage can we take using rebase before merge than merging directly. Read more for details. These contents come from a part of pro-git, and you can get the entire book from links in this link.

合并,合并

下面是两种 Merge 操作

  • 三方合并:两个分支 server 和 client,当前分支是 server,那么 merge 操作(#server: git merge client)将会对 {server.HEAD, client.HEAD, 两分支的最近的共同前驱} 进行“三方合并”,并将server的HEAD指向合并之后的快照。
  • 快进合并:如果一个合并可以通过直接移动HEAD指针来正确实现,那么这就是一个“快进合并”,的确像快进一样。快进合并是“三方合并”的一种特殊情况,共同前驱即为待merge分支的HEAD。比如分支A 在新产生分支B 后没有任何演化,那么 B merge A 就是一个快进合并。

变基,变基

顾名思义,“变基”,改变基础,基础就是之前提交过的”快照”。

变基操作的话我们用 serverclient 这两个分支举例不是很恰当,因为在普遍意义上这是两个平行的分支。现在把分支换成 masterbug-fix :产品出bug了,我们在 bug-fix 这个分支来修。

修好了提交代码之后,进行变基操作的 话(#bug-fix: git rebase master)。具体过程是:查找两分支的共同前驱C,计算 bug-fix.HEAD 针对C进行的修改Δ1,然后将 bug-fix.HEAD 指向 master.HEAD ,然后在移动后的bug-fix.HEAD上 ”重演“ Δ1,变基操作就结束了。

”重演“干了什么

根据Δ1的结果计算新的快照并提交,用到的信息来自之前的快照。然后视情况移除一些提交。

Sample

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 一些初始化仓库和分支的操作:在 master 初始提交(A)之后,创建 fix 分支,然后创建一个提交(B.f),然后切换回 master 并进行另一个提交(B.m)。 
PS > git checkout fix
PS > git log --oneline # 此时fix.HEAD 是 B.f,前驱为 A
7716237 B.f
d3e98e8 A
PS > git rebase master # 变基
First, rewinding head to replay your work on top of it...
Applying: B.f
PS > git log --oneline # 可以看到,B.f 的前驱变成了 master分支上的 A.m
2be85d9 B.f
8e92b64 A.m
d3e98e8 A
PS > git branch
* fix
master
PS > git checkout master
Switched to branch 'master'
PS > git log --oneline # master分支并没有什么变化
8e92b64 A.m
d3e98e8 A
PS > git merge fix # fast-forward 即“快进合并”
Updating 8e92b64..2be85d9
Fast-forward
fix | Bin 0 -> 16 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 fix
PS > git log --oneline
2be85d9 B.f
8e92b64 A.m
d3e98e8 A
PS > git branch -d fix #清理

Graph

rebase-sample

  • a) 变基前的状态
  • a -> b, 这个例子比较简单,两个分支的公共前驱就是A,Δ1就是B.f,之后就是在 B.m 上重演 B.f,相当于直接提交。不能简单认为fix的头指针直接指到 B.m 了。
  • b) 变基后的状态
  • c) 快进合并
  • d) 清理(Optional)

变基的风险,拉取公有仓库代码后,提交前如果使用了变基的话,可能会覆盖某些提交,别人再次提交之后可能出现同一个快照的两个副本,这种情况下使用变基需要整个团队的配合。

变基会消除掉提交记录中分支的真实轨迹,所以是否要保留这些信息、保留哪部分信息,因人而异。不过向开源库之类的项目 PR 前,将所做的修改 rebase 到 master 分支上是很值得肯定的。

Ref:

Pro Git: https://git-scm.com/book/en/v2/Git-Branching-Rebasing

@阿弥陀佛大锅炉

CATALOG
  1. 1. 合并,合并
  2. 2. 变基,变基
    1. 2.1. Sample
    2. 2.2. Graph