Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git diff thinks line endings are LF when EOL is set to CRLF in .gitattributes

Tags:

git

When I revert changes to a file with Windows line endings and .gitattributes defines the EOL as CRLF, git thinks the line endings have changed to LR, even though a hex editor shows CRLF.

This only happens when .gitattributes defines the EOL character.

Without .gitattributes:

This works correctly.

This is the original version of my file Web.config. The last two characters are 0d 0a (CR LF):

00000000: efbb bf3c 3f78 6d6c 2076 6572 7369 6f6e  ...<?xml version
00000010: 3d22 312e 3022 2065 6e63 6f64 696e 673d  ="1.0" encoding=
00000020: 2275 7466 2d38 223f 3e0d 0a              "utf-8"?>..     

I add a space character to the end of the first line, 20 0d 0a:

00000000: efbb bf3c 3f78 6d6c 2076 6572 7369 6f6e  ...<?xml version
00000010: 3d22 312e 3022 2065 6e63 6f64 696e 673d  ="1.0" encoding=
00000020: 2275 7466 2d38 223f 3e20 0d0a            "utf-8"?> ..    

Git diff shows the space character:

diff --git a/Web.config b/Web.config
index bc3c3c3..6215f5e 100644
--- a/Web.config
+++ b/Web.config
@@ -1,4 +1,4 @@
<U+FEFF><?xml version="1.0" encoding="utf-8"?>{+ +}

Revert file and all changes are gone:

$ git checkout Web.config

$ git status Web.config
On branch develop
Your branch is up-to-date with 'origin/develop'.

nothing to commit, working directory clean

With .gitattributes

This does not work correctly.

Define CRLF to .gitattributes:

*.config eol=crlf

Add the space character to the end of the first line:

00000000: efbb bf3c 3f78 6d6c 2076 6572 7369 6f6e  ...<?xml version
00000010: 3d22 312e 3022 2065 6e63 6f64 696e 673d  ="1.0" encoding=
00000020: 2275 7466 2d38 223f 3e20 0d0a            "utf-8"?> ..    

Git diff shows the space, but the CR is missing (^M):

diff --git a/Web.config b/Web.config
index bc3c3c3..9d3bc53 100644
--- a/Web.config
+++ b/Web.config
@@ -1,248 +1,248 @@
<U+FEFF><?xml version="1.0" encoding="utf-8"?>[-^M-]{+ +}

Revert file:

$ git checkout Web.config

$ git status Web.config
On branch develop
Your branch is up-to-date with 'origin/develop'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   Web.config

no changes added to commit (use "git add" and/or "git commit -a")

Git thinks the CR has been removed from ALL lines:

$ git diff --word-diff-regex=. Web.config
diff --git a/Web.config b/Web.config
index bc3c3c3..094d1d5 100644
--- a/Web.config
+++ b/Web.config
@@ -1,248 +1,248 @@
<U+FEFF><?xml version="1.0" encoding="utf-8"?>[-^M-]
<!--[-^M-]
  For more information on how to configure your ASP.NET application, please visit[-^M-]
  http://go.microsoft.com/fwlink/?LinkId=152368[-^M-]
  -->[-^M-]
<configuration>[-^M-]

But this is not the case in the hex editor:

00000000: efbb bf3c 3f78 6d6c 2076 6572 7369 6f6e  ...<?xml version
00000010: 3d22 312e 3022 2065 6e63 6f64 696e 673d  ="1.0" encoding=
00000020: 2275 7466 2d38 223f 3e0d 0a3c 212d 2d0d  "utf-8"?>..<!--.
00000030: 0a20 2046 6f72 206d 6f72 6520 696e 666f  .  For more info
00000040: 726d 6174 696f 6e20 6f6e 2068 6f77 2074  rmation on how t
00000050: 6f20 636f 6e66 6967 7572 6520 796f 7572  o configure your
00000060: 2041 5350 2e4e 4554 2061 7070 6c69 6361   ASP.NET applica
00000070: 7469 6f6e 2c20 706c 6561 7365 2076 6973  tion, please vis
00000080: 6974 0d0a 2020 6874 7470 3a2f 2f67 6f2e  it..  http://go.
00000090: 6d69 6372 6f73 6f66 742e 636f 6d2f 6677  microsoft.com/fw
000000a0: 6c69 6e6b 2f3f 4c69 6e6b 4964 3d31 3532  link/?LinkId=152
000000b0: 3336 380d 0a20 202d 2d3e 0d0a 3c63 6f6e  368..  -->..<con
000000c0: 6669 6775 7261 7469 6f6e 3e0d 0a20 203c  figuration>..  <

What is going on here and how do I get it to work correctly?

like image 233
Ryan Jenkin Avatar asked Nov 08 '16 03:11

Ryan Jenkin


People also ask

How do I fix git line endings?

#Set LF as your line ending default. #Save your current files in Git, so that none of your work is lost. #Remove the index and force Git to rescan the working directory. #Rewrite the Git index to pick up all the new line endings.

How do I know if my file is LF or CRLF?

use a text editor like notepad++ that can help you with understanding the line ends. It will show you the line end formats used as either Unix(LF) or Macintosh(CR) or Windows(CR LF) on the task bar of the tool. you can also go to View->Show Symbol->Show End Of Line to display the line ends as LF/ CR LF/CR.

Does git change line endings?

Git has changed line endings to match your new configuration. To ensure that all the line endings in your repository match your new configuration, backup your files with Git, delete all files in your repository (except the . git directory), then restore the files all at once.


2 Answers

The key here is that whether you use text=auto, text eol=crlf or text eol=lf, git will:

  1. Convert line endings to LF in the repository (i.e. upon git commit)
  2. Convert line endings to your preferred format when copying from the repository to your working tree (i.e. upon git checkout or git merge)

This is perhaps counter-intuitive, but remember git's origins from the Linux world and is not a bug. From the git documentation: "when a text file is normalized, its line endings are converted to LF in the repository".

As a corollary to this, I find when I join an existing project and .gitattributes needs to be introduced to normalise line endings, I find it's best to write a Powershell script (or whatever method you prefer) to normalise line endings in all files across the repository at one time. This is to avoid ongoing confusing diffs where the only change are line endings introduced by .gitattributes.

Finally in case it assists, I have previously published a sandbox to play with line ending settings on my GitHub: https://github.com/teamtam/git-line-endings

like image 53
TeamTam Avatar answered Oct 18 '22 01:10

TeamTam


This is a bug on git I faced some times. You may report it to the git team:

Questions or comments for the Git community can be sent to the mailing list by using the email address [email protected]. Bug reports for git should be sent to this mailing list.

https://git-scm.com/community

If you are on Windows you could also try to open a bug report on:

  1. https://github.com/git-for-windows/git/issues

May be this bug is fixed on the latest version of git 2.10.2, you could to update yours to the latest released, if is not already:

  1. https://en.wikipedia.org/wiki/Git
like image 39
user Avatar answered Oct 18 '22 01:10

user