project.pbxproj
文件存在冲突。然后我选择退出Xcode并手动合并冲突。接着我开始编辑我的project.pbxproj
文件,合并我们的更改。实际上我不知道Xcode如何管理文件,我只是在project.pbxproj
文件中添加了一些它原本没有的文本。当我完成后,我的项目无法打开。我猜想这是因为project.pbxproj
文件不能手动编辑导致的。因此,我想知道,当你遇到这个问题时,
project.pbxproj
文件存在冲突,应该如何解决?谢谢!
project.pbxproj
文件存在冲突。然后我选择退出Xcode并手动合并冲突。接着我开始编辑我的project.pbxproj
文件,合并我们的更改。实际上我不知道Xcode如何管理文件,我只是在project.pbxproj
文件中添加了一些它原本没有的文本。当我完成后,我的项目无法打开。我猜想这是因为project.pbxproj
文件不能手动编辑导致的。project.pbxproj
文件存在冲突,应该如何解决?我使用Git,但我们遇到了相同的问题——如果两个人都添加了文件,则会出现合并冲突。
通常情况下,编辑很容易。只需使用文本编辑器打开project.pbxproj文件,并查找合并冲突部分——通常这部分会被标记为类似于“<<<<<<<<”的内容。
>>>>>>>
Stuff 1
======
Stuff 2
<<<<<<<<
在99%的Xcode项目合并冲突情况下,您只需要接受合并的两个版本(因为两个人添加了不同的文件)- 所以您只需删除合并标记,就像上面的情况一样:
Stuff 1
Stuff 2
正如我所说的,在大多数情况下,这个方法非常有效。如果Xcode在合并后无法读取项目文件,只需获取最新未合并版本,并手动添加您的文件即可。
2023年跟进
这条建议仍然适用,但最近我一直在处理一个非常大而且旧的应用程序,具有复杂的Xcode项目文件和几位团队成员时常会添加大量内容。
手动检查合并冲突仍然是主要方法。多人添加新文件通常与使用合并冲突的两侧同样容易。
还有一种紧急备选方案,就是将您尝试合并到分支中的项目文件作为副本导入,并使用带有冲突的Xcode项目的副本来手动添加回您的更改。
特别是有几种情况可能会带来挑战,其中一个解决方案非常不明显...
首先,有时候,多个人同时编辑同名文件可能会导致包含该文件的组中出现多个具有不同标识符的条目。对于此问题,请在将文件包含的组中查找文件ID,并选择保留哪个文件ID以及舍弃哪个文件ID。
其次,引入类似位置的新组可能会导致冲突分割组。在这种情况下,您可能需要完全将合并冲突区域的一侧内容移出,并将其正确引入到项目文件中的其他组中。
最后,正是这个不明显的解决方案促使我更新了这个答案。有时候,您可能会遇到一个冲突,其中所有CoreData版本的条目都有完全不同的标识符。例如,如果两个团队同时增加了模型版本,则可能会发生这种情况。
在这种情况下,似乎您可以选择其中一侧,仅使用这些标识符。这有时有效。
但在某些情况下,如果我这样做,在加载项目时我将看不到任何模型版本 - Xcode会将它们全部删除。
解决方法再次是将合并的两侧保留下来,这意味着Core Data模型将有两个条目!如果这样做,Xcode在加载项目时将为所有模型选择有效的标识符,并保存一个正确的版本,而不是允许两个版本同时存在。
对于具有多个正在进行的版本增量的大型团队,我们发现有一个技巧能够帮助平滑过渡,那就是使用单独的分支进行CoreData模型更改。这样所有团队都将使用相同的CoreData版本,并具有相同的当前模型标识符和内部Xcode项目ID。该分支仅持有CoreData模型本身,而不包括任何与模型相关的类(尽管它可以有)。
很遗憾,你只能手动在一个检出中进行更改,然后检入新的“合并”项目,别无他法。
这个解决方案仅适用于git,但您可以向您的项目添加一个.gitattributes
文件,然后在该文件中添加以下行:
*.pbxproj merge=union
这将告诉git保留合并的两个版本,这通常是您想要的大多数情况。
手动解决合并冲突,需要检查每个冲突项的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.swift
和NewFileB.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
文件中,以忽略合并冲突,因为除非有一个复杂的脚本帮你检查,否则冲突的合并应始终手动检查。
到目前为止,我使用过的最好的pbx文件可视化合并工具是Visual Studio Code的合并工具。我在Code应用程序中打开pbx文件并解决冲突,然后再次打开XCode。
Attempt your merge in mercurial:
hg update FEATURE_BRANCH
hg merge default
*mercurial gives you a ton of crap about the pbxproj file having merge conflicts*
Open Xcode
Then back at the command line:
hg resolve -m ProjectName.xcodeproj/project.pbxproj
*merge any other broken files*
hg commit -m "manually merged with trunk"
#!/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
.gitattributes
解决方案相同的结果。 - Piotr Wittchen我遇到了一个棘手的问题。
不必手动处理这些冲突,你可以尝试这样做。
假设你在特性分支上。
project.pbxproj
project.pbxproj
)Run
react-native link