tag repositorio que crear git

que - Combinando múltiples repositorios de git.



git tag (12)

git-stitch-repo procesará la salida de git-fast-export --all --date-order en los repositorios de git dados en la línea de comandos, y creará una secuencia adecuada para git-fast-import que creará una nueva Repositorio que contiene todas las confirmaciones en un nuevo árbol de confirmación que respeta el historial de todos los repositorios de origen.

Digamos que tengo una configuración que parece algo así

phd/code/ phd/figures/ phd/thesis/

Por razones históricas, todos ellos tienen sus propios repositorios git. Pero me gustaría combinarlos en uno solo para simplificar un poco las cosas. Por ejemplo, ahora mismo podría hacer dos conjuntos de cambios y tengo que hacer algo como

cd phd/code git commit cd ../figures git commit

Sería bueno (ahora) simplemente realizar

cd phd git commit

Parece que hay un par de maneras de hacer esto usando submódulos o retirándolos de mis sub-repositorios, pero eso es un poco más complejo de lo que estoy buscando. Por lo menos, estaría feliz con

cd phd git init git add [[everything that''s already in my other repositories]]

pero eso no parece ser de una sola línea. ¿Hay algo en git que me pueda ayudar?


Aquí hay una solución que di here :

  1. Primero haga una copia de seguridad completa de su directorio de doctorado: ¡No quiero que me responsabilicen por sus años perdidos de trabajo duro! ;-)

    $ cp -r phd phd-backup

  2. Mueva el contenido de phd/code a phd/code/code y arregle el historial para que parezca que siempre ha estado allí (esto usa el comando filter-branch git):

    $ cd phd/code $ git filter-branch --index-filter / ''git ls-files -s | sed "s-/t-&code/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new / git update-index --index-info && mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE'' HEAD

  3. Lo mismo para el contenido de phd/figures y phd/thesis (simplemente reemplace el code con figures y thesis ).

    Ahora su estructura de directorio debería verse así:

    phd |_code | |_.git | |_code | |_(your code...) |_figures | |_.git | |_figures | |_(your figures...) |_thesis |_.git |_thesis |_(your thesis...)

  4. Luego crea un repositorio git en el directorio raíz, tira todo lo que contiene y elimina los repositorios antiguos:

    $ cd phd $ git init $ git pull code $ rm -rf code/code $ rm -rf code/.git $ git pull figures --allow-unrelated-histories $ rm -rf figures/figures $ rm -rf figures/.git $ git pull thesis --allow-unrelated-histories $ rm -rf thesis/thesis $ rm -rf thesis/.git

    Finalmente, ahora debería tener lo que quería:

    phd |_.git |_code | |_(your code...) |_figures | |_(your figures...) |_thesis |_(your thesis...)

Un lado bueno de este procedimiento es que dejará los archivos y directorios sin versión en su lugar.

Espero que esto ayude.

Sin embargo, solo una palabra de advertencia: si su directorio de code ya tiene un subdirectorio o archivo de code , las cosas pueden ir muy mal (lo mismo para las figures y thesis por supuesto). Si ese es el caso, simplemente cambie el nombre de ese directorio o archivo antes de pasar por todo este procedimiento:

$ cd phd/code $ git mv code code-repository-migration $ git commit -m "preparing the code directory for migration"

Y cuando finalice el procedimiento, agregue este paso final:

$ cd phd $ git mv code/code-repository-migration code/code $ git commit -m "final step for code directory migration"

Por supuesto, si el subdirectorio de code o el archivo no están versionados, solo use mv lugar de git mv , y olvídese de los git commit s.


En realidad, git-stitch-repo ahora admite ramas y etiquetas, incluidas las etiquetas anotadas (descubrí que había un error que informé y se solucionó). Lo que encontré útil es con las etiquetas. Dado que las etiquetas se adjuntan a las confirmaciones, y algunas de las soluciones (como el enfoque de Eric Lee) fallan al tratar con las etiquetas. Intenta crear una rama a partir de una etiqueta importada, y deshará todas las combinaciones / movimientos de git y lo enviará de vuelta como si el repositorio consolidado estuviera cerca de ser idéntico al repositorio del que proviene la etiqueta. Además, hay problemas si utiliza la misma etiqueta en varios repositorios que ''fusionó / ​​consolidó''. Por ejemplo, si tiene un anuncio A de repo, ambos tienen la etiqueta rel_1.0. Combinas el repositorio A y el repositorio B en el repositorio AB. Dado que las etiquetas rel_1.0 están en dos confirmaciones diferentes (una para A y otra para B), ¿qué etiqueta será visible en AB? Ya sea la etiqueta del repositorio A importado o del repositorio B importado, pero no ambos.

git-stitch-repo ayuda a resolver ese problema mediante la creación de etiquetas rel_1.0-A y rel_1.0-B. Es posible que no pueda desproteger la etiqueta rel_1.0 y esperar ambas, pero al menos puede ver ambas, y teóricamente, puede combinarlas en una rama local común y luego crear una etiqueta rel_1.0 en esa rama combinada (asumiendo que simplemente fusionar y no cambiar el código fuente). Es mejor trabajar con sucursales, ya que puedes combinarlas como ramas de cada repositorio en sucursales locales. (dev-a y dev-b se pueden fusionar en una rama dev local que luego se puede enviar al origen).


