Git rebase:你需要知道的一切

已發表: 2022-12-15
藍色背景上顯示 Linux 命令提示符的筆記本電腦。
fatmawati achmad zaenuri/Shutterstock.com
Git rebase 命令將一個分支移動到另一個分支頭部的新位置。 與 Git 合併命令不同,rebase 涉及重寫項目歷史記錄。 這是一個很棒的工具,但不要 rebase 其他開發人員基於其工作的提交。

Git rebase命令將兩個源代碼分支合併為一個。 Git merge命令也這樣做。 我們解釋了rebase的作用、它的使用方式以及何時使用merge

目錄

Git 爆炸式增長
什麼是 Git 合併?
什麼是 Git 變基?
如何變基到另一個分支
Git Rebase 與 Merge:您應該使用哪一個?
變基,還是不變基?

Git 爆炸式增長

由於對其他版本控制系統及其緩慢的更新和提交感到沮喪,以 Linux 內核聞名的 Linus Torvalds 在 2005 年抽出一個月的時間來編寫自己的版本。 他將其命名為 Git。

GitHub、GitLab 和 BitBucket 等站點共生地促進了 Git 並從中受益。 今天 Git 在全球範圍內使用,在 2022 年的一項調查中,71,000 名受訪者中有 98% 使用 Git 作為版本控制系統。

Git 的主要設計決策之一是速度。 特別是,與分支機構的合作必須盡可能快。 分支是版本控制系統的基本組成部分。 項目存儲庫將有一個主分支或主分支。 這是項目代碼庫所在的位置。 諸如新功能之類的開發在隔離的側分支中進行。 這可以防止在分支中完成的工作弄亂主分支,並且允許在代碼庫的不同部分同時進行開發。

如何選擇適合您團隊的 Git 工作流和分支模型
相關如何選擇適合您團隊的 Git 工作流和分支模型

隨著側分支中的開發完成,通過將開發分支合併到主分支,將更改轉移到主分支。 在其他版本控制系統中,使用分支是困難的,而且計算量大。 在 Git 中使用分支非常快,而且非常輕量級。 在其他系統中曾經是乏味且經常避免的練習,在 Git 中變得微不足道。

Git rebase命令是另一種將更改從一個分支轉移到另一個分支的方法。 mergerebase命令具有相似的目標,但它們以不同的方式實現目的並產生略有不同的結果。

什麼是 Git 合併?

那麼 Git merge命令是做什麼用的呢? 假設您創建了一個名為dev-branch來處理一項新功能。

一個 master 分支和一個名為 dev-branch 的未合併分支的圖
戴夫·麥凱/How-To-Geek

您進行了一些提交,並測試了您的新功能。 一切正常。 現在您想將新功能發送到master分支。 您必須在master分支中才能將另一個分支合併到它。

我們可以通過在合併之前明確檢查它來確保我們在master分支中。

 git結帳大師

我們現在可以告訴 Git 將dev-branch合併到當前分支,即master分支。

 git 合併開發分支

將dev-branch分支合併到master分支

我們的merge已經為我們完成了。 如果你檢出master分支並編譯它,它就會有新開發的功能。 Git實際執行的是三向合併。 它比較masterdev-branch分支中的最新提交,以及master分支中緊接在dev-branch創建之前的提交。 然後它在master分支上執行提交。

合併被認為是非破壞性的,因為它們不會刪除任何內容,也不會更改任何 Git 歷史記錄。 dev-branch仍然存在,之前的提交都沒有改變。 創建一個新的提交來捕獲三向合併的結果。

合併後,我們的 Git 存儲庫看起來像一個時間線,其中有一條備用線分支,然後返回到主時間線。

dev-branch 分支與 master 分支合併
戴夫·麥凱/How-To Geek

dev-branch分支已經併入master分支。

如果您在一個項目中有很多分支,項目的歷史就會變得混亂。 如果一個項目有很多貢獻者,通常就是這種情況。 因為開發工作分成許多不同的路徑,所以開發歷史是非線性的。 如果分支有自己的分支,理清提交歷史變得更加困難。

Git 分支如何工作?
相關Git 分支如何工作?

請注意,如果您在master分支中有未提交的更改,則需要先對這些更改執行一些操作,然後才能將任何內容合併到其中。 您可以創建一個新分支並在那裡提交更改,然後進行合併。 然後,您需要將臨時分支合併回主分支。

這行得通,但 Git 有一個命令可以實現同樣的事情,而無需創建新的分支。 stash命令為您存儲未提交的更改,並允許您使用stash pop回調它們。

你會像這樣使用它們:

 藏

git 合併開發分支

藏流行音樂

最終結果是一個合併的分支,其中恢復了未保存的更改。

什麼是 Git 變基?

Git rebase命令以完全不同的方式實現了它的目標。 它從你要變基的分支中獲取所有提交,並將它們重播到你要變基的分支的末尾。

