git filter-branch条件消息过滤器

时间:2017-02-11 09:17:54

标签: git

我正在尝试对影响我的存储库的给定部分的所有提交添加关键字。我试过这样的事情:

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命令的期望。

有人知道实现这个目标的方法吗?

2 个答案:

答案 0 :(得分: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 - 事实上,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选项,我们实际上并没有在这里合并任何树。你说:

  

... [flag]所有提交影响我的存储库的给定部分

和"影响"通常意味着"修改",这意味着"修改某事物" (因为每次提交都是一个快照,所以必须将它与其他一些提交进行比较才能看到发生了什么变化)。

对于大多数普通的单父提交,选择要比较的内容很容易:我们只是将它与其(单个)父项进行比较。对于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'

答案 1 :(得分:-1)

尝试调试过程。使用这样的东西:

echo $value >&2

>&2将重定向到错误流,并将显示在控制台上。