2013-01-08 137 views
18

我有一個項目,其中最初使用的是某些從屬代碼的子模塊。事實證明子模塊並不適合這個項目(在實踐中它們很難使用),所以我將每個子模塊轉換爲子樹(使用新的git-subtree功能)。將Git子模塊轉換爲子樹後合併錯誤

在我的工作存儲庫中,我已成功刪除每個子模塊,並將舊子模塊回購添加爲子樹。這沒有問題。

當我去到另一個克隆並嘗試從第一個拉,我從合併的步驟以下錯誤:

error: The following untracked working tree files would be overwritten by merge: 
     sub/.gitignore 
     sub/Makefile 
     sub/README 
     sub/src/main.c 
     ... and so on for all files in sub/ 
Aborting 

看來,這是因爲在sub/文件從來沒有真正存在主存儲庫,當Git應用修補程序更新.gitmodules時,它不會刪除包含子模塊文件的目錄。在處理下一個提交時,其中Git試圖創建sub/中的新文件現在是現在是主要存儲庫的一部分,所有這些文件與sub/中仍存在的文件相沖突。

我發現的解決方法是在git pull之前使用rm -rf sub,這可以避免此問題。

我的問題是,是否有任何命令行開關我可以git merge,說使用「覆蓋這種情況發生在工作目錄中存在的任何文件」?更好的辦法是,git merge將查看現有文件的內容,如果內容與它要創建的文件相同,則抑制錯誤消息並繼續。

UPDATE:我創建了Git存儲庫來演示這個問題,以準確地顯示我在說什麼。要重現:

$ git clone https://github.com/ghewgill/q14224966.git 
$ cd q14224966 
$ git submodule init 
$ git submodule update 
$ git merge origin/branch 

這將導致錯誤消息

error: The following untracked working tree files would be overwritten by merge: 
    sub/Makefile 
    sub/README 
    sub/src/main.c 
Please move or remove them before you can merge. 
Aborting 
+0

你試試這個:http://goo.gl/z1XP9? – Efthymis

+0

@Efthymis:完整的鏈接是http://stackoverflow.com/questions/1295171/git-merge-to-master-while-automatically-choosing-to-overwrite-master-files-with(請不要使用URL縮寫這裏)。我嘗試過'git merge -s遞歸-X他們的origin/master',並且發生同樣的錯誤。 –

+0

對不起,關於那 – Efthymis

回答

9

我知道你的問題是具體的合併,但我已經與合併git的子模塊類似的問題。我認爲這個解決方案可以解決你的問題,即使它不直接解決合併問題。

我發現通過強行檢出想要合併的分支,然後再回到主模塊,一切都可以通過子模塊實現。

要得到的東西在你的榜樣工作:

$ git clone https://github.com/ghewgill/q14224966.git 
$ cd q14224966 
$ git submodule init 
$ git submodule update 
$ git checkout -f origin/branch 
$ git checkout master 
$ git merge origin/branch 

這工作,因爲它基本上做你rm -rf一步你。當然,這有點迂迴,如果你只有一個子模塊就像你的例子那樣,也許不值得。但是我發現在一個有許多子模塊的項目中工作時,這是一個非常節省的時間。

而且,正如在評論中所指出的,如果你想避免在更改工作樹,您可以使用此:

$ git clone https://github.com/ghewgill/q14224966.git 
$ cd q14224966 
$ git submodule init 
$ git submodule update 
$ git reset origin/branch 
$ git reset --hard master 

這個工作在大致相同的方式,但避免了檢查淘汰過程中的其他文件。我沒有機會在野外使用它,但它似乎是一個合理的方法。

還有$ git merge -s subtree origin/branch。它適用於你的例子,但是當涉及多個子模塊時,它會產生意想不到的結果。不過,你可能會有更好的運氣。

+1

看到這一點,我看了一眼,看看這個方法有多聰明。我現在注意到你可以用'git reset origin/branch; git reset --hard master';這樣可以避免除想要的刪除之外的所有工作樹活動。 – jthill

+0

@jthill你說得對。您可以通過使用重置完全跳過工作樹的東西。我會更新我的答案以反映這一點。謝謝! –

+0

不幸的是,使用'git reset'的第二種解決方案失敗了,因爲它在分支創建後放棄了在master分支(比如'README')上所做的任何更改。 –

1

您無法獲得git-merge(或任何其他命令)強行打開它認爲它不知道的文件,否。 git很難不做任何事情完全不可逆轉。

