1

I have been using Git for last two years and it's merge has been one of the greatest merges that I have used so far but lately it is just behaving badly. Nothing has changed on my git but every time I do a merge it is just acting up.

For example: I started seeing things like

<<<<<<< HEAD

also ->>>>>>> Stashed changes

and

<<<<<<< Updated upstream

That is what I see inside my code after it finished auto-merge. Strangely enough, it has not asked me to manually resolve the conflicts in a while as it used to before. It never did that before. Any one has seen this behavior before?

Lost
  • 12,007
  • 32
  • 121
  • 193
  • 1
    I think this is related. This is what I see everytime I commit before I see the garbage above. `warning: LF will be replaced by CRLF in OpusOneCorp/Services/WebServices/Registration/User/Validations/Campaign/SouthernLivingValidator.cs. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in OpusOneCorp/Services/WebServices/Registration/User/Validations/Campaign/SouthernLivingValidator.cs. The file will have its original line endings in your working directory.` – Lost Jun 21 '13 at 18:04
  • If `git merge` did not tell you this time that there were conflicts, then it's quite likely that it did some time in the past, and then those files were inadvertently committed as-is without resolving the conflicts, meaning the committed versions of those files now contain conflict markers as if they were part of the normal text... – twalberg Jun 21 '13 at 19:07

1 Answers1

4

This sounds very much like a whitespace issue. Two possibilities (and probably both, based on your description):

Whitespace at end of lines

Many text editors will automatically indent your code for you. This means that, if you leave any blank lines in the middle of functions, they may actually contain spaces or tabs.

For example, imagine the following code:

    function somethingFunky() {
        setupFunkyProcess();
        prepareTheFunk();

        goFunky();
    }

If we turn on special codes view (or whatever your editor calls it), we may see:

»   function somethingFunky() {¶
»   »   setupFunkyProcess();¶
»   »   prepareTheFunk();¶
»   »   ¶
»   »   goFunky();¶
»   }¶

Or we may see:

»   function somethingFunky() {¶
»   »   setupFunkyProcess();¶
»   »   prepareTheFunk();¶
¶
»   »   goFunky();¶
»   }¶

Do you see the difference on the blank line? For most programming languages, it makes absolutely no difference. If it remains that way, it also makes zero difference to Git.

But imagine, during a future edit, it changes from one form to the other. Maybe you manually remove the whitespace, or maybe you switch to a text editor that strips white-space when you save. There will now be a technical difference between the two versions, but it is only whitespace; the diff will look like:

<<<<<<< HEAD

=======

>>>>>>> BranchToMergeFrom

Look familiar? With special codes activated, it is actually:

<<<<<<< HEAD¶
»   »   ¶
=======¶
¶
>>>>>>> BranchToMergeFrom¶

End of line characters

The other possibility, which would explain the warning in your comment:

warning: LF will be replaced by CRLF

is a change of end-of-line characters.

When you save a text file, a special code is used to signify the end of each line. Unfortunately, different operating systems disagree on the code to use. There's loads of info on Wikipedia (http://en.wikipedia.org/wiki/Newline) but all you need to know is a Windows PC and a Mac or Linux system will use a different EOL code.

If two developers are collaborating, but they use different operating systems, the different EOL codes will cause lots of conflict unless they agree to a common standard.

The way Git users usually manage this is to agree that all commits will use the Linux EOL code (Git was originally created to aid the development of the Linux kernel). Git can be configured to automatically convert the line endings when you commit. There are some nice instructions on Github: https://help.github.com/articles/dealing-with-line-endings .

What happens if you (or another developer) don't configure your system to manage this correctly? The files will technically be different but, as it's only whitespace, the diff messages may not be that helpful:

<<<<<<< WindowsEOL
This is my test file.
The contents are irrelevant; they are
simply here for the purpose of EOL comparison.

In this file, the line endings are Windows format.
In other words, CRLF
=======
This is my test file.
The contents are irrelevant; they are
simply here for the purpose of EOL comparison.

In this file, the line endings are Unix format.
In other words, LF
>>>>>>> UnixEOL

What can you do to resolve this?

Assuming some of these whitespace changes have already been commited to your repo, there is not much you can do other than be aware of what is happening during future edits.

If this is your repo, define some standards (Windows or Linux EOL, strip whitespace or not) and communicate it to your collaborators. If you are contributing to someone else's repo, try to find out what their standards are and stick to them yourself.

Depending on the extent of the problem (number of files, number of discrepancies, etc) you may want to perform a cleanup of the repo and commit with no other changes.

Chris Throup
  • 651
  • 1
  • 4
  • 19
  • Note: starting git 2.8+, merge markers will no longer introduce mixed line ending. See http://stackoverflow.com/a/35474954/6309 – VonC Feb 18 '16 at 07:12