The 3-way diff in JetBrains products, like IntelliJ, are the best, IMHO, because it helps you edit the resolved result, while updating both left and right diffs.<p>Their diff tool also has a magic-wand icon, which resolves trivial conflicts automatically. I still wonder why git doesn't do that by default... It's such a pain to resolve conflicts without that feature.<p>Also, you get syntax highlighting, structural editing, help, definition quick-lookup and similar IDE features available, while working on the resolved version of the code, which is syntactically correct usually, because there are no explicit, textual conflict markers in the resolved text.
The article suggests a good first step, but I recommend using a 3-way capable merge tool for an even better experience. 3-way merging with a reasonable UI should be the default, I don't really understand why it still isn't. It makes large and complex merges easy. My merge tool of choice was kdiff3 for the longest time, though these days I'm using Beyond Compare which is a commercial product.
If you're getting a lot of conflicts then you have folks working on the same code and diverging it significantly. I honestly don't think that's a problem tooling will improve because it's really an organizational/communication problem. Engineers have to know when to rebase (or merge in changes from the target) if they're working on code with other engineers. If you merge in/rebase sooner, then things tend to be painless. If it's been weeks or months then let the Circus O' Pain begin. This should be fairly easy to recognize in stand up, eg: "Oh, you're working on that module? I need to track your changes, so am I."
We never use merge except fast forward merges. So we never have merge conflicts.<p>Of course that means that we might need to rebase and that could hit conflicts. With diff3 style rebase conflicts are generally [1] easy to understand. When a commit does not apply cleanly the diff3 style output gives you 3 sections:<p>1. What the code looks like after the previous commit that has already been rebased to the new branch under work<p>2. What the code looked like in the original branch<p>3. What it looked like 1 commit later in the original branch.<p>Now the question the human is: You (or some one else) changed it from 2 to 3 in the past. Now your code is not 2 but 1. How do you introduce an equivalent change from 1 to something that works like 3?<p>Once I have learned that principle I could no longer understand why diff3 is not the default or how anyone can survive without it.<p>[1] Of course there can always be tricky changes. If an automatic diff tool choses unlucky alignments the result is not ideal for humans. But diff3 does not make things worse and generally it does not happen that often.<p>Edit: A couple of iterations needed. Don't try to type somewhat complex comments on your phone...
Sure, diff3 is better than nothing. zdiff3 is even better. But there's so much scope for better diffs still. For starters we could have semantically aware diffs that take into account where blocks are (I think there are some efforts to do this).<p>But even diff3 is missing information. Lets say the code started as A, you changed it to B. Then you rebase and `master` is C. You'll get basically "It's C now! But you changed it from A to B."<p>That's not enough information. Why was it changed to C? I don't know how to update my diff without that information. Really you need to see the change that changed it to C too.<p>There's so much scope for an advanced conflict resolution tool. Git gets it wrong in so many situations where you could do better.
Not sure if I like this better.<p>It seems even more complicated to track 3 context points in time rather than 2.<p>I'm open to changing my mind, but would need reasons. Botched rebases aren't a common issue for me (though merge conflict resolution can be unpleasant).
I like the idea but it is clearly incomplete. It gets the fact that there are 3 versions (and that it wants you to generate a 4th) but it misses the important thing which is that you want to see the differences. This option basically leaves you to do the diff yourself. Now the sinple option of just showing the two diffs probably isn't optimal either as the context will be duplicated noise, but I think that is already better. In fact I think the merge diff representation would work well here except for the fact that you want to be able to compile and test the code which you can do with the diff markers.
I've found configuring merge.conflictstyle diff3 without a tool to be superior than tools like kdiff3 and such. This was without any fancy merge conflict rendering. Nowadays some editors will also highlight the changes in a 3-way diff.<p>The reason no-tool is better is that you don't have to read files in whatever order kdiff3 shows them to you -- they're just files, and you open them.
The best is a 4-way diff<p>It you merge a file in two commits A and B, it would show version A, version B, the common ancestor, and the resulting merged file in four different views.<p>xxdiff could do that.
I hope someone solves the merge conflict problem once and for all. Each time there’s a merge conflict the project stops for days as no one knows how to resolve them. In the end the solution always is to delete the git repository and clone it again.