git filter不是'unmodifying'文件

max*_*xik 5 git sed git-filter

我正在使用一个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
Run Code Online (Sandbox Code Playgroud)

(为了更好的阅读,我添加了转义换行符并更改了单词以便简单匹配.在原始版本中没有可能的冲突.)

  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
Run Code Online (Sandbox Code Playgroud)

编辑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.
Run Code Online (Sandbox Code Playgroud)

请注意,此文件的签入版本仅包含前一次提交的LF.另请注意,除了文件中的过滤器规范外,该设置core.autocrlftrue.gitattributes.

max*_*xik 4

最后我解决了。有问题的文件处于奇怪的状态,似乎签出的版本具有 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
Run Code Online (Sandbox Code Playgroud)

状态不应报告任何变化。它对我来说在 Linux 和 Windows 上使用裸存储库都有效。