Necesito fusionar dos repositorios de Git en un tercer repositorio completamente nuevo. He encontrado muchas descripciones de cómo hacer esto usando una combinación de subárbol (por ejemplo, la respuesta de Jakub Narębski en ¿Cómo se combinan dos repositorios Git? ) Y siguiendo esas instrucciones en su mayoría funciona, excepto que cuando confirmo el subárbol fusionar todos los archivos de los repositorios antiguos se registran como nuevos archivos agregados. Puedo ver el historial de confirmación de los repositorios antiguos cuando lo hago git log
, pero si lo hago git log <file>
, solo muestra una confirmación para ese archivo: la fusión de subárbol. A juzgar por los comentarios sobre la respuesta anterior, no estoy solo al ver este problema, pero no he encontrado soluciones publicadas para ello.
¿Hay alguna forma de fusionar repositorios y dejar intacto el historial de archivos individuales?
fuente
Respuestas:
Resulta que la respuesta es mucho más simple si simplemente está tratando de pegar dos repositorios y hacer que parezca que fue así todo el tiempo en lugar de administrar una dependencia externa. Simplemente necesita agregar controles remotos a sus repositorios antiguos, fusionarlos con su nuevo maestro, mover los archivos y carpetas a un subdirectorio, confirmar el movimiento y repetir para todos los repositorios adicionales. Los submódulos, las fusiones de subárboles y las refinadas modificaciones tienen la intención de resolver un problema ligeramente diferente y no son adecuados para lo que estaba tratando de hacer.
Aquí hay un script de ejemplo de Powershell para pegar dos repositorios:
Obviamente, podría fusionar old_b en old_a (que se convierte en el nuevo repositorio combinado) si prefiere hacerlo: modifique el script para adaptarlo.
Si desea traer también ramas de características en progreso, use esto:
Esa es la única parte no obvia del proceso: no es una fusión de subárbol, sino un argumento de la fusión recursiva normal que le dice a Git que cambiamos el nombre del objetivo y que ayuda a Git a alinear todo correctamente.
Escribí una explicación un poco más detallada aquí .
fuente
git mv
no funciona tan bien. cuando más tarde use ungit log
en uno de los archivos movidos, solo obtendrá la confirmación del movimiento. Se pierde toda la historia previa. Esto es porquegit mv
es realmente,git rm; git add
pero en un solo paso .git log --follow
, o todas las herramientas de GUI lo hacen automáticamente. Con una combinación de subárbol no puede obtener el historial de archivos individuales, que yo sepa, por lo que este método es mejor.1
(el número uno) parals
y 'ojo' capital paraxargs
. Gracias por este consejo!Aquí hay una manera que no reescribe ningún historial, por lo que todas las ID de confirmación seguirán siendo válidas. El resultado final es que los archivos del segundo repositorio terminarán en un subdirectorio.
Agregue el segundo repositorio como control remoto:
Asegúrese de haber descargado todos los commits de secondrepo:
Cree una rama local a partir de la rama del segundo repositorio:
Mueva todos sus archivos a un subdirectorio:
Combina la segunda rama en la rama principal del primer repositorio:
Su repositorio tendrá más de una confirmación de raíz, pero eso no debería suponer un problema.
fuente
git remote show secondrepo
)--allow-unrelated-histories
. Vea la historia de esta publicación de respuestas.Han pasado algunos años y hay soluciones bien votadas, pero quiero compartir la mía porque era un poco diferente porque quería fusionar 2 repositorios remotos en uno nuevo sin eliminar el historial de los repositorios anteriores.
Crea un nuevo repositorio en Github.
Descargue el repositorio recién creado y agregue el antiguo repositorio remoto.
Obtenga todos los archivos del repositorio anterior para crear una nueva rama.
En la rama maestra, combine para combinar el repositorio antiguo con el recién creado.
Cree una nueva carpeta para almacenar todo el nuevo contenido creado que se agregó desde OldRepo y mueva sus archivos a esta nueva carpeta.
Por último, puede cargar los archivos de los repositorios combinados y eliminar de forma segura el OldRepo de GitHub.
Espero que esto pueda ser útil para cualquiera que trabaje con la fusión de repositorios remotos.
fuente
git remote rm OldRepo
.por favor, eche un vistazo al uso
para vincular dos historias al principio de sus vidas.
Si tienes rutas que se superponen, arréglalas con
cuando utilice el registro, asegúrese de "encontrar copias más difíciles" con
de esa manera encontrará cualquier movimiento de archivos en la ruta.
fuente
Convertí la solución de @Flimm this en algo
git alias
así (agregado a mi~/.gitconfig
):fuente
$GIT_PREFIX
?Esta función clonará el repositorio remoto en el directorio de repositorio local:
Cómo utilizar:
Aviso. Este script puede reescribir confirmaciones, pero guardará todos los autores y fechas, significa que las nuevas confirmaciones tendrán otros valores hash, y si intenta enviar cambios al servidor remoto, solo podrá presionar la tecla forzar, también reescribirá confirmaciones en el servidor. Así que haga copias de seguridad antes de iniciar.
¡Lucro!
fuente
git filter-branch --index-filter
a trabajar. Por lo general, recibo un mensaje de error de que el archivo de índice .new no existe. ¿Suena eso?git-add-repo.sh
con la función anterior, al final del archivo pon esta líneagit-add-repo "$@"
. Después de eso, puede usarlo desde zsh likecd current/git/package
ybash path/to/git-add-repo.sh https://github.com/example/example dir/to/save
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
falla a veces, por lo que debe agregar unif test
.Siga los pasos para integrar un repositorio en otro repositorio, teniendo un solo historial de git fusionando ambos historiales de git.
my/new/subdir
(3 veces) con la estructura del directorio donde desea tener el repositorio secundario.Si marca el registro de git en el repositorio principal ahora, debería hacer que se fusionen los compromisos del repositorio secundario. También puede ver la etiqueta que indica desde la fuente de confirmación.
El siguiente artículo me ayudó a incrustar un repositorio en otro repositorio, teniendo un solo historial de git al fusionar ambos historiales de git.
http://ericlathrop.com/2014/01/combining-git-repositories/
Espero que esto ayude. ¡Feliz codificación!
fuente
git filter-branch --prune-empty --tree-filter ' if [ ! -e my/new/subdir ]; then mkdir -p my/new/subdir; git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files my/new/subdir; fi'
Digamos que quiere fusionar repositorio
a
enb
(estoy asumiendo que están situados uno junto al otro):En caso de que desee colocar
a
en un subdirectorio, haga lo siguiente antes de los comandos anteriores:Para esto necesita
git-filter-repo
instalado (filter-branch
se desaconseja ).Un ejemplo de fusión de 2 grandes repositorios, colocando uno de ellos en un subdirectorio: https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731
Más sobre esto aquí .
fuente