An Xcode project is stored as a pbxproj file, which is a property list file format. A git repo could have a .gitattributes file to specify how such files are to be treated. Have you ever wondered what your gitattributes should be?

imho it should be

*.pbxproj diff merge

What does the above do?

gitattributes is in the format pattern attr1 attr2 ..., and the prefix - is to unset the attribute. Read the git documentation for more information how it works.


So merge means on merge conflict, use the built-in 3-way merge driver. Frankly I don’t know how the driver works.

You will see the usual merge conflicts <<<<<<< mine, ======= and >>>>>>> theirs

It is entirely possible to choose from any of the merge strategy: choose yours, choose theirs, choose both, or to edit manually. So it is better to decide as you deemed fit from the diff.

pbxproj is scarier to resolve, but possible. If unclear, choose the one that did more changes first, then run and fix. As you need to resolve all first because the project can run, you will want to note down all that are unclear, and remember to fix them.


diff means Git can generate diffs (textual patch), treating it as text.

If omitted, by default, if the file size is smaller than core.bigFileThreshold, it is treated as text. Otherwise treated as binary.

Somehow, could be due to legacy reasons, it is popular to treat pbxproj file as binary, and to perform union merge.

*.pbxproj binary merge=union

While the property list is not for human to edit manually, it is human readable text. It definitely should not be treated as a binary. Being binary also make Git GUI not showing the diff!

To merge both sides of the changes could also end badly. The author recognised 99% of the time the resolution is merge union. I agree. Most of pbxproj merge conflict is resolved by union of both. But when you specify auto merge in gitattributes, git will not give you the choice.

If you’re unlucky, you will end up with corrupted project in that 1%.. 🥹

Stackoverflow discussions here and here.

It is better to leave gitattributes empty than to set to the not-too-correct way.




Back to Home