當我這樣做時git rebase -i <commit>,它會拉出從該提交開始的提交串列,我必須通過更改為來選擇要編輯的pick提交e。但是當我更改pick并e關閉編輯器時,git 仍然會遍歷所有提交,而不僅僅是我想要編輯的那些。
例如,我這樣做git rebase -i --root并且只選擇編輯最新的提交。Git 仍然嘗試遍歷整個提交串列。在我關閉編輯器后,它說Rebasing (1/593)593 是串列中的提交數。它通過所有 593 個。它只會停止讓我編輯我選擇的那些。
有沒有辦法只針對一個特定的提交,即使它位于許多其他提交之間,而無需rebase遍歷整個串列?
uj5u.com熱心網友回復:
理解這一點的方法是理解 Git是什么。Git 遵循一些極其基本和重要的規則。這是其中的兩個:
任何提交都不能更改。
提交的父指標是該提交的一部分(因此,根據規則 1,不能更改)。
所以現在考慮這種情況:
A -- B -- C -- D (mybranch)
其中時間從左向右流動:A首先被創建,并且是B的父級,B的父級是C的父級,C的父級是D的父級。
現在假設我想更改 A 的提交訊息。好吧,我不能!您無法更改有關提交的任何內容。但是您可以做的是用不同的提交替換A - 一個具有不同提交訊息(但包含相同檔案)的提交。
但如果你這樣做,你有這個:
A -- B -- C -- D (mybranch)
A'
其中 A' 是類似于 A 的新提交,但其提交訊息不同。這不好,因為這不是我們想要的。我們希望歷史保持“相同”,在歷史中 A' 作為 B 的父級。好吧,我們不能那樣做!您不能更改 B 的父級。但是您可以做的是用一個看起來像 B 但以 A' 作為其父級的新提交替換B :
A -- B -- C -- D (mybranch)
A' -- B'
但是等等,還有更多!對于所有后續提交,我們必須繼續這樣做。當我們完成后,Git 只是將mybranch指標移動到新的歷史記錄:
A -- B -- C -- D
A' -- B' -- C' -- D' (mybranch)
這就是當您使用互動式變基來編輯 A 的提交訊息時發生的情況。您將獲得A 的所有新提交及其之后的所有提交。
這正是您所看到和詢問的。
要確定這是真的,請在示例 repo 上嘗試,并查看 SHA 編號。這是一個例子。我git log過去常常看我一開始有什么:
* 0c32c25 (HEAD -> main) d
* 12ec6ca c
* 28b1e17 b
* b8cb561 a
現在我互動變基到根;這是我編輯待辦事項串列的方法:
r b8cb561 a
pick 28b1e17 b
pick 12ec6ca c
pick 0c32c25 d
我改寫了第一個提交,以便它的訊息是a with a different commit message. 現在變基完成了,這就是我得到的:
* 0931c89 (HEAD -> main) d
* 45ebf0a c
* 084b06c b
* bcc0bed a with a different commit message
查看 SHA 編號。他們都變了。那是因為這些不是我開始的提交!他們都被替換了。
最后的觀察。如果你仔細觀察,你應該說:在圖中,被“替換”的原始A 到 D 會發生什么?
A -- B -- C -- D
A' -- B' -- C' -- D' (mybranch)
看起來他們還在那里。你是對的!他們還在那里。在你的大變基之后,你所有的提交都是重復的。新版本存在,舊版本也存在。這實際上是 Git 的一個非常酷的特性:提交被替換時不會被洗掉。
在這種特殊情況下,您無法輕松訪問原始 A 到 D。但如果您愿意,您可以。例如,您可以使用 reflog。或者您可以在進行變基之前在 D 上放置另一個分支名稱。
最終,回購將被“垃圾收集”。Git 會注意到沒有分支名稱指向 D,因此指向 C、B 和 A。它們被認為是“不可訪問的”,Git將洗掉它們。但這可能需要幾周的時間。如果您想這樣做,您有很多時間來恢復原件。酷,嗯?
uj5u.com熱心網友回復:
如何僅對特定提交進行變基
在編輯歷史記錄的呼叫中盡可能縮小范圍:
- 如果要編輯最近的提交,請使用
git commit --amend - 如果要編輯最近的第四次提交,請使用
git rebase -i HEAD~4 - 如果歷史足夠長以至于您不想計算,請在您要修改的那個之前找到提交的 sha1,然后使用
git commit -i <sha1> - 在所有情況下,除非您知道自己在做什么,否則請確保不要在合并點上變基(請參閱下文了解原因)。
為什么狹窄很重要
盲目的git rebase -i --root手術實際上是一件危險的事情。
無害的問題,性能:如果您要求 rebase 以相同的方式重新創建所有提交,它將一個一個地進行提交并重新創建它們中的每一個,但由于結果相同,它是一個 noop,您只是重新創建了完全相同的提交,只會浪費您和您的機器的時間。這就是您所觀察到的 (1/593)。
危險的問題,破壞合并:如果您的歷史記錄中有任何合并,默認情況下重新設定它們實際上會跳過它們,用具有相同代碼(我相信)但現在與原始歷史斷開連接的線性歷史替換原始歷史從被跳過的第一個合并開始。你可以git rebase -i --rebase-merges --root改用,但你為什么要白白做所有這些作業呢?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/488197.html
標籤:混帐 git-rebase
上一篇:githubssh密鑰名稱
