¿Dos repositorios de git en un directorio?

86

¿Es posible tener 2 repositorios git en un directorio? Creo que no, pero pensé en preguntar. Básicamente, me gustaría verificar los archivos de configuración de mi directorio de inicio (por ejemplo, .emacs) que deberían ser comunes en todas las máquinas en las que trabajo, pero que tienen un segundo repositorio para archivos locales (por ejemplo, .emacs.local), que contiene configuraciones específicas de la máquina. La única forma en que puedo pensar en hacer eso es tener la configuración local en un subdirectorio e ignorar ese subdirectorio del repositorio principal de git. ¿Alguna otra idea?

Joe Casadonte
fuente
git subtreehará el trabajo.
Syd Pao
Si no está tratando con demasiados archivos, también puede crear enlaces simbólicos / uniones.
jueves

Respuestas:

37

Si entiendo lo que está haciendo, puede manejarlo todo en un repositorio, usando ramas separadas para cada máquina y una rama que contenga sus archivos de configuración de directorio de inicio comunes.

Inicialice el repositorio y confirme los archivos comunes en él, quizás cambiando el nombre de la rama MASTER como Común. Luego, cree una rama separada desde allí para cada máquina con la que trabaje y confirme archivos específicos de la máquina en esa rama. Cada vez que cambie sus archivos comunes, combine la rama común en cada una de las ramas de la máquina y empuje a sus otras máquinas (escriba un script para eso si hay muchas).

Luego, en cada máquina, verifique la rama de esa máquina, que también incluirá los archivos de configuración comunes.

Paul
fuente
Si bien los submódulos también funcionarán, creo que este es el mejor enfoque para mí. Los archivos locales seguirán una plantilla y, a medida que hago cambios en la plantilla en la rama MASTER, puedo fusionarlos en las ramas locales de la máquina, actualizando de forma incremental los archivos de configuración locales. ¡Gracias por la ayuda!
Joe Casadonte
use Mercurial y Git ambos.
Linc
172

Este artículo cubre esto relativamente bien:

https://github.com/rrrene/gitscm-next/blob/master/app/views/blog/progit/2010-04-11-environment.markdown

Básicamente, si está trabajando desde la línea de comandos, esto es más simple de lo que imagina. Suponga que quiere 2 repositorios de git:

.gitone
.gittwo

Podrías configurarlos así:

git init .
mv .git .gitone
git init .
mv .git .gittwo

Puede agregar un archivo y enviarlo solo a uno así:

git --git-dir=.gitone add test.txt
git --git-dir=.gitone commit -m "Test"

Entonces, las opciones para git vienen primero, luego el comando, luego las opciones del comando git. Fácilmente podría alias un comando git como:

#!/bin/sh
alias gitone='git --git-dir=.gitone'
alias gittwo='git --git-dir=.gittwo'

Así que puedes comprometerte con uno u otro escribiendo un poco menos, como gitone commit -m "blah".

Lo que parece volverse más complicado es ignorarlo. Dado que .gitignore normalmente se encuentra en la raíz del proyecto, también necesitaría encontrar una manera de cambiar esto sin cambiar la raíz completa. O bien, puede usar .git / info / exclude, pero todas las ignoraciones que realice no se confirmarán ni presionarán, lo que podría arruinar a otros usuarios. Otros que usan cualquiera de los repositorios pueden enviar un .gitignore, lo que puede causar conflictos. No tengo claro cuál es la mejor manera de resolver estos problemas.

Si prefiere herramientas GUI como TortoiseGit, también tendrá algunos desafíos. Puede escribir un pequeño script que cambie el nombre de .gitone o .gittwo a .git temporalmente para que se cumplan las suposiciones de estas herramientas.

