搜尋
首頁開發工具Gitgit-rebase和git-merge是幹嘛的?差異是什麼?

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 的纪录:

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

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

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git rebase -i 7eb57cb

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-merge

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

git-rebase 与 git-merge 的差异

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

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

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git checkout string-library

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

git rebase master

执行结果:

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

git-rebase和git-merge是幹嘛的?差異是什麼?

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

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

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

git-rebase和git-merge是幹嘛的?差異是什麼?

因为已经先用 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刪除
git和github:探索他們的角色和功能git和github:探索他們的角色和功能May 09, 2025 am 12:25 AM

Git和GitHub在軟件開發中的角色和功能是管理代碼和協作開發。 Git通過commit、branch和merge等功能高效管理代碼版本,而GitHub則提供代碼託管和協作工具,如PullRequest和Issues,提升團隊協作效率。

GitHub:發現,共享和為代碼做出貢獻GitHub:發現,共享和為代碼做出貢獻May 08, 2025 am 12:26 AM

GitHub是開發者發現、分享和貢獻代碼的首選平台。 1)通過搜索功能查找特定代碼庫,如Python項目。 2)創建倉庫並推送代碼分享給全球開發者。 3)通過Fork和PullRequest參與開源項目並貢獻代碼。

將git與github使用:實用指南將git與github使用:實用指南May 07, 2025 am 12:11 AM

Git是一種版本控制系統,GitHub是基於Git的在線平台。使用Git和GitHub進行代碼管理和團隊協作的步驟包括:1.初始化Git倉庫:gitinit。 2.添加文件到暫存區:gitadd.。 3.提交更改:gitcommit-m"Initialcommit"。 4.關聯GitHub倉庫:gitremoteaddoriginhttps://github.com/username/repository.git。 5.推送代碼到GitHub:gitpush-uoriginmaste

GitHub的影響:軟件開發與協作GitHub的影響:軟件開發與協作May 06, 2025 am 12:09 AM

GitHub對軟件開發和協作的影響深遠:1.它基於Git的分佈式版本控制系統,提高了代碼安全性和開發靈活性;2.通過PullRequest等功能,提升了團隊協作效率和知識共享;3.GitHubActions等工具幫助優化開發流程,提高代碼質量。

使用GitHub:共享,管理和為代碼做出貢獻使用GitHub:共享,管理和為代碼做出貢獻May 05, 2025 am 12:12 AM

在GitHub上分享、管理和貢獻代碼的方法包括:1.創建倉庫並推送代碼,編寫README和LICENSE文件;2.使用分支、標籤和合併請求管理代碼;3.Fork倉庫、修改並提交PullRequest貢獻代碼。通過這些步驟,開發者可以有效利用GitHub提升開發效率和協作能力。

git vs. github:比較分析git vs. github:比較分析May 04, 2025 am 12:07 AM

Git是一個分佈式版本控制系統,GitHub是一個基於Git的協作平台。 Git用於版本控制和代碼管理,GitHub則提供額外的協作功能,如代碼審查和項目管理。

git vs. github:了解差異git vs. github:了解差異May 03, 2025 am 12:08 AM

Git是分佈式版本控制系統,GitHub是基於Git的在線平台。 Git用於版本控制、分支管理和合併,GitHub提供代碼託管、協作工具和社交網絡功能。

github:前端,git:後端github:前端,git:後端May 02, 2025 am 12:16 AM

Git是後端版本控制系統,GitHub是基於Git的前端協作平台。 Git管理代碼版本,GitHub提供用戶界面和協作工具,兩者協同工作提升開發效率。

See all articles

熱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

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具