【第1707期】谈谈 Git Merge 和 Git Rebase 的应用
前言
今日早读文章由@zhicheng翻译,@Miya授权分享。
正文从这开始~~
大部分开发者都有遇到过该用 Merge 还是 Rebase 的问题,网络上的各种相关介绍几乎都认为:“不要使用 Rebase,因为它会产生各种问题”。这里我将介绍 merge 和 rebase 的概念,为什么你应该(或者不应该)使用它们,以及怎么用。
Git Merge 和 Git Rebase 目的相同,它们都是把不同分支的提交合并到一起。虽然最终目的是一致的,但是其过程却颇为不同。了解它们之间的区别之后,你会成为一个更出色的开发者。
Git 社区对这个问题有很大争论,一些人坚持应该只用 rebase,另外一些人认为只用 merge,事实上两种方式各有优势。
Git Merge
对于使用版本控制系统的开发者来说,Merging 是常规操作。不管创建的分支是用来测试、修复 bug,还是别的什么原因,可能都会需要把分支的提交 merging 到其它的分支上。具体来说,merging 就是把源分支的提交放到目标分支里面。在这个过程里,只有目标分支改变,而源分支保持原样。
优点
简单易上手
保留了提交历史和时间次序
保留了分支的结构
缺点
提交历史被大量的 merge 提交污染了
使用 git bisect 调试变得更困难了
怎样做
使用 checkout 和 merge 命令把 master 分支 merge 到 feature 分支。
$ git checkout feature
$ git merge master
(or)
$ git merge master feature
这将会在 feature 分支上创建一个新的 “Merge 提交” 用来保留所有分支的记录。
Git Rebase
Rebase 是合并两个分支的另一种方式。Rebase 把所有的提交压缩成一个 “patch”。然后把 patch 添加到目标分支里。
和 merging 不同,rebasing 清除了历史,因为它完全是从一个分支转移到了另一个分支。在这个过程中,多余的记录被移除了。
Rebases 的提交从顶部按次序向下排列,而 merges 则自下而上。
优点
把复杂的历史变成优雅的提交线
操作单个提交变得很简单(比如,reverting)
避免了庞大的仓库、海量的分支以及烦人的 merge 提交
线性合并清除了中间的无用提交,对于 DevOps 团队来说是个好消息
缺点
Rebase 后 feature 分支间的上下文模糊了
在团队里 rebasing 公共分支是高风险的事
工作变多了:feature 分支需要经常更新
Rebasing 到远程分支需要 force push。最大的问题是人们经常已经 force push 了,才发现忘记了设置 git push 默认值。结果本地远程所有同名的分支都进行了更新,清理起来很要命。
如果你 rebase 出错并且很不幸重写了历史,很棘手,所以一定要明白操作的意义。
怎样做
下面的命令把 feature 分支 rebase 到 master 分支上。
$ git checkout feature
$ git rebase master
它把整个 feature 分支的提交移动到了 master 分支上。通过给每个源(feature) 分支创建了一个 brand 来 re-writing 项目的历史。
Interactive Rebasing
这个命令可以在移动 commit 前改变它们。这比普通的 rebase 更加强大,它提供了对分支提交历史的完整控制。另外,在合并 feature 分支到 master 前,还可以用它来清理混乱的提交历史。
$ git checkout feature
$ git rebase -i master
他会打开编辑器列出将要被移动的提交。
pick 22d6d7c Commit message#1
pick 44e8a9b Commit message#2
pick 79f1d2h Commit message#3
它清晰地展示了分支在 rebase 后的样子。通过重新调整,提交历史可以变成任何你想要的样子。如,可以把 pick 换成 fixup , squash , edit 等命令。
选哪个
所以,哪个是最好的?有没有专业的建议呢?很难明确告诉你该选哪一个,毕竟每个团队的情况不同。但还是有章可循。
团队在制定他们的 Git rebase vs. merge 策略时需要考虑很多问题。事实证明,工作流之间并无明显的高下之分,一切都取决于团队情况。
选择更直白的 rebasing 还是历史可塑性更强的 merging,要考虑团队对 rebasing 的了解情况以及 Git 熟悉程度。
最后,决定使用 merging 还是 rebasing 还应该考虑到分支策略。团队有必要制定一个合适的分支策略。
我的建议
随着团队增长,通过 merge 策略很难管理和追踪到每个提交。为了提交历史更清晰、更易于理解,使用 Rebase 是一个明智、高效的选择。
下面是针对不同环境的建议,可以最大限度地发挥 Rebase 的优势:
本地开发:如果你没有和别人协同工作,你应该使用 rebasing 而不是 merging ,这样历史记录会很清晰。如果你已经从仓库拉取了你的个人 fork,并且不准备和别的开发者一起工作,在分支 push 前 rebase 也是可以的。
你的代码准备好了被 review:你创建了 pull request。别人正在 review 你的代码,可能把它拉到了本地 review。如果这样,你最好别 rebase 你的代码。你应该创建一个 “rework” 提交来更新你的 feature 分支。它会让 pull request 的可塑性更强,也能避免历史突然丢失。
review 已经完成并且已经准备好了合并到目标分支。恭喜!你就要删除你的 feature 分支了。由于别的开发者不需要拉取、合并这些更改,这是你清理记录的好机会。你可以改写记录,折叠原始提交、“pr rework” 提交和 "merge"提交,使之成为一整个清晰的提交。作为可选,你还可以给这些提交创建一个明确的 merge,这样做实际上很有用。它会记录 feature 并入master 的时间。
结论
希望这些解释能让你对 Git merge 和 Git rebase 更了解。Merge .vs. rebase 策略之争永无止境。希望这篇文章可以帮助你扫清迷惑,找到一个适合自己的团队的方向。
关于本文 译者:@zhicheng 译文:https://mp.weixin.qq.com/s/E4RuFnTztECRT-sKjQnTpg 作者:@Vali Shah 原文:https://www.freecodecamp.org/news/an-introduction-to-git-merge-and-rebase-what-they-are-and-how-to-use-them-131b863785f/
为你推荐