2013 年更新:
最近的 git 版本授权使用与策略 recursive 和策略选项(-X)合并:
但使用“-Xignore-space-change”is also a possibility
jakub.g 还有comments,策略也适用于樱桃采摘:
git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize
这比ignore-all-space好得多。
在 Git 2.29(2020 年第四季度)之前,所有内部使用合并递归机制的“合并”操作都应遵循 merge.renormalize 配置,但其中许多没有。
参见Elijah Newren (newren)commit 00906d6、commit 8d55225、commit 6f6e7cf、commit fe48efb(2020 年 8 月 3 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit 4339259,2020 年 8 月 10 日)
merge: 使 merge.renormalize 适用于合并机器的所有用途
签字人:Elijah Newren
'merge' 命令并不是唯一的合并命令; checkout -m 或 rebase 等其他命令也可以。
不幸的是,检查“merge.renormalize”配置设置的唯一代码区域位于builtin/merge.c,这意味着它只会影响“merge”命令执行的合并。
将此配置设置的处理移至merge_recursive_config(),以便其他命令也可以从中受益。
原始答案(2009 年 5 月)
忽略eol样式的补丁已经在June 2007提出,但它只涉及git diff --ignore-space-at-eol,而不涉及git merge。
当时有人问过这个问题:
--ignore-space-at-eol 应该是git-merge 的一个选项吗?
合并是这个功能很重要的地方。
与这些选项生效的自动解析合并的语义是什么——它们仅用于重命名检测,还是我们,例如,不标记仅与空白更改发生冲突?如果我们不这样做,我们会自动接受哪个版本?
Julio C Hamano 并不十分热情:
这当然很诱人,但我怀疑应该留到以后的回合。
我怀疑它会引入两种不同类型差异的概念,一种是机械处理的(即与“git-merge-recursive”合并使用,并适用于
“git-am”),另一个需要人类检查才能理解。
对于后一种情况,调整输入通常可能很有用,即使比较经过调整的输入文件的输出可能不容易用于机械应用。
对于git merge,总体思路是依赖第三方合并工具。
例如,我已将 DiffMerge 设置为 Git 合并工具,设置了一个 规则集,允许该合并工具忽略特定类型文件的 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
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
系统级别的 git 配置:
git config ---system core.autoCRLF=false
- 测试当两行相同(但它们的 eol 字符)时,DiffMerge 或 KDiff3 将在合并期间忽略该行。
DOS 脚本(注意:dos2unix command comes from here,用于模拟 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):
此时(点击“return”),DiffMerge 或 KDiff3 将打开,您将自己查看实际合并了哪些行,忽略了哪些行。
警告:结果文件将始终处于带有 DiffMerge 的 Windows eol 模式 (CRLF)...
KDiff3 提供以一种或另一种方式保存。