在試驗 git 時,我創建了兩個沒有共同提交祖先的分支。讓我們稱他們為“主人”和“其他”。當前分支是“master”。
正如預期的那樣,嘗試通過以下方式合并“其他”:
git merge other
產生: fatal: refusing to merge unrelated histories
這正是我期望發生的。令我驚訝的是,通過以下方式運行 rebase:
git rebase other
成功了。
這讓我感到驚訝,因為我認為 rebase 需要一個共同的提交祖先,就像 git merge 一樣。git rebase 是否需要一個共同的祖先?
uj5u.com熱心網友回復:
我認為理解這一點的方法,就像很多 about 一樣rebase,是理解兩件事:
rebase只是cherry-pick:它根據連續的差異創建新的提交,保留舊的提交,并將它們附加到目標。區別僅在于之后,cherry pick 會提前目標分支名稱,而 rebase 會轉移源分支名稱。git rebase xxx是簡寫。因此,結果可能令人驚訝。
的完整形式git rebase是git rebase --onto x y z,這意味著:“從(但不包括)開始y,挑選每個連續的提交,x直到挑選出z。”
當您使用簡寫形式時,x通常是您指定的提交,z是當前分支,并且y是兩者的共同祖先。
但在某些情況下,速記并不適用。在這種情況下,沒有共同的祖先。因此,對于y,Git 選擇“根”,即虛無——就像您使用了帶有--root選項的完整形式一樣。
為了說明這一點,讓我們假設 branchone由 commitsa和 then組成,bbranchtwo由 commitsc和 then 組成d:
a <-- b (one)
c <-- d (two)
然后,如果您打開two并且您說git rebase one, oneis b,那么 Git 會從two( d)向后退到c并自言自語:我可以選擇差異“無到- c”b嗎?如果是這樣(因為沒有沖突),它確實如此。然后它說:我可以在我剛剛創建的提交上挑選差異“ c-to- d”嗎?如果是這樣,它確實如此。這就是結束——我們已經到達當前分支提交——所以它停止了,并將當前分支指標 ( HEAD) 移動到它創建的最后一個新提交:
a <-- b <-- c' <-- d' (two)
^
(one)
請注意,c'和d'是副本(即由 Git 創建的新提交)。原來的c和d仍然存在的,但現在沒有分支名稱指向它們,最終它們將通過垃圾收集被洗掉。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/387329.html
