git-merge可能忽略行结束差异吗? [英] Is it possible for git-merge to ignore line-ending differences?

查看:186
本文介绍了git-merge可能忽略行结束差异吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能让 git merge 忽略行结尾差异?

可能我问错误的问题......但:

我尝试过uisng config.crlf输入但事情有点混乱特别是当我在事实之后应用 时。



首先,在事实之后应用此配置似乎没有影响在应用此选项之前已提交到存储库的文件。另一件事是,突然所有的提交现在都会导致很多关于CRLF被转换为LF的恼人的警告消息。



老实说,我并不在乎线路是什么,结局被使用,我个人更喜欢Unix风格 \\\
,但是不管。我所关心的是为 git merge 变得有点聪明,并且忽略了行尾的差异。



有时我有两个相同的文件,但git会将它们标记为冲突(并且冲突是整个文件),仅仅是因为它们使用了不同的行尾字符。



更新:



我发现 git diff 接受一个 - ignore-space-at-eol 选项,是否可以让 git merge 使用这个选项?

解决方案

更新2013:



更新的git版本授权使用合并策略递归和策略选项 -X ):



 
git合并-s递归-Xignore-space-at-eol

但是使用 -Xignore-space-change 也是一种可能性




  • Fab-V 提及以下

     
    git merge master -s递归-X重新规格化


    $ b $ hr
    $ b $ p jakub.g 策略也可用于樱桃采摘 :

      git cherry-pick abcd123456 --strategy = recursive --strategy-option = renormalize 

    这比 ignore-all-space 要好的多。





    原始答案(2009年5月)

    忽略eol风格的补丁已在 2007年6月,但它只涉及 git diff --ignore-space-at-eol ,而不是 git merge



    当时,问题一直存在:


    - ignore-space-at-eol git-merge 的选项?

    合并是这个功能很重要的地方。

    这些选项有效的自动解析合并的语义是什么 - 它们只用于重命名检测,还是我们,例如,不是标志与只有空白变化冲突?如果我们不这样做,我们会自动接受哪个版本?


    Julio C Hamano并不热衷于:


    这当然是诱人的,但我怀疑应该留给后来轮。

    我怀疑它会引入两个概念不同类型的差异,一个需要机械处理(即用于合并git-merge-recursive,并使用
    git-am),另一个需要人类检查才能理解。 >
    即使比较输入文件的输出可能不容易用于机械应用,对于后一种情况,通常可能会有用。

    当谈到 git merge 时,总体思路是依赖于第三方合并工具。 strong>



    例如,我已经设置了 DiffMerge 成为Git mer的工具ge,设置规则集,允许合并工具忽略某些类型文件的eol。






    在Windows上使用MSysGit1.6.3进行安装,无论是DOS还是Git bash会话,使用DiffMerge或KDiff3:


    • 将目录设置为你的PATH(这里: c:\HOMEWARE\cmd )。

    • 在该目录中添加脚本merge.sh(wrapper为您最喜爱的合并工具)



    merge.sh:

     <!c $ c>#!/ bin / sh 

    #将以下参数传递给mergetool:
    #local base remote merge_result

    alocal = $ 1
    base = $ 2
    remote = $ 3
    result = $ 4

    if [-f $ base]
    then
    #C:/ Program文件/ SourceGear / DiffMerge / DiffMerge.exe$ alocal$ base$ remote-m --result =$ result--title1 =Mine--title2 =合并到:$ result --title3 =Theirs

    #用于合并尊重eol,KDiff3比DiffMerge更好t LF到CRLF)
    #KDiff3将显示eol选项(如果Windows:CRLF,如果是Unix LF)
    C:/ Program Files / KDiff3 / kdiff3.exe-m$ base$ alocal$ remote-o$ result
    else
    #并不总是一个共同的祖先:DiffMerge需要3个文件,BASE将是结果
    #C:/ Program文件/ SourceGear / DiffMerge / DiffMerge.exe$ alocal$ result$ remote-m --result =$ result--title1 =Mine--title2 =合并到:$ result --title3 =Theirs

    #KDiff3但是知道如何基于2个文件(而不仅仅是3个)
    C:/ Program Files / KDiff3 / kdiff3.exe进行合并 - m$ base$ remote-o$ result
    fi



      $
    • 为Git声明合并包装器



    Git配置命令:

      git config --global merge.tool diffmerge 
    git config --global mergetool.diffmerge.cmdmerge.sh \$ PWD / $ LOCAL \ \$ PWD / $ BASE \\$ PWD / $ REMOTE \\$ PWD / $ MERGED \\
    git config --global mergetool.diffmerge.trustExitCode false
    git config --global mergetool.diffmerge.keepBackup false




    • 检查autoCRLF是否为false



    git config at system级别:

      git config --- system core.autoCRLF = false 




    • 测试当两行相同(但是他们的eol字符)时,DiffMerge或KDiff3将会忽略这些行合并。



    DOS脚本(注意: dos2unix命令来自这里,用于模拟Unix eol风格。 ):



    C:\HOMEWARE\git\test> mkdir test_merge这个命令已被复制到本答复开头提到的目录中。
    C:\HOMEWARE\git\test> cd test_merge
    C:\HOMEWARE\git\test\test_merge> git init
    C:\HOMEWARE\ git\test\test_merge> echo a1> a.txt& echo a2>> a.txt
    C:\HOMEWARE\git\test\test_merge> git add a.txt
    C:\HOMEWARE\git\test\test_merge> git commit -m a.txt,windows eol style
    C:\HOMEWARE\git\test\test_merge> git checkout -b windows
    切换到一个新分支'windows'
    C :\HOMEWARE\git\test\test_merge> echo a3>> a.txt& echo a4>>> a.txt
    C:\HOMEWARE\git\test\test_merge> git add a.txt
    C:\HOMEWARE\git\test\test_merge> git commit -m 添加两行,windows eol style
    C:\HOMEWARE\\git\test\test_merge> git checkout master
    C:\HOMEWARE\git\test\test_merge> git checkout -b unix
    切换到新分支'unix'
    C:\HOMEWARE\git\test\test_merge> echo au3>> a.txt& echo au4>> a.txt&& echo au5>> a.txt
    C:\HOMEWARE\git\test\test_merge> dos2unix a.txt
    Dos2Unix:处理文件a.txt ...
    C:\HOMEWARE\\ \\ git \test\test_merge> git add a.txt
    C:\HOMEWARE\git\test\test_merge> git commit -m添加3行,所有文件的unix eol样式
    [unix c433a63]添加3行,所有文件unix eol样式

    C:\HOMEWARE\git\test\test_merge> git merge windows
    自动合并a。 txt
    CONFLICT(内容):合并a.txt中的冲突
    自动合并失败;修复冲突,然后提交结果。

    C:\HOMEWARE\git\test\test_merge> git ls-files -u
    100644 39b4c894078a02afb9b1dfeda6f1127c138e38df 1 a.txt
    100644 28b3d018872c08b0696764118b76dd3d0b448fca 2 a.txt
    100644 3994da66530b4df80189bb198dcfac9b8f2a7b33 3 a.txt

    C:\HOMEWARE\git\test\test_merge> git mergetool
    合并文件:a.txt

    'a.txt'的正常合并冲突:
    {local}:已修改
    {remote}:已修改
    命中并返回以开始合并解析工具(diffmerge):

    此时(点击返回),DiffMerge或KDiff3将打开,您将看到自己的线是实际上已合并,并忽略了哪些行。



    警告:结果文件将始终处于带有DiffMerge的Windows eol模式(CRLF)。 。
    KDiff3提供以各种方式保存。


    Is it possible for git merge to ignore line-ending differences?

    Maybe I'm asking the wrong question ... but:

    I tried uisng config.crlf input but things got a bit messy and out of control, specially when I applied it after the fact.

    For one thing, applying this config after the fact doesn't seem to affect files that were committed to the repository before applying this option. Another thing is that suddenly all commits now result in lots of annoying warning messages about CRLF being converted to LF.

    To be honest, I don't really care what line-ending is used, I personally prefer the Unix style \n, but whatever. All I care about, is for git merge to be a bit smarter and ignore the differences in line-endings.

    Sometimes I have two identical files, but git would mark them as being in conflict (and the conflict is the whole file) simply because they use a different line ending character.

    Update:

    I found out that git diff accepts a --ignore-space-at-eol option, would it be possible to let git merge use this option as well?

    解决方案

    Update 2013:

    More recent git versions authorize using merge with strategy recursive and strategy option (-X):

    git merge -s recursive -Xignore-space-at-eol
    

    But using "-Xignore-space-change" is also a possibility

    • Fab-V mentions below:

      git merge master -s recursive -X renormalize
      
      

    jakub.g also comments that the strategies work also with cherry-picking:

    git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize 
    

    This works much better than ignore-all-space.


    Original answer (May 2009)

    The patch for ignoring eol style has been proposed in June 2007, but it only concerns git diff --ignore-space-at-eol, not git merge.

    At the time, the question has been askeed:

    Should --ignore-space-at-eol be an option to git-merge ?
    Merges are where this functionality matters.
    What are the semantics of an auto-resolved merge with those options in effect -- are they only used for rename detection, or do we, e.g., not flag conflicts with only whitespace changes ? And if we don't, which version do we accept automatically ?

    Julio C Hamano was not exactly enthusiastic:

    This certainly is tempting, but I suspect that should be left to later rounds.
    I suspect that it would introduce a concept of two different kinds of diffs, one to be mechanically processed (i.e. use in merge with "git-merge-recursive", and apply with "git-am"), and another to be inspected by humans to understand.
    It often may be useful to munge the input for the latter case, even though the output from comparing munged input files may not be readily usable for mechanical application.

    The general idea, when it comes to git merge, is to rely on the third-party merge tool.

    For instance, I have setup DiffMerge to be the tool for Git merge, setting a ruleset which allow that merge tool to ignore eol for certain type of files.


    Setup on Windows, with MSysGit1.6.3, either for DOS or Git bash session, with DiffMerge or KDiff3:

    • set a directory into your PATH (here: c:\HOMEWARE\cmd).
    • add in that directory the script merge.sh (wrapper for your favorite merge tool)

    merge.sh:

    #!/bin/sh
    
    # Passing the following parameters to mergetool:
    #  local base remote merge_result
    
    alocal=$1
    base=$2
    remote=$3
    result=$4
    
    if [ -f $base ]
    then
        #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$base" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"
    
        # for merge respecting eol, KDiff3 is better than DiffMerge (which will always convert LF into CRLF)
        # KDiff3 will display eol choices (if Windows: CRLF, if Unix LF)
        "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$alocal" "$remote" -o "$result"
    else
        #there is not always a common ancestor: DiffMerge needing 3 files, BASE will be the result
        #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$result" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"
    
        # KDiff3 however does know how to merge based on 2 files (not just 3)
        "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$remote" -o "$result"
    fi
    

    • Declare your merge wrapper for Git

    Git config commands:

    git config --global merge.tool diffmerge
    git config --global mergetool.diffmerge.cmd "merge.sh \"$PWD/$LOCAL\" \"$PWD/$BASE\" \"$PWD/$REMOTE\" \"$PWD/$MERGED\"
    git config --global mergetool.diffmerge.trustExitCode false
    git config --global mergetool.diffmerge.keepBackup false
    

    • Check that autoCRLF is false

    git config at system level:

    git config ---system core.autoCRLF=false
    

    • Test that, when two lines are identical (but their eol chars), both DiffMerge or KDiff3 will ignore those line during a merge.

    DOS script (note: the dos2unix command comes from here, and is used to simulate a Unix eol-style. That command has been copied in the directory mentioned at the beginning of this answer.):

    C:\HOMEWARE\git\test>mkdir test_merge C:\HOMEWARE\git\test>cd test_merge C:\HOMEWARE\git\test\test_merge>git init C:\HOMEWARE\git\test\test_merge>echo a1 > a.txt & echo a2 >> a.txt C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "a.txt, windows eol style" C:\HOMEWARE\git\test\test_merge>git checkout -b windows Switched to a new branch 'windows' C:\HOMEWARE\git\test\test_merge>echo a3 >> a.txt & echo a4 >> a.txt C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "add two lines, windows eol style" C:\HOMEWARE\git\test\test_merge>git checkout master C:\HOMEWARE\git\test\test_merge>git checkout -b unix Switched to a new branch 'unix' C:\HOMEWARE\git\test\test_merge>echo au3 >> a.txt & echo au4 >> a.txt && echo au5 >> a.txt C:\HOMEWARE\git\test\test_merge>dos2unix a.txt Dos2Unix: Processing file a.txt ... C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "add 3 lines, all file unix eol style" [unix c433a63] add 3 lines, all file unix eol style C:\HOMEWARE\git\test\test_merge>git merge windows Auto-merging a.txt CONFLICT (content): Merge conflict in a.txt Automatic merge failed; fix conflicts and then commit the result. C:\HOMEWARE\git\test\test_merge>git ls-files -u 100644 39b4c894078a02afb9b1dfeda6f1127c138e38df 1 a.txt 100644 28b3d018872c08b0696764118b76dd3d0b448fca 2 a.txt 100644 3994da66530b4df80189bb198dcfac9b8f2a7b33 3 a.txt C:\HOMEWARE\git\test\test_merge>git mergetool Merging the files: a.txt Normal merge conflict for 'a.txt': {local}: modified {remote}: modified Hit return to start merge resolution tool (diffmerge):

    At this point (Hitting "return"), DiffMerge or KDiff3 will open, and you will see for yourself what lines are actually merged, and what lines are ignored.

    Warning: the result file will always be in Windows eol mode (CRLF) with DiffMerge...
    KDiff3 offers to save in one way or another.

    这篇关于git-merge可能忽略行结束差异吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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