views:

659

answers:

2

I have been an iphone developer for a while, and I have recently been including git in my workflow. I have used git settings found on http://shanesbrain.net/2008/7/9/using-xcode-with-git for my workflow so far.

Those settings tell git to exclude *.pbxproj from merges? Is there a real reason for doing this? For example, when I add a file to the project and push to origin, my fellow developers will not have that file added to their xcode project when they pull. Then if one of them builds a release this file may not be included. Shouldn't I just let git handle the merges for the project file? Could someone please explain why or why not this file should be in merges and how to properly handle the situation when files are added to the project. Thanks.

A: 

The short answer is that even if you don't include that line in .gitattributes, you won't be able to successfully merge two modified versions of a .pbxproj. It's a mess of JSON data without meaningful line breaks, so it's better for git to treat it as a binary.

See here for details: http://stackoverflow.com/questions/1549578/git-and-pbxproj

Tom
sounds like you could set up a commit filter to send the file through `simplejson` or some such tidier on its way to the index. It would still not be guaranteed to work though.
intuited
+7  A: 

I have worked on iPhone applications full time since the SDK launch, most of that time spent working on teams with multiple developers.

The truth is that it's way more harmful to disallow merging of that .pbxproj file than it is helpful. As you say, when you add a file unless other people get that file, they have to also add it to their project - in an application of any size, that sucks and it also takes away a huge benefit of source code control in that you cannot really revert to a complete earlier project state just through git.

The .pbxproj file is simply JSON (similar to XML). From experience, just about the ONLY merge conflict you were ever get is if two people have added files at the same time. The solution in 99% of the merge conflict cases is to keep both sides of the merge, which for git at least simply involves removing any >>>>, >>>>, and ==== lines. In fact this is so common that I have created a simple shell script to fix a .pbxproj file in a merge state from git, I run this from within the project directory (at the Classes level):

#!/bin/sh

    projectfile=`find -d . -name 'project.pbxproj'`
    projectdir=`echo *.xcodeproj`
    projectfile="${projectdir}/project.pbxproj"
    tempfile="${projectdir}/project.pbxproj.out"
    savefile="${projectdir}/project.pbxproj.mergesave"

    cat $projectfile | grep -v "<<<<<<< HEAD" | grep -v "=======" | grep -v "^>>>>>>> " > $tempfile
    cp $projectfile $savefile
    mv $tempfile $projectfile

Worst case if it fails (you ask XCode to load the project and it fails to load), you simply delete the .pbxproj file, check out the master from git, and re-add your files. But I've never had that happen in many months of use with this script, again working full time on iPhone applications with several other developers.

Here is my complete .gitignore file, showing what I do have it set to ignore as there are a few things you don't want - in my case really just emacs remnants and the whole build directory:

# xcode noise
build/*
*.pbxuser
*.mode1v3
*~

# old skool
.svn

# osx noise
.DS_Store
profile
Kendall Helmstetter Gelner
Do you use a .gitattributes file at all for your xcode project? And thank you for your insight. I think it will be much easier to try merging the pbxproj files in the future.
rickharrison
To date we have not been, though some aspects of that look interesting - but the people I have worked with have not been advanced git users, and so advocation of advanced features is not strong.
Kendall Helmstetter Gelner
“The .pbxproj file is simply JSON (similar to XML).” Actually, it's an OpenStep-formatted property list. Same basic ideas as JSON, but the syntax differs in a few places.
Peter Hosey