2009-04-06 11 views
22

¿Cómo configuro un proyecto de Git para que contenga otros proyectos?Proyectos dentro de proyectos usando Git

por ejemplo. Estoy trabajando en una aplicación de mapas en línea. Desarrollamos una herramienta GPS junto con un equipo en SF. Desarrollamos simultáneamente un script de Geomapping de Python junto con una preocupación diferente (que solo se preocupa por geomapping). Nuestros propios archivos centrales unen los dos y se basan en ellos para la aplicación que necesitamos.

Cada uno de los proyectos debe existir solo; las personas que tienen interés en el GPS solo tienen interés en el GPS, pero el proyecto "principal" que incluye a todos los demás debe estar accesible como proyecto.

He pasado algún tiempo tratando de entender los submódulos, pero parecen tener demasiada independencia para lo que se necesita.

Además, si es posible, sería bueno si cada uno de esos proyectos pudiera contener uno o dos scripts superpuestos. ¿Podría un proyecto de Git incluir un archivo que no forma parte de su 'raíz' para que cuando ambos equipos actualicen ambos archivos, ambos puedan beneficiarse?

¿Es esto factible con Git? Con Mercurial? ¿Importa el anfitrión (GitHub, Gitorious)?

Tengo la idea de usar Subversion para el 'padre' - ignorando las carpetas .git, y usando Git para los proyectos (ignorando las carpetas .svn) - pero eso es solo un último recurso.

edición:

Para explicar por qué no quiero submódulos:

  1. Cuando los usuarios descargan, la cremallera no incluye los submódulos (here & here). Lo mismo cuando incluso los colaboradores intentan configurar el proyecto. Este es un show stopper.
  2. Los submódulos están congelados, no retoman (fácilmente) la última versión del proyecto que se está señalando.
  3. Otras razones como se señala en las respuestas fantásticas a continuación y en este monologue at NoPugs.

Subtree-merging (presentado por Paul, a continuación) no funcionará: es difícil actualizar la fuente [de un subárbol] dentro del proyecto en el que se fusiona, y esa fuente debe residir fuera de la carpeta 'raíz' del proyecto. Al ser una aplicación web, es vital que todas mis páginas se vinculen internamente a una carpeta dentro de ellas, y que las pruebas y actualizaciones se realicen directamente dentro de esa carpeta. (Espero que esto sea claro y útil para otros.)

Todavía estudiando la configuración de "sucursales remotas", pero otras ideas siguen siendo bienvenidas.

+0

Las razones por las que estoy en contra de git-submodule: a) No puedo hacer que funcione. GIT Bash simplemente cuelga el comando para agregar el submódulo. b) Los submódulos deben actualizarse de manera independiente. Mejor para mí tener la última versión de los submódulos automáticamente. c) ¿Los submódulos tienen el código real o un puntero? – SamGoody

+0

Paul - Tienes tutoriales para el segundo método. Estoy encontrando a GIT lo suficientemente difícil. Además, ¿Importa que los subproyectos se almacenen localmente dentro del proyecto principal con estos métodos (superclase/clases/subproyecto1)? – SamGoody

+1

El método de Subárbol necesita tenerlos en un subdirectorio separado, pero eso puede ser en cualquier lugar. Git rastrea todo el árbol del proyecto en lugar de archivos individuales, por lo que cualquier disposición de archivos funciona para el método de bifurcación remota. No sé de una reseña del último método; Agregué enlaces para el método de subárbol. – Paul

Respuesta

13

no he encontrado submódulos que son particularmente útiles en los (pequeños) proyectos que he trabajado . Una vez que los haya configurado, trabajar en todo el proyecto requiere agregar parámetros adicionales a casi todos los comandos y la sintaxis no es completamente regular. Me imagino que si trabajara en proyectos más grandes con más submódulos, lo vería como una compensación más beneficiosa.

