Proyectos dentro de proyectos usando Git

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

p.ej. Estoy trabajando en una aplicación de maps 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 files 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 un proyecto.

Pasé algún time tratando de entender los submodules, pero parecen tener demasiada independencia para lo que se necesita.

Además, de ser posible, sería bueno que cada uno de esos proyectos pudiera contener uno o dos scripts superpuestos. ¿Podría un proyecto de Git include un file que no forma parte de su 'raíz' para que cuando ambos equipos actualicen ambos files, 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.

editar:

Para explicar por qué no quiero Submodules:

  1. Cuando los usuarios descargan, el zip no incluye los submodules ( aquí y aquí ). Lo mismo ocurre cuando incluso los queueboradores intentan configurar el proyecto. Este es un show stopper.
  2. Los submodules están congelados, no recogen (fácilmente) la última versión del proyecto al que se apunta.
  3. Otras razones, como se señala en las respuestas fantásticas a continuación y en este monólogo en NoPugs .

La fusión de subtreees (presentada por Paul, a continuación) no funcionará: es difícil actualizar la fuente [de un subtree] dentro del proyecto en el que se fusiona, y esa fuente debe residir fuera de la carpeta 'raíz' de el 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 testings y actualizaciones se realicen directamente dentro de esa carpeta. (Espero que esto sea claro y útil para otros).

Aún estudiando la creación de "sucursales remotas", pero otras ideas son bienvenidas.

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

Hay dos posibilidades que mantienen los subproyectos como repositorys git independientes que extrae de su repository principal (de integración):

  • Utilizando la combinación de subtree para llevar sus proyectos externos a subdirectorys separados en su repository principal que incluye sus files 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 include dependencies de proyecto, pero no funcionaría tan bien con los files compartidos. Otra explicación simple (enlace fijo) .

  • Configure cada proyecto como una twig remota en su repository principal y fusione desde cada uno de ellos en su twig master (integración) que también contiene sus files centrales. Esto requiere cierta disciplina: si realiza cambios en los proyectos externos en su repository principal, se deben realizar en la sucursal y luego fusionarse en el maestro; y nunca deseas fusionarte en las twigs del proyecto. Esto hace que sea fácil enviar cambios a los proyectos externos y es un uso perfectamente aceptable de las sucursales en Git.

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

Si intenta ejecutar SVN y Git en el mismo directory, hace que sea muy difícil utilizar la bifurcación en cualquiera de los sistemas, ya que SVN realiza la bifurcación copyndo directorys de files mientras Git rastrea los pointers. Ningún sistema vería automáticamente las twigs que creas en el otro. Creo que la "solución" es más problemática de lo que vale.

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 repository de subversión en sourceforge.

Usé git-submodule y git-svn y funcionó razonablemente bien. Los inconvenientes fueron:

  1. Para mantenerme actualizado con el repository de la biblioteca, tuve que realizar un nuevo compromiso para actualizar el submodule git hash "puntero". Esto se debe a que los submodules 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 submodules 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 comstackr / ejecutar / probar su código.

  3. Si usas la línea de command, es fácil arruinar tu repository con git-add. Esto se debe a que escribe git add subm<tab> para completar git add submodule , pero se completa automáticamente a git add submodule/ – observe la barra inclinada final. Si ejecuta el command con la barra inclinada, entonces carga el submodule y agrega todos sus files contenidos. Esto se mitiga mediante el uso de git-gui, git add . o simplemente entrenarte para eliminar la barra (me pasó las veces que me entrené para eliminarla)

  4. Los commit de submodules pueden arruinar git rebase -i. Olvidé los detalles exactos, pero es especialmente malo si tienes un submodule "sucio" y ejecutas un rebase interactivo. Normalmente con un tree sucio no se puede volver a establecer la base, pero los submodules no se verifican. Tener varias confirmaciones de submodule en un grupo de rebase también causa problemas. El último hash del submodule se compromete con la primera selección en su list, 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 submodule …) pero puede ser un PITA.

Los pasos para configurar esto fueron algo así como:

  1. Ejecute git svn clone https://project.svn.sourceforge.net/svnroot/project/project/trunk
  2. Presiona eso como un proyecto de git "real" para, por ejemplo, github
  3. Ahora en tu propio repository git, ejecuta el git submodule init
  4. git submodule add git://github.com/project subproject
  5. Empuja eso también, a tu propio repository esta vez.

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

Cada vez que necesite actualizar el código geomapping, 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 muchos tutoriales sobre el flujo de trabajo de un submodule de git, así que espero que esto te ayude a decidir.

De lo poco que he leído sobre Externals , parece ser un puerto de SVN 'external' para GIT.

Esto resuelve algunos de los problemas con los submodules de GIT, incluida la actualización a la última versión de forma automática.

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

Alternativamente, el siguiente software (parece que se puede usar con GitHub). Puede ser otra forma de despellejar al gato: Braid ( página de Softpedia )

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

Incluso si no tiene herramientas que hagan este tipo de suposiciones, un buen layout de repository requiere que se rompa un poco 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 de forma independiente o reutilizar. una gran franja de código dentro de algún proyecto independiente.

Extraer alguna subsección de un repository 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 el futuro.

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 submodules. 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.