[英]Git rebase conflicts after successful merge?
我有兩個分支:稱它們為master
和feature
。 我現在正在嘗試將最近的更改從master合並到功能。 與合並相比,我通常更喜歡使用基准,但是這兩個分支之間的分歧很大,因此我決定進行合並,而不要記錄所有解決沖突的記錄。 我完成了合並,並將其提交給功能部件,並認為我已完成。 一切看起來都不錯。
現在,我對master進行了少量更改,只是想將其重新設置為功能,但是git rebase master
現在使我與上一次合並中已處理的較舊的提交發生沖突。 奇怪的是, git merge master
沒有給出預期的沖突。 是什么賦予了?
之所以會發生這種現象,是因為當您merge
master時,更改會在feature
的頂部/末端進行。
重新設定基准時,來自master
的更改存在於feature
的開頭 。
這就是為什么當您在頂部合並時,修復所有沖突,再次合並,然后這些沖突已得到解決的原因。 但是,當重新設置基准時,您必須再次合並沖突,因為解決所有問題的上一次提交位於分支的末尾。
聽起來好像您最好選擇合並或重新建立基礎並在整個feature
壽命內堅持下去。
你的措辭(“變基[掌握做了小改動]進入功能”),似乎有點怪我,因為通常你會重訂feature
到master
。 (“ into”一詞並不能很好地應用。)此外,我認為它總是有助於繪制提交圖。 您可以使用gitk
或類似的查看器進行繪制,或者使用git log --graph
,也許還使用--oneline
來繪制垂直方向的圖。 但是在這里,我將畫一個水平的,單個大寫字母代表特別有趣的提交,小寫o
代表更無聊的提交。
為了我們的目的,我將省略任何已配置的上游( origin/master
和/或origin/feature
)。 如果確實存在,則可能需要將它們添加到自己的圖形中,然后注意,當git rebase
復制提交時,它不會移動任何其他指向現有提交的標簽(包括這些遠程跟蹤分支):它只移動一個標簽,即當前分支的標簽。
... - A - o - o - o - F <-- master
\ \
B - C - D - E - G <-- HEAD -> feature
幸運的是,這相當接近您的re-base設置,並且可以准確反映git merge
的結果。 在您進行合並之前和之后,提交A
是feature
與master
分開的原始基礎; B
到E
提交是在feature
; 在master
上進行了各種不太有趣的o
提交; 而提交F
是掌握技巧。 您正在使用分支feature
(以便HEAD
命名為branch feature
,而git status
表示“在分支功能上”),並且您運行了git merge master
並進行了合並和提交。
此合並在feature
上創建了最尖端的提交,即提交G
,這是一個合並提交。
之后,您簽出了分支master
(使HEAD
指向名稱master
)並進行了一次新提交,該提交移動了master
的尖端,因此讓我們將其添加到我們的圖中:
... - A - o - o - o - F - H <-- HEAD -> master
\ \
B - C - D - E - G <-- feature
最后,您想在master
的(新提示)上重新建立feature
,因此您進行了git checkout feature
:
... - A - o - o - o - F - H <-- master
\ \
B - C - D - E - G <-- HEAD -> feature
現在運行命令git rebase master
。
rebase
所做的是復制提交。
首先,它必須找到要復制的提交。 它應該復制的提交是那些可以從當前分支(即從名稱feature
到達的提交,而不是可以從您作為上游給出的分支(即master
到達的提交。
這是我們遇到的一個大問題。 查看最近git rebase
文檔中的這一段(相當密集):
當前分支中的所有提交但未在<upstream>中的提交所做的更改都保存到一個臨時區域。 這與
git log <upstream>..HEAD
將會顯示的提交集相同。 或通過git log 'fork_point'..HEAD
,如果--fork-point
是活動的(請參閱下面有關--fork-point
的描述); 或通過git log HEAD
,如果指定了--root
選項。
分支點的東西本身有點復雜,但是我們現在可以忽略它,因為使用命令git rebase master
意味着它已關閉。 因此,您可以看到要使用git log master..HEAD
重新建立的提交。 這是提交B
, C
, D
, E
和G
(除了通常重新分配合並的基礎以外)。
考慮到master
和feature
的合並基礎是commit G
,您可能想知道為什么這里包含B
到E
問題是,盡管合並提交G
指向提交F
(可從主服務器到達),但提交F
不會(也不能)“指向” G
因此,當我們從master
的尖端開始(新提交H
)並向后工作時,我們得到H
, F
,所有無聊的o
, A
以及A
之前A
所有內容:這些都是排除的提交。 當我們從feature
的頂端開始(提交G
)並向后工作時,我們在到達第一個排除的特征( A
)之前得到G
, E
, D
, C
和B
因此,這些都是重新定級的候選人。
如果您允許進行重新設置並解決所有沖突,最終將得到:
B' - C' - D' - E' <-- HEAD -> feature
/
... - A - o - o - o - F - H <-- master
\ \
B - C - D - E - G [abandoned]
(假設所有要復制的提交都具有要復制的實際更改;無需復制提交G
,因為這次它不會做任何貢獻)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.