这个git smudge/clean过滤器有什么问题?

9

我希望在我的git仓库中应用这个过滤器,在检出时从解决方案文件中删除一个部分,并在提交时添加该部分。

这是我想要删除或添加的部分:

GlobalSection(SubversionScc) = preSolution
    Svn-Managed = True
    Manager = AnkhSVN - Subversion Support for Visual Studio
EndGlobalSection

我已经在我的.git/info/attributes中设置了以下过滤器:

*.sln filter=SourceControlProvider

并将以下命令添加到我的配置文件中。

$ git config filter.SourceControlProvider.smudge "sed -e '/GlobalSection(SubversionScc)/,/EndGlobalSection/d' %"
$ git config filter.SourceControlProvider.clean "sed -n -e '/^Global$/ r ankhsvnsection ' < %"

嗯,它不起作用。我做错了什么?

ankhsvnsection是一个文本文件,位于与*.sln文件相同的目录中。


你有检查过是否使用更简单的sed工具可以正常工作吗?还是说在执行时找不到sed工具本身是个问题? - VonC
1个回答

19

我看到这里有几个问题:

  1. 你在两个过滤器的末尾都有一个%
    这没有特殊意义,将被作为额外参数传递给sed,可能会生成错误(除非你有一个名为%的文件)。
    过滤器应该是“流式”的(从stdin读取并写入stdout)。它们的定义可以包括%f,但实际上不应该被视为要读取或写入的文件;Git处理那部分,过滤器只需从stdin读取并写入stdout。

  2. 你的clean过滤器试图从%f重定向stdin。
    输入数据已经在stdin上,无需重定向。

  3. clean过滤器中的sed程序使用r命令访问另一个文件。
    过滤器似乎是从工作树的根目录运行的,但我不确定是否保证。

  4. clean过滤器中的sed命令使用-n。它的唯一输出将是ankhsvnsection文件的内容(假设输入具有Global行)。

  5. 某些版本的sed(至少是Mac OS X中旧的BSD版本)不允许在r命令的文件名后添加空格(即clean过滤器的sed程序中ankhsvnsection后的空格)。

在添加、更改或删除过滤器之后,你可能需要在Git应用该过滤器之前touch、修改或删除工作树文件。Git的索引记录了工作树文件的修改时间;如果它们没有改变,则Git将把git checkout -- filegit add file转换为无操作。

如果你想查看索引的实际内容(例如检查clean过滤器生成的内容),你可以使用git show :0:path/from/repo/root/to/file。通常不能使用git diff,因为它也会应用过滤器。

这些对我有用:

git config filter.SourceControlProvider.smudge "sed -e '/GlobalSection(SubversionScc)/,/EndGlobalSection/d'"
git config filter.SourceControlProvider.clean "sed -e '/^Global\$/ r ankhsvnsection'"

+1 发布可工作的代码行。其余部分包括一些小问题或长远目标(有些sed可能不喜欢文件名后的空格?来吧...除非加引号,否则没有任何sed会接收到这个空格)。 - sehe
3
@sehe:我的sed在问题的清理过滤器中使用的程序出了问题:“sed:1: "/^Global$/ r ankhsvnse ...": read命令后面有空格”。唯一的“不确定因素”是关于过滤器当前工作目录的警告;除此之外,其他一切都是必要的以使过滤器正常工作(至少在我的系统上是这样)。 - Chris Johnsen
我现在明白了。你所指的文件名是“r”命令的操作数。是的,你不能在后面加上空格。我明白了。 - sehe
(编辑了最后一点,以澄清哪个空间是问题所在,并且在哪个平台上。) - Chris Johnsen
非常感谢。我刚测试了清洗筛选器,它的效果非常好。 - mrt181

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接