Make Git use CRLF on its "<<<<<<< HEAD" merge lines
Asked Answered
S

3

11

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?

Merge using LFs

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:

Delete by selection

Leaving you with:

LFs sneak into file!

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.

Solmization answered 24/7, 2013 at 11:25 Comment(4)
You told us precisely zero information about your environment. What OS? If it's Windows, what Git distribution are you using? Is it Git for Windows or Cygwin Git or some third-party product integrating Git? What version? What EOL-related Git settings are in effect?Millesimal
I don't think much of that is relevant. All I asked was "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?" For the record I am using Cygwin Git on Windows. Currently I have autocrlf set to false.Solmization
You're underestimating complications Git has to deal with to handle EOL issues. A quick glance over the git-config manual page or searching SO for "git+cr+lf" would tell you. And then there's impedance mismatch between software platforms (for instance, Git for Windows implements many quirks to make the thing work on Windows) which may affect the way Git works.Millesimal
Starting git 2.8+ (March 2016), this issue won't happen again. See my answer belowAguilar
A
11

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.

Aguilar answered 18/2, 2016 at 7:6 Comment(0)
S
3

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.

Sendoff answered 24/7, 2013 at 15:17 Comment(2)
Thanks for linking the source code. It seems that the answer to my question is just No then :)Solmization
You could raise a bug with git core?Sendoff
C
1

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
Condign answered 24/7, 2013 at 12:31 Comment(1)
In my experiments, this worked, but it had the nasty side-effect of rewriting the file contents to unix line endings when they were committed. Do you know any way to avoid that?Sendoff

© 2022 - 2024 — McMap. All rights reserved.