2009-11-28 55 views
224

Tengo un repositorio de medios Git donde guardo todos mis archivos maestros y scripts de JavaScript y CSS que usaré en varios proyectos.¿Cómo trabajo con un repositorio git dentro de otro repositorio?

Si creo un nuevo proyecto que está en su propio repositorio de Git, ¿cómo uso los archivos de JavaScript de mi repositorio de medios en mi nuevo proyecto de manera que no tenga que actualizar ambas copias del script cuando hago cambios?

Respuesta

295

Buena pregunta. La clave es git submódulos.

empezar a leer el capítulo de submódulos de la Git Community Book o de la Users Manual

Digamos que tiene PROJECT1 repositorio, project2, y MEDIA ...

cd /path/to/PROJECT1 
git submodule add ssh://path.to.repo/MEDIA 
git commit -m "Added Media submodule" 

Repita en el otro repo ...

Ahora, lo bueno es que cada vez que realice cambios en MEDIA, puede hacerlo:

cd /path/to/PROJECT2/MEDIA 
git pull 
cd .. 
git add MEDIA 
git commit -m "Upgraded media to version XYZ" 

Esto acaba de registrar el hecho de que el submódulo MEDIA DENTRO DEL PROYECTO2 ahora está en la versión XYZ.

Le da 100% de control sobre qué versión de MEDIA utiliza cada proyecto. Los submódulos de Git son geniales, pero debe experimentar y conocerlos.

Con gran potencia viene la gran posibilidad de ser mordido en la grupa.

+0

Este flujo de trabajo me recuerda el uso de un módulo privado de NPM http://stackoverflow.com/questions/7575627/can-you-host-a-private-repository-for-your-organization-to-use-with- npm # answer-7807279 – cyrf

+0

Si prefiere que la versión predeterminada sea la última, puede agregar una secuencia de comandos para propagar la confirmación de MEDIA a todos los proyectos dependientes. – jiggunjer

+2

¿Cómo se integra esto con github? – theonlygusti

19

Si entiendo bien su problema que quieren las siguientes cosas:

  1. haya guardado sus archivos multimedia en un repositorio git única, que es utilizado por muchos proyectos
  2. Si modifica un archivo multimedia en cualquiera de los proyectos en su máquina local, debe aparecer inmediatamente en cualquier otro proyecto (por lo que no desea confirmar + presionar + jalar todo el tiempo)

Desafortunadamente no hay una solución definitiva para lo que quieras, pero hay algunas cosas por las cuales puedes hacer tu vida más fácil.

Primero debe decidir una cosa importante: ¿desea almacenar para cada versión en su repositorio de proyecto una referencia a la versión de los archivos multimedia? Entonces, por ejemplo, si tiene un proyecto llamado example.com, ¿necesita saber qué style.css usó hace 2 semanas, o el último es siempre (o sobre todo) el mejor?

Si no necesita saber que, la solución es fácil:

  1. crear un repositorio para los archivos multimedia y uno para cada proyecto
  2. crear un enlace simbólico en sus proyectos que apuntan a el repositorio de medios clonado localmente. Puede crear un enlace simbólico relativo (por ej. ../media) y asumir que todos verificarán el proyecto para que el directorio de medios esté en el mismo lugar, o escriban el nombre del enlace simbólico en .gitignore, y todos pueden decidir donde él/ella pone los archivos multimedia.

En la mayoría de los casos, sin embargo, desea conocer esta información de versión. En este caso, tiene dos opciones:

  1. Almacene cada proyecto en un gran repositorio. La ventaja de esta solución es que solo tendrá 1 copia del depósito de medios. La gran desventaja es que es mucho más difícil cambiar entre versiones de proyecto (si realiza el pago en una versión diferente, siempre modificará TODOS los proyectos)

  2. Use los submódulos (como se explica en la respuesta 1). De esta manera, almacenará los archivos multimedia en un repositorio, y los proyectos contendrán solo una referencia a una versión específica de repo de medios. Pero de esta manera normalmente tendrá muchas copias locales del repositorio de medios, y no podrá modificar fácilmente un archivo multimedia en todos los proyectos.

Si yo fuera usted, probablemente elegiría la primera o la tercera solución (enlaces simbólicos o submódulos). Si decide usar submódulos todavía se pueden hacer muchas cosas para hacer la vida más fácil:

  1. Antes de comprometerse puede cambiar el nombre del directorio submódulo y poner un enlace simbólico a un directorio de medios comunes. Cuando esté listo para comprometerse, puede eliminar el enlace simbólico y eliminar el submódulo, y luego confirmar.

  2. Puede agregar una de sus copias del depósito de medios como repositorio remoto a todos sus proyectos.

Puede agregar directorios locales como un control remoto de esta manera:

cd /my/project2/media 
git remote add project1 /my/project1/media 

Si modifica un archivo en/mi/proyecto 1/medios, puede comprometerse y tire de ella desde/mi/project2/media sin empujarla a un servidor remoto:

cd /my/project1/media 
git commit -a -m "message" 
cd /my/project2/media 
git pull project1 master 

que son libres para eliminar estas confirmaciones más tarde (con git reset), ya que no los ha compartido con otros usuarios.

+1

para proyectos relacionados con la web donde trabaje desde la carpeta 'www' de Apache, debe colocar un archivo' .htaccess' en la raíz de la carpeta 'www' o del proyecto, con' Opciones + SeguirSímbolos'' en ella, o mejor aún ' {new line} Opciones + FollowSymLinks {new line} RewriteEngine on {new line}' (reemplace '{new line}' con actual new line') –

22

Considere usar subtree en lugar de submódulos, esto hará que la vida de los usuarios de repos sea mucho más fácil. Puede encontrar una guía más detallada en Pro Git book.

+6

Aquí hay otro artículo informativo sobre subárbol vs submódulo: http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/ –

+0

Según ese artículo, uno de los inconvenientes es: > La responsabilidad de no mezclar super y sub -el código de proyecto en commits está contigo. Nadie tiene tiempo para eso (IMO) –

2

Tuve problemas con subárboles y submódulos que sugieren las otras respuestas ... principalmente porque estoy usando SourceTree y parece bastante problemático.

En su lugar, terminé usando SymLinks y parece funcionar bien, así que lo estoy publicando aquí como una posible alternativa.

Hay una guía completa aquí: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/

Pero básicamente sólo tiene que MKLINK los dos caminos en un símbolo del sistema elevado. Asegúrese de usar el/J prefijo de enlace duro. Algo similar a esto: mklink/JC: \ projects \ MainProject \ plugins C: \ projects \ SomePlugin

También puede usar rutas de carpetas relativas y ponerlas en un murciélago para que las ejecute cada persona cuando primero comprueban su proyecto.

Ejemplo: mklink/J.\ Assets \ TaqtileTools .. \ TaqtileHoloTools

Una vez que la carpeta ha sido vinculada, puede que necesite ignorar la carpeta dentro de su repositorio principal que hace referencia a ella. De lo contrario, eres bueno para ir.

Nota He eliminado mi respuesta duplicada de otra publicación ya que dicha publicación fue marcada como una pregunta duplicada a esta.

Cuestiones relacionadas