So i’m not a git expert. But i’ve been using it for about a month and i’m mostly really happy. The only time it drives me crazy is when i get this damned message.
~/code/tt (master) $ git pull
You are in the middle of a conflicted merge.
It’s like this swamp in the gitverse. Normally merging is fine everything goes along with tons of merges branches for each feature which i merge back in. I really like it. But when merges fail git does not provide any path out of the swamp. Your magical merging technology has failed you and now you must find your own way out. Every command leads to the same damned message. “You are in the middle of a conflicted merge.” Well i know that! Trying git resolve doesn’t do much, that’s not even a command.
~/code/tt (master) $ git resolve
git: 'resolve' is not a git-command. See 'git --help'.
So what to do, well first resolve the conflict in your merging program of choice. Almost always for me it’s just textmate, open the damned conflicted file and edit it. FileMerge and others work too, but we’re just diffing shit, it’s not too hard.
Now here’s the trick, once you fix the problem, add the files which you’ve had to edit, and commit them.
~/code/tt (master) $ git add lib/im/response.rb
~/code/tt (master) $ git commit -m 'I hate failed merges'
Created commit 34d2648: I hate failed merges
That’s it. I’m writing this blog post because i keep forgetting what to do, and when i search on google for the error message, You are in the middle of a conflicted merge. i get some damned message on the kernel dev list about the development of git.
So here the steps are:
- Pull the update from master, or whereever – git pull
- See the dreaded merge failed message
- Edit the files which failed to merge correctly cleaning up the code
- Run your tests / specs just to make sure you caught everything
- Add and commit the manually merged file. git add path/to/file.rb; git commit -m “work damnit”
- Go back to pushing and pulling in peace
Git’s an amazing piece of technology with some really broken parts to it’s interface which makes learning how it works hard.
To me it’s similar to the differences between the GNU stack and Solaris. I came to know about the GNU tools through Linux, it was just how everything worked. Then one day i had to use Solaris, and the commands had all the same names, and worked. But not as well. The GNU tools have really amazing user interface and interaction design. Seriously. Read GNU Standards for Command Line Interfaces and you’ll be amazed, that’s what we all think of as linux and unix. It works, it’s standardized. It makes it easy to guess what’s next and discover how the application works. It’s not given credit, but that document, and the extensive toolset like readline, built on it, is what makes the internet work. It’s discoverable, it’s built on the idea that you can pipe information from one program to another, and that they will all work. If you don’t believe me, just look at DJB’s amazing, but far from standard apps.
So what should git do? Well it should suggest a solution. Or make a solution documented in the examples of the man file. It’s pretty damned simple, fix the merge, add the file, commit, and you’re done. Instead it locks up and prevents you from doing anything until you intuit your way out of the problem. Insanity.
PS. Yes i’m lazy and should submit the fix myself, people are submitting contributions to git all the time.
4 Comments, Comment or Ping
I understand the frustration that it doesn’t “just work”, but what exactly do you expect it to do? You asked git to merge, it tried, but it couldn’t figure out the correct merge automatically.
So it gives you the same working directory file containing conflict markers that CVS or SVN do (I like to enable “merge.conflictsyle=diff3″), and, in addition, three original versions (both merge heads plus the common ancestor) in the index.
Basically, the final fallback merge algorithm is “stop and ask the user what to do”.
And then it avoids doing any *more* damage until the unfinished merge situation is resolved somehow. Anyone who’s accidentally checked a file *with* conflict markers into CVS will tell you how handy that safety feature is.
You can always abandon the merge with “git reset –hard” and try again later.
You can add cleverer and cleverer merge heuristics, but you can’t find one that will *always* do the right thing, so you will always need a manual fallback. I mean, if branch A refactored function foo() one way and branch B did it a different way, there’s no way for software to do that automatically.
(In fact, Linus has specifically avoided such cleverness because it carries with it an unpleasant risk of quietly doing the *wrong* thing.)
But I’m unclear on what better solution you expect.
January 2nd, 2010
If you have your diff editor configured you can just type “git mergetool” and it’ll open the first conflicted file in that editor (you don’t even have to paste in the path; it just does the first one). On OSX, it throws it to FileMerge, which 90% of the time is all I need.
When you’re done and save your file, close the editor (close it entirely, not just the window) and go back to your shell. The editor will have exited and the terminal should have moved on to the next file, hit enter and it launches again, repeat.
When you’re done continue with your steps above (add them, commit them). You’ll likely have some .orig files to clean up, but that’s usually not that tough.
January 13th, 2010
Thank you, thank you, thank you so much
Very useful article.
March 15th, 2011
If you have to explain the message, then it is a bad message. A better message is a better solution (in this instance).
Something like “Git was unable to automatically merge your changes with the master” would be better but this may still be unhelpful for some.
A better solution is to suggest available options to fix the problem.
For example:
Your options are:
1. Discard your local changes.
To do this use: git reset –hard
then: git pull
then retype your changes.
2. Manually merge you changes.
To do this use: git mergetool
then: git commit; git pull; git push
March 21st, 2012
Reply to “Git: You are in the middle of a conflicted merge.”