目录
git-rebase
git-merge
git-rebase 与 git-merge 的差异
使用 git-rebase 合併的优缺点
该用 git-rebase 或 git-merge?
git-merge 派
git-rebase 派
个人主观观点
首页 开发工具 git git-rebase和git-merge是干嘛的?差异是什么?

git-rebase和git-merge是干嘛的?差异是什么?

Jul 15, 2022 am 10:36 AM
git github

git-rebase和git-merge是干嘛的?git-rebase 与 git-merge 的差异是什么?下面本篇文章给大家介绍一下git-rebase 与 git-merge 的区别,希望对大家有所帮助!

git-rebase和git-merge是干嘛的?差异是什么?

用 Git 做版本控管应该是大部分工程师每天都会碰到的工作流程之一,但我在使用上不外乎就是 pushpullmergecheckoutlog 等几个指令,更深入一点就一问三不知了,在面试时被问到了这个问题:「你知道 Git 的 merge 和 rebase 有什麽不同吗?」

听完后我直接困惑,对我来说 rebase 就是用来整理 commit 的工具,居然还可以和 merge 做比较?【推荐学习:《Git教程》】

git-rebase

先来说说平常我会用 rebase 这个指令来干嘛,假如我新增了一个单元测试,然后 commit,这时候 log 就会多一条 commit 的纪录:

image.png

但是在 commit 完才发现,我少写了另一个测试案例,因此在补上之后,我又 commit 了一次:

image.png

这时记录中会多出另外一条 commit,不过对我来说,这两个 commit 在做的其实是同一件事,于是我在 push 到 remote 之前,就会想要先整理一下 commit,把这两条记录合并起来。

要把这两条记录合并起来有两个方法,第一个是 reset 到添加第一个测试案例之前,然后直接做一次 commit。第二个方法就是用 rebase 来处理!

首先让我们看看目前的 log:

image.png

我的目的是把 9dc67ff87af945 整理成一个,所以要调整的 commit  是从 init, 也就是  commit id为 7eb57cb 之后的所有 commit,搭配上 rebase 指令的话就是:

git rebase -i 7eb57cb
登录后复制

输入完后就会跳到 vim 的编辑画面:

image.png

画面上会看到 7eb57cb 后的所有 commit(目前就只有  9dc67ff87af945 ),接着把 9dc67ffpick 改成 squash,表示把它与前一个 commit 做合并。先点一下 i 后开始用 vim 编辑内容:

image.png

编辑完后,可以点 esc 再输入 :wq 做保存,如果只是好奇进来玩看看,不想保存的话就输入 :q!。结束上面的流程后,再查看一次 log,会发现两条 commit 变成一笔了。保存完会跳到 commit message 的画面,这边可以让你输入合并后的 commit message,但我就不改了,一样直接保存:

image.png

结束上方的流程后,再查看一次 log,会发现两笔 commit 变成一笔了:

image.png

先 nice,上述的操作为 rebase 的 interactive mode,在 git rebase 后输入的 -i 其实就是 interactive 的缩写。

git-merge

大家应该对 merge 指令都非常熟悉,因为在做新功能的时候,通常都会拉一个分支出去,完成后再 merge 回 master 或 develop 等主要分支。操作流程如下:

image.png

在 merge 的时候会有两种情况,第一种是  fast-forward,会把被合并分支的 HEAD 的 reference 移到要合併分支内最新的 commit 上,上方操作的 merge 结果就是 fast-forward,master 的 HEAD 被移到 string-library 的最新 commit,画成图的话就是这样子:

image.png

但是如果在执行 merge 的时候产生冲突,那分支的合并行为就会和 fast-forward 有点不同了。举例来说,我分别在 master 和 string-library 的同一个文件添加内容,那当我执行 merge 的时候就会要求先修复冲突:

image.png

修复完后,再执行 commit 完成合并,而这一次合并时,会再多一个 commit 是有关 merge 了 string-library 分支的纪录:

image.png

这个情况画成图就会像这样子:

image.png

git-rebase 与 git-merge 的差异

看完上方对 rebasemerge 的介绍后,你也许会想说:

「咦?那这两个不是完全不同的东西吗?」

对的,原本我也是这麽认为,一直到我去看了 git-rebase 的文档,才发现原来我一直误会它了。在 git book 的 rebase 篇章,第一段就说明了,在 Git 里有两种方法可以用来整合两个分支,而这两个在上方都有提到,分别为 mergerebase

image.png

从上方的 merge 例子已经知道了,merge 在合并的时候会有 fast-forward,和冲突时用一个 commit 记录合并变更的两种情形。而 rebase 的整合方式非常有趣,依照关于 rebase 的另一段说明,它可以「把某个分支中所有 commit 的过程,以另一个分支的 commit 为基础重播一遍」:

image.png

这是什麽意思呢?首先让我们回到上述的例子,并在 master 分支上用 reset,让 master 的版本回到合并 string-library 之前:

image.png

现在我们要用 rebase 指令,将 string-library 所有的 commit 修改,以 master 的 commit 为基础跑一次。使用 rebase 合并的第一步,要先切到想重播 commit 的分支:

git checkout string-library
登录后复制

然后再输入 git rebase 指令,并于后方指定要在哪个分支上重播:

git rebase master
登录后复制

执行结果:

image.png

在 rebase 重播 commit 的过程中,和 merge 相似的地方在于,如果有冲突的话还是需要解决,但在解决后,并不是使用 commit 指令进行合并,而是要输入 git rebase --continue,让 rebase 可以继续重播接下来的 commit:

image.png

重播完成时,会显示目前重播到哪个 commit,以 string-library 来说就是最新的add string unit test D。这时候的分支关系,画成图就会变成:

image.png

