Xcode项目文件的git合并冲突

46
在Xcode中,如何避免项目文件在Git上的冲突?(我使用手动的Git操作,不使用Xcode界面上的Git)
我从Github上克隆了mapbox-ios-sdk,并进行了修改,现在远程主机已经更改。当我尝试将远程更改合并到本地后,项目文件中会发生合并冲突。(具体来说,是.xcodeproj文件夹下的project.pbxproj文件)
我认为项目文件不应该被忽略,因为如果有任何新文件加入到项目中,.pbxproj文件将会被改变。(或者我错了,这个文件应该被忽略吗?但显然它一开始没有被忽略在mapbox-ios-sdk中。毕竟人们需要这个项目文件。)但是我也曾在与其他合作者合作的项目中遇到过这种冲突,这让我无法使用Git。
我该找出如何手动解决冲突还是有更好的方法来处理这个问题?

我在使用kdiff3和Sourcetree结合时取得了良好的结果。大多数冲突都会自动解决;未解决的冲突会以可视化方式呈现。最糟糕的情况是通过Xcode项目导航器重新添加一个或两个文件到项目中。 - Tom Howard
这个回答解决了你的问题吗?如何在Xcode中使用svn合并冲突(文件project.pbxproj)? - TT--
10个回答

33

很多网站只是建议使用一个 .gitattributes 文件,其中包含:

*.pbxproj merge=union

我们会在尝试使用脚本之前尝试这种方法。如果我们发现任何问题,我会确保更新这篇文章。如果其他人有对这种方法的评论,请包括在内。


4
请访问http://roadfiresoftware.com/2015/09/automatically-resolving-git-merge-conflicts-in-xcodes-project-pbxproj/了解详情。 - Amr Lotfy
刚开始使用这个工具,非常好用。它自动解决了我们项目中的一些重命名冲突问题。 - Hendies

30

当你向项目中添加新文件时,.pbxproj文件将发生变化。如果两个或多个协作者同时添加文件(未先获取彼此的更改),则会产生冲突。我们通过在添加新文件之前和之后执行以下步骤来避免这种情况:

  1. 在添加文件之前,提交您的更改,然后从主分支上拉取代码以获取最新版本。如果有人已经添加了文件,则您现在拥有最新的 .pbxproj 文件。
  2. 添加您的文件。
  3. 立即提交并将您的更改推送到主分支(希望在另一个合作者添加另一个文件之前完成)。

虽然这样做有些懦弱,但我们不愿意手动解决 .pbxproj 文件的冲突。

此外,还可以查看这篇有着出色回答的 Stack Overflow 问题:如何正确使用 XCode 和 Git?


看起来这对于少数合作者来说可能完美运作,但有些繁琐。你提供的链接似乎对于大型项目非常有帮助。无论如何,似乎Xcode项目本身就不太适合用于源代码控制。 :/ - huggie
实际上,我们只有三名合作者。 - cmac
9
这并不是一个好策略,因为我们在这里喜欢有意义且始终正常运行的提交。这样会削弱这一点。 - Daniel
这是一种让人沮丧的工作方式,您推荐什么工具来处理合并? - Alex Nolasco
2
当你使用特性分支和/或超过一两个协作者时,这是不可行的。 - Kevin R
显示剩余3条评论

6
你应该检查一下我的脚本xUnique,它是目前在苹果采取行动之前合并Xcode项目文件的最佳解决方案。

它是什么 & 如何工作

  1. project.pbxproj转换为JSON格式
  2. 遍历JSON中的所有objects,为每个UUID赋予绝对路径,并使用路径的MD5十六进制摘要创建新的UUID
    • 此json对象中的所有元素实际上连接成为一棵树
    • 我们使用其唯一属性给树的每个节点赋予一个路径属性;此路径是到根节点的绝对路径,
    • 对于节点,应用MD5十六进制摘要来生成UUID
  3. 用MD5十六进制摘要替换所有旧的UUID,并删除不在当前节点树和格式错误的UUID
  4. 对包括childrenfilesPBXFileReferencePBXBuildFile列表在内的项目文件进行排序,并删除这些列表中的所有重复条目
    • 如果您想了解实现,请参见xUnique.py中的sort_pbxproj方法;
    • 它是从我修改的sort-Xcode-project-file移植来的,对PBXFileReferencePBXBuildFile的排序有所不同
  5. 使用不同的选项,您可以更灵活地使用xUnique

请查看README文件以获取更多详细信息。


不,我们在我们的项目中使用了25个以上的子项目,并且它运行得非常好。 - Xiao
尝试您的项目,希望它能对我们有所帮助。谢谢! - Alex Nolasco
没问题。我在 README 中建议了这个。你遇到什么问题了吗? - Xiao
1
它支持CocoaPods吗? - igrek
1
@igrek 我没有在 xUnique 中使用 cocoapods。如果 cocoapods 强制按照 24 个字符的 UUID 读写项目文件,那么它将无法工作。如果不是这样,它应该可以正常工作。 - Xiao
显示剩余2条评论

4
在大多数情况下,您可以通过以下代码来修复合并问题,即删除git添加的行:
#!/bin/bash
FILE={PRODUCT_NAME}.xcodeproj/project.pbxproj
sed '/======/d' $FILE | sed '/<<<<</d' | sed '/>>>>>/d' > temp
cat temp > $FILE
rm temp

但是,如果您重命名项目的组并导致冲突,则需要手动删除原始组的额外行。


1
这非常危险。合并冲突意味着潜在的冲突意图,需要实际选择哪个是正确的。这忽略了这种担忧,只是盲目地添加了两个更改。 - ScottyBlades

3

我需要在我的分支中获取主代码,因此我正在从主分支获取并且我的.pbxproj文件有更改,而主分支具有不同的配置。 因此,在.pbxproj文件中显示冲突。 按照以下步骤解决它:

在Finder中打开.pbxproj文件-> 右键单击文件选择显示包内容-> 选择.pbxproj文件并使用TextEdit打开-> 它会显示以下冲突行。

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

你必须从Head Changes和Your Changes中选择正确的那一个,并删除其余的内容。现在提交您的代码。

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

如果一切正常,就推送你的代码。
git push

2
当这是由两个或多个合作者/分支添加文件引起的(根据我的经验,这种情况一直存在,并且可以通过查看差异来检查),我会执行以下操作:
  1. 通过“使用我们的”或“使用他们的”(哪个添加了大部分文件)来解决冲突。
  2. 提交(这将产生一个包含所有添加的文件但某些文件不在项目中的存储库)。
  3. 在Xcode中使用“添加文件到...”从其他合作者/分支添加缺失的文件(它们很容易找到,因为它们在项目目录中,而Xcode会为您突出显示)。
  4. 提交。
(我并不确定步骤2是否真的必要 - 但对我来说感觉更整洁)。

2
您也可以手动使用Mergepbx进行操作,步骤如下:
  1. 使用brew安装Mergepbx

    brew install mergepbx

  2. 每次在项目文件中出现冲突时,运行以下命令自动解决冲突。

    git mergetool --tool=mergepbx PROJECT.pbxproj


1

1
如果其他方法都失败了,虽然很繁琐,但您可以在git客户端中打开您的pbxproj文件,然后手动逐个文件进行检查,确保每个文件要么被删除,要么有4行(6次出现)。

1

我曾经遇到同样的问题,所以我用Swift编写了一个工具,可以解决由于添加、删除、移动和重命名文件和组而导致的冲突。你可以将其设置为git合并驱动程序,这样当你合并分支时自动运行脚本。

你可以在这里查看:XcodeMergeDriver


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接