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.
merge
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 try to run and fix whatever errors that come up eg. missing new files, removed files.
diff
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.
The popular not-too-correct way
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.
When to merge union?
While it is not right to simply union from both, there are circumstances where it is faster to resolve with union.
I speak on a personal experience: I once had a long lived branch with 100+ conflicts in pbxproj to resolve 😭
While possible, resolving that many conflicts will take time and patience. The alternative is to cheat and do a merge union (for this once only), and resolve any Xcode errors manually – it is likely for errors such as removed files yet still in complile sources, for example.