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?
#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.
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.
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.
The key here is that whether you use text=auto
, text eol=crlf
or text eol=lf
, git will:
git commit
)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
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:
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With