git – Pasos para convertir un repositorio múltiple en un repositorio único

Pregunta:

¿Cuáles son los mejores pasos para convertir repositorios múltiples en repositorios mono?

Esto es lo que tengo hasta ahora:

  1. para cada repositorio, consulte la rama más reciente (rama de integración, generalmente)
  2. para cada repositorio, copie la carpeta del repositorio en el nuevo repositorio de git (el repositorio mono)
  3. para cada carpeta, elimine la carpeta .git anterior
  4. Organice todos los archivos, confirme y envíe el nuevo mono-repositorio

Mi única pregunta en este momento: ¿los archivos .gitignore existentes funcionarán correctamente para las subcarpetas en el nuevo mono-repositorio?

Respuesta:

No copie los archivos, combine los repositorios. Git no hace una gran diferencia entre "repositorio diferente" y "rama diferente". Más precisamente, un repositorio es una colección de etiquetas y ramas. Asumiré que desea fusionar la rama maestra de todos los repositorios.

Enfoque general (pero vea la discusión de git-subtree a continuación):

  1. Piense en el diseño de su monorepo. Asumiré que, para empezar, tendrás cada repositorio actual como una subcarpeta del monorepo para evitar conflictos.

  2. Para cada repositorio actual, mueva el contenido del repositorio a una subcarpeta y confirme el cambio. Puede usar el comando git mv para hacer esto fácilmente.

    Por ejemplo, si su componente se llama libfoo y actualmente tiene este diseño de repositorio:

     Makefile README.txt src/ ... include/ ...

    Entonces podríamos moverlo a una carpeta libfoo/ :

     libfoo/ Makefile README.txt src/ ... include/ ...
  3. Cree un nuevo repositorio para su monorepo y agregue todos los repositorios existentes como "remotos". A pesar de su nombre, un repositorio remoto puede ser una ruta a algún directorio del mismo sistema de archivos. Luego, git fetch --all controles remotos para cargar su historial en la base de datos git de monorepo. Luego, puede enumerar todas las ramas con git branch --all . Esto se verá así:

     * master remotes/libfoo/master remotes/libbar/master ...
  4. Para cada control remoto, combine su rama maestra. No debería haber conflictos porque todo está en un directorio separado.

  5. Ahora ya está hecho, y tiene un monorepo sin pérdida de historial. Puede quitar los controles remotos.

Pero cuidado: solo puede fusionar una rama de cada repositorio. Si uno de los repositorios originales tiene varias ramas, ya no se pueden fusionar sin conflictos excesivos. Considere volver a agruparlos después de mover el contenido del repositorio a una carpeta, pero antes de fusionar todo en monorepo.

En la práctica, puede utilizar git subtree para automatizar la mayoría de estos pasos. El comando de subárbol le permite fusionar una rama específica en un directorio específico.

  1. inicializar el monorepo y hacer al menos un compromiso
  2. para cada repositorio existente, agréguelo como un subárbol, por ejemplo:

     git subtree add -P libfoo/ ../path/to/libfoorepo master

    El -P / --prefix es el directorio bajo el cual se debe agregar el contenido del repositorio. En lugar de la ruta a un repositorio, se puede utilizar cualquier URL de repositorio. De forma predeterminada, esto agregará el historial completo, alternativamente, puede --squash el historial en una única confirmación.

Git-subtree es una herramienta extremadamente poderosa para manipular monorepos. También puede extraer un directorio en un repositorio separado ( git subtree push ) o fusionar actualizaciones del repositorio original ( git subtree pull ). Por ejemplo, puede usar esto para traducir diferentes ramas.

  • Para traducir una rama de feature :
  • Cree una nueva rama en la función monorepo: git checkout -b feature
  • Extraiga los cambios de la feature libfoo en el directorio correcto de la función monorepo: git subtree pull -P libfoo/ ../path/to/libfoorepo feature .
  • Opcional: cambie la base de la rama a la maestra para simplificar el gráfico del historial.

Pero considere si un monorepo es realmente apropiado para su caso de uso. Aún puede ser deseable tener diferentes repositorios disponibles de forma independiente. El principal competidor son los submódulos git, donde un repositorio se monta como un subdirectorio de otro. Sin embargo, la experiencia no es perfecta. El historial de la rama no se comparte con el submódulo. Si edita código en un submódulo, debe confirmar ese trabajo por separado. Los submódulos de Git son más útiles para "vender" dependencias externas que están ancladas a una versión específica, no para el desarrollo combinado.

Independientemente del enfoque que utilice, los archivos gitignore seguirán funcionando porque los patrones coinciden en relación con el archivo gitignore. Un repositorio puede contener varios archivos gitignore.

Leave a Comment

Your email address will not be published. Required fields are marked *

web tasarım