2013-07-15 16 views
1

對於具有子模塊的項目的CI構建,我想確保工作樹完全匹配在中央存儲庫中提交的狀態。如何更新本地子模塊,以便它們與子模塊的中央列表相匹配?

取出,檢查出上層項目的修訂後,我請執行下列步驟來更新子模塊:

git submodule foreach 'git reset --hard && git clean -xdf' 
git submodule update --init 

這似乎對所有的情況都是不同的,如果一個子模塊在中央資料庫中刪除。在這種情況下,作業工作副本仍包含已刪除的子模塊。

另外,超級項目上的git clean -xdf似乎沒有碰到過時的子模塊。

那麼,是否有可能自動檢測陳舊的本地子模塊並刪除它們?

回答

1

問題是您的repo的配置仍然完全受到陳舊的子模塊數據的污染。我設法通過首先清理回購配置來運行git clean -xdf

我從源代碼使用git 1.8.1.3,但子模塊刪除仍然是一個主要的頭痛。我完全喪失了爲什麼子模塊信息存儲在repo配置中。我們完全停止使用它們,並將其更改爲子樹合併。

比方說,陳舊的子模塊位於目錄foo

如果子模塊仍然列在您的.git/config文件中,但已從.gitmodules中刪除,則子模塊已上游刪除。你需要做的,現在4兩件事:

  • 刪除子模塊富數據從.git/config
  • 刪除過時的子模塊的gitfile rm foo/.git
  • 刪除過時的子模塊的回購rm -rf .git/modules/foo
  • 立即清潔:git clean -xdf
+0

但是,如何自動檢測到本地子模塊是陳舊的?我正在尋找一種增量式解決方案,即不需要克隆我以前克隆過的解決方案。所以在每次獲取時盲目地移除'.git/modules/foo'不是一個選項。 – oberlies

+0

引用自己:如果子模塊仍然作爲子模塊列在您的.git/config文件中,但已從.gitmodules中刪除,則子模塊將被上游刪除。 – SzG

+0

對,我只需要'grep' /'awk' /'sed'把它們變成兩個列表,並將它們與'comm'進行比較。我現在會接受這個答案,但保留一旦我(或其他人)已經編寫腳本來完成您接受的答案的權利,該腳本將執行您描述的所有步驟。 – oberlies

0

我已經想出了一個Perl腳本來清​​除子模塊刪除後的repo配置。不幸的是,它只有在過時的子模塊目錄位於超級項目的根目錄時纔有效。因爲,猜測在子模塊的git-link和.gitmodules條目被刪除後,git不會保存它在樹中的位置。即使repo配置是完全骯髒的,乾淨刪除所需的單個信息也不可用。寫這個git維護者是值得的。目前,我建議大家單獨留下子模塊。

無論如何,這是腳本。此後git clean -xdf確實工作。誠實。 :-)

#!/usr/bin/perl         
our %mods;          
open MOD, ".gitmodules" or die $!;    
while (<MOD>) {         
    if (/\[submodule "(.+)"\]/) {    
     $mods{$1} = 1;       
    }           
}            
close MOD;          
rename ".git/config", ".git/config~" or die $!; 
open BAK, ".git/config~";      
unlink ".git/config~";       
open CFG, ">.git/config";      
our $print_on = 1;        
while (<BAK>) {         
    if (/\[submodule "(.+)"\]/) {    
     $print_on = $mods{$1};     
     unlink "$1/.git" unless $print_on;  
    } elsif (/^\[/) {       
     $print_on = 1;       
    }           
    print CFG if $print_on;      
}            
close BAK;          
close CFG;