Git rebase:你需要知道的一切
已發表: 2022-12-15
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 rebase命令是另一種將更改從一個分支轉移到另一個分支的方法。 merge和rebase命令具有相似的目標,但它們以不同的方式實現目的並產生略有不同的結果。
什麼是 Git 合併?
那麼 Git merge命令是做什麼用的呢? 假設您創建了一個名為dev-branch來處理一項新功能。

您進行了一些提交,並測試了您的新功能。 一切正常。 現在您想將新功能發送到master分支。 您必須在master分支中才能將另一個分支合併到它。
我們可以通過在合併之前明確檢查它來確保我們在master分支中。
git結帳大師
我們現在可以告訴 Git 將dev-branch合併到當前分支,即master分支。
git 合併開發分支

我們的merge已經為我們完成了。 如果你檢出master分支並編譯它,它就會有新開發的功能。 Git實際執行的是三向合併。 它比較master和dev-branch分支中的最新提交,以及master分支中緊接在dev-branch創建之前的提交。 然後它在master分支上執行提交。
合併被認為是非破壞性的,因為它們不會刪除任何內容,也不會更改任何 Git 歷史記錄。 dev-branch仍然存在,之前的提交都沒有改變。 創建一個新的提交來捕獲三向合併的結果。
合併後,我們的 Git 存儲庫看起來像一個時間線,其中有一條備用線分支,然後返回到主時間線。

dev-branch分支已經併入master分支。
如果您在一個項目中有很多分支,項目的歷史就會變得混亂。 如果一個項目有很多貢獻者,通常就是這種情況。 因為開發工作分成許多不同的路徑,所以開發歷史是非線性的。 如果分支有自己的分支,理清提交歷史變得更加困難。
請注意,如果您在master分支中有未提交的更改,則需要先對這些更改執行一些操作,然後才能將任何內容合併到其中。 您可以創建一個新分支並在那裡提交更改,然後進行合併。 然後,您需要將臨時分支合併回主分支。
這行得通,但 Git 有一個命令可以實現同樣的事情,而無需創建新的分支。 stash命令為您存儲未提交的更改,並允許您使用stash pop回調它們。
你會像這樣使用它們:
藏 git 合併開發分支 藏流行音樂
最終結果是一個合併的分支,其中恢復了未保存的更改。
什麼是 Git 變基?
Git rebase命令以完全不同的方式實現了它的目標。 它從你要變基的分支中獲取所有提交,並將它們重播到你要變基的分支的末尾。
以我們之前的例子為例,在我們執行任何操作之前,我們的 Git 存儲庫看起來像這樣。 我們有一個名為dev-branch ,我們想將這些更改移動到master分支。

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


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 合併新功能

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

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

Git Rebase 與 Merge:您應該使用哪一個?
這不是rebase與merge的情況。 它們都是功能強大的命令,您可能會同時使用它們。 也就是說,在某些用例中, rebase並不能很好地工作。 使用merge的錯誤導致的取消選擇錯誤令人不快,但是rebase導致的取消選擇錯誤是地獄般的。
如果您是唯一使用存儲庫的開發人員,那麼您使用rebase做一些災難性的事情的可能性就會降低。 例如,您仍然可以在錯誤的方向上rebase基,並將您的 master 分支rebase到您的new-feature分支上。 要恢復您的master分支,您需要再次rebase ,這次是從您的new-feature分支到您的master分支。 這將恢復您的master分支,儘管歷史看起來很奇怪。
不要在其他人可能工作的共享分支上使用rebase 。 當您將重新設置基礎的代碼推送到遠程存儲庫時,您對存儲庫的更改會給很多人帶來問題。
如果你的項目有多個貢獻者,安全的做法是只在你的本地存儲庫上使用rebase ,而不是在公共分支上。 同樣,如果拉取請求構成代碼審查的一部分,請不要使用rebase 。 或者至少,在創建拉取請求後不要使用rebase 。 其他開發人員可能正在查看您的提交,這意味著這些更改位於公共分支上,即使它們不在master分支上也是如此。
危險在於您要對已經推送到遠程存儲庫的提交進行rebase ,而其他開發人員可能已經基於這些提交進行了工作。 您的本地rebase將使那些現有的提交消失。 如果您將這些更改推送到存儲庫,您將不會受到歡迎。
其他貢獻者將不得不通過混亂的merge才能將他們的工作推回存儲庫。 如果您隨後將他們的更改拉回到您的本地存儲庫,您將面臨取消挑選一堆重複更改的麻煩。
變基,還是不變基?
在你的項目中, Rebase可能是非法的。 可能存在當地的文化異議。 一些項目或組織將rebase視為異端和褻瀆行為的一種形式。 有些人認為 Git 歷史應該是不可侵犯的、永久的記錄所發生的事情。 因此, rebase可能不在討論之列。
但是,在本地使用,在私有分支上, rebase是一個有用的工具。
在你 rebase之後推送,並將它限制在你是唯一開發人員的分支上。 或者至少,所有開發都已停止,並且沒有其他人基於您分支機構的提交開展任何其他工作。
這樣做,您將避免任何問題。
相關:如何檢查和更新你的 Git 版本



