git 过滤不是 'unmodifying' 文件

git filter not 'unmodifying' file

我正在使用一个 IDE,它在一些已生成但强烈需要的库文件中生成一个版本。因此,如果我想将库与多个版本一起使用,或者我看到大量实际上毫无意义的更改,就会出现问题。

总结: 我想忽略一个 单行 我认为 git 的一个或多个文件的过滤器是正确的方法。我能够 grep 毫无问题地找到相关行,因为人们可能会进一步阅读。

长话短说,我设置了一个 git 过滤器来恢复对头文件中版本的任何修改。 (请注意,可能有与此文件相关的不同修改。)

[filter "ignore-version"]
    smudge = cat %f || cat
    clean  = git ls-files %f --error-unmatch >&- 2>&- \
              && sed \"/version/c $(git show HEAD:%f | grep version)\" || cat

(为了更好的阅读,我添加了转义换行符,为了简单起见,将单词更改为匹配。在原始版本中,不可能发生冲突。)

  1. git ls-files 检查文件是否已经在存储库中(当前 HEAD

1.1 如果存在,sed 将做肮脏的工作,用已经跟踪的行替换整行

1.2 如果没有,cat 只会继续(这应该确保尚未跟踪的文件不会丢失)

到目前为止,一切正常。 (我可以接受过滤器默默地将所有 CRLF 转换为 LF...)

问题:固定文件被​​标记为已被git修改,尽管存储库的最新文件和过滤后的版本是二进制相等的。我使用 kdiff 作为单独的工具进行了检查。


编辑 1:这是一些显示两个文件版本相等的输出:

$ git show HEAD:file.txt | md5sum
9f95c28cebe4f45b8efb7b0ae64dfa56
$ cat file.txt | md5sum
894e7d1b28180b7a193bf3cdd6ceaacb
$ cat file.txt | git ls-files file.txt --error-unmatch >&- 2>&- \
              && sed \"/version/c $(git show HEAD:file.txt | grep version)\" 
              || cat | md5sum
9f95c28cebe4f45b8efb7b0ae64dfa56

编辑 2: 此外,差异的输出...

$ git diff file.txt
warning: LF will be replaced by CRLF in file.txt.
The file will have its original line endings in your working directory.

请注意,此文件的签入版本仅包含 LF 与上一次提交一样。另请注意,设置 core.autocrlftrue,除了 .gitattributes 文件中的过滤器规范外没有任何其他内容。

终于解决了。问题文件处于一种奇怪的状态,似乎签出的版本具有 unix 样式的行结尾,这对于 git 配置是不正确的(签出 windows 样式,提交 unix 样式)。在 暂存 这个特定文件后,它立即从暂存区中删除,没有任何提及,现在被认为没有变化。所以我认为 git 在暂存期间(行尾)清理了工作目录文件,现在它可以工作了。

抱歉打扰了。


完整检查问题的步骤:

git init
echo "version=0.1" > file.txt
echo "*.txt filter=ignore-version" > .gitattributes
git config --local filter.ignore-version.clean 'git ls-files %f --error-unmatch >&- 2>&- \
    && sed -b "/version/c $(git show HEAD:%f | grep version)" || cat'
git config --local filter.ignore-version.smudge 'cat %f || cat'
git add file.txt .gitattributes
git commit -m "initial commit"
# -----
echo "version=0.2" > file.txt
git status

状态不应报告任何变化。在 Linux 和 Windows.

上都使用裸存储库对我有用