Merging XCode project files is the bane of any iOS or OS X developers day. In this weeks iOS Dev Weekly there was a tip from Roadhouse Software on how to get rid of (most of) the pain using the union merge strategy. There is however a much better way!

Using merge=union will choose both sets of changes automatically when a merge conflict is detected. In most cases this is exactly what you want with pbxproj files, however git has no idea what an XCode project file should look like and will happily create an invalid file, causing even more problems!

Mergepbx is a tool created by Simon Wagner that solves this problem by knowing exactly what a valid project file should look like. It will look at the two sets of changes and intelligently merge them to create a valid project file. In cases where there actually is a real conflict (for example one developer deleted a file and another renamed it) it will fall back to letting you resolve the conflict yourself.

Installing mergepbx is pretty straightforward. It can now be installed using homebrew:

brew install mergepbx

You can now run a command each time you have conflicts in your project file to automatically resolve them:

git mergetool --tool=mergepbx PROJECT.pbxproj

We can go one better than this. We can set up git to automatically run mergepbx whenever it finds conflicts in your project file!

We first need to set up mergepbx as a merge driver. In your ~/.gitconfig file (create it if it doesn’t exist) add:

[merge "mergepbx"]

name = XCode project files merger

driver = mergepbx %O %A %B

You now need to edit the .gitattributes file in the root of each of your iOS project repositories to tell git to merge the project file using this new merge driver. Add this line to the file, creating the file if it doesn’t exist:

*.pbxproj merge=mergepbx

This is exactly the same line as recommended in the original tip from Roadhouse Software, just using mergepbx instead of union.

I have been using mergepbx for around a year and it has saved me countless hours. If it saves you the same amount of time please consider sending Simon a cup of tea!