![](/img/trans.png)
[英]Difference between git merge with commits in common and git merge with unrelated branches
[英]Merge Git branches based on a specified pair of commits as the common base
是否可以基於指定的提交對作為通用基礎在Git中合並分支?
場景:
兩個單獨的Git存儲庫,“ 我們的 ”和“ 他們的 ”。
“ 他們的 ”是在已知時間使用“ 我們的 ”的工作副本(僅文件)創建的。 “ 他們的 ”中的最初提交是添加“ 我們的 ”文件的快照。
現在,我們希望將“ 他們的 ”合並為“ 我們的 ”:
git remote add theirs <their repository path>
git pull theirs <their branch> --allow-unrelated-histories
git merge
將尋找git merge
的共同祖先。 但是,“ 我們的 ”和“ 他們的 ”之間沒有共同的承諾。
因為我們可以在“ 我們的 ”中找到提交,而工作副本與“ 他們的 ”中的初始提交匹配,所以我認為Git應該能夠明智地開始合並,但是我們需要指示Git處理這兩個特定的承諾作為共同基礎。
“他們”是在已知時間使用“我們”的工作副本(僅文件)創建的。 “他們的”中的最初提交將添加“我們的”文件的快照。
在您的情況下,最好的選擇可能是在相應的“我們的”提交中添加用假父母替代品:
git replace --edit <THEIRS_INIT>
在標題中添加“ parent <OURS_COMMIT>
”行,然后保存
合並完成后,您可以刪除替換項。
因此,讓我們開始在一個倉庫中獲取所有對象,然后再考慮合並
git fetch theirs
所以現在你有了
A -- B -- C -- D -- E -- F -- G <--(master)
d -- H -- I -- J <--(theirs/master)
d
處的內容( TREE
)與D
處的內容相同。
現在要合並H
通過J
進入master
處理D
作為合並基礎。 您可能可以提出一些管道命令的腳本組合,這些命令實際上可以做到這一點。 但是我不會。
相反,我會考慮如何最好地結合歷史。 最簡單的方法是通過J
將H
變基為D
類似的,但是處理更少的東西/發生奇怪的事情的機會更少,是重定H
而不是重新定級。 (由於d
和D
的內容相同,所以任何一個操作的結果都應該相同。)
要重設H
可以將git filter-branch
與--parent-filter
選項一起使用。 您需要查找d
和D
的提交ID(SHA)值,然后可能使用sed
腳本將d
ID替換為D
ID。 有關詳細信息,請參見filter-branch
文檔。 我很確定確實有這種情況的示例。
如果你不想處理,像我說的是底墊應該是在這種情況下等價的。 仍然需要一種表達解析為D
-如master~3
中的例子中,或提交ID是細-和一個解析為d
- theirs/master~3
中的示例。
git checkout theirs/master
git checkout -b temp
git rebase --onto master~3 theirs/master~3
這給你
A -- B -- C -- D -- E -- F -- G <--(master)
\
H' -- I' -- J' <--(temp)
d -- H -- I -- J <--(theirs/master)
現在您可能只想將temp
合並到master
並丟棄theirs/master
; 但潛在的下側將是H'
I'
和J'
是新的提交(用新的ID值等),所以如果你要保持維護theirs
回購和希望遷移更改回和第四,這種方法會使您在下次遷移時遇到相同的問題。
因此,如果要保持theirs
,可以進行如下調整:
理想的情況是在這種情況下,你會想從使用原始提交theirs
,但是這不是非常容易的事情。 你可以做的反而是作出一種“假合並”的theirs/master
成temp
合並前temp
來master
。
git checkout temp
git merge -s ours theirs/master
現在你有
A -- B -- C -- D -- E -- F -- G <--(master)
\
H' -- I' -- J' -- JJ <--(temp)
/
d -- H -- I -- J <--(theirs/master)
JJ
似乎是“邪惡的合並”-它的內容不是將J'
與J
合並的自然/默認結果。 但是,鑒於這些歷史,這樣的合並應該發生沖突-即不應該有這樣的事情,作為這樣一個合並“自然/默認結果”。 因此,它沒有那么麻煩。
這意味着J
, J'
和JJ
都具有相同的內容,並且合並master
temp
仍應為您提供正確的結果
A -- B -- C -- D --- E --- F --- G --- M <--(master)
\ /
H' -- I' -- J' -- JJ <--(temp)
/
d -- H -- I -- J <--(theirs/master)
此時,您可以刪除temp
。
保留的目的d
, H
, I
, J
,和JJ
是,就像我說的,以便於從未來的更新theirs
。 在將來獲取時,您可能會得到
A -- B -- C -- D --- E --- F --- G --- M -- N -- O -- P <--(master)
\ /
H' -- I' -- J' -- JJ
/
d -- H -- I -- J -- K -- L <--(theirs/master)
從此狀態開始,您可以簡單地將theirs/master
合並到master
因為git會計算J
為合並基礎。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.