美文网首页
[git] merging 和 rebasing 的区别是什么?

[git] merging 和 rebasing 的区别是什么?

作者: _liuz | 来源:发表于2017-04-04 16:37 被阅读0次

来源:Atlassian Git Tutorial

概念

git rebasegit merge 目的一样,都是为了把某一分支的变化整合到另一分支,只是处理方式不同。

假如我们为了开发新特性,从 master 主干拉取新分支 feature 单独开发。此后,如果其他人更新主干代码,会造成分叉历史(forked history)。

A forked commit historyA forked commit history

如果主干的新提交与开发中的新特性相关,需要合并到 feature 分支。我们有两种选择:合并(merging)或变基(rebasing)。

Merge 选项

最简单的做法是将 master 分支合并到 feature 分支:

git checkout feature
git merge master

它会在 feature 分支产生一个新的 merge commit,把两个分支历史合并到一起,形成如下的分支结构:

Merging master into the feature branchMerging master into the feature branch

Merge 的好处是:它是无损操作non-destructive operation),feature 分支的提交历史被完整保留,这能避免 rebase 潜在的一些陷阱。

但是这还意味着,每次我们整合上游的变化时,feature 分支都生成多余的 commit 节点。如果 master 分支比较活跃,将严重污染 feature 的分支历史。尽管 git log 的高级特性可以缓解这个问题,其他人理解项目历史时,还是会很困难。

Rebase 选项

作为 merge 的替代选项,我们还可以将 feature 变基(rebase)到 master 分支。命令如下:

git checkout feature
git rebase master

这会把整个 feature 分支移动到 master 分支的顶端,实际上整合了 master 所有的新提交。rebase 没有使用新的提交,而是重写了项目历史:旧分支的每个提交,都会转换为一个全新的提交。

Rebasing the feature branch onto masterRebasing the feature branch onto master

rebase 的主要优点是,项目的提交历史能变得十分清爽。首先,它能避免 git merge 引入的多余 commit 节点。第二,从上图可以看出,rebase 可以产生完美的线性提交历史。这样在提交历史中导航就会十分简单,可以使用 git log, git bisectgitk 等命令。

但是,纯洁的提交历史也有两个代价:安全性和可回溯性。如果不遵循 rebase 黄金法则,重写项目历史可能会对合作开发带来灾难性的后果。并且,rebase 失去了 merge 带来的上下文信息 - 你会看不出什么时间上游提交引入到当前分支。

交互式 rebase

交互式 rebase 让你有机会修改提交历史。它提供了对 feature 分支历史的完全控制。它主要用来清理 feature 混乱提交历史,然后再合并至 master 分支。

使用 i 选项开启交互式 rebase:

git checkout feature
git rebase -i master

这会打开一个文本编辑器,列举出所有的提交:

pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

这个列表精确定义了 rebase 提交后的分支结构。通过修改 pick 命令,或者调整列表元素的顺序,可以随意修改提交历史。举个例子,如果第二个提交只是修改了第一个提交的小问题,可以把二者合并为一个条目,使用 fixup 命令即可:

pick 33d5b7a Message for commit #1
fixup 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

当保存关闭文件后,Git 就会依照你的指令执行 rebase 操作,形成下面的分支结构:

Squashing a commit with an interactive rebaseSquashing a commit with an interactive rebase

像这样删除掉无关紧要的提交节点后,feature 分支历史就能更容易理解。git merge 做不到这些。

rebase 黄金法则

理解了 rebase 的概念后,最重要的是知道什么时候不要 rebase 。git rebase 的黄金法则是永远不要在公共分支上执行 git rebase 操作

比如,如果把 master 变基到 feature 分支,分支结构就会变成:

Rebasing the master branchRebasing the master branch

rebase 会把所有 master 提交节点移动到 feature 分支提交历史的顶端。问题是这个变动只是发生在你的仓库,其他人还继续在原来 master 分支工作。因为 rebase 产生了全新提交,Git 会认为你的 master 分支已经与其他人的 master 分支产生分歧。

所以,执行 git rebase 前,一定先问问自己,“有没有其他人也在这个分支做开发?”如果回答“有”,马上离开键盘,考虑一种无损的方式(比如,git revert 命令)。如果只是自己开发,你可以随心所欲的修改历史。

相关文章

  • [git] merging 和 rebasing 的区别是什么?

    来源:Atlassian Git Tutorial 概念 git rebase 与 git merge 目的一样,...

  • Git: Merge vs Rebase

    本文翻译自atlassian的git教程,原文地址是 merging-vs-rebasing 前言 git reb...

  • Merging 和 Rebasing 的大比拼

    虽然 merging 和 rebasing 在 git 中相似时,但他们提供不同的功能。为了让你的历史尽可能的干净...

  • git-Merging vs. Rebasing

    原文:https://www.atlassian.com/git/tutorials/merging-vs-reb...

  • git学习笔记-Merging vs. Rebasing

    git rebase 该命令同git merge解决的问题一样,这两个命令都是将改动从一个分支整合到另一个分支,但...

  • Merging VS. Rebasing

    原文地址 对于初学者来说git rebase命令就如同Git当中的巫术一样,应该被敬而远之。但是它在小心使用情况下...

  • git一些错误解决办法

    一、git (master|MERGING) 解决方法: 1、 git reset -hard head 进行代码...

  • GIT入门

    git 学习笔记 1、Git 和 SVN的区别是什么。 三个区别:【存储】、【使用】、【管理】 存储:Git是对修...

  • Git - ours vs theirs

    转自: https://nitaym.github.io/ourstheirs/ Git Merging Let'...

  • git merging状态

    一般使用下面命令就可以了 git reset --hard head 该命令是回退版本信息 在Git中,用HEAD...

网友评论

      本文标题:[git] merging 和 rebasing 的区别是什么?

      本文链接:https://www.haomeiwen.com/subject/tofzottx.html