基本操作
假设一个很常见的操作,从 main 分支拉取一个特性分支,并且出现分叉:

可以用下图表示:

如果通过合并操作将特性分支整合到主分支,会最终变成:

这样做很简单,但查看日志会发现这些分叉和合并。
因此可以选择通过变基的方式整合代码:
❯ git checkout feature/1
❯ git rebase main
变基时的主次是很重要的,变基(rebase)的意思是改变当前分支的地基为目标分支,因此为了将特性分支合并到主分支,就需要先签出到特性分支,变基到主分支,再签出到主分支进行合并。
现在查看日志:

可以看到分叉不见了。
用下图表示分支状态:

这里因为变基生成的新提交(d2a88c1)是 Git 基于最新的主分支提交(4d8f42c)计算出的提交,它包含了分叉后的整合结果,这个快照和上面的合并后的快照完全一致,但不同的是这里不再有分叉了。变基前的分叉提交(a59f05f)在这里不再需要,在日志中不再体现,因此用灰色和虚线表示。
变基并不是主要目的,在这里我们的最终目的是将feature/1整合到主分支,并且让主分支的日志保持线性,因此在变基后还是需要进行合并操作:
❯ git checkout main
❯ git merge feature/1
因为已经进行了变基,没有分叉,所以这里是快速合并(Fast-Forward)。
合并后的日志:

分支状态:

特殊变基
假设存在这样的提交记录:

用图表示:

如果我们希望将再feature/1.1中但不在feature/1中的内容变基到主分支,可以:
❯ git rebase --onto main feature/1 feature/1.1
查看日志:

用图表示:

这里变基到主分支的5d6284b仅包含了9806496中的补丁。
现在就像前面说的,可以通过快速合并的方式让主分支包含这个补丁:
❯ git checkout main
❯ git merge feature/1.1

后续如果需要将feature/1中的补丁合并到主分支,在feature/1上变基到main即可,与基本操作中的一致,这里不再赘述。
变基的风险
总的来说,变基可以提供一种分支整合方式——将一个分支上的若干个补丁整合到另一个分支上的最新提交。这种方式可以让你从一些个人的开发分支整合变更到主分支上后,主分支的提交记录变得更干净和线性。
但需要注意的是,如果你未来要变基的提交记录已经通过远程仓库进行了分享,有其它人使用这些提交记录进行后续开发并执行分支合并操作,就可能导致一些问题。具体说明可以查看。
总的来说,不要对已经通过远程仓库与他人分享并协作的提交记录进行变基。
变基与合并
对于这两种分支整合方式,不同的人有不同的见解,Git 同时提供这两种不同方式是为了提供更多的灵活性,两者并没有优劣之分。
一种观点认为,合并的方式可以提供完整、精确的提交记录,对我们梳理整个项目的开发细节是有用的。但另一种观点认为,变基可以让主分支的提交记录变得线性且干净。具体是采用变基还是合并,取决于具体开发团队的取舍。
The End.
参考资料

文章评论