git-merge 是否可以忽略行尾差异?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/861995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible for git-merge to ignore line-ending differences?
提问by hasen
Is it possible for git merge
to ignore line-ending differences?
是否可以git merge
忽略行尾差异?
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.
我尝试了 uisngconfig.crlf input
但事情变得有点混乱和失控,特别是当我事后应用它时。
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.
一方面,事后应用此配置似乎不会影响应用此选项之前提交到存储库的文件。另一件事是,现在突然所有提交都会导致大量关于 CRLF 转换为 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.
老实说,我真的不在乎使用什么行尾,我个人更喜欢 Unix 风格\n
,但无论如何。我所关心的git merge
只是变得更聪明一点,忽略行尾的差异。
Sometimes I have two identical files, but git would mark them as being in conflict (and the conflict is the wholefile) simply because they use a different line ending character.
有时我有两个相同的文件,但是 git 会将它们标记为冲突(并且冲突是整个文件),因为它们使用不同的行结束字符。
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?
我发现git diff
接受一个--ignore-space-at-eol
选项,是否也可以让git merge
使用这个选项?
采纳答案by VonC
Update 2013:
2013 年更新:
More recent git versions authorize using merge with strategy recursive
and strategy option(-X
):
最近的 git 版本授权使用合并策略recursive
和策略选项( -X
):
- 来自“ Git 合并和修复带有两个分支的混合空格和制表符”:
git merge -s recursive -Xignore-space-at-eol
But using "-Xignore-space-change
" is also a possibility
但使用“ -Xignore-space-change
”也是一种可能
jakub.galso commentsthat the strategies work also with cherry-picking:
git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize
This works much better than ignore-all-space
.
这比ignore-all-space
.
Original answer (May 2009)
原始答案(2009 年 5 月)
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
.
2007年6 月提出了忽略 eol 样式的补丁,但它只关注git diff --ignore-space-at-eol
,而不是git merge
.
At the time, the question has been askeed:
当时有人问过这个问题:
Should
--ignore-space-at-eol
be an option togit-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 ?
应该
--ignore-space-at-eol
是一个选项git-merge
?
合并是此功能很重要的地方。
具有这些选项的自动解决合并的语义是什么——它们是仅用于重命名检测,还是我们例如不标记仅与空格更改的冲突?如果我们不这样做,我们会自动接受哪个版本?
Julio C Hamano was not exactly enthusiastic:
Julio C Hamano 并不十分热情:
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.
这当然很诱人,但我怀疑这应该留给以后的几轮。
我怀疑它会引入两种不同类型的差异的概念,一种是机械处理的(即与“git-merge-recursive”合并使用,并与“git-am”一起使用),另一种由人类去理解。
对于后一种情况,修改输入通常可能很有用,即使比较修改后的输入文件的输出可能不容易用于机械应用。
The general idea, when it comes to git merge
, is to rely on the third-party merge tool.
一般的想法,当涉及到时git merge
,是依靠第三方合并工具。
For instance, I have setup DiffMergeto be the tool for Git merge, setting a rulesetwhich allow that merge tool to ignore eol for certain type of files.
例如,我将DiffMerge设置为 Git 合并工具,设置了一个规则集,允许该合并工具忽略某些类型文件的 eol。
Setup on Windows, with MSysGit1.6.3, either for DOS or Git bash session, with DiffMerge or KDiff3:
在 Windows 上设置,使用 MSysGit1.6.3,用于 DOS 或 Git bash 会话,使用 DiffMerge 或 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)
- 在您的 PATH 中设置一个目录(此处:)
c:\HOMEWARE\cmd
。 - 在该目录中添加脚本 merge.sh(您最喜欢的合并工具的包装器)
merge.sh:
合并.sh:
#!/bin/sh
# Passing the following parameters to mergetool:
# local base remote merge_result
alocal=
base=
remote=
result=
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 声明您的合并包装器
Git config commands:
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
- Check that autoCRLF is false
- 检查 autoCRLF 是否为假
git config at system level:
系统级别的 git 配置:
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.
- 测试一下,当两行相同(但它们的 eol 字符相同)时,DiffMerge 或 KDiff3 将在合并期间忽略这些行。
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.):
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):
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.
此时(点击“返回”),DiffMerge 或 KDiff3 将打开,您将亲眼看到哪些行实际合并,哪些行被忽略。
Warning: the result file will always be in Windows eol mode (CRLF) with DiffMerge...
KDiff3 offers to save in one way or another.
警告:结果文件将始终处于带有 DiffMerge 的 Windows eol 模式 (CRLF) 中...
KDiff3 提供以一种或另一种方式保存。
回答by Fabio
I was looking for the same answer and I found out this
我正在寻找相同的答案,我发现了这一点
Merging branches with differing checkin/checkout attributes
If you have added attributes to a file that cause the canonical repository format for that file to change, such as adding a clean/smudge filter or text/eol/ident attributes, merging anything where the attribute is not in place would normally cause merge conflicts.
To prevent these unnecessary merge conflicts, git can be told to run a virtual check-out and check-in of all three stages of a file when resolving a three-way merge by setting the merge.renormalize configuration variable. This prevents changes caused by check-in conversion from causing spurious merge conflicts when a converted file is merged with an unconverted file.
As long as a "smudge→clean" results in the same output as a "clean" even on files that are already smudged, this strategy will automatically resolve all filter-related conflicts. Filters that do not act in this way may cause additional merge conflicts that must be resolved manually.
合并具有不同签入/签出属性的分支
如果您向文件添加了导致该文件的规范存储库格式更改的属性,例如添加清洁/污迹过滤器或 text/eol/ident 属性,则合并该属性未到位的任何内容通常会导致合并冲突.
为了防止这些不必要的合并冲突,可以通过设置 merge.renormalize 配置变量来告诉 git 在解决三向合并时运行文件的所有三个阶段的虚拟检出和检入。当转换的文件与未转换的文件合并时,这可以防止由签入转换引起的更改导致虚假合并冲突。
只要“污迹→清洁”导致与“清洁”相同的输出,即使在已经污迹的文件上,此策略将自动解决所有与过滤器相关的冲突。不以这种方式运行的过滤器可能会导致必须手动解决的其他合并冲突。
So running this command in any repository will do the trick:
因此,在任何存储库中运行此命令都可以解决问题:
git config merge.renormalize true
回答by Fab V.
After reading https://stackoverflow.com/a/12194759/1441706and https://stackoverflow.com/a/14195253/1441706
阅读https://stackoverflow.com/a/12194759/1441706和https://stackoverflow.com/a/14195253/1441706 后
for me, this command did the trick perfectly:
对我来说,这个命令完美地解决了这个问题:
git merge master -s recursive -X renormalize
回答by Rune Schjellerup Philosof
As in this answer: https://stackoverflow.com/a/5262473/943928
在这个答案中:https: //stackoverflow.com/a/5262473/943928
You could try: git merge -s recursive -Xignore-space-at-eol
你可以试试: git merge -s recursive -Xignore-space-at-eol
回答by Ben Hymers
What I did was leave everything as default (i.e. autocrlf=true), touch all files (find . -exec touch {} \;), let git see them as 'modified' and commit them back, and be done with it. Otherwise you'll always either be plagued by annoying messages or surprising differences, or have to turn off all of git's whitespace features.
我所做的是将所有内容保留为默认值(即 autocrlf=true),触摸所有文件(find . -exec touch {} \;),让 git 将它们视为“已修改”并将它们提交回来,然后完成它。否则你要么总是被烦人的消息或令人惊讶的差异所困扰,要么不得不关闭 git 的所有空白功能。
You'll lose blame information, but it's better to do it sooner rather than later :)
你会丢失责备信息,但最好早点做 :)
回答by Jake
"git merge -Xrenormalize" works like a charm.
“git merge -Xrenormalize”就像一个魅力。
回答by antman
http://stahlforce.com/dev/index.php?tool=remcrlf
http://stahlforce.com/dev/index.php?tool=remcrlf
I tried it, but if after the last line in your code you didn't already have CRLF it adds by itself a LF and the file looks changed in git. Other than that it works.
我试过了,但是如果在你的代码的最后一行之后你还没有 CRLF,它会自己添加一个 LF 并且文件在 git 中看起来已经改变了。除此之外,它的工作原理。
回答by Dean Smith
It doesn't look like this can be done directly but this post suggests a work around.
看起来这不能直接完成,但这篇文章提出了一个解决方法。
回答by hasen
It seems to me now that the best way is to normalized the line endings on both branches (and commit) before merging them.
现在在我看来,最好的方法是在合并之前规范化两个分支(和提交)上的行尾。
I googled "convert crlf to lf" and found this as the first results:
http://stahlforce.com/dev/index.php?tool=remcrlf
我用谷歌搜索“将 crlf 转换为 lf”,发现这是第一个结果:http://stahlforce.com/dev/index.php?tool=remcrlf
I downloaded it and used, seems like a nice tool.
我下载并使用了,看起来是个不错的工具。
>sfk remcr . .py
Be sure though to specify a directory and a file type (e.g. .py) otherwise it might try to mess with the contents of the .git
directory!
一定要指定一个目录和文件类型(例如.py),否则它可能会试图弄乱.git
目录的内容!
回答by rjmunro
AFAICT, (I haven't tried it) you could use git diff
to compare the branch you want to merge to the common ancestor, then apply the results with git apply
. Both commands have --ignore-whitespace
options to ignore line ending and white space errors.
AFAICT,(我还没有尝试过)您可以使用git diff
将要合并的分支与共同祖先进行比较,然后将结果应用到git apply
. 这两个命令都有 --ignore-whitespace
忽略行结束和空格错误的选项。
Unfortunately, if the patch doesn't apply cleanly, the whole operation is aborted. You can't fix merge conflicts. There is a --reject
option to leave unpatchable hunks in .rej
files, which helps, but isn't the same as having the merge conflicts shown in one file.
不幸的是,如果补丁应用不干净,整个操作就会中止。您无法修复合并冲突。有一个--reject
选项可以在.rej
文件中留下不可修补的块,这有帮助,但与在一个文件中显示合并冲突不同。