Chris,
Thanks for the reply, just now getting info together to follow up on this thread.
My merges all really don't have any actual conflicts. However, the output of git rebase says there's a conflict and makes me go through a merge step. My mergetool also says there is a conflict by searching for "next conflict"
For example, in the following example, the file SomeController.m was added to the Xcode project file in the master branch but when I rebase my feature branch, I get the following "conflict". This is the the diff statements added to my project.pbxproj file after the rebase:
<<<<<<< HEAD F0BFA27F1614D4E200E58B11 /* SomeController.m in Sources */, ======= >>>>>>> Separated and refactored error handlers from their view controllers. F097BF3A15F1896600F2ED1C /* AnotherViewController.m in Sources */, F097BF3D15F18CC700F2ED1C /* ThirdPartyErrorHandler.m in Sources */, F097BF4215F1A72400F2ED1C /* FacebookLiker.m in Sources */,
My merge program says that the following is conflicted and needs to be added from the merging branch:
F0BFA27F1614D4E200E58B11 /* SomeController.m in Sources */, F097BF3A15F1896600F2ED1C /* AnotherViewController.m in Sources */, F097BF3D15F18CC700F2ED1C /* ThirdPartyErrorHandler.m in Sources */, F097BF4215F1A72400F2ED1C /* FacebookLiker.m in Sources */,
Nothing is shown as changed in the current branch, as the above suggests.
But once I select those 4 four files to include in the merge, the target association for the new file is lost. Hence, my project is corrupted.
One other data point, my co-workers have the same "conflict" problems that corrupt the Xcode project, so it doesn't SEEM to be a specific configuration on my system.
Does this make sense?
Doug Hill Schematic Labs, Inc.
On Sep 28, 2012, at 2:52 PM, Chris Hanson wrote: On Sep 28, 2012, at 11:54 AM, Doug Hill < email@hidden> wrote: Again, any help in figuring this out would be greatly appreciated. As of now, doing a rebase/merge corrupts my Xcode project files. Are Xcode projects not compatible with merge?
Xcode projects are designed to be extremely merge-friendly. That's why many parts of them are written out line-by-line (rather than all on a single line), and why they have extensive comments.
It sounds like the tool you're doing to compare your files when the merge fails during rebase shows the inherent merge conflicts that result from this as a single line. That's bad, and can lead you to make incorrect decisions. If you look at how "git diff" presents the conflict as text, it should be clear.
For example, I just created a simple example project (a Cocoa app), created a "Preferences" branch, added CMHMainWindowController.{h,m,xib} in the "master" branch, and added CMHPreferencesWindowController.{h,m,xib} in the "Preferences" branch. I then tried to rebase the "Preferences" branch from the "master" branch:
First, rewinding head to replay your work on top of it... Applying: Add preferences window controller. Using index info to reconstruct a base tree... M MergeExample.xcodeproj/project.pbxproj <stdin>:121: trailing whitespace. <stdin>:128: trailing whitespace. warning: 2 lines add whitespace errors. Falling back to patching base and 3-way merge... Auto-merging MergeExample.xcodeproj/project.pbxproj CONFLICT (content): Merge conflict in MergeExample.xcodeproj/project.pbxproj Failed to merge in the changes. Patch failed at 0001 Add preferences window controller. The copy of the patch that failed is found in: /Projects/Test/MergeExample/.git/rebase-apply/patch When you have resolved this problem, run "git rebase --continue". If you prefer to skip this patch, run "git rebase --skip" instead. To check out the original branch and stop rebasing, run "git rebase --abort".
This is the kind of conflict it sounds like you're getting.
When I do "git diff" and pipe the result to my text editor, here are what the diffs look like (apologies for the size, but I feel it's important to be complete here):
diff --cc MergeExample.xcodeproj/project.pbxproj index c5d2382,6aa1659..0000000 --- a/MergeExample.xcodeproj/project.pbxproj +++ b/MergeExample.xcodeproj/project.pbxproj @@@ -13,8 -13,8 +13,13 @@@ 9F30B1AA16164BB7009B3B6A /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 9F30B1A816164BB7009B3B6A /* Credits.rtf */; }; 9F30B1AD16164BB7009B3B6A /* CMHAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F30B1AC16164BB7009B3B6A /* CMHAppDelegate.m */; }; 9F30B1B016164BB7009B3B6A /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9F30B1AE16164BB7009B3B6A /* MainMenu.xib */; }; + 9F30B1B916164C25009B3B6A /* CMHMainWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F30B1B716164C25009B3B6A /* CMHMainWindowController.m */; }; + 9F30B1BB16164C36009B3B6A /* CMHMainWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9F30B1BD16164C36009B3B6A /* CMHMainWindowController.xib */; }; + 9F30B1C116164C82009B3B6A /* CMHPreferencesWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F30B1BF16164C82009B3B6A /* CMHPreferencesWindowController.m */; }; + 9F30B1C316164C8D009B3B6A /* CMHPreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9F30B1C516164C8D009B3B6A /* CMHPreferencesWindowController.xib */; }; ++>>>>>>> Add preferences window controller. /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@@ -31,9 -31,9 +36,15 @@@ 9F30B1AB16164BB7009B3B6A /* CMHAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CMHAppDelegate.h; sourceTree = "<group>"; }; 9F30B1AC16164BB7009B3B6A /* CMHAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CMHAppDelegate.m; sourceTree = "<group>"; }; 9F30B1AF16164BB7009B3B6A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; }; + 9F30B1B616164C25009B3B6A /* CMHMainWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHMainWindowController.h; sourceTree = "<group>"; }; + 9F30B1B716164C25009B3B6A /* CMHMainWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMHMainWindowController.m; sourceTree = "<group>"; }; + 9F30B1BC16164C36009B3B6A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CMHMainWindowController.xib; sourceTree = "<group>"; }; + 9F30B1BE16164C82009B3B6A /* CMHPreferencesWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHPreferencesWindowController.h; sourceTree = "<group>"; }; + 9F30B1BF16164C82009B3B6A /* CMHPreferencesWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMHPreferencesWindowController.m; sourceTree = "<group>"; }; + 9F30B1C416164C8D009B3B6A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CMHPreferencesWindowController.xib; sourceTree = "<group>"; }; ++>>>>>>> Add preferences window controller. /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@@ -89,9 -89,9 +100,15 @@@ 9F30B1AB16164BB7009B3B6A /* CMHAppDelegate.h */, 9F30B1AC16164BB7009B3B6A /* CMHAppDelegate.m */, + 9F30B1B616164C25009B3B6A /* CMHMainWindowController.h */, + 9F30B1B716164C25009B3B6A /* CMHMainWindowController.m */, + 9F30B1BD16164C36009B3B6A /* CMHMainWindowController.xib */, + 9F30B1BE16164C82009B3B6A /* CMHPreferencesWindowController.h */, + 9F30B1BF16164C82009B3B6A /* CMHPreferencesWindowController.m */, + 9F30B1C516164C8D009B3B6A /* CMHPreferencesWindowController.xib */, ++>>>>>>> Add preferences window controller. 9F30B1AE16164BB7009B3B6A /* MainMenu.xib */, 9F30B1A016164BB7009B3B6A /* Supporting Files */, @@@ -165,7 -165,7 +182,11 @@@ 9F30B1A416164BB7009B3B6A /* InfoPlist.strings in Resources */, 9F30B1AA16164BB7009B3B6A /* Credits.rtf in Resources */, 9F30B1B016164BB7009B3B6A /* MainMenu.xib in Resources */, + 9F30B1BB16164C36009B3B6A /* CMHMainWindowController.xib in Resources */, + 9F30B1C316164C8D009B3B6A /* CMHPreferencesWindowController.xib in Resources */, ++>>>>>>> Add preferences window controller. runOnlyForDeploymentPostprocessing = 0; @@@ -178,7 -178,7 +199,11 @@@ 9F30B1A616164BB7009B3B6A /* main.m in Sources */, 9F30B1AD16164BB7009B3B6A /* CMHAppDelegate.m in Sources */, + 9F30B1B916164C25009B3B6A /* CMHMainWindowController.m in Sources */, + 9F30B1C116164C82009B3B6A /* CMHPreferencesWindowController.m in Sources */, ++>>>>>>> Add preferences window controller. runOnlyForDeploymentPostprocessing = 0; @@@ -209,12 -209,12 +234,21 @@@ + 9F30B1BD16164C36009B3B6A /* CMHMainWindowController.xib */ = { + 9F30B1BC16164C36009B3B6A /* en */, + name = CMHMainWindowController.xib; + 9F30B1C516164C8D009B3B6A /* CMHPreferencesWindowController.xib */ = { + 9F30B1C416164C8D009B3B6A /* en */, + name = CMHPreferencesWindowController.xib; ++>>>>>>> Add preferences window controller. /* End PBXVariantGroup section */
Again, sorry for the length.
You can see from the "git diff" output that there were additions in both the "master" and "Preferences" branches — the former indicated by " +" and the latter indicated by "+ " (note the spacing, "master" changes are indented). I've also colored the output (if it comes through in Mail) such that the "master" changes are green and the "Preferences" changes are blue.)
Since those additions happened at the same places in the file — typically at the ends of lists — you get conflicts. This is expected and normal when two people modify the same portion of a file, whether it's C source code or an Xcode project. What you need to do to resolve conflicts like these, where both branches contain additions, is just edit the project file to contain both sets of changes, first the master and then the branch.
Typically the next question is, why did adding three files — implementation, header, and xib — to each branch cause changes in so many different sections of the project? That's because each section represents something different to Xcode. Section by section, the changes above are to: - Build Files: These indicate the addition of the files to build phases in targets, such as Compile Sources and Copy Bundle resources.
- File References: These are the pointers to the actual files in the project. File references are per-project in Xcode, while build files are per-target. This allows you to create multiple targets that all build a single file without adding that file to the project several different times.
- Group Structure: The next three sections represent changes to the group structure of the project, which is what's presented in the Project Navigator in Xcode. This allows moving a file's icon in your project's group hierarchy to only change the group hierarchy, not the file reference itself.
- Variant Groups: These represent files with one or more localization, so they can be represented just once in the build files and in the group structure, while they stand in for one file references in each localization.
The hexadecimal numbers are global IDs that let the various objects in the project file cross-reference each other, for example the build files point to their associated file references and variant groups via these global IDs.
Hopefully this makes what's going on clearer and makes it much easier for you to resolve conflicts in your project files in the future.
-- Chris
|