如何在Xcode中使用svn合并冲突(文件project.pbxproj)?


69

我们团队中有两名成员。我们使用Xcode的SCM(使用SVN)来管理我们的源代码文件。
我们都将文件添加到我们的Xcode项目中。他致力于SVN服务器。更新时,Xcode发现project.pbxproj文件中存在冲突。然后,我选择退出Xcode并手动合并冲突。然后,我开始编辑我的project.pbxproj,合并我们的更改。其实我不知道Xcode如何管理文件,我只是添加一些project.pbxproj文件没有的文本。完成后,我的项目无法打开。我猜是因为project.pbxproj不能手动编辑文件。

所以,我想知道,当您发现此问题时,project.pbxproj文件存在冲突,如何解决?

谢谢!

Answers:


25

不幸的是,除了在一次检出中手动进行更改然后检入新的“合并”项目外,您无能为力。


1
花了一个小时的时间后,找到了一个神奇的解决方案。这似乎是我唯一可以接受的答案。
Kiran Ruth R

141

我使用git,但我们看到了相同的问题-如果两个人添加文件,则存在合并冲突。

通常,编辑是很容易的。只需使用文本编辑器进入project.pbxproj文件,然后查找合并冲突部分-通常这会由类似以下内容的标记:

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

在99%的Xcode项目合并冲突情况下,您只想接受合并的两面(因为两个人添加了不同的文件),因此您只需删除合并标记,在上述情况下,最终会像这样:

Stuff 1
Stuff 2

就像我说的,这在MOST情况下效果很好。如果完成后Xcode无法读取项目文件,则只需获取最新的未合并版本,然后再次手动添加文件即可。


1
另一个回答一个非常类似的问题用于治疗pbxproj文件作为二进制文件声称:stackoverflow.com/questions/1549578/git-and-pbxproj/...
约什-梅特卡夫

4
他们是完全错误的。为什么自动化系统合并任何文本格式都比编码本身更难?这个不成立。多年以来,我每天都在与其他人一起处理XCode项目,每次应用上述合并策略(尽管这些天我只是告诉合并工具接受任何冲突的双方)。这种方法很好用。现在是情节提要,在那里,我需要做更多的实验,然后才能声称它可行。
Kendall Helmstetter Gelner 2011年

2
至少对于xcode 5来说,这是行不通的。似乎它使用了一些魔术数字,并在向项目中添加某些东西时为所有资源重新生成了这些数字。当发生冲突时,您应该删除两个冲突的资源,手动添加它们,以便xcode可以再次生成那些魔术数字。
Morteza Milani 2014年

我一点也没有看到,在最近的项目中添加新资源时,只有新资源会获得新数字(标识符)。在XCode 5中处理了其他人共享的项目后,我的建议仍然保持不变。
Kendall Helmstetter Gelner 2014年

此解决方案适用于Xcode 8版本8.0(8A218a)
JLONG

13

该解决方案仅适用于git,但是您可以将.gitattributes文件添加到项目中,然后在该文件中添加以下行:

*.pbxproj merge=union

这将告诉git保留合并的双方,这将是您绝大多数时候想要的。


过去,这对我来说效果很好。绝对推荐。试图记住我在过去的项目中使用的设置,就是这样。感谢您的提醒。
LunaCodeGirl

8

要手动解决合并冲突,请检查UUID每个冲突项。

例:

<<<<<<< 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

检查每个UUID:

  • 如果在两个版本中均发生,请在一个版本中将其删除: ExistingFile.swift
  • 如果它不比较分支发生,保持它:NewFileA.swiftNewFileB.swift
  • 如果未在文件中的其他任何地方引用它,即您只能在整个project.pbxproj文件中找到一个实例,那么我认为删除它是伪造的并且是安全的。

结果将是:

    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 */; };

注意:我不建议添加*.pbxproj merge=union.gitattribues文件中来基本上忽略合并冲突,因为除非有复杂的脚本为您执行,否则应始终手动检查冲突的合并。


1
问题已被作者删除。我认为UUID发生两次的可能性很小。请参阅UUID中的唯一
曼努埃尔

3

当我遇到其他问题/答案时,我正在寻找解决该问题的简单方法:

