# Git教程 - 5 变基

什么是变基?

变基也是合并分支的一种方式。

不是已经有merge了还需要变基?

在实际的开发中,一个项目周期很长,会存在反复的创建、修改、合并、删除分支的操作,可能会再分支上创建分支等等,使用merge合并分支是,在提交记录中会将所有的分支创建合并等过程全部显示出来,会导致记录很混乱,查找很麻烦。


那么变基是什么意思呢?先用工作树演示一下:

比方说我们在 master 分支上创建了 bug1 分支,然后在 bug1 分支上修改并提交了两次代码 C4 和 C6。

如果是直接使用 merge 命令进行合并,那么最终工作树将是如下这样:

如果使用变基呢?

看看上面的图,bug1 分支是从 C3 节点创建的,所以 C3 节点是 bug1 分支的

变基就是修改 bug1 分支的基,将基变为 C7。变成如下这样:

变成这样以后,我们重新使用 merge 命令,就可以直接移动 master 指针从 C7 移动到 C6,变成快速合并。最终就变成一条线了。

上面只是示意变基的意思,但是变基时是做了如下操作:

  1. 发起变基时,git 会首先找到两条分支的最近的共同祖先,在上面也就是 C3;
  2. 对比当前分支(bug1)相对于祖先的历史提交,并且将它们提取出来存储到一个临时文件中,也就是说将上面 bug1 分支所有修改的内容(C4、C6)存储到临时文件中;
  3. 然后将当前分支(bug1)指向目标分支的新基底 (master 的 C7),也就是将 bug1 指向 C7;
  4. 然后在 bug1 分支重新执行之前保存到临时文件中的操作,也就是在 C7 后面重新执行 C4、C6 的修改操作。

下面演示一下上面的操作:

还是修改1.txt,首先在主分支进行了3次修改和提交。然后创建并切换到 bug1 分支上进行了1次修改和提交。

然后切换到主分支进行了1次修改和提交,再切换到 bug1 分支进行一次修改和提交,然后再切换到主分支进行了1次修改和提交。

提交记录和工作树使用 Git Graph 查看如下:

变基的方式有很多种,下面讲解一下在 bug1 分支上执行变基。

  1. 首先切换到 bug1 分支

    git switch bug1
    
    1
  2. 在 bug1 分支上执行变基,将 bug1 分支的基变到master

    git rebase master
    
    1

    变基和 merge 一样,可能会出现冲突。

  3. 合并冲突

    如果没有冲突,直接到步骤4;

    如果有冲突,则需要合并冲突,合并完冲突后,需要将冲突文件加入暂存

    git add 1.txt
    
    1

    然后执行 continue 命令,继续 rebase:

    git rebase --continue
    
    1
  4. rebase 完成,切换到 master 分支,在 master 分支上 merge bug1分支

    git switch master
    git merge bug1
    
    1
    2

    因为现在各个节点是在一条线上了,所以直接就是快速合并了。

最终工作树:

变基和 merge 最终的结果是一样的,但是变基会使得提交记录更整洁清晰。大部分情况下合并和变基是可以互换的。

但是如果要变基的分支已经提交到了远程仓库,那么尽量不要变基,因为提交到了远程仓库可能会被别人拿下来修改,如果此时变基,提交记录会更混乱。