365Git

  1. Search
  2. About
  3. Subscribe
  4. Archive
  5. Random

365Git

Regular small snippets and workflows for Git

My original plan of a post everyday turned out to be unrealistic, but I'll carry on posting as regularly as I can.

Find me @abizern on twitter if you have anything you'd like me to cover.

Newer
Older
  • Fixing merge conflicts

    Branching is great. Being able to work on code that you don’t have to check in, that doesn’t risk polluting the main branch until it’s finished is great; but you have to be able to bring the changes back in at some stage. One way is to use git merge. Here’s a nice contrived example of a simple repository containing two files. Greetings.txt and Partings.txt. There are three branches; master, es and fr. The currently checked out branch is es so the HEAD reference points to that. Can you spot the deliberate mistakes in the contents of the files?

    Before the merge

    I want to merge the changes from the fr branch into the es branch and since I am on the es branch already, I use the command git merge fr, and that’s when the problems start. It looks like the merge didn’t work and has left me with conflicts.

    Merge conflict

    Conflicts are an unavoidable fact of working with merges in any version control system. If there has been a change to the same line in both branches then git does not know which one to apply. Although it’s very good at interleaving changes to different lines in files, there is nothing magical about git: it isn’t going to risk corrupting my files in cases where there is a conflict. So, that means that they need to be fixed by hand. Before we look at ways of fixing these commits, let’s take a look at the state of our repository now.

    Examining the conflicts

    Run git status to see the state of your working directory.

    git status

    Here you can see that the two files are in the working directory, but not in the index. These files have been modified by git with familiar conflict markers.

    cat files

    Notice that it has marked the changes to the HEAD and fr branches in each case. What this doesn’t show you are the hidden references to the state of the files at each branch. This is what your repository looks like now:

    With Conflicts

    Quick and dirty resolution

    For small files like this the fixes are quite simple:

    1. Search for the conflict markers in each file.
    2. Edit the file to the state that you want, and remember to remove the conflict markers.
    3. Add the changed files to the index with git add.
    4. Once all the conflicted files are fixed, commit them with git commit.
    5. Edit the commit message to show that I’ve merged the files and fixed the conflicts.

    Not so dirty resolution

    In this case, I can see that files in one or the other branch should take priority. That is, changes in those files are the ones to be applied in conflicts. So here; I am on the es branch and I can see that I want my version of the Greetings.txt file to be in the merge, and the fr branch version of Partings.txt is the correct one. What I can do is to use the references to check out the version of the file that I want. So what I do here is:

    1. Get the es version of Greetings.txt with git checkout --ours Greetings.txt. Note: I am using --ours because it is the one from the branch I am currently on.
    2. Get the fr version of Partings.txt with git checkout --theirs Partings.txt. Note: I am using --theirs because it is the one from the branch I am merging with.
    3. Do a quick sanity check of the files; and I can see that the correct versions exist, and without the conflict markers.
      Resolving es conflict
    4. Add the files to the index with git add .
    5. Commit the changes with git commit
    6. Edit the commit message to show that I’ve merged the files and fixed the conflicts.

    Resolved Merge

    After resolving the conflicts and checking in the changes this is what the repository looks like.

    post merge

    You can see that there is a new commit with the correct versions of the files. Also, since this was a merge commit, this new commit has two parents which are the commits that it merged.

    Summary

    This is a contrived example but merge conflicts are a fact of life. Git doesn’t replace communication between team members and cannot read minds when deciding which changes to apply if there are conflicts. It’s also generally safe to merge branches because you will be asked to resolve conflicts rather than have changes applied under you that might mess up the project.

    There are other ways of joining branches and dealing with the conflicts. If you can’t remember them all, the quick and dirty method is the one that you can always use.

    Of course, if things become too much of mess, and there are too many conflicts to resolve all at once, you can always about a merge (before resolving and committing, of course) with git reset --merge which will restore the repository to the state it was before you started the merge. You can then use other methods to get your project into shape before trying to merge changes.

    Tagged: conflict day9 git merge checkout

    Posted on April 1, 2010 with 40 notes ()

    1. lingeriedive reblogged this from 365git
    2. brooklyndeckerswimsuit reblogged this from 365git
    3. evamendes-hq reblogged this from 365git
    4. kate-upton-hq reblogged this from 365git
    5. bodyslanguage reblogged this from 365git
    6. iosova likes this
    7. mangalcun likes this
    8. rosiode likes this
    9. pixelsa likes this
    10. chabad-chabad likes this
    11. lanka-news-today likes this
    12. galoshesandrainboots likes this
    13. benign-mesothelioma likes this
    14. fightthepower1z3 likes this
    15. 365git posted this

Field Notes Theme. Designed by Manasto Jones. Powered by Tumblr.