4

I've read this question and the answers, but what isn't clear to me is WHO creates the "changes that do not appear in any parent".

Is it the git merge algorithm screwing up?

Or is it because the user has to manually adjust the conflicts to get the thing to build, introducing new code which wasn't in either parent?

Community
  • 1
  • 1
Benjol
  • 63,995
  • 54
  • 186
  • 268
  • I have added a concrete way to show an evil merge: `git log -c` shows lines with '++'. See my edited answer below. – VonC Apr 16 '13 at 12:31
  • I once added `git://devil@github.com/hell.git` as a remote and pulled... Got a lot of evil merges in the process. I do not recommend doing that. – ereOn Mar 22 '16 at 12:25

3 Answers3

4

It is explained in the first comment of the correct answer. You merge without doing a commit (either through conflict or --no-commit) and then add additional changes to the merge before committing.

Note, resolving a merge conflict is not evil, you simply pick code which exists in one or both sides of the conflict. If you add some code which does not exist in either side, you have now turned the merge evil.

Community
  • 1
  • 1
Justin
  • 4,097
  • 1
  • 22
  • 31
  • Sometimes the only way to properly resolve a conflict is to add code which doesn't exist in either parent, of course, and while that merge resolution would be evil, I'd say it's more lawful evil, as opposed to a "chaotic evil" merge adding code which has nothing to do with the contents of the merge. – Cascabel Jun 18 '10 at 13:25
  • @Jefromi, that's kind of what my question was working towards. I didn't see how you could reconcile "Don't break the build" and avoiding evil merges. – Benjol Jun 18 '10 at 13:48
  • @Benjol: Well, sometimes all you have to do is choose the line from one parent over the analogous line from the other - but you're right, most of the time in the real world you have to do more. – Cascabel Jun 18 '10 at 13:52
3

That comment was an interesting illustration of how an "evil" merge can occur:

Sometimes the minimal manual resolution results in lines that weren't there.
Eg.

  • 'ours' changes the name of a function,
  • 'theirs' changes the return value,
  • we need a method with new name and new return val).

Is this an evil one? IOW: are evil merges sometimes necessary

Note that this article mentions "evil merges" in another context (unintented merges), and advocate for always rebasing, rather than merging... but that would ignore the danger of a git pull --rebase.


Junio C Hamano, main maintainer for git, precise in his April 2013 blog post:

A canonical example of where "evil merge" happens in real life (and is a good thing) is to adjust for semantic conflicts. It almost never have anything to do with textual conflicts.

(typically an API change, for instance: you add a parameter, while another developer add a call to that function... but without any extra parameter)

That means you have to fix the semantic conflict (like a missing argument for a function which now takes one) at the time of the merge, which means creating a line which:

  • doesn't exist in your code (where you did correctly made API changes)
  • doesn't exist in the remote branch you are now merging (where the other developer wasn't aware of the API change)

That makes the merge an "evil merge".

With "git log -c/--cc", such a line will show with double-plus in the multi-way patch output to show that "this did not exist in either parent".

From git log man page:

Diff Formatting

-c::

With this option, diff output for a merge commit shows the differences from each of the parents to the merge result simultaneously instead of showing pairwise diff between a parent and the result one at a time.
Furthermore, it lists only files which were modified from all parents.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
0

It happens when a developer has a merge conflict that he must manually fix, and in doing so, he changes code that is not related to the merge conflict itself. Git's merging algorithms will not insert unrelated, "evil" code changes by itself.

mipadi
  • 398,885
  • 90
  • 523
  • 479
  • To be nit-picky, you could add code that was *related* to the merge conflict, without it being code from either parent, and you'd have a merge that was at least moderately evil. – Cascabel Jun 18 '10 at 13:22