我的存储库中有一些.resx files,其中包含我的应用的字符串翻译。这种方法很有效,除了在单独的git分支中将新字符串添加到文件末尾时的合并冲突。 KDiff3在合并XML列表中并不能很好地发挥作用。
resx文件基本上是键/值对的列表,没有特定的顺序。为了避免合并冲突,我因此希望在提交之前按字母顺序对这些对进行排序,并且我使用了优秀的SortRESX program来使用git过滤器执行此操作:
git config --global filter.resx.clean SortRESX
git config --global filter.resx.smudge cat
完成这项工作。但是,如果我签出一个未排序的文件,它将立即由过滤器排序,并且git不允许我放弃这些更改 - 我在交换分支之前被迫提交文件的排序版本。如何在不提交的情况下丢弃过滤器所做的更改?
答案 0 :(得分:1)
但是,如果我签出未分类的文件,它将立即被过滤器
排序
这不应该发生(我想!)。我相信其他事情确实在发生。
clean
过滤器的意图/想法是,当文件添加到索引时应用,并在提取文件时应用涂抹过滤器从索引到工作树(这就是为什么git checkout
必须首先将文件从提交写入索引,然后在将其复制到工作树时使用git checkout <commit> -- <path>
)。请注意,行尾/ CRLF转换被视为一种过滤形式(如果可能,在内部完成,但如果需要,可以在用户提供的实际过滤器的管道上完成)。
(在某些特殊情况下,我可能会错过某些代码运行clean
过滤器的代码。但我不这么认为:Git源代码的这一部分相当明显。)
我相信正在发生的事情更加微妙。当Git应用污迹过滤器时,会自动在索引中将缓存条目标记为“脏”。 (这段代码相当不太明显,所以我在这里可能是错的。)由于这个标记,当Git进入检查文件的状态时,它说:嗯,这个缓存条目标记为脏,我最好在其上运行clean
过滤器并确定无误。因此它运行您的clean
过滤器,对键/值对进行排序,然后比较导致底层blob。这些不同,所以Git现在声明工作树条目“真正脏”,即使原始的,未排序的工作树条目实际上与当前提交匹配。
换句话说,Git假设等效git cat-file <hash-id> | smudge | clean
产生与<{1}}相同的相同位,如果没有,则应该提交文件 - 当您尝试规范化存储库中存储的行结尾时,实际上通常是正确的。这并不意味着签出的副本已经排序;您的git cat-file <hash-id>
过滤器(顺便提一下,您可以丢弃:不存在的过滤器意味着“单独留下”)没有对文件进行排序,并且工作树副本仍未排序。只是Git坚持要 排序。
这最终意味着答案:
如何在不提交的情况下放弃过滤器所做的更改?
是简单地忽略Git的抱怨,并检查其他提交。您可能必须使用cat
标志来执行此操作,这最多是令人不安的(最糟糕的是,可能会导致您丢失您想要保留的更改!)。所以有一个稍好的(ish)方法:暂时禁用“干净”过滤器(通过编辑--force
)。
禁用过滤器(或用.gitattributes
替换,只做慢一点的同样的事情),Git现在,在检查状态时,看到设置了“脏”标志,并重复其嗯,我最好运行cat
过滤器。这次过滤器是无操作,结果二进制位与blob匹配,Git清除脏标志。您现在可以在任何时候恢复过滤器,因为现在缓存条目不再标记为脏,Git将跳过所有这些测试。
(在声明文件“真正脏”之前,有一种方法可以让Git尝试两个比较:一个使用实际配置的clean
过滤器,然后如果说“脏”,则使用 no 过滤器一次更多时间。这将自动决定工作树文件基于“未清除”的in-repo blob,但是无论如何最终匹配那个blob,实际上“不脏”。当然这意味着你不会被鼓励修复你的行结尾,但如果这是一个用户定义的开关,你可以为包含不洁对象的旧存储库设置它。 ,就像你可以为这样的存储库设置clean
一样。)