Make Git use CRLF on its “<<<<<<< HEAD” merge lines

巧了我就是萌 提交于 2019-12-17 18:47:05

问题


Is it possible to ask Git to use CRLF instead of just LF at the end of the lines it puts into a file when it needs merging?

If resolving conflicts in a text editor without visible EOL characters, it is easy to accidentally end up with these LFs getting merged if you delete by selection:

Leaving you with:

And now two LFs have sneaked their way into your otherwise CRLF file!

Obviously one alternative is to just take more care over line endings when resolving merges, but I thought I would ask in case there were a way to tell Git to use CRLF for the lines it generates here.


回答1:


Is it possible to ask Git to use CRLF instead of just LF at the end of the lines it puts into a file when it needs merging?

It... actually is possible, from git 2.7.2+ (February 2016).
And you don't have to do anything.

See commit 15980de, commit 86efa21 (27 Jan 2016) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit ab2c107, 17 Feb 2016)

merge-file: let conflict markers match end-of-line style of the context

When merging files with CR/LF line endings, the conflict markers should match those, lest the output file has mixed line endings.

This is particularly of interest on Windows, where some editors get really confused by mixed line endings.

The original version of this patch by Beat Bolli respected core.eol, and a subsequent improvement by this developer also respected gitattributes.
This approach was sub-optimal, though: git merge-file was invented as a drop-in replacement for GNU merge and as such has no problem operating outside of any repository at all!

Another problem with the original approach was pointed out by Junio Hamano: legacy repositories might have their text files committed using CR/LF line endings (and core.eol and the gitattributes would give us a false impression there). Therefore, the much superior approach is to simply match the context's line endings, if any.

We actually do not have to look at the entire context at all:

  • if the files are all LF-only, or if they all have CR/LF line endings, it is sufficient to look at just a single line to match that style.
  • And if the line endings are mixed anyway, it is still okay to imitate just a single line's eol: we will just add to the pile of mixed line endings, and there is nothing we can do about that.

So what we do is: we look at the line preceding the conflict, falling back to the line preceding that in case it was the last line and had no line ending, falling back to the first line, first in the first post-image, then the second post-image, and finally the pre-image.
If we find consistent CR/LF (or undecided) end-of-line style, we match that, otherwise we use LF-only line endings for the conflict markers.

Note that while it is true that there have to be at least two lines we can look at (otherwise there would be no conflict), the same is not true for line endings: the three files in question could all consist of a single line without any line ending, each. In this case we fall back to using LF-only.




回答2:


There is no setting which controls the line endings used for the "<<<<" markers in git; they are hardcoded to use '\n' in the git source code (see line 173 of xmerge.c).

If you set the "eol" or "core.eol" settings to "crlf", then the "<<<<" markers will have \r\n line endings in the file (this happens during the smudge/clean filter step, after the code linked above), but this has a major side-effect: the files will be "normalised" on their way into the repository, so you will commit files with unix line endings.

This is likely to be not what you want on a .Net project like the example above.

So I don't have a good answer for you, sorry.




回答3:


I'm not sure if there's a global way of doing this, but you can set the default EOL character for each file extension in the .gitattributes file (see the End-of-line conversion section of the gitattributes docs.

For example, edit the .gitattributes file in the git project root so that it contains something like this:

*.cs         eol=crlf
*.config     eol=crlf


来源:https://stackoverflow.com/questions/17832616/make-git-use-crlf-on-its-head-merge-lines

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!