如何在Xcode中正确使用Git?


94

我曾经是iPhone开发人员,有一段时间了,最​​近我在工作流程中加入了git。到目前为止,我已经在http://shanesbrain.net/2008/7/9/using-xcode-with-git上找到了我的工作流程中使用的git设置。

这些设置告诉git从合并中排除* .pbxproj吗?是否有这样做的真正原因?例如,当我将一个文件添加到项目中并推送到源时,同伴开发人员在提取时不会将该文件添加到他们的xcode项目中。然后,如果其中一个构建了发行版,则可能不包含该文件。我不应该让git处理项目文件的合并吗?为什么或为什么不应该将此文件合并,以及在将文件添加到项目时如何正确处理这种情况?


9
我不使用XCode,但是如果* .pbxproj文件类似于Visual Studio的* .csproj文件(某种程度的文件列表),那么该设置对我来说似乎是很愚蠢的。听起来好像有人厌倦了合并冲突,因为两个人将文件添加到项目中,并认为最好的解决方案是搞砸一切……
R. Martinho Fernandes

XCode的问题(对于Visual Studio不确定)是.pbxproj文件几乎不可读,因此手动解决冲突没有任何意义。
汤姆(Tom)2010年

7
* .pbxproj文件实际上结构良好,在块末尾和开始段之间只有很长的一段路程。节省的好处是该文件的换行符位置很好,因此仅修改行和自动合并通常就可以很好地解决它。这也意味着合并块通常很容易理解-您可以看到一侧添加了几组文件,另一侧添加了不同组的文件。
Kendall Helmstetter Gelner'4

Answers:


136

自从SDK推出以来,我就全职从事iPhone应用程序的工作,大部分时间都花在与多个开发人员一起工作的团队中。

事实是,禁止合并该.pbxproj文件有害无益。如您所说,当您添加文件时,除非其他人获得了该文件,否则他们也必须将其添加到他们的项目中-在任何大小的应用程序中,这都很糟糕,并且还剥夺了源代码控制的巨大好处,因为您仅仅通过git就无法真正还原到完整的早期项目状态。

.pbxproj文件只是一个属性列表(类似于XML)。根据经验,如果两个人同时添加文件,您可能会遇到的唯一合并冲突就是。在99%的合并冲突案例中,解决方案是保留合并的两面,对于git而言,至少简单地涉及删除任何>>>>,<<<<和====行。实际上,这是如此普遍,以至于我创建了一个简单的shell脚本来将git的.pbxproj文件修复为合并状态,我从项目目录(在“类”级别)运行此脚本:

#!/bin/sh

    projectfile=`find -d . -name 'project.pbxproj'`
    projectdir=`echo *.xcodeproj`
    projectfile="${projectdir}/project.pbxproj"
    tempfile="${projectdir}/project.pbxproj.out"
    savefile="${projectdir}/project.pbxproj.mergesave"

    cat $projectfile | grep -v "<<<<<<< HEAD" | grep -v "=======" | grep -v "^>>>>>>> " > $tempfile
    cp $projectfile $savefile
    mv $tempfile $projectfile

最坏的情况是,如果失败(您要求XCode加载项目而加载失败),则只需删除.pbxproj文件,从git中检出master文件,然后重新添加文件。但是在使用此脚本的许多个月中,我从未发生过这种情况,再次与其他几位开发人员一起在iPhone应用程序上全职工作。

您可以尝试代替脚本使用的另一种方法(在下面的注释中指出),是将此行添加到.gitattributes文件中:

*.pbxproj text -crlf -diff -merge=union

然后git将始终对.pbxproject文件进行合并的两面,其效果与我仅在不进行任何额外工作的情况下提供的脚本相同。

最后,这是我完整的.gitignore文件,显示了我将其设置为忽略的内容,因为有一些您不需要的东西-在我的情况下,实际上只是emacs残余和整个构建目录:

# xcode noise
build/*
*.pbxuser
*.mode1v3
*~

# old skool
.svn

# osx noise
.DS_Store
profile

3
您是否为您的xcode项目使用了.gitattributes文件?并感谢您的见解。我认为将来尝试合并pbxproj文件会容易得多。
rickharrison 2010年

1
到目前为止,尽管其中的某些方面看起来很有趣,但到目前为止我们还没有做到这一点-但是我与之共事的人还不是git高级用户,因此对高级功能的拥护并不强烈。
Kendall Helmstetter Gelner'4

1
“ .pbxproj文件只是JSON(类似于XML)。” 实际上,这是一个OpenStep格式的属性列表。与JSON的基本思路相同,但语法在某些地方有所不同。
Peter Hosey

1
要尝试的另一件事-设置merge = union: stackoverflow.com/questions/2729109/...
肯德尔黑尔姆施泰特Gelner

1
我同意@KendallHelmstetterGelner而非运行脚本,从而消除这些特殊的线,你可以更新与您.gitattribute union开关:*.pbxproj text/plain -crlf -diff -merge union
Besi 2012年


8

坦白说,现有的答案具有误导性。

如果您从不删除或重命名文件,那么使用merge=union直接组合不同提交中的差异的策略是一个好主意。

但是,在现实世界中,有时确实需要删除或重命名文件。合并差异而不进行任何修改会带来很多问题在这种情况下,,这些问题通常会导致“工作空间完整性-无法加载项目”问题,这甚至使您无法运行该项目。

到目前为止,我得到的最好的解决方案是:

1)精心设计项目,并在开始时添加所有需要的文件,因此您几乎不需要更改 project.pbxproj

2)使您的功能微不足道。不要在分支机构中做太多事情。

3)出于任何原因,如果您需要修改文件结构并引起冲突project.pbxproj,请使用您喜欢的文本编辑器手动解决。当您使任务变得微不足道时,冲突可能很容易解决。


3

简短的答案是,即使您不包括该行.gitattributes,也可能无法轻松合并.pbxproj的两个修改版本。git最好将其视为二进制文件。

有关详细信息,请参见此处:Git和pbxproj

更新:即使git书仍然同意这个答案,但我不再这样做。我.pbxproj像其他任何非二进制源文件一样对我进行版本控制。


听起来您可以设置一个提交过滤器以通过文件simplejson或通过这种方式将文件发送到索引。仍然不能保证它能正常工作。
直觉

1
这不是JSON格式的文件。外观相似,但细节上有许多不同。
12

它在git书中说了它的JSON,但看起来好像是错误的。git-scm.com/book/ch7-2.html
huggie 2012年

1
好。.pbxproj该文件实际上是一个旧样式的NeXT / Cocoa PList文件,该文件较旧,并且比JSON定义的时间要早​​得多,现在被Apple弃用。(但是他们在某些地方仍在使用它)书中提到文件是完全错误的。我删除了否决票,因为您明确提到了它。
2013年

2

我确实创建了一个Python脚本,可以处理XCode Project文件中的合并冲突。

如果您想尝试一下,可以在这里查看:https : //github.com/simonwagner/mergepbx

您将必须将其安装为合并驱动程序,因此当您在项目文件中发生合并冲突时,它将自动被调用(README.md将告诉您如何执行此操作)。

它应该比使用merge=unionas 更好mergepbx理解项目文件的语义,因此可以正确解决冲突。

但是该项目仍然是Alpha版本,不要指望它能理解那里的每个项目文件。

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.