但許多子模塊,你可以您刪除有點容易,更安全與git submodule foreach

$ git submodule foreach 'rm -rf $toplevel/$path' 
Entering 'sub' 
$ git merge origin/branch 
Updating a231acd..6b4d2f4 
Fast-forward 
... 
+0

這使得'rm -rf'稍微簡單一些,但它仍然是相同的解決方案。 –

+0

唉,是的。但是你將不得不爲這種情況做些特別的事情,所以,最好的辦法就是運行最簡單的東西 – Eevee

0

它試圖

混帳取--all

git的復位--hard origin/master

但它不起作用。

您可以使用「我們的」合併策略:

混帳合併-s我們的老主

你也可以使用git-藏匿保存更改然後混帳藏匿申請恢復。

+0

使用'merge -s ours'並不會完成合並,也不能解決問題。 –

+0

是啊,這是一個問題,你不能合併:D,但你嘗試存儲? – GLES

+0

不幸的是,存儲不起作用,因爲當你不存儲數據時,你仍然必須做一些*合併。 –

1

(警告:我從來沒有與子樹工作,我不知道你的實際回購的複雜程度,所以這些解決方案實際上可能並不適合你。)

從與樣品回購玩耍,我已經發現了兩個解決方案都似乎工作,雖然他們產生不同的承諾樹:

  1. 使用git merge -s resolve origin/branch

    ~/q14224966[master]> git reset --hard origin/master 
    HEAD is now at a231acd add submodule 
    ~/q14224966[master]> touch other.c && git add . && git commit -m "New commit." 
    [master bc771ac] New commit. 
    0 files changed 
    create mode 100644 other.c 
    ~/q14224966[master]> git merge -s resolve origin/branch 
    Trying really trivial in-index merge... 
    error: Merge requires file-level merging 
    Nope. 
    Trying simple merge. 
    Simple merge failed, trying Automatic merge. 
    Adding sub/Makefile 
    Adding sub/README 
    Adding sub/src/main.c 
    Merge made by the 'resolve' strategy. 
    .gitmodules | 3 --- 
    sub   | 1 - 
    sub/Makefile | 1 + 
    sub/README  | 1 + 
    sub/src/main.c | 1 + 
    5 files changed, 3 insertions(+), 4 deletions(-) 
    delete mode 160000 sub 
    create mode 100644 sub/Makefile 
    create mode 100644 sub/README 
    create mode 100644 sub/src/main.c 
    ~/q14224966[master]> ls 
    README main.c other.c sub/ 
    ~/q14224966[master]> cd sub/ 
    ~/q14224966/sub[master]> ls 
    Makefile README src/ 
    ~/q14224966/sub[master]> git status 
    # On branch master 
    # Your branch is ahead of 'origin/master' by 5 commits. 
    # 
    nothing to commit (working directory clean) 
    ~/q14224966/sub[master]> cd .. 
    ~/q14224966[master]> git status 
    # On branch master 
    # Your branch is ahead of 'origin/master' by 5 commits. 
    # 
    nothing to commit (working directory clean) 
    

    這裏的resul婷犯樹:git commit tree - merge option

  2. 使用,而不是合併衍合:

    ~/q14224966[master]> git reset --hard origin/master 
    HEAD is now at a231acd add submodule 
    ~/q14224966[master]> touch other.c && git add . && git commit -m "New commit." 
    [master ae66060] New commit. 
    0 files changed 
    create mode 100644 other.c 
    ~/q14224966[master]> git rebase origin/branch 
    First, rewinding head to replay your work on top of it... 
    Applying: New commit. 
    ~/q14224966[master]> ls 
    README main.c other.c sub/ 
    ~/q14224966[master]> cd sub/ 
    ~/q14224966/sub[master]> ls 
    Makefile README src/ 
    ~/q14224966/sub[master]> git status 
    # On branch master 
    # Your branch is ahead of 'origin/master' by 4 commits. 
    # 
    nothing to commit (working directory clean) 
    ~/q14224966/sub[master]> cd .. 
    ~/q14224966[master]> git status 
    # On branch master 
    # Your branch is ahead of 'origin/master' by 4 commits. 
    # 
    nothing to commit (working directory clean) 
    

    這裏的commit的結果樹:git commit tree - rebase option

+0

我嘗試過使用'merge -s resolve',但如果子模塊中的文件仍然存在(確保你以'git reset --hard origin/master && rm -rf sub && git submodule update'開頭) 。 –