上图在经过 rebase 之后,string-library 里 07e38fb 修改,会以 master 的 commit 为基底再重播一次。

需要注意的是,重播后的 commit id 会和原本的不一样,这等于完全改写了分支内所有的 commit 历史纪录。

另外,执行完 rebase 后,string-library 其实还没有被合并回 master 分支上,因此还是要再切回 master 执行 merge,以完成合併:

image.png

因为已经先用 rebase 在重播时处理完 commit 的冲突了,所以现在 merge 就会直接走 fast-forward 合并,也不会另外多一个 merge 的 commit 纪录。

使用 git-rebase 合併的优缺点

优点

  • 不会在合併时产生多馀的 commit。

  • 可以在重播的时候以 commit 为单位处理冲突。

  • 合併时会依分支的 commit 排列,能够比较清楚的 review issue 或 feature 处理的过程。如果使用 merge,在合併后就会依照时间顺序穿插排列两个分支的 commit。

  • 在贡献开源项目的时候,如果在 push 前先做 rebase,那作者就能够直接以 fast-forward 的方式合并,不需要再另外解冲突。

缺点

最大的缺点就是上方提到的,使用 rebase 会修改 commit 的历史纪录,如果在自己的 local 整理 commit 或是分支那还好,但如果不小心去异动到 remote 的分支,然后又更不小心用了 git push -f,那可能就会被同事讨厌,或被投稿到纯靠北工程师。

该用 git-rebase 或 git-merge?

在查了一些资料后,发现 rebase 和 merge 都各有拥护者,我先阐述他们的想法,再主观提一下自己的观点。

git-merge 派

支持 git-merge 派的工程师们认为,版本纪录有价值的地方就在于项目的 commit,也就是这个项目的「历史实际上发生过哪些事情」,如果你去修改了这些历史纪录那就很不好。因此即使不同分支的内容在 merge 后都混在一起,但这些内容仍然说明了这个项目的历史。

git-rebase 派

支持 git-rebase 派的工程师则觉得,commit 是在说这个项目的「演进过程」,发生了什麽事情才是重要的,即使修改了 commit 的历史,但是发生的事情依然没有改变,既然可以用更清楚简洁的纪录供后人阅读,那就应该要这麽做。

个人主观观点

我个人还是会使用 git-rebase 来修改 commit,让历史纪录更为简单好阅读,但使用上仅限于 push 到 remote 之前,如果今天已经把纪录 push 到 remote,那即使多乱我也不会去修改它们,毕竟 remote 的纪录就是大家共有的,不随意修改,也是尊重团队内的其他成员。

【相关视频教程推荐:web前端

以上是git-rebase和git-merge是干嘛的?差异是什么?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

git怎么更新代码 git怎么更新代码 Apr 17, 2025 pm 04:45 PM

更新 git 代码的步骤:检出代码:git clone https://github.com/username/repo.git获取最新更改:git fetch合并更改:git merge origin/master推送更改(可选):git push origin master

git怎么下载项目到本地 git怎么下载项目到本地 Apr 17, 2025 pm 04:36 PM

要通过 Git 下载项目到本地,请按以下步骤操作:安装 Git。导航到项目目录。使用以下命令克隆远程存储库:git clone https://github.com/username/repository-name.git

git下载不动怎么办 git下载不动怎么办 Apr 17, 2025 pm 04:54 PM

解决 Git 下载速度慢时可采取以下步骤:检查网络连接,尝试切换连接方式。优化 Git 配置:增加 POST 缓冲区大小(git config --global http.postBuffer 524288000)、降低低速限制(git config --global http.lowSpeedLimit 1000)。使用 Git 代理(如 git-proxy 或 git-lfs-proxy)。尝试使用不同的 Git 客户端(如 Sourcetree 或 Github Desktop)。检查防火

git怎么删除仓库 git怎么删除仓库 Apr 17, 2025 pm 04:03 PM

要删除 Git 仓库,请执行以下步骤:确认要删除的仓库。本地删除仓库:使用 rm -rf 命令删除其文件夹。远程删除仓库:导航到仓库设置,找到“删除仓库”选项,确认操作。

git commit怎么用 git commit怎么用 Apr 17, 2025 pm 03:57 PM

Git Commit 是一种命令,将文件变更记录到 Git 存储库中,以保存项目当前状态的快照。使用方法如下:添加变更到暂存区域编写简洁且信息丰富的提交消息保存并退出提交消息以完成提交可选:为提交添加签名使用 git log 查看提交内容

如何解决PHP项目中的高效搜索问题?Typesense助你实现! 如何解决PHP项目中的高效搜索问题?Typesense助你实现! Apr 17, 2025 pm 08:15 PM

在开发一个电商网站时,我遇到了一个棘手的问题:如何在大量商品数据中实现高效的搜索功能?传统的数据库搜索效率低下,用户体验不佳。经过一番研究,我发现了Typesense这个搜索引擎,并通过其官方PHP客户端typesense/typesense-php解决了这个问题,大大提升了搜索性能。

git怎么提交空文件夹 git怎么提交空文件夹 Apr 17, 2025 pm 04:09 PM

在 Git 中提交空文件夹,只需遵循以下步骤:1. 创建空文件夹;2. 将文件夹添加到暂存区;3. 提交更改,并输入提交消息;4. (可选)将更改推送到远程存储库。注意:空文件夹的名称不能以 . 开头,如果文件夹已存在,需要使用 git add --force 添加。

git怎么合并代码 git怎么合并代码 Apr 17, 2025 pm 04:39 PM

Git 代码合并过程:拉取最新更改以避免冲突。切换到要合并的分支。发起合并,指定要合并的分支。解决合并冲突(如有)。暂存和提交合并,提供提交消息。

See all articles