Hay dos posibilidades que mantienen a los sub-proyectos como repositorios Git independientes que se tira de en tu repositorio principal (integración):

  • Usando subárbol fusionarto bring your external projects into separate subdirectories en tu repositorio principal que incluye su archivos centrales Esto hace que sea fácil actualizar el proyecto principal desde los proyectos externos, pero es complicado enviar los cambios a los proyectos externos. Pienso en esto como una buena forma de incluir dependencias de proyecto, pero no funcionaría tan bien con los archivos compartidos. Another simple explanation (link fixed).

  • Configure cada proyecto como una rama remota en tu repositorio principal y se funden entre cada uno de ellos en su rama master (integración) que también contiene sus archivos principales. Esto requiere cierta disciplina: si realiza cambios en los proyectos externos en su repositorio principal, se deben realizar en la sucursal y luego fusionarse en el maestro; y nunca deseas fusionarte en las ramas del proyecto. Esto facilita el envío de cambios a los proyectos externos y es un uso perfectamente aceptable de las sucursales en Git.

    Sus scripts compartidos pueden manejarse como otra rama independiente en su directorio principal desde la cual sus socios externos pueden extraer y presionar como una rama remota.

Si intenta ejecutar SVN & Git en el mismo directorio, que hacen que sea muy difícil de usar ramificación en uno u otro sistema, porque no SVN ramificación mediante la copia de los archivos y directorios Git punteros. Ningún sistema vería automáticamente las ramas que creas en el otro. Creo que la "solución" es más problemática de lo que vale.

+0

Después de mucho tiempo de intentarlo, todavía no puedo hacer funcionar su segundo método. Configurar la rama y fusionarla estaba bien, pero más allá de eso estoy perdido. ¿Sería posible describir un flujo de trabajo más completo? ¿Sería apropiado preguntar esto como su tema y comenzar un nuevo hilo? – SamGoody

+0

¿Qué estás tratando de hacer que no puedes? Básicamente está creando ramas de proveedores, que son bastante comunes en svn. (En realidad, la 'rama de proveedor' parece tener dos usos diferentes: un informe incluido de un proveedor como usted lo desea, o una rama de publicación para un proveedor específico.) Estoy viajando con muy poco acceso a la red, pero intentaré obtener algo más escrito para esto. – Paul

+0

Comencé un nuevo hilo sobre el tema en http://stackoverflow.com/questions/769786/vendor-branches-in-git, disculpe mi evidente frustración allí. Muchas gracias. – SamGoody

3

He usado git para unir mi propio proyecto alojado en github y una biblioteca de UI externa que quería usar. La biblioteca está alojada en un repositorio de subversión en sourceforge.

Utilicé git-submodule y git-svn y funcionó bastante bien. Los inconvenientes fueron:

  1. Con el fin de mantenerse al día con el repositorio biblioteca, que tuvo que realizar una nueva comprometen a actualizar el submódulo git de hash "puntero". Esto se debe a que los submódulos de git, a diferencia de svn: externals, están anclados a una identificación de confirmación particular. Esto puede no ser un inconveniente real si realmente quieres fijar una versión estable, estaba trabajando con código que era WIP.

  2. La extracción inicial de un git repo con submódulos requiere un paso adicional con "git submodule init". Esto no es un problema para usted, pero para otros que usen su código deberán recordar o se les pedirá que realicen este paso antes de compilar/ejecutar/probar su código.

  3. Si utiliza la línea de comandos, es fácil arruinar su repositorio con git-add. Esto se debe a que escribe git add subm<tab> para completar a git add submodule, pero se completa automáticamente a git add submodule/ - tenga en cuenta la barra al final. Si ejecuta el comando con la barra inclinada, entonces carga el submódulo y agrega todos sus archivos contenidos. Esta es mitigado mediante el uso de git-gui, git add . o simplemente entrenarse para eliminar la barra (me ha pasado tantas veces que me entrené para eliminarlo)

  4. submódulos comete lío lata hasta git rebase -i. Olvidé los detalles exactos, pero es especialmente malo si tienes un submódulo "sucio" y ejecutas un rebase interactivo.Normalmente con un árbol sucio no se puede volver a establecer la base, pero los submódulos no se verifican. Tener varias confirmaciones de submódulo en un grupo de rebase también causa problemas. El último hash del submódulo se compromete con la primera selección en su lista, y esto es bastante complicado de arreglar más tarde. Esto se puede solucionar con un flujo de trabajo más cuidadoso (es decir, decidiendo cuidadosamente cuándo realizar los commit de su submódulo ...) pero puede ser un PITA.