Chris Moschini
fuente
1
Establecerlo como un alias arroja este error: $ git config --global alias.pub '--git-dir = ~ / Server / www / .gitpublic' $ git pub add. fatal: alias 'pub' cambia las variables de entorno Puede usar '! git' en el alias para hacer esto. ¿Dónde colocaría el "! Git" en este caso?
JaredBroad
1
@JaredBroad Interesante: te estaba sugiriendo que uses un alias de Bash, no un alias de git. Me gustaalias gitone='git --git-dir=.gitone'
Chris Moschini
10
Puede configurar los repositorios para usar sus propios archivos de exclusión y puede rastrearlos, es decir, gitone config core.excludesfile gitone.excludey gitone add gitone.exclude. Hice un script que amplía esta solución: github.com/capr/multigit
2
@JaredBroad Lo hice así git config --global alias.youralias '!git --git-dir="/d/MyProject/_git"'entonces git youralias status:)
starikovs
1
Si asume que los .gitignorearchivos generalmente se configuran y olvidan, entonces puede hacer diferentes copias para cada repositorio y luego copiar la versión relevante en el directorio como parte del alias. Esto se aplica a otros archivos en la raíz que pueden entrar en conflicto, como README.mdy .gitattributes.
jueves
15

Eche un vistazo al submódulo git .

Los submódulos permiten incrustar repositorios externos dentro de un subdirectorio dedicado del árbol de fuentes, siempre apuntando a una confirmación en particular.

Odia_
fuente
8
No es bueno para archivos que necesitan estar en la raíz de su directorio. La única posibilidad es llenar la raíz de los enlaces simbólicos a estos.
WhyNotHugo
6

RichiH escribió una herramienta llamada vcsh que es una herramienta para administrar dotfiles usando repositorios desnudos falsos de git para poner más de un directorio de trabajo en $ HOME. Nada que ver con csh AFAIK.

Sin embargo, si tenía varios directorios, una alternativa a los submódulos de git (que son un dolor en las mejores circunstancias y este uso de ejemplo no es la mejor de las circunstancias) es gitslave, que deja los repositorios esclavos comprobados en la punta de un rama en todo momento y no requiere el proceso de tres pasos para realizar un cambio en el repositorio subsidiario (verifique en la rama correcta, realice y confirme el cambio, luego vaya al superproyecto y confirme el nuevo submódulo).

Seth Robertson
fuente
6

Es posible mediante el uso de la variable, GIT_DIRpero tiene muchas advertencias si no sabe lo que está haciendo.

tzervo
fuente
4

Sí, los submódulos son probablemente lo que quieres. Otra opción sería tener su copia de trabajo en un subdirectorio y luego apuntar enlaces simbólicos desde su directorio de inicio a los archivos de interés.

Pat Notz
fuente
3

mi método preferido es usar un repositorio en un subdirectorio y usar enlaces simbólicos recursivos:

git clone repo1
cd somerepo
git clone repo2
cd repo2
./build

donde el archivo ' repo / build ' se parece a:

#!/bin/bash 
SELF_PATH="$(dirname "$(readlink -f "$0")" )"  # get current dir 
cd .. && git stash && git clean -f -d ''       # remove previous symlinks
cp -sR "$SELF_PATH"/* ../.                     # create recursive symlinks in root

precaución : no use 'git add'.

codificador de salvacion
fuente
0

La otra opción es colocarlos en carpetas separadas y crear enlaces físicos simbólicos de una carpeta a otra.

Por ejemplo, si existen los repositorios:

  1. Repo1 / CarpetaA
  2. Repo1 / CarpetaB

Y:

  1. Repo2 / CarpetaC

Puede enlazar simbólicamente las carpetas FolderAy FolderBdesde el Repo1 al Repo2. Para Windows, el comando para ejecutar en Repo1 sería:

User@Repo1$ mklink /J FullPath/Repo2/FolderA FullPath/Repo1/FolderA
User@Repo1$ mklink /J FullPath/Repo2/FolderB FullPath/Repo1/FolderB
User@Repo1$ printf "/FolderA/*\n/FolderB/*\n" >> .gitignore

Para los archivos en los repositorios principales, necesitaría un enlace simbólico a cada uno de ellos, y también agregarlos al repositorio .gitignorepara evitar ruido, a menos que lo desee.

usuario
fuente
0

Descargo de responsabilidad: esto no es publicidad. Soy el desarrollador de la biblioteca proporcionada.

Creé una extensión de git para manejar casos en los que desea mezclar varios repositorios en una carpeta. La ventaja de la biblioteca es realizar un seguimiento de los repositorios y los conflictos de archivos. lo puedes encontrar en github . También hay 2 repositorios de ejemplo para probarlo.

user1810087
fuente