How to deal with project.pbxproj in conjunction with git

Toni Sučić
3 min readFeb 25, 2018

There’s a thing that has been driving me nuts ever since I started programming in Xcode, and that’s the infamous project.pbxproj file.

The project.pbxproj file contains metadata like settings, file references, configuration, and targeted platforms which Xcode uses to build your project.

Whenever you add, move, delete or rename a file / folder in Xcode (among other things), it will result in project.pbxproj being modified. Git, of course, recognizes this and adds it to the staging area. Now, the problem with this is that once you have enough changes in your staging area, and you want to split them up into logically segregated commits, it becomes extremely tedious because you have to manually go through the changes in the project.pbxproj file and find the ones that correspond with the files or folders you modified.

Why is this a problem?

Scenario #1

Imagine you add the files Logger.swift and bg-image.png to the project. You decide to commit the newly added Logger.swift & bg-image.png files in two separate commits called “Add logging class” and “Add background image”, respectively. However, you forgot to add the corresponding changes in the project.pbxproj file, so now, if your colleague clones the project, he’ll get weird errors in Xcode because the files are there but the corresponding project.pbxproj info is not present in the repo he cloned, because it wasn’t included in the past two commits.

Scenario #2

You have a bunch of changes in the staging area and decide to commit them. You’ve committed five commits, each being self contained and not dependent on subsequent commits… or so you think. All of a sudden you realize that while doing this, you forgot to commit the changes in project.pbxproj, so you decide to commit all the changes therein at once in one commit that succeeds the five foregoing commits. A couple of days later, you realize that you’ve inadvertently introduced a bug into the code which is so hard to find that you decide to revert to a past commit, but the commit you reverted to happens to be one of those commits that was committed without the corresponding project.pbxproj changes, so Xcode starts complaining. This happens because the commit you reverted to is dependent on a subsequent commit.

Scenario #3

You’re working on a project with someone else. There are four branches: master, develop, onboarding, preferences. You and your colleague are working on the onboarding and preferences branches, respectively. Every now and then, you synchronize the develop branch with your onboarding branch and in doing so, you merge your project.pbxproj file with the one on the develop branch. If you’re lucky, your colleague hasn’t done the same a few times already and you don’t get any merge conflicts. But, as is often the case, your colleague has made some changes to it and consequently, merge conflicts arise.

And that’s just the tip of the ice berg. There are many issues that could occur as a consequence of forgetting about project.pbxproj or managing it poorly.

Is there a solution to this?

There is one basic rule you can adhere to in order to decrease the likelihood of the aforementioned issues occurring.

Commit newly added, moved, deleted or renamed files / folders ASAP — even if they’re empty

If you do this right away as opposed to postponing it indefinitely, you can clear the changes in project.pbxproj before they become too numerous. By committing the changes in project.pbxproj with the corresponding file / folder changes the moment they appear, and doing so regularly and consistently, you won’t have to worry about their later becoming too numerous to handle. This deals with the issues raised in the first & second scenarios.

The third scenario is more difficult to deal with. In this case, communication is crucial. Try to avoid merging a myriad of changes in your project.pbxproj file into the develop branch. Instead, merge small changes frequently, and make sure to inform anyone who’s working in their own branch about it so that they can run git merge/rebase in the branch they’re working on to synchronize their project.pbxproj file with the one on the develop branch that you just updated. Using a merge driver like this one is also a good idea as it eases the process of handling merges in project.pbxproj.

tl;dr

Make sure that there aren’t any uncommitted changes in project.pbxproj at all times. When running git status, you shouldn’t see project.pbxproj there, and if you do, deal with it immediately.

--

--