以我們之前的例子為例,在我們執行任何操作之前,我們的 Git 存儲庫看起來像這樣。 我們有一個名為dev-branch ,我們想將這些更改移動到master分支。

一個 master 分支和一個名為 dev-branch 的未合併分支的圖
戴夫·麥凱/How-To-Geek

rebase之後,它看起來像是一個單一的、完全線性的變化時間線。

master 分支與 dev-branch rebased on it
戴夫·麥凱/How-To Geek

dev-branch已被移除, dev-branch -branch 中的提交已添加到 master 分支。 最終結果就像dev-branch中的提交實際上首先直接提交到master分支一樣。 提交不只是附加到master分支上,它們被“重放”並重新添加。

這就是rebase命令被認為具有破壞性的原因。 rebased 分支不再作為單獨的分支存在,並且項目的 Git 歷史已被重寫。 您無法在稍後確定哪些提交最初是對dev-branch進行的。

然而,它確實給您留下了一個簡化的、線性的歷史。 與具有數十個甚至數百個分支和合併的存儲庫相比,閱讀 Git 日誌或使用圖形化 git GUI 查看存儲庫的圖形,重新設置的存儲庫很容易理解。

如何變基到另一個分支

讓我們嘗試一個git rebase示例。 我們有一個項目有一個名為new-feature的分支。 我們會rebase這樣將該分支重新定位到master分支。

首先,我們檢查master分支沒有未完成的更改。

 混帳狀態

我們檢查new-feature分支。

 git checkout 新功能

我們告訴 Git 將當前分支rebase到 master 分支。

 git 變基大師

我們可以看到我們仍然有兩個分支。

 分支

我們交換回master分支

git結帳大師

我們將新功能分支合併到當前分支,在我們的例子中是master分支。

 git 合併新功能
具有新功能的主分支重新基於它
戴夫·麥凱/How-To Geek

有趣的是,最終合併後我們仍然有兩個分支。

使用 Git branch 命令列出 git 倉庫中的分支
戴夫·麥凱/How-To Geek

不同的是,現在new-feature分支的頭部和master分支的頭部被設置為指向同一個提交,並且 Git 歷史沒有顯示曾經有一個單獨new-feature分支,除了分支標籤。

master 分支與 dev-branch rebased on it
戴夫·麥凱/How-To Geek

Git Rebase 與 Merge:您應該使用哪一個?

這不是rebasemerge的情況。 它們都是功能強大的命令,您可能會同時使用它們。 也就是說,在某些用例中, rebase並不能很好地工作。 使用merge的錯誤導致的取消選擇錯誤令人不快,但是rebase導致的取消選擇錯誤是地獄般的。

如果您是唯一使用存儲庫的開發人員,那麼您使用rebase做一些災難性的事情的可能性就會降低。 例如,您仍然可以在錯誤的方向上rebase基,並將您的 master 分支rebase到您的new-feature分支上。 要恢復您的master分支,您需要再次rebase ,這次是從您的new-feature分支到您的master分支。 這將恢復您的master分支,儘管歷史看起來很奇怪。

不要在其他人可能工作的共享分支上使用rebase 。 當您將重新設置基礎的代碼推送到遠程存儲庫時,您對存儲庫的更改會給很多人帶來問題。

如果你的項目有多個貢獻者,安全的做法是只在你的本地存儲庫上使用rebase ,而不是在公共分支上。 同樣,如果拉取請求構成代碼審查的一部分,請不要使用rebase 。 或者至少,在創建拉取請求後不要使用rebase 。 其他開發人員可能正在查看您的提交,這意味著這些更改位於公共分支上,即使它們不在master分支上也是如此。

危險在於您要對已經推送到遠程存儲庫的提交進行rebase ,而其他開發人員可能已經基於這些提交進行了工作。 您的本地rebase將使那些現有的提交消失。 如果您將這些更改推送到存儲庫,您將不會受到歡迎。

如何修復、編輯或撤消 Git 提交(更改 Git 歷史記錄)
相關如何修復、編輯或撤消 Git 提交(更改 Git 歷史記錄)

其他貢獻者將不得不通過混亂的merge才能將他們的工作推回存儲庫。 如果您隨後將他們的更改拉回到您的本地存儲庫,您將面臨取消挑選一堆重複更改的麻煩。

變基,還是不變基?

在你的項目中, Rebase可能是非法的。 可能存在當地的文化異議。 一些項目或組織將rebase視為異端和褻瀆行為的一種形式。 有些人認為 Git 歷史應該是不可侵犯的、永久的記錄所發生的事情。 因此, rebase可能不在討論之列。

但是,在本地使用,在私有分支上, rebase是一個有用的工具。

在你 rebase之後推送,並將它限制在你是唯一開發人員的分支上。 或者至少,所有開發都已停止,並且沒有其他人基於您分支機構的提交開展任何其他工作。

這樣做,您將避免任何問題。

相關:如何檢查和更新你的 Git 版本