{"id":168055,"date":"2014-04-16T05:00:23","date_gmt":"2014-04-16T12:00:23","guid":{"rendered":"http:\/\/css-tricks.com\/?p=168055"},"modified":"2017-01-16T06:06:36","modified_gmt":"2017-01-16T13:06:36","slug":"deal-merge-conflicts-git","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/deal-merge-conflicts-git\/","title":{"rendered":"How to Deal with Merge Conflicts in Git"},"content":{"rendered":"

Everybody has a list of things they don’t like: an appointment at the dentist, a traffic jam, or a canceled flight. When I was preparing my book<\/a>, I wasn’t surprised that a lot of designers and developers would add merge conflicts to this list without hesitation.<\/p>\n

When using Git for version control, there is nothing to fear. Once you understand how merge conflicts work and how to deal with them, I’m sure you’ll be able to cross them off this list.<\/p>\n

You Cannot Break Things<\/h3>\n

The first thing that you should keep in mind is that you can always undo a merge and go back to the state before the conflict occurred. You’re always able to undo and start fresh<\/strong>.<\/p>\n

If you’re coming from another version control system (e.g. Subversion) you might be traumatized: conflicts in Subversion have the (rightful) reputation of being incredibly complex and nasty. One reason for this is that Git, simply stated, works completely different in this regard than Subversion. As a consequence, Git is able to take care of most things during a merge – leaving you with comparatively simple scenarios to solve.<\/p>\n

Also, a conflict will only ever handicap yourself<\/em>. It will not<\/em> bring your complete team to a halt or cripple your central repository. This is because, in Git, conflicts can only occur on a your<\/em> local machine – and not on the server.<\/p>\n

How a Merge Conflict Occurs<\/h3>\n

In Git, “merging” is the act of integrating another branch into your current working branch. You’re taking changes from another context (that’s what a branch effectively is: a context) and combine them with your current working files. Have a look at this introduction to branching<\/a> if you’re new to the concept in general.<\/p>\n

A great thing about having Git as your version control system is that it makes merging extremely easy: in most cases, Git will figure out how to integrate new changes.<\/p>\n

However, there’s a handful of situations where you might have to step in and tell Git what to do. Most commonly, this is when there are changes to the same file on both branches. Even in this case, Git will most likely be able to figure it out on its own. But if two people changed the same lines in that same file, or if one person decided to delete it while the other person decided to modify it, Git simply cannot know what is correct. Git will then mark the file as having a conflict – which you’ll have to solve before you can continue your work.<\/p>\n

How to Solve a Merge Conflict<\/h3>\n

When faced with a merge conflict, the first step is to understand what happened. Did one of your colleagues edit the same file on the same lines as you? Did they delete a file that you modified? Did you both add a file with the same name?<\/p>\n

Git will tell you that you have “unmerged paths” (which is just another way of telling you that you have one or more conflicts) via “git status”:<\/p>\n

<\/figure>\n

Conflict Markup<\/h4>\n

Let’s take an in-depth look on how to solve the most common case: when two changes affected the same file on the same lines.<\/p>\n

Now is the time to have a look at the contents of the conflicted file. Literally open it in your code editor. Git is nice enough to mark the problematic area in the file by enclosing it in “<<<<<<< HEAD<\/strong>” and “>>>>>>> [other\/branch\/name]<\/strong>“.<\/p>\n

The code from your current branch<\/strong> is on top, the code from the branch you are merging in<\/strong> is on the bottom.<\/figcaption><\/figure>\n

The contents after the first marker originate from your current working branch. After the angle brackets, Git tells us where (from which branch) the changes came from. A line with “=======<\/strong>” separates the two conflicting changes.<\/p>\n

Cleaning Up<\/h4>\n

Our job is now to clean up these lines: when we’re done, the file should look exactly as we want it to look. It can be necessary to consult the teammate who wrote the conflicting changes to decide which code is finally correct. Maybe it’s yours, maybe it’s theirs, or maybe a mixture between the two.<\/p>\n

Opening the raw file in your editor and cleaning it up there is perfectly valid, but not very comfortable. Using a dedicated merge tool can make this job a great deal easier. You can configure your tool of choice using the “git config” command. Consult your tool’s documentation for detailed instructions. Note that just because you have git installed doesn’t mean you have a dedicated merge tool installed, these are separate, optional software tools.<\/p>\n

Then, in case of a conflict, you can later invoke it by simply typing “git mergetool”.<\/p>\n

For this example, I’ve used Kaleidoscope<\/a> on Mac:<\/p>\n

<\/figure>\n

The left and right panes stand for the conflicting changes; a far more elegant visualization than <<<<<<<<\/strong>” and “>>>>>>><\/strong>“.<\/p>\n

You can now simply toggle which change shall be taken. The middle pane shows the resulting code; in good tools, you can even edit this further.<\/p>\n

Now, after cleaning up the file with the final code, all that’s left is to save it. To give Git a hint that you’re done with this file, you should quit the merge tool to continue. Behind the scenes, this told Git to execute a “git add” command on the (now formerly) conflicted file. This marks the conflict as solved. Should you decide not<\/strong> to use a merge tool and instead clean up the file in your editor, you’ll have to mark the file as resolved by hand (by executing “git add <filename>”).<\/p>\n

Finally, after resolving all conflicts, a merge conflict situation needs to be concluded by a regular commit.<\/p>\n

How to Undo a Merge<\/h3>\n

As already said, you can return to the state before you started the merge at any time. This should give you the confidence that you can’t break anything. On the command line, a simple “git merge –abort” will do this for you.<\/p>\n

In case you’ve made a mistake while resolving a conflict and realize this only after completing the merge, you can still easily undo it: just roll back to the commit before the merge happened with “git reset –hard <commit-hash>” and start over again.<\/p>\n

Tools Can Make Things Easier<\/h3>\n

I’ve already mentioned it briefly: being equipped with good tools can make your life quite a bit easier. A proper merge tool<\/a> will help you better understand a conflict scenario and make the right decision.<\/p>\n

Have Confidence<\/h3>\n

With all the safety nets in place that Git provides, there’s really no need to be afraid of merge conflicts in any way. Once understood how they work and what your options are, you should be ready to merge like there’s no tomorrow. Always keep in mind: you can’t break anything!<\/p>\n

Note from the Editor<\/h3>\n

Tobias modestly left out Tower as an excellent tool to help with merge conflicts. In fact one of the reasons I personally use Tower is because I like how it helps with merge conflicts. <\/p>\n

It’s very clear when you have a conflict:<\/p>\n


\n<\/figure>\n

And right-clicking on the conflicted file gives you some nice options:<\/p>\n

<\/figure>\n

So my process is usually:<\/p>\n

    \n
  1. Is it very obvious to me whether my changes to this file or the other branches changes to this file should “win”? If so, select the relevant “Resolve <file> Using Mine” or “Resolve <file> Using Theirs”<\/li>\n
  2. If I need a closer look, pop it open in a code editor and check it out. Then maybe still I can use one of those options.<\/li>\n
  3. If it’s more complicated, manually fix it up and then choose “Mark <file> as Manually Resolved” from Tower.<\/li>\n
  4. Sometimes use a Merge Tool if there is a lot of complex fixes, which Tower also supports opening conflicts in via the “Open <file> in Merge Tool” option.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"

    Everybody has a list of things they don’t like: an appointment at the dentist, a traffic jam, or a canceled flight. When I was preparing my book, I wasn’t surprised that a lot of designers and developers would add merge conflicts to this list without hesitation. When using Git for version control, there is nothing […]<\/p>\n","protected":false},"author":247217,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[4],"tags":[766,1038,1045],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":354389,"url":"https:\/\/css-tricks.com\/merge-conflicts-what-they-are-and-how-to-deal-with-them\/","url_meta":{"origin":168055,"position":0},"title":"Merge Conflicts: What They Are and How to Deal with Them\u200b","date":"October 28, 2021","format":false,"excerpt":"Merge conflicts... Nobody likes them. Some of us even fear them. But they are a fact of life when you're working with Git, especially when you're teaming up with other developers. In most cases, merge conflicts aren't as scary as you might think. In this fourth part of our \u201cAdvanced\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/10\/conflict-in-textfile@2x.png?fit=1130%2C622&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":316153,"url":"https:\/\/css-tricks.com\/cmdz-for-git-is-here\/","url_meta":{"origin":168055,"position":1},"title":"CMD+Z for Git is Here","date":"July 23, 2020","format":false,"excerpt":"Version control with Git has become a \"commodity\" by now: virtually every software project today uses Git, and virtually every developer knows Git to some extent. This explains why I sometimes hear the following question when I talk about what I do for a living: \"A desktop client for Git?\u2026","rel":"","context":"In "Sponsored"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/07\/tower_testimonials@2x.png?fit=1200%2C550&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":356700,"url":"https:\/\/css-tricks.com\/cherry-picking-commits-in-git\/","url_meta":{"origin":168055,"position":2},"title":"Cherry-Picking Commits in Git","date":"November 17, 2021","format":false,"excerpt":"In part 5 of this series, we looked at rebasing and merging. Although there are a couple of differences between git merge and git rebase, both commands have the same goal: they integrate changes from one branch into another.","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/11\/git-cherry-picking.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":354734,"url":"https:\/\/css-tricks.com\/rebase-vs-merge-integrating-changes-in-git\/","url_meta":{"origin":168055,"position":3},"title":"Rebase vs. Merge: Integrating Changes in Git","date":"November 2, 2021","format":false,"excerpt":"This article is part of our \u201cAdvanced Git\u201d series. Be sure to follow us on Twitter or sign up for our newsletter to hear about the next articles! Most developers understand that it's important to use branches in Git. In fact, I've written an entire article on branching strategies in\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/10\/rebase-git.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":175076,"url":"https:\/\/css-tricks.com\/sponsored-tower-2-0-make-git-easy\/","url_meta":{"origin":168055,"position":4},"title":"Tower 2.0 is Here – To Make Git Easy!","date":"July 24, 2014","format":false,"excerpt":"Most people wouldn't call version control their hobby. But in the last few years, people have also become aware of how valuable it is. Nowadays, you won't find a top programmer, web developer, or web designer who doesn't use version control. In part because it helps you produce better results\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":352569,"url":"https:\/\/css-tricks.com\/better-collaboration-with-pull-requests\/","url_meta":{"origin":168055,"position":5},"title":"Better Collaboration With Pull Requests","date":"October 11, 2021","format":false,"excerpt":"This article is part of our \u201cAdvanced Git\u201d series. Be sure to follow us on Twitter or sign up for our newsletter to hear about the next articles! In this third installment of our \u201cAdvanced Git\u201d series, we\u2019ll look at pull requests \u2014 a great feature which helps both small\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/09\/Untitled-3-2.png?fit=1200%2C375&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/168055"}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/247217"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=168055"}],"version-history":[{"count":5,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/168055\/revisions"}],"predecessor-version":[{"id":250052,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/168055\/revisions\/250052"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=168055"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=168055"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=168055"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}