46

In Xcode, what's the best way to avoid Git conflict in the project file? (I am in manual git, not using Xcode interface for git)

I've cloned mapbox-ios-sdk from Github, hacked it, and now the remote master has changed. When I tried to pull the remote changes into my local, after merging there would be merge conflict in the project file. (Specifically, I mean the project.pbxproj in the .xcodeproj)

I do not really think project file should be put into the ignore, since if there are any new files the project file, the .pbxproj file seems to be changed. (Or am I just plain wrong and this file should be put to ignore? But obviously it wasn't on ignored in the mapbox-ios-sdk to begin with. People need the project file after all.) But I've also ran into this conflict before in my collaboration project with another collaborator and it's keeping me from using Git altogether.

Should I figure out how to manually resolve conflict or is there a better way to deal with this?

huggie
  • 17,587
  • 27
  • 82
  • 139
  • I have had good results using kdiff3 in conjunction with Sourcetree. The majority of conflicts are resolved automatically; those which are not are presented visually. My worst case scenario has been re-adding one or two files to the project through Xcode project navigator. – Tom Howard Mar 28 '18 at 13:44
  • Does this answer your question? [How to merge conflicts (file project.pbxproj) in Xcode use svn?](https://stackoverflow.com/questions/2004135/how-to-merge-conflicts-file-project-pbxproj-in-xcode-use-svn) – TT-- Jun 07 '23 at 03:45

10 Answers10

33

A lot of websites simply suggest to use a .gitattributes file with:

*.pbxproj merge=union

We're gonna try this approach before trying to use scripts. If we find any issues I'll be sure to update this post. Also if anyone else has comments to this approach please include.

Alex Zavatone
  • 4,106
  • 36
  • 54
Warpzit
  • 27,966
  • 19
  • 103
  • 155
  • 4
    Details in http://roadfiresoftware.com/2015/09/automatically-resolving-git-merge-conflicts-in-xcodes-project-pbxproj/ – Amr Lotfy Feb 12 '17 at 09:10
  • Just started using this now - worked an absolute treat. Auto-resolved a number of renaming conflicts within our project – Hendies Nov 08 '17 at 19:15
30

.pbxproj will change when you add new files to the project. There will be conflicts if two or more collaborators add files at the same time (without getting one another's changes first). We are avoiding this in my project by following these steps before and after adding new files:

  1. Before adding a file, commit your changes, then pull from the master so that you have the latest.If someone has added a file, you now have the latest .pbxproj
  2. Add your file(s).
  3. Immediately commit and push your changes up to the master (hopefully, before another collaborator has added another file).

It's wimpy, but we don't relish manually resolving .pbxproj conflicts.

Also, see this Stack Overflow question with excellent responses: How to use Git properly with XCode?

Community
  • 1
  • 1
cmac
  • 906
  • 10
  • 19
  • It looks like this would work perfectly for a few collaborators, though cumbersome. The link you give appears to be pretty helpful for large project, though. In any case it would appear that Xcode project is just not really good for source control to begin with. :/ – huggie Oct 16 '12 at 05:17
  • Indeed, we only have three collaborators. – cmac Oct 16 '12 at 05:37
  • 9
    Not a great strategy, seeing as here we like to have meaningful, always functioning commits. This would undermine that. – Daniel Mar 12 '13 at 17:28
  • This is a sad way to work, what tool do you recommend for dealing with merges? – Alex Nolasco Sep 26 '14 at 17:26
  • 2
    This isn't workable when you work with feature branches and/or more than one or two collaborators. – Kevin R Feb 13 '15 at 08:13
  • I'm beginning to think this is the only solution as git auto merge union breaks up the goddamn file. +1 –  Dec 06 '18 at 08:57
  • If more than two people are working on different features? then what? – Dipendra Sharma May 29 '19 at 15:31
  • My git begin to show me ```modified: ../MovieWorld.xcodeproj/project.pbxproj``` every time I commit, which is not happened before. Really boring, I need to manually git add that file again then I could commit the changes. What is the root cause of this? – Zhou Haibo Apr 22 '20 at 09:34
6

You should check my script xUnique, it is now the best solution to merge Xcode project file before Apple takes action on it.

What it does & How it works

  1. convert project.pbxproj to JSON format
  2. Iterate all objects in JSON and give every UUID an absolute path, and create a new UUID using MD5 hex digest of the path
    • All elements in this json object is actually connected as a tree
    • We give a path attribute to every node of the tree using its unique attribute; this path is the absolute path to the root node,
    • Apply MD5 hex digest to the path for the node
  3. Replace all old UUIDs with the MD5 hex digest and also remove unused UUIDs that are not in the current node tree and UUIDs in wrong format
  4. Sort the project file inlcuding children, files, PBXFileReference and PBXBuildFile list and remove all duplicated entries in these lists
    • see sort_pbxproj method in xUnique.py if you want to know the implementation;
    • It's ported from my modified sort-Xcode-project-file, with some differences in ordering PBXFileReference and PBXBuildFile
  5. With different options, you can use xUnique with more flexibility

Check README file for more details.

Xiao
  • 12,235
  • 2
  • 29
  • 36
4

In most case, you can fix the merge by following code, remove the lines which git adds:

#!/bin/bash
FILE={PRODUCT_NAME}.xcodeproj/project.pbxproj
sed '/======/d' $FILE | sed '/<<<<</d' | sed '/>>>>>/d' > temp
cat temp > $FILE
rm temp

but if you rename the group of your project and it leads to conflicts, you will manually delete the extra lines of your original group.

summer1991
  • 387
  • 2
  • 6
  • 1
    This is highly risky. A merge conflict means potentially conflicting intentions that require an actual choice of which is correct. This ignores that concern and simply adds both changes blindly. – ScottyBlades Jan 27 '21 at 06:32
3

I need to get master code in my branch So, I was taking pull from master and I have a change in my .pbxproj file and master has different configuration. So, It was showing conflict in .pbxproj file. Follow these steps to resolve it

Open .pbxproj in Finder-> Right click on file Choose Show Package Contents-> Choose .pbxproj file and open it with TextEdit-> It will show conflict lines as below.

<<<<<<< HEAD"
// head changes
===========
// Your changes
>>>>>>>>

You have to choose the right one from head Changes and your changes and Delete the rest. Now commit you code

git add .
git commit -m"conflict resolved"
git status // Check you files status

If everything is fine the push you code.

git push
Gurjinder Singh
  • 9,221
  • 1
  • 66
  • 58
2

When this is caused by adding files from two or more collaborators/branches (which in my experience has always been the case to date and can be checked by looking at the diff) I do this:

  1. Resolve the conflict by "use ours" or "use theirs" (whichever has added the most files).
  2. Commit (this produces a repo that contains all the added files but some are not in the project).
  3. Within Xcode use "Add Files To..." to add the missing files from the other collaborator/branch (they are easy to find as they are in the project directory and Xcode usefully highlights them for you).
  4. Commit.

(I am not convinced step 2 is really necessary - but feels neater to me).

Ali Beadle
  • 4,486
  • 3
  • 30
  • 55
2

You can also use Mergepbx manually do it as follows

  1. Install Mergepbx using brew.

    brew install mergepbx

  2. Run a command each time you have conflicts in your project file to automatically resolve them.

    git mergetool --tool=mergepbx PROJECT.pbxproj

Vineeth Joseph
  • 5,177
  • 3
  • 17
  • 31
1

I made an app for fixing things in Xcode project files when these sort of things go wrong. You'd still have to do some manually merging first though, unfortunately. https://itunes.apple.com/us/app/xsaviour/id1449886415?mt=12

Mark Bridges
  • 8,228
  • 4
  • 50
  • 65
1

If all else fails, while tedious. you can open your pbxproj in your git client, then manually, go file by file and ensure each one is either removed or has 4 lines (6 occurrences).

ScottyBlades
  • 12,189
  • 5
  • 77
  • 85
1

I had the same problem, so I wrote a tool in Swift that will resolve conflicts due to adding, deleting, moving, and renaming files and groups. You can set it up as a git merge driver so the script runs automatically when you merge a branch.

You can check it out here: XcodeMergeDriver

Istvan
  • 1,627
  • 1
  • 11
  • 17