我想最好的解決將是修補水銀的Git的subrepository支持始終使用Git的遞歸選項(例如git clone --recursive
拉動更新的Git和subrepository等之後克隆一個Git和subrepository,git pull --recurse-submodules && git submodule update
時)。我知道Git開發人員特別選擇不自動初始化子模塊,因爲他們希望支持的工作流之一是「我從不想看到任何子模塊」,但也許「始終初始化所有子模塊」是更好的匹配默認Mercurial操作模式(我沒有太多的Mercurial用戶,所以我對默認的Mercurial風格會有什麼不瞭解)。
等到那個時候,你也許可以通過翻譯subrepo/.gitmodules
項爲.hgsub
項解決此問題。手動操作很容易,但如果重要的話,您可能會自動執行該操作(使用git config
從.git/config
和/或.gitmodules
中提取路徑和URL)。如果你正在處理的.gitmodules
文件變化很大(每次更改.gitmodules
時你都必須非常勤奮地同步.hgsub
),這可能沒有吸引力。
我有四個存儲庫進行測試的: - 一個「葉」儲存庫(沒有GIT中的子模塊)
gitsuper -
- gitsub一個GIT中「上層項目」;
gitsub/
是gitsub作爲子模塊
- hgsuper2 - 一個水銀「上層項目」;
gitsuper/
是gitsuper作爲subrepository,
gitsuper/gitsub
是gitsub作爲subrepository。
- hgsuper2-clone - 克隆的Mercurial「superproject」;
gitsuper/
是gitsuper作爲subrepository,
gitsuper/gitsub
是gitsub作爲subrepository。
我建造和測試他們是這樣的:
- 創建gitsub。添加並提交一些內容。
- 創建gitsuper。
- 添加一些內容。
git submodule add url-of-gitsub gitsub && git submodule init
git commit -m 'added gitsub'
- 創建hgsuper2。
- 添加一些內容。
git clone --recursive url-of-gitsuper gitsuper
echo 'gitsuper = [git]url-of-gitsuper' >> .hgsub
echo 'gitsuper/gitsub = [git]url-of-gitsub' >> .hgsub
最後兩個步驟可以從gitsuper/.git/config
和gitsuper/.gitmodules
位被自動化。
hg add .hgsub && hg commit -m 'added Git subrepositories'
- 克隆hgsuper2克隆從hgsuper2。
它得到gitsuper/
和gitsuper/gitsub/
中的適當內容。
- 更新並提交新內容至gitsub。
- 更新gitsuper。
- 添加或更改內容並將其放置。
(cd gitsub && git pull origin master)
git add gitsub && git commit -m 'updated gitsuper content (also gitsub)'
- 在hgsuper2,拉從Git的suprepositories變化。
(cd gitsuper && git pull --recurse-submodules && git submodule update)
內容在gitsuper/
和gitsuper/gitsub/
由拉更新。
hg commit -m 'updated gitsuper (and its contents)'
- 拉進hgsuper2克隆。
hg pull -u
Git的內容已更新。
我的測試工作(使用水銀1.8.1和Git 1.7.4.1),但我注意到一個錯誤。 Mercurial創建並檢出一個奇怪的Git分支(origin/master
(即refs/heads/origin/master
),而不是使用分離的HEAD(像Git對子模塊做的那樣)或僅使用master
(即refs/heads/master
))。它也似乎變得有點有時楔入,導致這樣的錯誤:
fatal: git checkout: branch origin/master already exists
abort: git checkout error 128 in gitsuper
我工作圍繞這一問題通過進入有問題(基於Git的,水銀subrepository)的Git倉庫,並刪除分支git checkout HEAD~0 && git branch -D origin/master
(第一個分離HEAD和(更重要的是)離開分支,所以它可以被下一個命令刪除)。只要您在Git存儲庫中沒有任何本地更改,此解決方法就完全安全。
另一個小問題是,你將需要運行git submodule init
讓Git的知道它的子模塊,是由水銀創建(子模塊克隆到正確的地方一個Git超級倉庫發出的Git子模塊命令之前,但他們由Mercurial建立,因此.git/config
中沒有他們的條目)。同樣,如果您計劃從基於Git的Mercurial子庫中創建對由Git管理的內容的更改,那麼您應該小心始終在Git子庫之前添加任何Git子模塊,提交和推送承諾參與Mercurial「超級項目」。否則,可能會在那裏水銀使用gitsuper和gitsub的一個組合而gitsuper本身指的是不同版本gitsub的結束與一個局面。換句話說,由於您將繞過Git的子模塊代碼(通過將Git子模塊作爲Mercurial子庫進行管理),您需要小心將Git的子模塊視圖與Mercurial的子模塊保持同步。
令人驚歎的答案。賞金是你的。感謝所有的努力。我要測試解決方法,並且可能會在mercurial的代碼和郵件列表中進行一些關於修補此行爲的搜索。 – 2011-04-03 19:19:46
當時你的回答確實很棒,但我只是放棄了所有這些瘋狂。 :) – 2015-05-14 04:57:51