Commits

Ryan Wilcox committed 7fae5e1

added tip on merging binary files

  • Participants
  • Parent commits f359bfd

Comments (0)

Files changed (1)

File advanced/2009-11-29-merging-binary-files.html

+{% extends "_tip.html" %}
+{%hyde
+    title: Handling Binary Files in a merge
+    author_name: Ryan Wilcox
+    author_link: http://www.wilcoxd.com/
+    created: 2009-11-29
+%}
+
+
+{% block excerpt %}
+Mostly we deal with text, source code etc. But sometimes we put binary files into our repository and dealing with the inevitable merge conflict is not as easy as source code.
+{% endblock %}
+
+
+{% block tip %}
+
+Say you're building a website, and you keep your images in the Hg repository for the site. Eventually two people are going to change that file at the same time and have a merge conflict.
+
+Setting up Mercurial for different merge tools
+--------------------------------------------------
+
+In your ~/.hgrc file, you should add the following section
+
+    [merge-tools]
+    diff_images.args = $output $other
+    [merge-patterns]
+    **.png = diff_images
+
+Now, create a diff\_images_ shell script, set it to executable, and put it on your $PATH. Mine is:
+
+    open -a GraphicConverter $1 $2 -W 
+    # opens the first and second parameter with GraphicConverter, waiting
+    # until same is quit before letting the shell continue.
+
+Now a merge that contains .png files that conflict will open up GraphicConverter. There will be two images that open up: one as it exists in the your source tree now, and one from Mercurial. You can tell the difference because the one from mercurial will have a lot of random-seeming letters after the file extension. For example, if your conflicting file is image.png, GraphicConverter will open up two windows: image.png and image.png~other.bQkQxd.
+
+Manually move your changes from the new file into the original file (image.png), saving the original when done and quitting GraphicConverter. These are the changes that will be committed.
+
+How this setup works
+--------------------------------------------
+
+First, diff\_images.args sets up two parameters to pass into the graphics tool:     
+    * "$output" is the file that Mercurial will commit, and contains the version from the first parent.
+    * "$other" is the version from revision you are merging in.
+    
+There are other options that the .args parameter provides:
+
+  * "$local" is a copy of $output, but changes to this file will be ignored in the merge
+  * "$base" is the file from the revision right before the contents of the file diverged.
+    
+You could use these to set up a three way merge, if you desired, or enhance diff\_images to show the user the contents of the file *before* this merge mess happened.
+
+Next, the [merge-patterns] section associates what merge tool to use when a file name matches a particular pattern. 
+
+Without the merge-pattern section, diff\_images would be considered for a diff candidate, but skipped over because Mercurial will assume that diff\_images can't handle diffing binary files. Adding lines to [merge-pattern] will tell Mercurial that diff\_images can handle the file types specified.
+
+Instead of putting in a merge-patterns section, you could add a line, like diff\_images.args, that tells Mercurial that diff\_images can handle binary documents:
+    diff_images.binary = True
+
+However, this will make diff\_images a candidate for *all* binary differences, which GraphicConverter may not be up to (for example, diffing mp3s would not be a good task for GraphicConverter).
+
+When Things go terribly wrong: aborting the merge
+--------------------------------------------------
+
+Merges can _not_ be aborted via the standard `hg revert` mechanism. Try it and you'll get:
+    $ hg revert --all
+    abort: uncommitted merge - please provide a specific revision
+
+But you just want to blow away your merge work and start from scratch. Use `hg checkout --clean` for this.
+
+References
+-------------------------------------------------
+  * [Merge Tool Configuration on the Mercurial Wiki](http://mercurial.selenic.com/wiki/MergeToolConfiguration)
+  * [Issue 1533: "abort: outstanding uncommitted merges should mention update -C"](http://mercurial.selenic.com/bts/issue1533)
+  * [Binary Files in Mercurial explained, on the Mercurial Wiki](http://mercurial.selenic.com/wiki/BinaryFiles)
+  
+{% endblock %}
+