https://stackoverflow.com/a/14180388/307217

这个解决方案的简单性让我完全不知所措,我试图合并到一个独立的功能分支中,该分支在主干之后几乎有200个修订版本,XCode和Mercurial对此并不满意。在尝试此解决方案之前,我尝试手动合并pbxproj文件(冲突超过100次)8次。

基本上,解决方案是这样的(假设您使用Mercurial,因为它很棒):

  1. 尝试合并:

    hg update FEATURE_BRANCH
    hg merge default
    *mercurial gives you a ton of crap about the pbxproj file having merge conflicts*
    
  2. 开启Xcode

  3. 在顶部工具栏中,选择Xcode-> Open Developer Tool-> FileMerge
  4. 在左侧,打开有冲突的“ project.pbxproj”文件(其中包含合并冲突标记的文件)
  5. 在右侧,打开您的“ project.pbxproj.orig”
  6. 选择File-> Save Merge并保存在'project.pbxproj'文件中
  7. 然后回到命令行:

    hg resolve -m ProjectName.xcodeproj/project.pbxproj
    *merge any other broken files*
    hg commit -m "manually merged with trunk"
    
  8. 吃蛋糕,因为你做完了

1
原来Xcode 5 FileMerge几乎在所有情况下都崩溃了。很好地将它运送出苹果…
Engin Kurutepe 2013年

1
它糟透了,但老实说,与微软相比,苹果通常不会发布很多错误。至少这对夫妻,他们的船不仅影响其用户(即程序员)的一小部分,我们知道如何谷歌其他的合并工具
G.希勒

2

如上所述,处理冲突的最常见方法是:

  1. 接受“一切”
  2. 将文件重新导入到项目中

我写了一个bash脚本来处理上面的(1)。

请注意,这只会解决最常见的合并冲突情况!

#!/bin/bash
#
#
#
if [ $# -eq 0 ]
 then
    echo "File must be provided as argument, darnit!"
    exit 1
fi

if [ $# -eq 2 ]
 then
    echo "only ONE File must be provided as argument, darnit!"
    exit 1
fi


echo "Will remove lines from file:" $1
grep -v "<<<<<" $1  | grep -v ">>>>>>" | grep -v "====" > out.tmp;mv out.tmp $1
echo "Done removing lines from file:" $1

2

有时可以在不同的分支中重新创建一个或几个文件(例如ManagedObjects),因此当您合并时,一个块中的一个文件可能有两个声明。在这种情况下,您应该删除其中一个声明。


2

我碰巧遇到了这个棘手的问题。

您可以尝试这种方式,而不是手动处理这些冲突。
假设您在要素分支上。

  1. Git结帐大师。
  2. 复制内容到 project.pbxproj
  3. 将Google Checkout转到您的功能分支,并将其粘贴。(覆盖中的当前内容project.pbxproj
  4. react-native link
    

1

到目前为止,我用于pbx文件的最佳可视合并工具是Visual Studio Code的合并工具。我在Code应用程序中打开pbx文件并修复冲突,然后再次打开XCode。




0

我知道90%的冲突是明确的,并且您可以接受冲突中的两种更改,因此如果您耐心等待我发现使用xUnique之类的工具可以为您带来很多帮助,您就不必担心会解决它。


-25

做最好的事情可能是简单地接受任何您的版本他的全部版本,没有试图将两者结合起来。另外,请考虑所涉及的文件是否应该完全存在于存储库中;让每个人都有自己的版本可能更合适。

查看有关如何解决冲突的文档


这个。.pbxproj文件非常简单(如果冗长),只要您耐心,通常的合并技术就可以正常工作。
斯蒂芬·佳能2010年

13
project.pbxproj是要放入存储库中的重要文件,因为它告诉Xcode如何构建项目。不签入等同于不签入Makefile
史蒂夫·马德森

4
这个答案很危险,不正确。不要只接受其中一个,否则您的项目将缺少文件。是的,它应该在存储库中,否则每个人都会以不同的方式构建项目,并产生不同的结果。
DougW

同意DougW-遵循此答案将导致痛苦和棘手的错误。
2012年

这个答案无法改善
djskinner
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.