web-dev-qa-db-ja.com

XcodeでGitを適切に使用するには?

私はしばらくの間iPhone開発者であり、最近ワークフローにgitを含めています。これまでのワークフローでは http://shanesbrain.net/2008/7/9/using-xcode-with-git にあるgit設定を使用しました。

これらの設定は、gitに* .pbxprojをマージから除外するように指示しますか?これを行う本当の理由はありますか?たとえば、プロジェクトにファイルを追加し、Originにプッシュすると、仲間の開発者がプルしたときにそのファイルがxcodeプロジェクトに追加されません。その後、それらの1つがリリースをビルドする場合、このファイルは含まれない可能性があります。 gitにプロジェクトファイルのマージを処理させるだけではいけませんか?このファイルをマージする必要があるのはなぜですか?また、ファイルをプロジェクトに追加するときの状況を適切に処理する方法は?

90
rickharrison

私はSDKの発売以来、iPhoneアプリケーションにフルタイムで取り組んできましたが、そのほとんどの時間は複数の開発者がいるチームで働いていました。

真実は、.pbxprojファイルのマージを許可するよりも、それが役立つよりもずっと有害であるということです。あなたが言うように、他の人がそのファイルを取得しない限り、あなたがファイルを追加するとき、彼らはそれを彼らのプロジェクトに追加しなければなりません-任意のサイズのアプリケーションで、それはあなたがソースコード管理の大きな利点を奪いますgitだけでは完全に以前のプロジェクト状態に戻すことはできません。

.pbxprojファイルは、単なるプロパティリストです(XMLに似ています)。経験から、ちょうど2人が同時にファイルを追加した場合に発生するのは、マージ競合のみです。マージの競合ケースの99%での解決策は、マージの両側を維持することです。gitでは、少なくとも>>>>、<<<<、および====行を削除するだけです。実際、これは非常に一般的であるため、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からマスターをチェックアウトし、ファイルを再度追加します。しかし、私はこのスクリプトで何ヶ月も使用したことがありませんでした。また、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

これは、Xcode 4.6およびGit 1.7.5で機能します。

これで.gitattributesファイルを追加してコミットします。

*.pbxproj binary merge=union

私は別のチームメンバーでこれをテストしましたが、うまく機能します。

から取得: http://robots.thoughtbot.com/post/33796217972/xcode-and-git-bridging-the-gap

9
oneyenjug

率直に言って、既存の答えは誤解を招くものです。

ファイルを削除または名前変更するneverの場合、異なるコミットの違いを直接組み合わせるmerge=union戦略を使用することをお勧めします。

ただし、現実の世界では、ファイルを削除または名前変更する必要がある場合があります。変更せずに差分をマージすると、これらの状況では多くの問題になり、これらの問題は通常「ワークスペース整合性-プロジェクトを読み込めませんでした」という問題が発生し、プロジェクトを実行できなくなります。

私がこれまでに得た最高のソリューション:

1)プロジェクトを適切に設計し、最初に必要なすべてのファイルを追加するので、project.pbxprojを変更する必要はほとんどありません。

2)機能を小さくします。ブランチであまり多くのことをしないでください。

3)何らかの理由で、ファイル構造を変更してproject.pbxprojの競合を取得する必要がある場合は、お好みのテキストエディターを使用して手動で解決してください。タスクを小さくすると、競合を簡単に解決できる場合があります。

6
Brian

簡単な答えは、その行を.gitattributesに含めなくても、.pbxprojの2つの変更されたバージョンを簡単にマージできない場合があるということです。 gitがバイナリとして扱う方が良いです。

詳細はこちらをご覧ください: Git and pbxproj

更新:git book それでも同意する がこの答えになったとしても、私はもうしません。 .pbxprojは、他の非バイナリソースファイルと同様にバージョン管理します。

3
Tom

XCode Projectファイルのマージの競合を処理できるPythonスクリプトを作成しました。

試してみたい場合は、こちらで確認できます: https://github.com/simonwagner/mergepbx

マージドライバーとしてインストールする必要があるため、プロジェクトファイルでマージの競合が発生すると自動的に呼び出されます(README.mdにその方法が表示されます)。

mergepbxはプロジェクトファイルのセマンティクスを理解しているため、merge=unionを使用するよりもうまく動作するはずです。したがって、競合は正しく解決されます。

ただし、プロジェクトはまだアルファ版であり、そこにあるすべてのプロジェクトファイルを理解することを期待しないでください。

2
Simon