27

"man gitglossary" contains this definition of an evil merge:

An evil merge is a merge that introduces changes that do not appear in any parent.

I am not sure I understand the point the authors are trying to get at. Why is it evil ?

Jakub Narębski
  • 309,089
  • 65
  • 217
  • 230
krosenvold
  • 75,535
  • 32
  • 152
  • 208
  • 4
    I came here from [this page](http://stackoverflow.com/questions/2910044/does-git-have-evil-twin-issues/2910388#2910388) and I found it very helpful to realize, that it isn't `git's evil merge`: evil merge is **not some natural phenomenon** that sometimes happens; Rather, it is something people will sometimes do in git (just like people sometimes cause other accidents like pushing --forced changes to a public repo). The takeaway here is: don't do that! (_or at least preserve merge semantics_) – sehe Apr 07 '11 at 07:05
  • sehe is right, these are the words of Linus Torvalds himself: an "evil merge" is something that makes changes that came from neither side and aren't actually resolving a conflict – Adam Kurkiewicz Jul 21 '15 at 16:21
  • 1
    Note that if you *repeat* the merge (as you would using, e.g., Git 2.18's new `--rebase-merges` feature), the special actions you took when you made the evil merge—or the special actions someone else took when *they* made it— **will not be repeated automatically** and the merge result will differ. The merge will have lost its "evil-ness", in other words. That could be another reason to call it "evil", especially if the result was good / important. – torek Apr 10 '19 at 23:52

4 Answers4

25

Because it's putting things in the code that no one ever asked to be there. As if you had this code:

$foo = bar;
$baz = qxx;

and this change:

$foo = bar;
$foo++;
$baz = qxx;

got merged with this change:

$foo = bar;
$foo--;
$baz = qxx;

in a fashion that somehow produced:

$foo = bar;
$foo++;
$foo--;
--$baz;
$baz = qxx;

Clearly, this is evil.

I would guess that it's of enough concern to be in man gitglossary because the more involved your merging algorithms are, the more likely it is that they will produce such a thing.

chaos
  • 122,029
  • 33
  • 303
  • 309
  • 3
    To produce this, simply call git-merge with the --no-commit option, add some more changes, check them in, and commit. The pregenerated merge commit message will automatically be used. – Cascabel Sep 22 '09 at 21:31
  • 3
    @Jefromi By this definition, any merge with a conflict that has to be resolved manually is an evil merge? There is a strong semantic difference to what @chaos says; you could potentially get his results without getting any kind of conflict in the merge process. Which is truly evil. – krosenvold Sep 23 '09 at 05:44
  • 10
    Where did --$baz; come from. I didn't think GIT produced code at random. To me it's evil enough that the increment and decrement got merged without anyone clarifying which is the correct code. The result being that the two changes break the code. The line that came from nowhere would have to be put in by someone manually "correcting" the merge. At that point, it's not GIT's fault?!?!? – Lee Louviere Apr 26 '11 at 18:25
  • I see. Evil merge being the merge process introducing code not written by the programmers. Again, I think it's evil enough that a merge can produce an increment followed by a decrement, given no one's paying enough attention. The merge makes the two versions meaningless. – Lee Louviere Apr 26 '11 at 18:27
  • 11
    @Xaade: `git` itself won't produce that result. It will produce a version with conflict markers (i.e.: `<<<<<< HEAD\n [code from head]\n ======\n [code from branch]\n >>>>>> branch`, and it won't commit. It is then up to the programmer to manually solve the conflict. If they do so without introducing new code, then it's not evil. So chaos's last example would not be an evil merge without the `--$baz;` line. That would be a **stupid merge**, but the fault would lie with the programmer, not with git. – naught101 Jul 03 '12 at 03:36
  • @LeeLouviere -- this is not right. See my answer quoting Linus Torvalds – Adam Kurkiewicz Jul 21 '15 at 16:27
22

In the words of Linus Torvalds himself (taken from the git mailing list):

an "evil merge" is something that makes changes that came from neither side and aren't actually resolving a conflict

Adam Kurkiewicz
  • 1,526
  • 1
  • 15
  • 34
9

I think it might be named 'evil merge' because it is difficult corner case for "git blame" to solve when annotating file (generating line-wise history annotations).


Evil merge migh be needed when you developed feature 'A' on main branch, and feature 'B' on side branch, and those features conflict in semantic (non-textual) way. An example would be using the same name for global variable, with different meanings -- this requires renaming the variable for one of features.

For evil merge "git show --cc" has non-empty compact combined diff (but I am not sure if it is equivalence relation; the implication might be in one direction only, i.e. "evil merge" then non-empty "git diff-tree -p --cc").

Jakub Narębski
  • 309,089
  • 65
  • 217
  • 230
  • 1
    Intuitively, @chaos' response feels more correct, but I know that you're good with these things ;) It feels like you're describing a good old merge conflict, where 2 people have solved overlapping parts of the same problem - or maybe even the same problem. Once the merge is finished, why would you want to recreate it? Isn't it overly poetic to call this "fairly regular" incident "evil" ? – krosenvold Sep 23 '09 at 05:53
  • 2
    Resolving a conflict *usually* involves choosing one of versions over the other, sometimes choosing one version lines over lines from other version. Evil merge has lines which are not in any of its parents, so it cannot be automatically recreated even by a most sophisticated (generic) merge strategy. – Jakub Narębski Sep 23 '09 at 08:26
  • *(Removed line about "evil" merge and automated process)* – Jakub Narębski Sep 23 '09 at 08:32
  • 6
    I think you rightly emphasised 'usually'. 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? +1 – inger Jul 28 '10 at 21:20
5

It is worth to mention that an "evil change" from an "evil merge" can be lost silently while rebasing an "evil merge" containing an "evil change" which does not conflict with other commits. Using --preserve-merges does not help in such a case.

jbialobr
  • 1,382
  • 1
  • 13
  • 14
  • so the allowed conflict resolving changes (see Torvalds "...and aren't actually resolving a conflict") are lost then, too? – springy76 Apr 18 '23 at 08:34