查看原文
其他

【第1707期】谈谈 Git Merge 和 Git Rebase 的应用

zhicheng 前端早读课 2019-09-12

前言

今日早读文章由@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 分支。

  1. $ git checkout feature

  2. $ git merge master


  3. (or)


  4. $ 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 分支上。

  1. $ git checkout feature

  2. $ git rebase master

它把整个 feature 分支的提交移动到了 master 分支上。通过给每个源(feature) 分支创建了一个 brand 来 re-writing 项目的历史。

Interactive Rebasing

这个命令可以在移动 commit 前改变它们。这比普通的 rebase 更加强大,它提供了对分支提交历史的完整控制。另外,在合并 feature 分支到 master 前,还可以用它来清理混乱的提交历史。

  1. $ git checkout feature

  2. $ git rebase -i master

他会打开编辑器列出将要被移动的提交。

  1. pick 22d6d7c Commit message#1

  2. pick 44e8a9b Commit message#2

  3. 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/

为你推荐

【第923期】基于 Git、Svn 的 Commit 实现可增量构建的前端持续集成解决方案

【第1083期】git commit 时使用 Emoji

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存