git过滤器不是'unmodifying'文件 [英] git filter not 'unmodifying' file

查看:153
本文介绍了git过滤器不是'unmodifying'文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个IDE,它在一些生成的但强烈需要的库文件中生成一个版本。因此,如果我想使用具有多个版本的库,或者看到一些实际上没有意义的更改,则会出现问题。


$ b 摘要: strong>我想忽略一个或多个文件的单行行,我认为git的过滤器是正确的方法。我可以在 grep 的相关行中没有任何问题,因为人们可能会看到进一步阅读。



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

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

(为了更好的阅读效果,我添加了换行符,为了简单起见, )
$ b $ ol

  • 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>& $ \\ b $ b&& sed \/ version / c $(git show HEAD:file.txt | grep version)\
    ||猫|的md5sum
    9f95c28cebe4f45b8efb7b0ae64dfa56






    修改2:另外,输出的区别...

      $ git diff file.txt 
    警告:LF将被file.txt中的CRLF替换。
    该文件将在工作目录中具有其原始行结尾。

    请注意,此文件的签入版本只包含 LF 由之前的提交。还要注意,设置 core.autocrlf true ,除 .gitattributes file。

    解决方案

    最后,我解决了它。问题文件处于一种奇怪的状态,看起来好像签出的版本具有unix风格的行结尾,这对于git配置是不正确的(检查windows风格,提交unix风格)。在将这个特定的文件分段之后,它立即从暂存区域中删除,没有任何提及,现在被认为是不变的。所以我认为git在临时(行结束)期间清理了工作目录文件,现在它可以工作。



    对不起。






    完成检查问题的步骤:

      git init 
    echoversion = 0.1> file.txt
    echo* .txt filter = ignore-version> .gitattributes
    git config --local filter.ignore-version.clean'git ls-files%f --error-unmatch>& - 2>& $ \\ b $ b&& 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 -minitial commit
    #-----
    echoversion = 0.2> file.txt
    git status

    状态不应报告任何更改。它在Linux和Windows上都使用裸存储库。


    I am working with an IDE which produces a version in some generated, but strongly required files of libraries. So there is an issue if I want to use the library with multiple versions or I see a load of changes which are in fact senseless.

    Summary: I want to ignore a single line of one or multiple files which I thought git's filters are the right approach. I am able to grep for the relevant line without a problem as one might see reading further.

    Long story short, I set up a git filter to revert any modification to the version in the header file. (Please note that there might be different modifications which are relevant in this file.)

    [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
    

    (I added escaped line breaking for better reading and changed the word to match for simplicity. In the original version there are no collisions possible.)

    1. git ls-files checks if the file is already in the repository (currently HEAD)

    1.1 if present, sed will do the dirty work to replace the whole line with the already tracked one

    1.2 if not, cat will do nothing but go ahead (this should ensure a not yet tracked file will not get lost)

    So far, it works. (I can live with the fact that the filter silently converts all CRLF to LF...)

    Problem: The fixed file is marked as modified by git, although the most recent file of the repository and the filtered version are binary equal. I checked this using kdiff as separate tool.


    Edit 1: Here is some output which shows the equality of the two file versions:

    $ 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
    


    Edit 2: Additionally, the output of the difference...

    $ 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.
    

    Please note that the checked in version of this file contains only LF as by the previous commit. Note also that the setting core.autocrlf is true without having anything but the filter specification in the .gitattributes file.

    解决方案

    Finally, I solved it. The file of question was in a strange state, it seems like the checked out version had unix style line endings which is not right regarding the git configuration (check out windows style, commit unix style). After staging this particular file it was instantly removed from staging area without any mention and is now considered unchanged. So I think git cleaned the working directory file during staging (line endings) and now it works.

    Sorry for the noise.


    Steps to completly check the problem:

    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
    

    Status should not report any changes. It worked for me using bare repositories on both, Linux and Windows.

    这篇关于git过滤器不是'unmodifying'文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