在使用 merge
或 rebase
對不同分支進行整合時,如果對同一個檔案的同一個部分進行了不同的修改,就會遇到檔案衝突。
git checkout
命令可以使用 --ours
和 --theirs
選項,這是一種無需合併的快速方式,可以選擇留下一邊的修改而丟棄掉另一邊修改。
這裡主要說明在使用 git checkout --ours
或者 git checkout --theirs
時,--ours(--theirs)
的具體指向是什麼。
預先假設 git 倉庫有分支 dev
,在快照 C1 處新建分支 fix
;
分支 fix
相繼提交了 C2、C3 快照;
分支 dev
提交了 C4 快照。
c2---C3 (fix)
/
C0---C1---C4 (dev)
1. 使用 merge
遇到衝突
切換到 dev
分支。
使用 git merge
命令將分支 fix
合併到分支 dev
,兩條分支都對檔案 file1
的同一個部分做了不同的修改;此時,會出現合併衝突。
假設我們需要保留 dev
分支上對 file1
的變更,放棄 fix
分支的變更,可以使用:
git checkout --ours
--ours
,此時表示的是 dev
分支的變更。
假設我們需要保留 fix
分支上對 file1
的變更,放棄 dev
分支的變更,可以使用:
git checkout --theirs
--theirs
,此時表示的是 fix
分支的變更。
2. 使用 rebase
遇到衝突
同樣的前提,使用 rebase
對分支進行處理,將 dev
分支作為目標基底分支,將分支 fix
合併到分支 dev
。
假設我們需要保留 dev
分支上對 file1
的變更,放棄 fix
分支的變更,可以使用:
git checkout --theirs
--theirs
,此時表示的是 dev
分支的變更。
假設我們需要保留 fix
分支上對 file1
的變更,放棄 dev
分支的變更,可以使用:
git checkout --ours
--ours
,此時表示的是 fix
分支的變更。
3. 使用 rebase
時反直覺的指向
這可能和 rebase
的實現有關。
使用 rebase
,將 fix
分支合併到 dev
分支:
git checkout fix
git rebase dev
分支 fix
是當前分支,dev
是變基操作的目標基底分支。
執行時,會先找到這兩個分支(fix
和 dev
)的最近共同祖先 C1,然後對比當前分支 fix
相對該祖先的歷次提交(C2、C3 快照),提取相應的修改並存為臨時檔案,然後將當前分支指向目標基底 C4,最後將之前另存為臨時檔案的修改依次應用為 C2'、C3'。
如果檔案 file1
出現合併衝突,--ours
指的是當前分支 fix
的修改;--theirs
指的是目標基底 dev
的修改。