2014-10-28 90 views
10

我有兩個分支AB。兩者都包含一個子模塊(在文件夾sub中),但是在不同的提交中(不會從一個快速前進到另一個)。如果子模塊未初始化,如何解決git子模塊衝突

A B 
|/
BASE 

我已經簽出A,但子模塊尚未初始化。現在我合併B,我在子模塊上發生衝突。

$ git status 
Unmerged paths: 
    (use "git add <file>..." to mark resolution) 

     both modified: sub 

發行git checkout --ours sub什麼也不做(如果該子模塊初始化它的工作原理,也git checkout-index -f --stage=2 -- sub不工作)。 git add sub導致錯誤error: pathspec 'sub' did not match any file(s) known to git.

$ git diff sub 
diff --cc sub 
index 533da4e,ab2af77..0000000 
--- a/sub 
+++ b/sub 
@@@ -1,1 -1,1 +1,1 @@@ 
- Subproject commit 533da4ea00703f4ad6d5518e1ce81d20261c40c0 
-Subproject commit ab2af775ec467ebb328a7374653f247920f258f3 
++Subproject commit 0000000000000000000000000000000000000000 

git submodule init -- sub什麼都不做。另外git submodule update --init --force -- sub不起作用:Skipping unmerged submodule sub

那麼,如何解決此子模塊衝突(在初始化子模塊後不中止合併並重試)?

回答

12

什麼讓你的情況有點惱人的是,git不會讓你初始化一個未裝入的子模塊,所以只需將submodule設置爲子模塊所需的狀態然後運行git add將不起作用。你可以做的是直接更新索引,而不需要通過工作樹。

更新索引的一種方法是使用git reset。如果您知道子模塊處於所需狀態的提交,則可以使用該提交。例如,以下任一可能是你想要什麼:

git reset master -- sub 
git reset [email protected]{upstream} -- sub 
git reset HEAD -- sub 
git reset MERGE_HEAD -- sub 

另一種選擇是直接使用管道命令git update-index更新索引。要做到這一點,您需要知道gitlink類型的對象(即父庫中指向子模塊的目錄條目)是0160000.沒有辦法從最初的原則中弄清楚,但您可以從git ls-files -s或以下參考(見「1110(gitlink)」下的4位對象類型):https://github.com/gitster/git/blob/master/Documentation/technical/index-format.txt

要使用這種方法,找出你要設置的子模塊,然後運行哈希值,例如:

git update-index --cacheinfo 0160000,533da4ea00703f4ad6d5518e1ce81d20261c40c0,sub 
2

這就像普通的合併:你必須在該路徑提供正確的內容,所以git可以提交它。子模塊內容以其當前提交ID的形式存儲,所以當它具有正確的內容時,必須將子模塊的路徑添加到項目中(就像添加任何文件的路徑一樣),這意味着它的HEAD引用了正確的提交。通常你可以通過普通的結帳來獲得。

就你而言,你不能在子模塊路徑上同時擁有正確的合併結果的內容,並且根本沒有內容。 必要唯一的事情是在HEAD的正確提交ID在該路徑有一個回購。包含repo真的不在乎那個路徑上的子模塊repo的來源,唯一重要的是在HEAD中提交id。

+2

那麼「這工作就像普通的合併」,但是'git checkout --ours'和'git add'不起作用。如何「在該路徑上提供正確的內容」? - 「唯一需要的是在HEAD中用正確的提交ID在該路徑上進行回購」 - 但是,如何初始化子模塊無法實現? – MrTux 2014-10-29 13:37:10

+0

子模塊只是一個回購。 「唯一需要的是在這條路上有一個**回購**。」 'git clone u:// r/l -b $ yourbranch path/to/repo; git add path/to/repo; git commit -m done'。 – jthill 2014-10-29 14:53:58

+0

此選項適用於我。我只是在子模塊位置克隆了缺失回購的正確版本,然後合併就完成了。 – 2018-03-06 00:16:36