83

I am diffing a file between forked and upstream Bitbucket repositories:

$ git diff origin/branchA..upstream/branchB -- some/file/path.xyz

It seems to return the same difference for almost every file:

-<U+FEFF>@using Sitecore.Mvc
+@using Sitecore.Mvc^M

What is the exact meaning of ^M that only shows up after the first line? I see this issue when I compare other files as well. I am on a Windows Server 2008 R2 machine. core.autocrlf is set to true. The .gitattributes is set to text eol=lf. My Git version is 2.5.1.windows.1.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Moo
  • 3,369
  • 4
  • 22
  • 41

1 Answers1

146

^M represents carriage return. This diff means something removed a Unicode BOM from the beginning of the line and added a CR at the end.

The ^ symbol stands for Control, so ^M means Ctrl+M.

To get from that to the actual ASCII character code, you take the base character and flip bit 6 (i.e. XOR with 64). For letters, that just means subtract 64. So e.g. ^A is character code 1 (because A is 65). ^M is 77 - 64 = 13 (because M is 77), which corresponds to carriage return in ASCII.

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • 46
    I love answers like this that "teach a man to fish". Not only do I now understand `^M`, but also potentially any other such control characters I may encounter in the future. – gilly3 May 15 '20 at 16:56
  • 13
    `git config core.whitespace cr-at-eol` to hide it from the diff – SwiftArchitect Aug 21 '21 at 10:15
  • 14
    If you're here because git in WSL (Ubuntu) is showing every file changed with carriage returns vs. git in Windows or VS code showing no differences, you might need `git config --global core.autocrlf true` instead. See: https://github.com/microsoft/WSL/issues/184#issuecomment-209913528 – Mecha Wailmer Sep 26 '22 at 17:18