GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS

Written by thoughtbot

Xcode and git: bridging the gap

Apple integrated git into Xcode 4 in 2011 much to the relief of iOS developers everywhere. Unfortunately when collaborating on projects with multiple developers, Xcode and git can still seem miles apart.

Here are some ways that we can bridge the gap.

.gitignore

The first adjustment is to tell git to ignore certain files generated by the OS X Finder and Xcode, artifacts from the build process and automatic backup files. The Xcode configuration files pertain to each developer's install of Xcode and don't need to be kept under version control.

Add the following contents to a .gitignore file at your project's root.

# OS X Finder .DS_Store

# Xcode per-user config *.mode1 *.mode1v3 *.mode2v3 *.perspective *.perspectivev3 *.pbxuser *.xcworkspace xcuserdata

# Build products build/ *.o *.LinkFileList *.hmap

# Automatic backup files *~.nib/ *.swp *~ *.dat *.dep

Ignoring these files helps us avoid needless merge conflicts during development. There is one exception, though…

project.pbxproj

project.pbxproj is an important file in the Xcode configuration bundle. It is responsible for maintaining references to all of the linked files and their groupings, linked frameworks, and most importantly, the project's build settings. Because of this, we cannot exclude project.pbxproj from version control.

During development, you may find that you encounter rather large merge conflicts in this file when multiple people have added or removed files or changed project and target settings.

"Easy enough", you say blithely. "I can just manually resolve these conflicts…"

Famous last words.

The problem with merging this file is that it's not really supposed to be human readable. It's in a custom format that is similar to a property list (but not quite) and it's not readily apparent how the contents of this file pertain to your project.

99% of the time, the resolution you want is a union between both sides of the conflict. Luckily it's easy to perform this union automatically in git…

.gitattributes

Adding a .gitattributes file to your project allows you to affect how certain operations are performed in git by assigning attributes to a particular path.

In our case, we're going to use .gitattributes to tell git that any file with the extension .pbxproj should be treated as binary. Place a .gitattributes file with the following contents in your project's root directory.

*.pbxproj binary merge=union

Because of the custom format used in this type of file, this is exactly what we want. When a merge conflict arises for this file, git will automatically combine the changes from both sides of the conflict, applying the upstream changes first.

Wrapping Up

With the addition of these two files, git is now equipped to handle changes to the project made by multiple developers and we can spend more time writing code and developing new features.