Comment utiliser correctement Git avec Xcode?

94

Je suis développeur iphone depuis un certain temps et j'ai récemment inclus git dans mon workflow. Jusqu'à présent, j'ai utilisé les paramètres git trouvés sur http://shanesbrain.net/2008/7/9/using-xcode-with-git pour mon flux de travail.

Ces paramètres indiquent à git d'exclure * .pbxproj des fusions? Y a-t-il une vraie raison de faire cela? Par exemple, lorsque j'ajoute un fichier au projet et le pousse à l'origine, mes collègues développeurs n'auront pas ce fichier ajouté à leur projet xcode lorsqu'ils tirent. Ensuite, si l'un d'eux crée une version, ce fichier peut ne pas être inclus. Ne devrais-je pas laisser git gérer les fusions du fichier projet? Pourquoi ou pourquoi pas ce fichier devrait-il être en fusion et comment gérer correctement la situation lorsque des fichiers sont ajoutés au projet?

Rickharrison
la source
9
Je ne travaille pas avec XCode, mais si les fichiers * .pbxproj ressemblent aux fichiers * .csproj de Visual Studio (une sorte de liste de fichiers), ce paramètre me semble plutôt idiot. On dirait que quelqu'un était fatigué des conflits de fusion lorsque deux personnes ont ajouté des fichiers au projet et ont pensé que la meilleure solution était de tout gâcher ...
R. Martinho Fernandes
Le problème avec XCode (pas sûr de Visual Studio) est que les fichiers .pbxproj sont à peine lisibles par l'homme, il n'est donc pas logique de résoudre les conflits à la main.
Tom
7
* Les fichiers .pbxproj sont en fait assez bien structurés, vous avez juste de longs segments entre la fin du bloc et les segments de début. L'avantage est que le fichier a des sauts de ligne très bien placés, il est donc difficile de le gâcher en modifiant simplement les lignes et la fusion automatique fonctionne généralement très bien. Cela signifie également que les blocs de fusion sont généralement faciles à comprendre - vous pouvez voir un côté avec quelques ensembles de fichiers ajoutés, l'autre avec différents ensembles de fichiers ajoutés.
Kendall Helmstetter Gelner

Réponses:

136

J'ai travaillé sur des applications iPhone à plein temps depuis le lancement du SDK, la plupart de ce temps passé à travailler en équipe avec plusieurs développeurs.

La vérité est qu'il est bien plus dangereux d'interdire la fusion de ce fichier .pbxproj que cela n'est utile. Comme vous le dites, lorsque vous ajoutez un fichier à moins que d'autres personnes ne l'obtiennent, ils doivent également l'ajouter à leur projet - dans une application de n'importe quelle taille, c'est nul et cela enlève également un énorme avantage au contrôle du code source en ce que vous ne peut pas vraiment revenir à un état de projet antérieur complet uniquement via git.

Le fichier .pbxproj est simplement une liste de propriétés (similaire à XML). Par expérience, à peu près le SEUL conflit de fusion que vous avez rencontré est si deux personnes ont ajouté des fichiers en même temps. La solution dans 99% des cas de conflit de fusion est de conserver les deux côtés de la fusion, ce qui pour git implique au moins simplement de supprimer toutes les lignes >>>>, <<<< et ====. En fait, c'est si courant que j'ai créé un simple script shell pour corriger un fichier .pbxproj dans un état de fusion à partir de git, je l'exécute depuis le répertoire du projet (au niveau des classes):

#!/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

Dans le pire des cas, si cela échoue (vous demandez à XCode de charger le projet et le chargement échoue), vous supprimez simplement le fichier .pbxproj, extrayez le maître de git et rajoutez vos fichiers. Mais je n'ai jamais eu cela pendant de nombreux mois d'utilisation avec ce script, travaillant à nouveau à plein temps sur des applications iPhone avec plusieurs autres développeurs.

Une autre option (indiquée dans les commentaires ci-dessous) que vous pouvez essayer d'utiliser à la place du script, consiste à ajouter cette ligne à un fichier .gitattributes:

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

Ensuite, git prendra toujours les deux côtés d'une fusion pour les fichiers .pbxproject, ayant le même effet que le script que j'ai fourni uniquement sans aucun travail supplémentaire.

Enfin, voici mon fichier .gitignore complet, montrant ce que je l'ai configuré pour ignorer car il y a quelques choses que vous ne voulez pas - dans mon cas, en réalité, juste les restes d'emacs et tout le répertoire de construction:

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

# old skool
.svn

