How to merge conflicts (file project.pbxproj) in Xcode use svn?

Unfortunately, there's not much you can do except to make the changes manually in one check out and then check-in the newly "merged" project.


I use git but we see the same issue - if two people add files there's a merge conflict.

Usually the editing is very easy though. Simply go into the project.pbxproj file with a text editor, and look for the merge conflict section - usually this is marked by something like :

>>>>>>>
Stuff 1
======
Stuff 2
<<<<<<<<

In 99% of Xcode project merge conflict cases, you simply want to accept both sides of the merge (because two people added different files) - so you would simply delete the merge markers, in the above case that would end up like:

Stuff 1
Stuff 2

Like I said, this works great in MOST cases. If Xcode will not read the project file when you are done, just take the most recent un-merged version and manually add your files again.


To manually solve the merge conflicts, check the UUID of each conflicting item.

Example:

<<<<<<< HEAD
    6B01C4B72008E70000A19171 /* ExistingFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B01C4B62008E70000A19171 /* ExistingFile.swift */; };
    3F01C4B72008E70000889299 /* NewFileA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F01C4B72008E70000889299 /* NewFileA.swift */; };
=======
    6B01C4B72008E70000A19171 /* ExistingFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B01C4B62008E70000A19171 /* ExistingFile.swift */; };
    4DF01C4B72008E70000882ED /* NewFileB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF01C4B72008E70000882ED /* NewFileB.swift */; };
>>>>>>> branch_to_merge

Check each UUID:

  • If it occurs in both versions, remove it in one version: ExistingFile.swift
  • If it does not occur on the comparing branch, keep it: NewFileA.swift and NewFileB.swift
  • If it is not referenced anywhere else in the file, i.e. you can only find one occurrence in the whole project.pbxproj file, I would assume it is an artefact and safe to delete it.

The result would be:

    6B01C4B72008E70000A19171 /* ExistingFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B01C4B62008E70000A19171 /* ExistingFile.swift */; };
    3F01C4B72008E70000889299 /* NewFileA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F01C4B72008E70000889299 /* NewFileA.swift */; };
    4DF01C4B72008E70000882ED /* NewFileB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF01C4B72008E70000882ED /* NewFileB.swift */; };

Note: I don't recommend adding *.pbxproj merge=union to the .gitattribues file to basically ignore merge conflicts because a conflicting merge should alway be checked manually unless there is a sophisticated script doing that for you.


This solution is only for git, but you can add a .gitattributes file to your project then within that file add the following line:

*.pbxproj merge=union

This will tell git to keep both sides of the merge which will be what you want the vast majority of the time.