2010-07-10 16 views
12

Tengo dos repositorios git que están relacionados tangencialmente. A saber, el contenido de uno era un predecesor del otro. Me gustaría de alguna manera anteponer el historial completo del depósito A al depositario B, de modo que la punta de A sería un padre del primer conjunto de cambios del repositorio B? Las historias en ambos son bastante lineales.¿Cómo concatenar dos historias de git?

¿Esto es posible?

Respuesta

9

Usted podría tratar de usar el archivo de injerto (.git/info/grafts) donde se puede sobrescribir la paternidad de una confirmación (como el primero de projectB tener para los padres el último de projectA)

Véase también "What are .git/info/grafts for?" y "How to prepend the past to a git repository?" para más sobre esta manipulación.


skaleecomments sobre el artículo "Git: Grafting repositories" (de SO usuario Ben Straub) para un ejemplo concreto.

Ahora lo que queremos hacer es cambiar el primer commit en el “nuevo” repo (“New commit #1”) de modo que su padre es la última confirmación en el “viejo” de recompra (“viejo # 3”). ¡Un poco de vudú:

git fetch ../old master:ancient_history 

Git permite hacer salir de cualquier otro repositorio git, si esta cesión temporal se relaciona con ella o no! ¡Brillante! Esto nos deja con esto:

enter image description here

Nota cómo cambiamos el nombre de la antigua rama principal a ancient_history. Si no lo hubiéramos hecho, Git habría intentado fusionar los dos, y probablemente habría renunciado con disgusto.

Ahora todavía tenemos un problema.
Los dos árboles no están conectados, y de hecho, un git pull ni siquiera obtendrá la rama ancient_history. Necesitamos una forma de hacer una conexión entre los dos.

Git tiene una función llamada injerto, que básicamente simula un enlace primario entre dos confirmaciones.
para hacer uno, basta con insertar una línea en el archivo .git/info/grafts en este formato:

[ref] [parent] 

Ambos tienen que ser el hash completo de las confirmaciones de que se trate. Así que vamos a encontrar ellos:

$ git rev-list master | tail -n 1 
d7737bffdad86dc05bbade271a9c16f8f912d3c6 

$ git rev-parse ancient_history 
463d0401a3f34bd381c456c6166e514564289ab2 

$ echo d7737bffdad86dc05bbade271a9c16f8f912d3c6 \ 
     463d0401a3f34bd381c456c6166e514564289ab2 \ 
     > .git/info/grafts 

(en una línea, como suggested por ssokolow)

echo $(git rev-list master | tail -n 1) $(git rev-parse ancient_history) > .git/info/grafts 

Hay.Ahora nuestra historia se parece a esto:

enter image description here

clonar esta reporto resultados en esta:

enter image description here

Woops. Resulta que los injertos solo tienen efecto para el repositorio local. Podemos solucionar este problema con la aplicación juiciosa de git fast-import:

$ git fast-export --all > ../export 

$ mkdir ../nuevo-complete 

$ cd ../nuevo-complete 

$ git init 

$ git fast-import < ../export 
git-fast-import statistics: [...] 

(en una línea, como suggested por ssokolow)

git filter-branch $(git rev-parse ancient_history)..HEAD 

Esto convierte efectivamente nuestro enlace de “falsa” la historia en Están solos.
Todos los ingenieros tendrán que volver a clonar desde este nuevo repositorio, ya que los hashes serán todos diferentes, pero ese es un pequeño precio a pagar por el tiempo de inactividad y un historial completo.

enter image description here

Como Qix comentarios below:

fast-import parece que acaba de importar la información de git, pero no comprueba nada.
git init originalmente lo pone en maestro, por lo que necesita un git reset --hard HEAD para realmente verificar los archivos después de fast-import.

+0

Funcionó muy bien para mí, gracias VonC, no pensé que sería así de simple. – SilentGhost

+1

Luego puede reescribir el historial usando 'git filter-branch' para hacer que el injerto sea permanente ... pero esto reescribe el historial. –

+0

Artículo corto y prolijo que realmente me ayudó a entender qué son los injertos y paso a paso cómo unir esas historias: http://ben.straubnet.net/post/939181602/git-grafting-repositories – skalee

Cuestiones relacionadas