Muy a menudo ocurre que estás escribiendo un proyecto de algún tipo, y después de un tiempo queda claro que algún componente del proyecto es realmente útil como un componente independiente (una biblioteca, quizás). Si ha tenido esa idea desde el principio, es muy probable que la mayor parte de ese código esté en su propia carpeta.
¿Hay alguna forma de convertir uno de los subdirectorios en un proyecto Git en un submódulo?
Idealmente, esto sucedería de manera que todo el código en ese directorio se elimine del proyecto principal y el proyecto del submódulo se agregue en su lugar, con todo el historial apropiado, y de manera que todas las confirmaciones del proyecto principal apunten a las confirmaciones del submódulo correctas. .
git
git-submodules
nada101
fuente
fuente
Respuestas:
Para aislar un subdirectorio en su propio repositorio, utilice
filter-branch
en un clon del repositorio original:Entonces no es más que eliminar su directorio original y agregar el submódulo a su proyecto principal.
fuente
git remote rm <name>
después de la rama del filtro y luego quizás agregar un nuevo control remoto. Además, si hay archivos ignorados, agit clean -xd -f
puede ser útil-- --all
se puede reemplazar con el nombre de una rama si el submódulo solo debe extraerse de esta rama.git clone <your_project> <your_submodule>
Solo descarga archivos para your_submodule?git clone source destination
simplemente le dice a Git la ubicación de dónde colocar sus archivos clonados. La magia real para filtrar los archivos de su submódulo ocurre en elfilter-branch
paso.filter-branch
está en desuso hoy en día. Puede usargit clone --filter
, pero su servidor Git debe estar configurado para permitir el filtrado, de lo contrario obtendráwarning: filtering not recognized by server, ignoring
.Primero cambie dir a la carpeta que será un submódulo. Luego:
fuente
Sé que este es un hilo antiguo, pero las respuestas aquí aplastan cualquier confirmación relacionada en otras ramas.
Una forma sencilla de clonar y mantener todas esas ramas y confirmaciones adicionales:
1 - Asegúrate de tener este alias de git
2 - Clone el control remoto, tire de todas las ramas, cambie el control remoto, filtre su directorio, presione
fuente
Se puede hacer, pero no es sencillo. Si busca
git filter-branch
,subdirectory
ysubmodule
, hay algunos escritos decentes sobre el proceso. Básicamente, implica la creación de dos clones de su proyecto, utilizandogit filter-branch
para eliminar todo excepto un subdirectorio en uno y eliminando solo ese subdirectorio en el otro. Luego, puede establecer el segundo repositorio como un submódulo del primero.fuente
Status quo
Vamos a suponer que tenemos un repositorio llamada
repo-old
que contiene un sub directoriosub
que nos gustaría convertir en un sub módulo con su propio reporepo-sub
.Además, se pretende que el repositorio original
repo-old
se convierta en un repositorio modificadorepo-new
donde todas las confirmaciones que toquen el subdirectorio existente previamente apuntaránsub
a las confirmaciones correspondientes de nuestro repositorio de submódulos extraídorepo-sub
.Cambiemos
Es posible lograr esto con la ayuda de
git filter-branch
un proceso de dos pasos:repo-old
arepo-sub
(ya mencionado en la respuesta aceptada )repo-old
arepo-new
(con el mapeo de compromiso adecuado)Observación : Sé que esta pregunta es antigua y ya se ha mencionado que
git filter-branch
está en desuso y podría ser peligrosa. Pero, por otro lado, podría ayudar a otros con repositorios personales que son fáciles de validar después de la conversión. ¡Así que ten cuidado ! ¡Y avíseme si hay alguna otra herramienta que haga lo mismo sin ser obsoleta y que sea segura de usar!Explicaré cómo me di cuenta de ambos pasos en Linux con la versión 2.26.2 de git a continuación. Las versiones anteriores pueden funcionar hasta cierto punto, pero eso debe probarse.
En aras de la simplicidad, me limitaré al caso en el que solo hay una
master
rama y unorigin
control remoto en el repositorio originalrepo-old
. También tenga en cuenta que confío en las etiquetas git temporales con el prefijotemp_
que se eliminarán en el proceso. Entonces, si ya hay etiquetas con nombres similares, es posible que desee ajustar el prefijo a continuación. Y, por último, tenga en cuenta que no he probado esto de forma exhaustiva y puede haber casos en los que la receta falle. ¡Así que haga una copia de seguridad de todo antes de continuar !Los siguientes fragmentos de bash se pueden concatenar en un gran script que luego se debe ejecutar en la misma carpeta donde
repo-org
reside el repositorio . ¡No se recomienda copiar y pegar todo directamente en una ventana de comando (aunque lo he probado con éxito)!0. Preparación
Variables
Script de filtro
1. Extracción de subdirectorios
2. Reemplazo de subdirectorio
Observación: si el repositorio recién creado se
repo-new
cuelga durantegit submodule update --init
, intente volver a clonar el repositorio de forma recursiva una vez en su lugar:fuente
Esto hace la conversión en el lugar, puede retroceder como lo haría con cualquier rama de filtro (yo uso
git fetch . +refs/original/*:*
).Tengo un proyecto con un
utils
biblioteca que comenzó a ser útil en otros proyectos y quería dividir su historial en submódulos. No pensé en mirar SO primero, así que escribí el mío, crea el historial localmente, por lo que es un poco más rápido, después de lo cual, si lo desea, puede configurar el.gitmodules
archivo del comando auxiliar y demás, y enviar los historiales del submódulo a cualquier lugar usted quiere.El comando despojado en sí está aquí, el documento en los comentarios, en el que sigue sin despojar. Ejecútelo como su propio comando, con
subdir
set, comosubdir=utils git split-submodule
si estuviera dividiendo elutils
directorio. Es hacky porque es único, pero lo probé en el subdirectorio Documentation en el historial de Git.fuente