Los pasos para configurar esto eran algo a lo largo de las líneas de:

  1. Run git svn clone https://project.svn.sourceforge.net/svnroot/project/project/trunk
  2. empuje que como un proyecto Git "real" para, por ejemplo, github
  3. Ahora en su propio repositorio git, ejecute git submodule init
  4. git submodule add git://github.com/project subproject
  5. empuje que fuera también, a su propio repo este momento.

Eso es todo, más o menos. Tendrás un nuevo "subproyecto" de directorio, que en tu caso sería la biblioteca geomapping.

Cada vez que usted necesita para actualizar el código geomapping, tendría que ejecutar algo como:

cd subproject 
git svn rebase 
git svn push # this updates the git mirror of the subproject 
cd .. 
git add subproject # careful with the trailing slash! 
git commit -m "update subproject" 
git push # this pushes the commit that updates the subproject 

No he visto a muchos tutoriales en un flujo de trabajo git submódulo, así que espero que esto ayude a decidir.

+0

Bonito escrito. No uso submódulos, en gran parte debido a tus puntos 3 y 4. Creo que lo has hecho tan simple como puede ser. Algún día habrá una porcelana que maneja los submódulos de manera intuitiva. – Paul

+0

De acuerdo. Una vez que te das cuenta de que en realidad están simplemente inmovilizados svn: externos, es bastante fácil. Las trampas hasta que asimilas submódulos son enormes verrugas en la IU. – richq

1

Por lo poco que he leído sobre Externals, parece ser un puerto de SVN 'externos' a GIT.

Esto resuelve algunos de los problemas con los submódulos GIT, incluida la actualización a la última versión automáticamente.

Si bien no tengo experiencia con SVN Externals o con este proyecto, podría ser una mejor solución para algunos de los publicados.

Alternativamente, el siguiente software (parece que se puede usar con GitHub). Puede ser otra manera para algunos a la piel del gato: Braid (Softpedia page)

+0

Parece interesante, gracias por el enlace – richq

0

Depende de qué tipo de proyecto que está trabajando, y qué herramientas, en su caso, la necesidad de interactuar con el SMC. Rails, por ejemplo, a menudo usa Capistrano para implementar, y Capistrano hace ciertas suposiciones sobre cómo se verá la estructura de su directorio en relación con la raíz de su repositorio. En este caso, si tiene varias aplicaciones de rieles interrelacionadas, debe usar submódulos. Cada aplicación tiene su propio repositorio, y luego tienes un repositorio más grande que administra cada uno de los repositorios independientes como submódulos.

Incluso si no tiene herramientas que hagan este tipo de suposiciones, un buen diseño de repositorio requiere que rompa un poco las cosas si existe la más mínima posibilidad de que algún día quiera usar una subsección de un proyecto más grande independientemente, o reutilizar una gran franja de código dentro de algún proyecto independiente.

Extraer alguna subsección de un repositorio como su propia entidad separada mientras se mantiene el historial de versiones es difícil en git, por lo que es una buena idea planificar con anticipación.

En cuanto a su pregunta específica, sinceramente, yo llamaría a eso un ejemplo perfecto de dónde sería ideal un par de submódulos.Con respecto a compartir scripts, si por alguna razón eso es realmente un problema que resulta problemático, siempre puedes usar un enlace simbólico.

+0

¿Cómo usaría un enlace simbólico para ofrecer una descarga del programa completo, incluidos los submódulos? El término "enlace simbólico" es nuevo para mí (un usuario de Win/Mint) pero de un Google rápido no veo qué resolvería. Y mi entorno es PHP, con la consideración de mudarme a Python (TurboGears). – SamGoody

+0

El lenguaje de programación es irrelevante en este caso, pero obviamente, Windows no tiene enlaces simbólicos. Aunque para poder ejecutar git, necesitas enlaces simbólicos para empezar, y creo que el puerto de git para Windows básicamente obtiene ese enlace simbólico a través de msys. Esencialmente, si el proyecto A necesita un script que esté en el proyecto B, pero son submódulos separados, puede crear un enlace simbólico dentro del proyecto A al script en el proyecto B, y verificar el enlace simbólico en git. El enlace simbólico debe ser relativo. –

Cuestiones relacionadas