git-merge是否可以忽略行尾差异?

has*_*sen 146 git merge git-svn line-endings eol

是否可以git merge忽略行尾差异?

也许我问的是错误的问题......但是:

我试过了,config.crlf input但事情变得有点乱,失控,特别是当我在事后应用它时.

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

说实话,我真的不在乎使用什么行结尾,我个人更喜欢Unix风格\n,但无论如何.我所关心的只是为了git merge变得更聪明,而忽略了行尾的差异.

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

更新:

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

Von*_*onC 112

2013年更新:

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

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

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

  • Fab-V提到下面:
    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 
Run Code Online (Sandbox Code Playgroud)

这比用得好多了ignore-all-space.


原始答案(2009年5月)

忽略eol风格的补丁已于20076月提出,但它只关注git diff --ignore-space-at-eol,而不是git merge.

当时,这个问题已被搁置:

应该--ignore-space-at-eol是一个选择git-merge吗?
合并是这个功能很重要的地方.
自动解析合并与这些有效选项的语义是什么 - 它们仅用于重命名检测,还是我们,例如,不标记只有空格更改的冲突?如果我们不这样做,我们会自动接受哪个版本?

Julio C Hamano不是很热心:

这当然是诱人的,但我怀疑这应该留待以后的几轮.
我怀疑它会引入两种不同类型的差异的概念,一种是机械处理的(即用于与"git-merge-recursive"合并,并用"git-am"),另一种用于检查人类要明白.
对于后一种情况,输入的输入通常可能是有用的,即使比较munged输入文件的输出可能不容易用于机械应用.

总而言之git merge,就是依靠第三方合并工具.

例如,我已将DiffMerge设置为Git merge的工具,设置一个规则集,允许该合并工具忽略某些类型文件的eol.


在Windows上安装MSysGit1.6.3,用于DOS或Git bash会话,使用DiffMerge或KDiff3:

  • 将目录设置到PATH(此处:) c:\HOMEWARE\cmd.
  • 在该目录中添加脚本merge.sh(您最喜欢的合并工具的包装器)

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
Run Code Online (Sandbox Code Playgroud)
  • 为Git声明你的合并包装器

Git配置命令:

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
Run Code Online (Sandbox Code Playgroud)
  • 检查autoCRLF是否为false

系统级的git配置:

git config ---system core.autoCRLF=false
Run Code Online (Sandbox Code Playgroud)
  • 测试当两条线相同(但它们的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 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):

在这一点上(击中"返回"),DiffMerge或KDiff3会打开,你会看到自己什么都行实际上合并,什么行会被忽略.

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


Fab*_*bio 93

我正在寻找相同的答案,我发现了这一点

合并具有不同签入/签出属性的分支

如果您为文件添加了导致该文件的规范存储库格式更改的属性,例如添加clean/smudge过滤器或text/eol/ident属性,那么合并属性不存在的任何内容通常会导致合并冲突.

为了防止这些不必要的合并冲突,可以告诉git在通过设置merge.renormalize配置变量解析三向合并时运行文件的所有三个阶段的虚拟签出和签入.当转换后的文件与未转换的文件合并时,这可以防止由签入转换引起的更改导致虚假合并冲突.

只要"涂抹→清洁"产生与"干净"相同的输出,即使对于已经弄脏的文件,此策略也会自动解决所有与过滤器相关的冲突.不以这种方式操作的过滤器可能会导致必须手动解决的其他合并冲突.

因此,在任何存储库中运行此命令都可以解决问题:

git config merge.renormalize true
Run Code Online (Sandbox Code Playgroud)

  • 这应该是默认答案.自从第一次提出问题以来,已经发生了很大变化,git对此的处理现在已经与merge.renormalize一起构建了. (18认同)

小智 23

阅读/sf/answers/853633161//sf/answers/993667741/

对我来说,这个命令完美地完成了这个操作:

git merge master -s recursive -X renormalize
Run Code Online (Sandbox Code Playgroud)


Run*_*sof 6

如在这个答案:https://stackoverflow.com/a/5262473/943928

你可以尝试: git merge -s recursive -Xignore-space-at-eol