He creado una herramienta que hace esta tarea. El método utilizado es similar (internamente hace algunas cosas como --filter-branch) pero es más amigable. Es GPL 2.0

http://github.com/geppo12/GitCombineRepo


La secuencia que sugeriste

git init git add * git commit -a -m "import everything"

Funcionará, pero perderá su historial de compromiso.


La solución @MiniQuark me ayudó mucho, pero desafortunadamente no tiene en cuenta las etiquetas que se encuentran en los repositorios de origen (al menos en mi caso). A continuación se muestra mi mejora a la respuesta de @MiniQuark.

  1. Primero cree el directorio que contendrá repo compuesto y repos fusionados, cree el directorio para cada uno fusionado.

    $ mkdir new_phd
    $ mkdir new_phd / code
    $ mkdir new_phd / figures
    $ mkdir new_phd / thesis

  2. Haz una extracción de cada repositorio y recupera todas las etiquetas. (Presentar instrucciones solo para el subdirectorio de code )

    $ cd new_phd / code
    $ git init
    $ git pull ../../original_phd/code master
    $ git fetch ../../original_phd/code refs / tags / *: refs / tags / *

  3. (Esto es una mejora al punto 2 en la respuesta de MiniQuark) Mueva el contenido de new_phd/code a new_phd/code/code y agregue code_ code_ antes de cada etiqueta

    $ git filter-branch --index-filter ''git ls-files -s | sed "s- / t /" * - & code / - "| GIT_INDEX_FILE = $ GIT_INDEX_FILE.new git update-index --index-info && mv $ GIT_INDEX_FILE.new $ GIT_INDEX_FILE ''--tag-name-filter'' sed" s -. * - código _ & - "''HEAD

  4. Después de hacerlo, habrá el doble de etiquetas que antes de hacer una rama de filtro. Las etiquetas antiguas permanecen en repo y se agregan nuevas etiquetas con prefijo code_ .

    $ git tag
    mytag1
    code_mytag1

    Eliminar las etiquetas antiguas manualmente:

    $ ls .git / refs / tags / * | grep -v "/ code_" | xargs rm

    Repita el punto 2,3,4 para otros subdirectorios.

  5. Ahora tenemos estructura de directorios como en @MiniQuark anwser point 3.

  6. Haga como en el punto 4 de MiniQuark anwser, pero después de hacer un tirón y antes de eliminar .git dir, busque etiquetas:

    $ git fetch catálogo refs / tags / *: refs / tags / *

    Continuar..

Esta es solo otra solución. Espero que ayude a alguien, me ayudó :)


La solución git-filter-branch funciona bien, pero tenga en cuenta que si su repositorio de git proviene de una importación de SVN, puede fallar con un mensaje como:

Rewrite 422a38a0e9d2c61098b98e6c56213ac83b7bacc2 (1/42)mv: cannot stat `/home/.../wikis/nodows/.git-rewrite/t/../index.new'': No such file or directory

En este caso, debe excluir la revisión inicial de la rama del filtro, es decir, cambiar la HEAD al final a [SHA of 2nd revision]..HEAD : ver:

http://www.git.code-experiments.com/blog/2010/03/merging-git-repositories.html


Para fusionar un segundo proyecto dentro de un proyecto principal:

A) En el segundo proyecto.

git fast-export --all --date-order > /tmp/secondProjectExport

B) En el proyecto principal:

git checkout -b secondProject git fast-import --force < /tmp/secondProjectExport

En esta rama, haz toda la transformación pesada que necesitas hacer y comprométalos.

C) Luego de vuelta al maestro y una combinación clásica entre las dos ramas:

git checkout master git merge secondProject


Podrías probar la estrategia de fusión de subárbol . Le permitirá fusionar el repositorio B en el repositorio A. La ventaja sobre git-filter-branch es que no requiere que reescriba su historial (rompiendo las sumas de SHA1).


Quizás, simplemente (de manera similar a la respuesta anterior, pero usando comandos más simples) haciendo de cada uno de los repositorios antiguos separados una confirmación que mueve el contenido a un subdirigente adecuadamente nombrado, por ejemplo:

$ cd phd/code $ mkdir code # This won''t work literally, because * would also match the new code/ subdir, but you understand what I mean: $ git mv * code/ $ git commit -m "preparing the code directory for migration"

y luego fusionar los tres repositorios separados en uno nuevo, haciendo algo así como:

$ cd ../.. $ mkdir phd.all $ cd phd.all $ git init $ git pull ../phd/code ...

Luego guardará sus historias, pero continuará con un solo repositorio.


Voy a lanzar mi solución aquí también. Es básicamente un contenedor de script bash bastante simple alrededor de git filter-branch . Al igual que otras soluciones, solo migra ramas maestras y no migra etiquetas. Pero las historias maestras completas de compromiso se migran y es un script corto de bash, por lo que debería ser relativamente fácil para los usuarios revisar o modificar.

https://github.com/Oakleon/git-join-repos


La respuesta de git-stitch-repo de Aristóteles Pagaltzis solo funciona para repositorios con historia simple y lineal.

La respuesta de MiniQuark funciona para todos los repositorios, pero no maneja etiquetas y ramas.

Creé un programa que funciona de la misma manera que describe MiniQuark, pero usa un compromiso de combinación (con N padres) y también recrea todas las etiquetas y ramas para señalar estos compromisos de combinación.

Vea el repositorio de git-merge-repos para ver ejemplos de cómo usarlo.