¿Cómo usar Git correctamente con Xcode?

94

He sido desarrollador de iPhone por un tiempo y recientemente he incluido git en mi flujo de trabajo. He utilizado la configuración de git que se encuentra en http://shanesbrain.net/2008/7/9/using-xcode-with-git para mi flujo de trabajo hasta ahora.

¿Esas configuraciones le dicen a git que excluya * .pbxproj de las fusiones? ¿Existe una razón real para hacer esto? Por ejemplo, cuando agrego un archivo al proyecto y lo envío al origen, mis compañeros desarrolladores no tendrán ese archivo agregado a su proyecto xcode cuando extraigan. Entonces, si uno de ellos crea una versión, es posible que este archivo no se incluya. ¿No debería dejar que git maneje las fusiones para el archivo del proyecto? ¿Por qué o por qué no este archivo debería estar en fusiones y cómo manejar adecuadamente la situación cuando se agregan archivos al proyecto?

Rickharrison
fuente
9
No trabajo con XCode, pero si los archivos * .pbxproj son como los archivos * .csproj de Visual Studio (algo así como una lista de archivos), esta configuración me parece bastante idiota. Parece que alguien estaba cansado de los conflictos de fusión cuando dos personas agregaron archivos al proyecto y pensaron que la mejor solución era arruinar todo ...
R. Martinho Fernandes
El problema con XCode (no estoy seguro acerca de Visual Studio) es que los archivos .pbxproj apenas son legibles por humanos, por lo que no tiene sentido resolver los conflictos a mano.
Tom
7
* Los archivos .pbxproj están bastante bien estructurados, solo tiene largos tramos entre el final del bloque y los segmentos de inicio. La salvación es que el archivo tiene saltos de línea muy bien colocados, por lo que es difícil estropearlo simplemente modificando líneas y la combinación automática generalmente funciona muy bien. También significa que los bloques de combinación son generalmente fáciles de entender: puede ver un lado con algunos conjuntos de archivos agregados y el otro con diferentes conjuntos de archivos agregados.
Kendall Helmstetter Gelner

Respuestas:

136

He trabajado en aplicaciones de iPhone a tiempo completo desde el lanzamiento del SDK, la mayor parte de ese tiempo lo he pasado trabajando en equipos con varios desarrolladores.

La verdad es que es mucho más dañino no permitir la fusión de ese archivo .pbxproj que útil. Como dice, cuando agrega un archivo a menos que otras personas obtengan ese archivo, también tienen que agregarlo a su proyecto, en una aplicación de cualquier tamaño, eso apesta y también quita un gran beneficio del control del código fuente en el sentido de que usted realmente no puede volver a un estado de proyecto anterior completo solo a través de git.

El archivo .pbxproj es simplemente una lista de propiedades (similar a XML). Por experiencia, el ÚNICO conflicto de fusión que ha tenido es si dos personas han agregado archivos al mismo tiempo. La solución en el 99% de los casos de conflicto de fusión es mantener ambos lados de la fusión, que para git al menos simplemente implica eliminar cualquier línea >>>>, <<<< y ====. De hecho, esto es tan común que he creado un script de shell simple para arreglar un archivo .pbxproj en un estado de fusión desde git, lo ejecuto desde el directorio del proyecto (en el nivel de Clases):

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

En el peor de los casos, si falla (le pide a XCode que cargue el proyecto y no se carga), simplemente elimine el archivo .pbxproj, consulte el maestro de git y vuelva a agregar sus archivos. Pero nunca me ha pasado eso en muchos meses de uso con este script, nuevamente trabajando a tiempo completo en aplicaciones de iPhone con varios otros desarrolladores.

Otra opción (señalada en los comentarios a continuación) que puede intentar usar en lugar del script es agregar esta línea a un archivo .gitattributes:

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

Luego, git siempre tomará ambos lados de una combinación para los archivos .pbxproject, teniendo el mismo efecto que el script que proporcioné solo sin ningún trabajo adicional.

Por último, aquí está mi archivo .gitignore completo, que muestra lo que tengo configurado para ignorar, ya que hay algunas cosas que no desea, en mi caso, solo los restos de emacs y todo el directorio de compilación:

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

# old skool
.svn