# osx noise
.DS_Store
profile
Kendall Helmstetter Gelner
la source
3
Utilisez-vous un fichier .gitattributes pour votre projet xcode? Et merci pour votre perspicacité. Je pense qu'il sera beaucoup plus facile d'essayer de fusionner les fichiers pbxproj à l'avenir.
rickharrison
1
À ce jour, nous ne l'avons pas été, bien que certains aspects de cela semblent intéressants - mais les personnes avec lesquelles j'ai travaillé n'ont pas été des utilisateurs avancés de git, et donc la promotion de fonctionnalités avancées n'est pas forte.
Kendall Helmstetter Gelner
1
"Le fichier .pbxproj est simplement JSON (similaire à XML)." En fait, c'est une liste de propriétés au format OpenStep. Mêmes idées de base que JSON, mais la syntaxe diffère à quelques endroits.
Peter Hosey
1
Une autre chose à essayer - set merge = union: stackoverflow.com/questions/2729109/…
Kendall Helmstetter Gelner
1
Je suis d' accord avec @KendallHelmstetterGelner au lieu de l' exécution de votre script, ce qui supprime ces lignes spéciales, vous pouvez mettre à jour votre .gitattribute avec le unioncommutateur: *.pbxproj text/plain -crlf -diff -merge union.
Besi
9

Cela fonctionne pour moi dans Xcode 4.6 et Git 1.7.5.

Ajoutez et validez le fichier .gitattributes avec ceci:

*.pbxproj binary merge=union

J'ai testé cela avec un autre membre de l'équipe et fonctionne très bien.

Tiré de: http://robots.thoughtbot.com/post/33796217972/xcode-and-git-bridging-the-gap

oneyenjug
la source
Merge = union is good mais l'outil mergepbx devrait être la réponse acceptée.
Alper
8

Franchement, les réponses existantes sont trompeuses.

Si vous ne supprimez ou ne renommez jamais de fichiers, alors utiliser la merge=unionstratégie, qui combine directement les différences entre différents commits, est une bonne idée.

Cependant, dans le monde réel, nous devons parfois supprimer ou renommer des fichiers. La fusion des différences sans aucune modification poserait de nombreux problèmes dans ces situations, et ces problèmes conduisent généralement au problème «Intégrité de l'espace de travail - Impossible de charger le projet», ce qui vous empêche même d'exécuter le projet.

La meilleure solution que j'ai eue jusqu'à présent:

1) Concevez bien le projet et ajoutez tous les fichiers nécessaires au début, vous aurez donc rarement besoin de changer le fichier project.pbxproj.

2) Rendez vos fonctionnalités minuscules. Ne faites pas trop de choses dans une succursale.

3) Pour une raison quelconque, si vous devez modifier la structure du fichier et générer des conflits project.pbxproj, utilisez votre éditeur de texte préféré pour les résoudre manuellement. Au fur et à mesure que vous réduisez vos tâches, les conflits peuvent être faciles à résoudre.

Brian
la source
3

La réponse courte est que même si vous n'incluez pas cette ligne .gitattributes, vous ne pourrez peut-être pas facilement fusionner deux versions modifiées d'un .pbxproj. Il vaut mieux que git le traite comme un binaire.

Voir ici pour plus de détails: Git et pbxproj

Mise à jour: même si le livre git est toujours d'accord avec cette réponse, je ne le fais plus. Je contrôle ma version .pbxprojcomme n'importe quel autre fichier source non binaire.

À M
la source
on dirait que vous pourriez mettre en place un filtre de validation pour envoyer le fichier simplejsonou un tel plus propre sur son chemin vers l'index. Cependant, il ne serait toujours pas garanti de fonctionner.
intuité le
1
Ce n'est pas un fichier au format JSON. Cela ressemble mais présente de nombreuses différences dans les détails.
eonil
Il dit son JSON dans le livre git, mais il semble que ce soit faux. git-scm.com/book/ch7-2.html
huggie
1
D'ACCORD. .pbxprojest en fait un ancien fichier NeXT / Cocoa PList, qui est plus ancien et défini beaucoup plus tôt que JSON, et maintenant obsolète par Apple. (mais ils l'utilisent encore à certains endroits) La mention du fichier dans le livre est complètement fausse. J'ai supprimé le vote parce que vous l'avez mentionné explicitement.
eonil le
2

J'ai créé un script Python capable de gérer les conflits de fusion dans les fichiers du projet XCode.

Si vous voulez l'essayer, vous pouvez le vérifier ici: https://github.com/simonwagner/mergepbx

Vous devrez l'installer en tant que pilote de fusion, il est donc appelé automatiquement lorsque vous avez un conflit de fusion dans votre fichier de projet (le README.md vous dira comment faire).

Cela devrait fonctionner beaucoup mieux que d'utiliser merge=unioncomme mergepbxcomprend la sémantique de votre fichier de projet et résoudra donc correctement le conflit.

Cependant, le projet est toujours alpha, ne vous attendez pas à ce qu'il comprenne tous les fichiers de projet qui existent.

Simon
la source