2017-02-11 79 views
0

我正在嘗試向所有影響給定部分存儲庫的提交添加關鍵字。我試過這樣的:git filter-branch條件消息過濾器

git filter-branch --msg-filter \ 
'value=$(git ls-files -s | grep -v "folderX" | grep -q .) \ 
([[ $value -eq 1 ]] && echo "[flag]" && cat) || cat' HEAD 

但它不起作用。看來git ls-files -s會返回空白。我不確定在過濾器分支操作期間瞭解存儲庫的狀態,以及過濾器中的git命令。

有人知道一種方法來實現嗎?

回答

0

這裏的第一個問題是:the --msg-filter is run with no index in place

if test -n "$filter_index" || 
    test -n "$filter_tree" || 
    test -n "$filter_subdir" 
then 
     need_index=t 
else 
     need_index= 
fi 

因爲你只有一個$filter_msg -in事實上,git filter-branch總是有一個,這只是它的cat默認情況下,這留下need_index設置到空字符串,所以後來,因爲filter-branch迭代通過每個提交被複制(這,如上所述,從git-filter-branch.sh截斷):

while read commit parents; do 
    [snip] 
      if test -n "$need_index" 
      then 
        GIT_ALLOW_NULL_SHA1=1 git read-tree -i -m $commit 
      fi 
    [snip] 

由於提交的樹沒有被讀入索引,因此git ls-files(讀取索引)沒有發現任何內容。

最簡單的方法是用git ls-tree -r $GIT_COMMIT_ID代替git ls-files

這得到了第二個問題:

value=$(git ls-files -s | grep -v "folderX" | grep -q .) 

我不知道你正試圖在這裏測試什麼,但絕不grep -q產生任何輸出,只有退出狀態。因此,value將始終設置爲空字符串。

此外,似乎沒有理由檢查舞臺編號和散列(-s)。如果我們有一個索引,階段號將始終爲零,因爲儘管有-m選項,但我們實際上並沒有在這裏合併任何樹。你說:

... [國旗]所有提交影響我的倉庫

的給定部分和「影響」通常是指「修改」,意思是「關於修改一些東西「(因爲每個提交都是一個快照,所以必須將其與其他提交進行比較以查看更改內容)。

對於大多數普通的單親提交而言,選擇比較對象很容易:我們只是將其與單親父母進行比較。對於root提交不太明顯,但我們通常要將它們與空樹進行比較(請參閱Is git's semi-secret empty tree object reliable, and why is there not a symbolic name for it?)。對於合併來說,最不明顯的是:我們是與第一位父母還是所有父母進行比較?如果所有家長,我們是否考慮修改一個文件,如果它被更改爲其中任何一個,或者只有它被更改爲全部他們?

在任何情況下,您可能都希望在這裏做一些更復雜的事情,而不僅僅是測試快照中是否存在某些文件。無論測試結果如何,您可能希望您的消息過濾器在測試完成後變得更簡單:

--msg-filter 'some-test-here && echo -n "[flag] "; cat' 
+0

感謝您的回答。我最終使用了'git diff-tree --no-commit-id --name-only -r $ GIT_COMMIT',它也可以在沒有索引的情況下運行 – Romain

+0

請注意,'git diff-tree'比較了所有父代的提交,合併,考慮修改文件,如果它不同於每個父母。對於一個標準的雙親合併,這意味着文件F被改變,如果:(a)父母雙方都提供了真正的改變,或者(b)提交者進行了所謂的「邪惡合併」。這通常是注意合併的相當好的標準,因此可能是對的。 :-) – torek

-1

嘗試調試過程。使用這樣的事情:

echo $value >&2 

>&2會重定向到錯誤流,並會出現在控制檯上。