Tengo un repositorio Git que contiene varios subdirectorios. Ahora he descubierto que uno de los subdirectorios no está relacionado con el otro y debe separarse a un repositorio separado.
¿Cómo puedo hacer esto mientras mantengo el historial de los archivos dentro del subdirectorio?
Supongo que podría hacer un clon y eliminar las partes no deseadas de cada clon, pero supongo que esto me daría el árbol completo al revisar una revisión anterior, etc. Esto podría ser aceptable, pero preferiría poder fingir que dos repositorios no tienen un historial compartido.
Solo para dejarlo claro, tengo la siguiente estructura:
XYZ/
.git/
XY1/
ABC/
XY2/
Pero me gustaría esto en su lugar:
XYZ/
.git/
XY1/
XY2/
ABC/
.git/
ABC/
git filter-branch
ver mi respuesta a continuación.Respuestas:
Actualización : Este proceso es tan común, que el equipo de git hizo que fuera mucho más sencillo con una nueva herramienta,
git subtree
. Ver aquí: Separar (mover) subdirectorio en repositorio Git separadoDesea clonar su repositorio y luego usarlo
git filter-branch
para marcar todo menos el subdirectorio que desea en su nuevo repositorio para recolectar basura.Para clonar su repositorio local:
(Nota: el repositorio se clonará mediante enlaces duros, pero eso no es un problema ya que los archivos enlazados no se modificarán en sí mismos; se crearán nuevos).
Ahora, conservemos las ramas interesantes que queremos reescribir también, y luego eliminemos el origen para evitar presionar allí y asegurarnos de que el origen no haga referencia a las confirmaciones antiguas:
o para todas las sucursales remotas:
Ahora es posible que también desee eliminar etiquetas que no tienen relación con el subproyecto; También puede hacerlo más tarde, pero es posible que necesite recortar su repositorio nuevamente. No lo hice y obtuve un
WARNING: Ref 'refs/tags/v0.1' is unchanged
para todas las etiquetas (ya que no estaban relacionadas con el subproyecto); Además, después de eliminar tales etiquetas, se recuperará más espacio. Aparentementegit filter-branch
debería poder reescribir otras etiquetas, pero no pude verificar esto. Si desea eliminar todas las etiquetas, usegit tag -l | xargs git tag -d
.Luego use filter-branch y reset para excluir los otros archivos, para que puedan ser eliminados. Agreguemos también
--tag-name-filter cat --prune-empty
para eliminar confirmaciones vacías y reescribir etiquetas (tenga en cuenta que esto tendrá que quitar su firma):o, alternativamente, para reescribir solo la rama HEAD e ignorar las etiquetas y otras ramas:
Luego, elimine los reflogs de respaldo para que el espacio pueda ser verdaderamente recuperado (aunque ahora la operación es destructiva)
y ahora tiene un repositorio git local del subdirectorio ABC con todo su historial preservado.
Nota: Para la mayoría de los usos,
git filter-branch
debería tener el parámetro agregado-- --all
. Si, eso es realmente --space--all
. Estos deben ser los últimos parámetros para el comando. Como Matli descubrió, esto mantiene las ramas y etiquetas del proyecto incluidas en el nuevo repositorio.Editar: se incorporaron varias sugerencias de los comentarios a continuación para garantizar, por ejemplo, que el repositorio se reduzca realmente (que no siempre fue el caso antes).
fuente
--no-hardlinks
? Eliminar un enlace duro no afectará al otro archivo. Los objetos Git también son inmutables. Solo si cambia los permisos de propietario / archivo que necesita--no-hardlinks
.filter-branch
es--prune-empty
eliminar las confirmaciones ahora vacías.-- --all
. También corrígit remote rm origin
, ygit tag -l | xargs git tag -d
antes delgit filter-branch
comando. Esto redujo mi.git
directorio de 60M a ~ 300K. Tenga en cuenta que necesitaba ejecutar ambos comandos para obtener la reducción de tamaño.The Easy Way ™
Resulta que esta es una práctica tan común y útil que los señores superiores de Git lo hicieron realmente fácil, pero debe tener una versión más nueva de Git (> = 1.7.11 de mayo de 2012). Consulte el apéndice sobre cómo instalar el último Git. Además, hay un ejemplo del mundo real en el tutorial a continuación.
Prepara el viejo repositorio
Nota:
<name-of-folder>
NO debe contener caracteres iniciales o finales. Por ejemplo, la carpeta llamadasubproject
DEBE pasar comosubproject
, NO./subproject/
Nota para usuarios de Windows: cuando la profundidad de la carpeta es> 1,
<name-of-folder>
debe tener un separador de carpeta de estilo * nix (/). Por ejemplo, la carpeta llamadapath1\path2\subproject
DEBE pasar comopath1/path2/subproject
Crea el nuevo repositorio
Enlace el nuevo repositorio a GitHub o donde sea
Limpieza interior
<big-repo>
, si lo deseaNota : Esto deja todas las referencias históricas en el repositorio. Consulte el Apéndice a continuación si realmente le preocupa haber cometido una contraseña o si necesita disminuir el tamaño del archivo de su
.git
carpeta....
Tutorial
Estos son los mismos pasos que los anteriores , pero seguir mis pasos exactos para mi repositorio en lugar de usarlos
<meta-named-things>
.Aquí hay un proyecto que tengo para implementar módulos de navegador JavaScript en el nodo:
Quiero dividir una sola carpeta
btoa
, en un repositorio Git separadoAhora tengo una nueva rama,
btoa-only
que solo tiene commitsbtoa
y quiero crear un nuevo repositorio.A continuación, creo un nuevo repositorio en GitHub o Bitbucket, o lo que sea, y lo agrego como
origin
¡Día feliz!
Nota: Si creó un repositorio con a
README.md
,.gitignore
yLICENSE
, primero deberá extraer:Por último, querré eliminar la carpeta del repositorio más grande
...
Apéndice
Latest Git en macOS
Para obtener la última versión de Git con Homebrew :
Último Git en Ubuntu
Si eso no funciona (tiene una versión muy antigua de Ubuntu), intente
Si eso todavía no funciona, intente
Gracias a rui.araujo por los comentarios.
Limpiando tu historia
De forma predeterminada, eliminar archivos de Git en realidad no los elimina, solo confirma que ya no están allí. Si realmente desea eliminar las referencias históricas (es decir, tiene una contraseña confirmada), debe hacer esto:
Después de eso, puede verificar que su archivo o carpeta ya no aparezca en el historial de Git
Sin embargo, no puede "empujar" eliminaciones a GitHub y similares. Si lo intentas, obtendrás un error y tendrás que hacerlo
git pull
antes de que puedasgit push
, y luego volverás a tener todo en tu historial.Por lo tanto, si desea eliminar el historial del "origen", es decir, eliminarlo de GitHub, Bitbucket, etc., deberá eliminar el repositorio y volver a enviar una copia podada del repositorio. Pero espera, ¡ hay más ! - Si realmente le preocupa deshacerse de una contraseña o algo así, deberá podar la copia de seguridad (consulte a continuación).
Haciendo
.git
más pequeñoEl comando eliminar historial mencionado anteriormente todavía deja atrás un montón de archivos de copia de seguridad, porque Git es muy amable al ayudarlo a no arruinar su repositorio por accidente. Eventualmente eliminará archivos huérfanos a lo largo de los días y meses, pero los dejará allí por un tiempo en caso de que se dé cuenta de que eliminó accidentalmente algo que no quería.
Entonces, si realmente desea vaciar la basura para reducir el tamaño de clon de un repositorio de inmediato, debe hacer todo esto realmente extraño:
Dicho esto, recomendaría no realizar estos pasos a menos que sepa que necesita hacerlo, en caso de que haya eliminado el subdirectorio incorrecto, ¿sabe? Los archivos de copia de seguridad no deben clonarse cuando presiona el repositorio, solo estarán en su copia local.
Crédito
fuente
git subtree
sigue siendo parte de la carpeta 'contrib' y no está instalado de forma predeterminada en todas las distribuciones. github.com/git/git/blob/master/contrib/subtreepopd
ypushd
hace que esto sea bastante implícito y más difícil de asimilar lo que pretende hacer ...La respuesta de Paul crea un nuevo repositorio que contiene / ABC, pero no elimina / ABC de / XYZ. El siguiente comando eliminará / ABC de / XYZ:
Por supuesto, pruébelo primero en un repositorio 'clone --no-hardlinks', y sígalo con los comandos reset, gc y podar que Paul enumera.
fuente
git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch ABC" --prune-empty HEAD
y será mucho más rápido. index-filter funciona en el índice, mientras que tree-filter tiene que pagar y organizar todo para cada confirmación .--index-filter
método, es posible que también desee hacerlogit rm -q -r -f
, de modo que cada invocación no imprima una línea para cada archivo que elimine.Descubrí que para eliminar correctamente el historial anterior del nuevo repositorio, debe realizar un poco más de trabajo después del
filter-branch
paso.Haz el clon y el filtro:
Elimine todas las referencias a la historia antigua. "Origen" estaba haciendo un seguimiento de su clon, y "original" es donde filter-branch guarda las cosas viejas:
Incluso ahora, su historial podría estar atascado en un paquete que fsck no tocará. Rómpelo en pedazos, creando un nuevo paquete de archivos y eliminando los objetos no utilizados:
Hay una explicación de esto en el manual para filter-branch .
fuente
git gc --aggressive --prune=now
todavía falta algo como , ¿no?git gc --aggressive --prune=now
redujo gran parte del nuevo repositorioEditar: Bash script agregado.
Las respuestas dadas aquí funcionaron solo parcialmente para mí; Muchos archivos grandes permanecieron en el caché. Lo que finalmente funcionó (después de horas en #git en freenode):
Con las soluciones anteriores, el tamaño del repositorio era de alrededor de 100 MB. Este lo redujo a 1,7 MB. Tal vez ayude a alguien :)
El siguiente script bash automatiza la tarea:
fuente
Esto ya no es tan complejo que solo puede usar el comando git filter-branch en un clon de su repositorio para eliminar los subdirectorios que no desea y luego pasar al nuevo control remoto.
fuente
The result will contain that directory (and only that) as its project root.
y, de hecho, esto es lo que obtendrá, es decir, la estructura original del proyecto no se conserva.Actualización : El módulo git-subtree fue tan útil que el equipo git lo incorporó al núcleo y lo creó
git subtree
. Ver aquí: Separar (mover) subdirectorio en repositorio Git separadogit-subtree puede ser útil para esto
http://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt (en desuso)
http://psionides.jogger.pl/2010/02/04/sharing-code-between-projects-with-git-subtree/
fuente
He aquí una pequeña modificación en CoolAJ86 's 'La manera más fácil ™' respuesta con el fin de dividir múltiples subcarpetas (digamos
sub1
ysub2
) en un nuevo repositorio git.The Easy Way ™ (múltiples subcarpetas)
Prepara el viejo repositorio
Nota:
<name-of-folder>
NO debe contener caracteres iniciales o finales. Por ejemplo, la carpeta llamadasubproject
DEBE pasar comosubproject
, NO./subproject/
Nota para usuarios de Windows: cuando la profundidad de su carpeta es> 1,
<name-of-folder>
debe tener un separador de carpeta de estilo * nix (/). Por ejemplo, la carpeta llamadapath1\path2\subproject
DEBE pasar comopath1/path2/subproject
. Además, no use elmv
comando peromove
.Nota final: la diferencia única y grande con la respuesta base es la segunda línea del guión "
git filter-branch...
"Crea el nuevo repositorio
Vincula el nuevo repositorio a Github o donde sea
Limpieza, si lo desea
Nota : Esto deja todas las referencias históricas en el repositorio. Consulte el Apéndice en la respuesta original si realmente le preocupa haber cometido una contraseña o si necesita disminuir el tamaño del archivo de su
.git
carpeta.fuente
sub1
ysub2
carpetas no existían con la versión inicial, tuve que modificar mi--tree-filter
script de la siguiente manera:"mkdir <name-of-folder>; if [ -d sub1 ]; then mv <sub1> <name-of-folder>/; fi"
. Para el segundofilter-branch
comando, reemplacé <sub1> con <sub2>, omití la creación de <name-of-folder> e incluí-f
despuésfilter-branch
para anular la advertencia de una copia de seguridad existente.La pregunta original quiere que XYZ / ABC / (* archivos) se convierta en ABC / ABC / (* archivos). Después de implementar la respuesta aceptada para mi propio código, noté que en realidad cambia XYZ / ABC / (* files) en ABC / (* files). La página man de filter-branch incluso dice:
En otras palabras, promueve la carpeta de nivel superior "arriba" un nivel. Esa es una distinción importante porque, por ejemplo, en mi historia había renombrado una carpeta de nivel superior. Al promover las carpetas "arriba" en un nivel, git pierde continuidad en el commit donde hice el cambio de nombre.
Mi respuesta a la pregunta es hacer 2 copias del repositorio y eliminar manualmente las carpetas que desea mantener en cada una. La página del manual me respalda con esto:
fuente
targetdir
había cambiado de nombre en algún momento ygit filter-branch
simplemente lo había llamado un día, ¡eliminando todas las confirmaciones realizadas antes del cambio de nombre! ¡Impactante, teniendo en cuenta cuán experto es Git en el seguimiento de tales cosas e incluso la migración de fragmentos de contenido individuales!git rm
requiere múltiples argumentos, por lo que no hay razón para ejecutarlo para cada archivo / carpeta:BYEBYE="dir/subdir2 dir2 file1 dir/file2"; git filter-branch -f --index-filter "git rm -q -r -f --cached --ignore-unmatch $BYEBYE" --prune-empty -- --all
Para añadir a la respuesta de Paul , descubrí que, en última instancia, para recuperar espacio, tengo que empujar HEAD a un repositorio limpio y que reduce el tamaño del directorio .git / objects / pack.
es decir
Después de la ciruela pasa gc, también haz:
Entonces puedes hacer
y el tamaño de ABC / .git se reduce
En realidad, algunos de los pasos que requieren mucho tiempo (por ejemplo, git gc) no son necesarios con el empuje para limpiar el repositorio, es decir:
fuente
La forma correcta ahora es la siguiente:
git filter-branch --prune-empty --subdirectory-filter FOLDER_NAME [first_branch] [another_branch]
GitHub ahora incluso tiene un pequeño artículo sobre tales casos.
Pero asegúrese de clonar su repositorio original para separar el directorio primero (ya que eliminaría todos los archivos y otros directorios y probablemente necesite trabajar con ellos).
Entonces su algoritmo debería ser:
git filter-branch
archivos de solo izquierda debajo de algún subdirectorio, empuje a un nuevo control remotofuente
Parece que la mayoría (¿todas?) De las respuestas aquí se basan en alguna forma de
git filter-branch --subdirectory-filter
y su tipo. Esto puede funcionar "la mayoría de las veces", sin embargo, en algunos casos, por ejemplo, cuando cambiaste el nombre de la carpeta, por ejemplo:Si realiza un estilo de filtro git normal para extraer "move_me_renamed", perderá el historial de cambios de archivos que se produjo desde atrás cuando inicialmente se movía move_this_dir ( ref ).
Por lo tanto, parece que la única forma de mantener realmente todo el historial de cambios (si el suyo es un caso como este), es, en esencia, copiar el repositorio (crear un nuevo repositorio, establecer que sea el origen), luego destruir todo lo demás y cambie el nombre del subdirectorio al padre así:
git branch -a
git checkout --track origin/branchABC
cp -r oldmultimod simple
cd simple
git rm otherModule1 other2 other3
git mv moduleSubdir1/* .
rmdir moduleSubdir1
git status
git remote set-url origin http://mygithost:8080/git/our-splitted-module-repo
git remote -v
git push
git checkout branch2
Esto sigue al documento de github "Dividir una subcarpeta en un nuevo repositorio" pasos 6-11 de para llevar el módulo a un nuevo repositorio.
Esto no le ahorrará espacio en su carpeta .git, pero conservará todo su historial de cambios para esos archivos, incluso en todos los cambios de nombre. Y esto puede no valer la pena si no hay "mucha" historia perdida, etc. ¡Pero al menos se garantiza que no perderá compromisos más antiguos!
fuente
Recomiendo la guía de GitHub para dividir subcarpetas en un nuevo repositorio . Los pasos son similares a la respuesta de Paul , pero encontré sus instrucciones más fáciles de entender.
Modifiqué las instrucciones para que soliciten un repositorio local, en lugar de uno alojado en GitHub.
fuente
If you create a new clone of the repository, you won't lose any of your Git history or changes when you split a folder into a separate repository.
Sin embargo, de acuerdo con los comentarios sobre todas las respuestas aquí, tantofilter-branch
y elsubtree
guión resultan en la pérdida de la historia donde sea que se haya cambiado el nombre de un subdirectorio. ¿Hay algo que se pueda hacer para abordar esto?Cuando se ejecuta
git filter-branch
con una versión más nueva degit
(2.22+
¿tal vez?), Dice usar esta nueva herramienta git-filter-repo . Esta herramienta ciertamente simplificó las cosas para mí.Filtrado con filtro-repo
Comandos para crear el
XYZ
repositorio a partir de la pregunta original:supuestos: * el repositorio XYZ remoto era nuevo y estaba vacío antes del envío
Filtrando y moviendo
En mi caso, también quería mover un par de directorios para una estructura más consistente. Inicialmente, ejecuté ese
filter-repo
comando simple seguido degit mv dir-to-rename
, pero descubrí que podía obtener un historial ligeramente "mejor" usando la--path-rename
opción. En lugar de ver la última modificación5 hours ago
en archivos movidos en el nuevo repositorio, ahora veolast year
(en la interfaz de usuario de GitHub), que coincide con los tiempos modificados en el repositorio original.En vez de...
Finalmente corrí ...
Notas:git filter-repo --subdirectory-filter dir-matching-new-repo-name
). Ese comando convirtió correctamente ese subdirectorio a la raíz del repositorio local copiado, pero también resultó en un historial de solo las tres confirmaciones que tomó para crear el subdirectorio. (No me había dado cuenta de que--path
podría especificarse varias veces; por lo tanto, obviando la necesidad de crear un subdirectorio en el repositorio fuente.) Dado que alguien se había comprometido con el repositorio fuente en el momento en que noté que había fallado en llevar adelante el historial, simplemente utilicégit reset commit-before-subdir-move --hard
después delclone
comando y agregué--force
elfilter-repo
comando para que funcione en el clon local ligeramente modificado.git
, pero finalmente cloné git-filter-repo y lo vinculé a$(git --exec-path)
:fuente
filter-repo
herramienta (que presenté el mes pasado en stackoverflow.com/a/58251653/6309 )git-filter-repo
definitivamente debería ser el enfoque preferido en este punto. Es mucho, mucho más rápido y seguro quegit-filter-branch
, y protege contra muchas de las trampas con las que uno puede toparse al reescribir el historial de git. Esperemos que esta respuesta reciba más atención, ya que es la que se debe abordargit-filter-repo
.Tuve exactamente este problema, pero todas las soluciones estándar basadas en git filter-branch fueron extremadamente lentas. Si tiene un repositorio pequeño, entonces esto puede no ser un problema, fue para mí. Escribí otro programa de filtrado de git basado en libgit2 que, como primer paso, crea ramas para cada filtrado del repositorio primario y luego los empuja para limpiar los repositorios como el siguiente paso. En mi repositorio (500Mb 100000 commits) los métodos estándar de ramificación de filtro git tomaron días. Mi programa tarda minutos en hacer el mismo filtrado.
Tiene el fabuloso nombre de git_filter y vive aquí:
https://github.com/slobobaby/git_filter
en GitHub.
Espero que sea útil para alguien.
fuente
Use este comando de filtro para eliminar un subdirectorio, al tiempo que conserva sus etiquetas y ramas:
fuente
Por lo que vale, así es cómo se usa GitHub en una máquina con Windows. Digamos que tiene un repositorio clonado en residir en
C:\dir1
. La estructura de directorios es el siguiente:C:\dir1\dir2\dir3
. Eldir3
directorio es el que quiero que sea un nuevo repositorio separado.Github:
MyTeam/mynewrepo
Aviso de golpe:
$ cd c:/Dir1
$ git filter-branch --prune-empty --subdirectory-filter dir2/dir3 HEAD
Devuelto:
Ref 'refs/heads/master' was rewritten
(para su información: dir2 / dir3 distingue entre mayúsculas y minúsculas).$ git remote add some_name [email protected]:MyTeam/mynewrepo.git
git remote add origin etc
. no funcionó, regresó "remote origin already exists
"$ git push --progress some_name master
fuente
Como mencioné anteriormente , tuve que usar la solución inversa (eliminar todas las confirmaciones sin tocar mi
dir/subdir/targetdir
) que parecía funcionar bastante bien, eliminando aproximadamente el 95% de las confirmaciones (según lo deseado). Sin embargo, quedan dos pequeños problemas.PRIMERO ,
filter-branch
hizo un trabajo explosivo al eliminar los commits que introducen o modifican el código, pero aparentemente, los commits de fusión están debajo de su estación en el Gitiverse.Este es un problema cosmético con el que probablemente pueda vivir (dice ... retrocediendo lentamente con los ojos apartados) .
SEGUNDO: ¡ los pocos commits que quedan están casi TODOS duplicados! Parece que he adquirido una segunda línea de tiempo redundante que abarca casi toda la historia del proyecto. Lo interesante (que puede ver en la imagen a continuación), es que mis tres sucursales locales no están todas en la misma línea de tiempo (que es, ciertamente, por qué existe y no es solo basura recolectada).
Lo único que puedo imaginar es que una de las confirmaciones eliminadas fue, tal vez, la única confirmación de combinación que
filter-branch
realmente eliminó , y que creó la línea de tiempo paralela ya que cada hebra ahora no fusionada tomó su propia copia de las confirmaciones. ( encogiéndose de hombros ¿Dónde está mi TARDiS?) Estoy bastante seguro de que puedo solucionar este problema, aunque realmente me encantaría entender cómo sucedió.En el caso del loco mergefest-O-RAMA, probablemente lo dejaré solo, ya que se ha arraigado firmemente en mi historial de compromisos, amenazándome cada vez que me acerco, no parece estar causando realmente cualquier problema no cosmético y porque es bastante bonito en Tower.app.
fuente
La manera más fácil
git splits
. Lo creé como una extensión git, basado en la solución de jkeating .Dividir los directorios en una sucursal local.
#change into your repo's directory cd /path/to/repo #checkout the branch git checkout XYZ
#split multiple directories into new branch XYZ git splits -b XYZ XY1 XY2
Crea un repositorio vacío en alguna parte. Asumiremos que hemos creado un repositorio vacío llamado
xyz
en GitHub que tiene ruta:[email protected]:simpliwp/xyz.git
Empuje al nuevo repositorio.
#add a new remote origin for the empty repo so we can push to the empty repo on GitHub git remote add origin_xyz [email protected]:simpliwp/xyz.git #push the branch to the empty repo's master branch git push origin_xyz XYZ:master
Clone el repositorio remoto recién creado en un nuevo directorio local
#change current directory out of the old repo cd /path/to/where/you/want/the/new/local/repo #clone the remote repo you just pushed to git clone [email protected]:simpliwp/xyz.git
fuente
git splits
)Es posible que necesite algo como "git reflog expire --expire = now --all" antes de la recolección de basura para limpiar realmente los archivos. git filter-branch solo elimina referencias en el historial, pero no elimina las entradas de registro que contienen los datos. Por supuesto, prueba esto primero.
El uso de mi disco disminuyó drásticamente al hacer esto, aunque mis condiciones iniciales fueron algo diferentes. Quizás --subdirectory-filter niega esta necesidad, pero lo dudo.
fuente
Echa un vistazo al proyecto git_split en https://github.com/vangorra/git_split
Convierta los directorios de git en sus propios repositorios en su propia ubicación. No hay subárbol de negocios divertidos. Este script tomará un directorio existente en su repositorio git y lo convertirá en un repositorio independiente propio. En el camino, copiará todo el historial de cambios para el directorio que proporcionó.
fuente
Pon esto en tu gitconfig:
fuente
Estoy seguro de que git subtree está bien y es maravilloso, pero mis subdirectorios de código administrado por git que quería mover estaban en eclipse. Entonces, si está usando egit, es dolorosamente fácil. Tome el proyecto que desea mover y haga equipo-> desconéctelo, y luego equipo-> compártalo en la nueva ubicación. De forma predeterminada, intentará usar la ubicación del repositorio anterior, pero puede desmarcar la selección de uso existente y elegir el nuevo lugar para moverla. Todos granizan egit.
fuente
Puedes probar fácilmente el https://help.github.com/enterprise/2.15/user/articles/splitting-a-subfolder-out-into-a-new-repository/
Esto funcionó para mí. Los problemas que enfrenté en los pasos anteriores son
en este comando
git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME BRANCH-NAME
ElBRANCH-NAME
es maestrosi el último paso falla al comprometerse debido a un problema de protección, siga: https://docs.gitlab.com/ee/user/project/protected_branches.html
fuente
He encontrado una solución bastante sencilla, la idea es copiar el repositorio y luego simplemente eliminar la parte innecesaria. Así es como funciona:
1) Clona un repositorio que te gustaría dividir
2) Mover a la carpeta git
2) Eliminar carpetas innecesarias y confirmarlo
3) Eliminar el historial de formularios de carpetas innecesarias con BFG
4) Verifique que el historial no contenga los archivos / carpetas que acaba de eliminar
5) Ahora tiene un repositorio limpio sin ABC, así que simplemente empújelo a un nuevo origen
Eso es. Puede repetir los pasos para obtener otro repositorio,
simplemente elimine XY1, XY2 y cambie el nombre de XYZ -> ABC en el paso 3
fuente