# osx noise
.DS_Store
profile
Kendall Helmstetter Gelner
fuente
3
¿Utiliza un archivo .gitattributes para su proyecto xcode? Y gracias por tu conocimiento. Creo que será mucho más fácil intentar fusionar los archivos pbxproj en el futuro.
rickharrison
1
Hasta la fecha no lo hemos sido, aunque algunos aspectos parecen interesantes, pero las personas con las que he trabajado no han sido usuarios avanzados de git, por lo que la defensa de las características avanzadas no es fuerte.
Kendall Helmstetter Gelner
1
"El archivo .pbxproj es simplemente JSON (similar a XML)". En realidad, es una lista de propiedades con formato OpenStep. Las mismas ideas básicas que JSON, pero la sintaxis difiere en algunos lugares.
Peter Hosey
1
Otra cosa para intentar: establecer merge = union: stackoverflow.com/questions/2729109/…
Kendall Helmstetter Gelner
1
Estoy de acuerdo con @KendallHelmstetterGelner en lugar de ejecutar la secuencia de comandos, que elimina las líneas especiales, se podría actualizar su .gitattribute con el unioninterruptor: *.pbxproj text/plain -crlf -diff -merge union.
Besi
8

Francamente, las respuestas existentes son engañosas.

Si nunca elimina o cambia el nombre de los archivos, entonces merge=uniones una buena idea usar la estrategia, que solo combina las diferencias en diferentes confirmaciones directamente.

Sin embargo, en el mundo real, a veces necesitamos eliminar o cambiar el nombre de los archivos. Fusionar las diferencias sin ninguna modificación crearía muchos problemas en estas situaciones, y estos problemas generalmente conducen al problema "Integridad del espacio de trabajo: no se pudo cargar el proyecto", lo que hace que ni siquiera pueda ejecutar el proyecto.

La mejor solución que obtuve hasta ahora:

1) Diseñe bien el proyecto y agregue todos los archivos necesarios al principio, por lo que rara vez necesitará cambiar el project.pbxproj.

2) Haz que tus rasgos sean pequeños. No hagas demasiadas cosas en una sucursal.

3) Por cualquier motivo, si necesita modificar la estructura del archivo y obtener conflictos project.pbxproj, use su editor de texto favorito para resolverlos manualmente. A medida que reduzca sus tareas, los conflictos pueden ser fáciles de resolver.

Brian
fuente
3

La respuesta corta es que incluso si no incluye esa línea .gitattributes, es posible que no pueda fusionar fácilmente dos versiones modificadas de un .pbxproj. Es mejor que git lo trate como un binario.

Consulte aquí para obtener más detalles: Git y pbxproj

Actualización: aunque el libro de git todavía está de acuerdo con esta respuesta, yo ya no lo hago. Yo controlo mi versión .pbxprojcomo cualquier otro archivo fuente no binario.

Tom
fuente
Parece que podría configurar un filtro de confirmación para enviar el archivo simplejsono algo más ordenado en su camino hacia el índice. Sin embargo, todavía no estaría garantizado que funcione.
intuido el
1
No es un archivo con formato JSON. Parece similar pero tiene muchas diferencias en los detalles.
eonil
Dice su JSON en el libro de git, pero parece que está mal. git-scm.com/book/ch7-2.html
huggie
1
OKAY. .pbxprojfile es en realidad un archivo NeXT / Cocoa PList de estilo antiguo, que es más antiguo y está definido mucho antes que JSON, y ahora está desaprobado por Apple. (pero todavía lo están usando en algunos lugares) La mención sobre el archivo en el libro es completamente incorrecta. Eliminé el voto en contra porque lo mencionaste explícitamente.
eonil
2

Creé una secuencia de comandos de Python que puede manejar conflictos de fusión en archivos de XCode Project.

Si quieres probarlo, puedes consultarlo aquí: https://github.com/simonwagner/mergepbx

Tendrá que instalarlo como un controlador de fusión, por lo que se llamará automáticamente cuando tenga un conflicto de fusión en su archivo de proyecto (el archivo README.md le dirá cómo hacerlo).

Debería funcionar mucho mejor que usar merge=unioncomo mergepbxentiende la semántica de su archivo de proyecto y, por lo tanto, resolverá el conflicto correctamente.

Sin embargo, el proyecto sigue siendo alfa, no espere que comprenda todos los archivos de proyecto que existen.

Simón
fuente