una toda subir repositorio omitir nueva ignorar dentro crear como carpetas carpeta git git-submodules git-subtree git-filter-branch

subir - git divide el repositorio por subcarpeta y conserva todas las ramas antiguas



omitir carpetas git (2)

Respuesta corta

git filter-branch ofrece exactamente la funcionalidad que desea. Con la opción --subdirectory-filter puede crear un nuevo conjunto de confirmaciones donde el contenido de subDirectory encuentra en la raíz del directorio.

git filter-branch --prune-empty --subdirectory-filter subDirectory -- --branches

Recorrido

El siguiente es un ejemplo para realizar esto de una manera segura. dir1 realizar esto para cada subdirectorio que se aislará en su propio repositorio, en este caso dir1 .

Primero clona tu repositorio para mantener los cambios aislados:

git clone yourRemote dir1Clone cd dir1Clone

Para preparar el repositorio clonado, recrearemos todas las ramas remotas como locales. Nos saltamos el que comienza con * ya que esa es la rama actual, que en este caso sería de lectura (no branch) ya que estamos en un estado sin cabeza:

# move to a headless state # in order to delete all branches without issues git checkout --detach # delete all branches git branch | grep --invert-match "*" | xargs git branch -D

Para recrear todas las sucursales remotas localmente, veremos los resultados de git branch --remotes . Nos saltamos los que contienen -> ya que no son ramas:

# get all local branches for remote git branch --remotes --no-color | grep --invert-match "/->" | while read remote; do git checkout --track "$remote" done # remove remote and remote branches git remote remove origin

Finalmente ejecute el comando filter-branch . Esto creará nuevas confirmaciones con todas las confirmaciones que tocan el subdirectorio dir1 . Todas las ramas que también toquen este subdirectorio se actualizarán. La salida mostrará una lista de todas las referencias que no se actualizaron, como es el caso de las sucursales que no tocan dir1 en absoluto.

# Isolate dir1 and recreate branches # --prune-empty removes all commits that do not modify dir1 # -- --all updates all existing references, which is all existing branches git filter-branch --prune-empty --subdirectory-filter dir1 -- --all

Después de esto, tendrá un nuevo conjunto de confirmaciones que tienen dir1 en la raíz del repositorio. Solo agregue su control remoto para enviar los nuevos compromisos, o use estos como un nuevo repositorio por completo.

Como último paso adicional si te importa el tamaño del repositorio:

Incluso si todas las sucursales donde se actualizó su repositorio seguirán teniendo todos los objetos del repositorio original, solo se podrá acceder a ellos a través de los registros de ref. Si quieres soltar estos, lee cómo hacer basura recolecta confirmaciones.

Algunos recursos adicionales:

Tengo un repositorio git con 2 directorios y varias sucursales, quiero dividirlas y crear todas las sucursales

`-- Big-repo |-- dir1 `-- dir2 Branches : branch1, branch2, branch3 ...

Lo que quiero

Quiero dividir dir1 y dir2 como dos repositorios separados y retener las ramas branch1, branch2 ... en ambos repositorios.

dir1 Branches : branch1, branch2, branch3 ... dir2 Branches : branch1, branch2, branch3 ...

Lo que intenté:

Soy capaz de dividirlos en 2 repos utilizando

git subtree split -P dir1 -b dir1-only git subtree split -P dir2 -b dir2-only

Pero, no está creando ninguna rama después de la separación.

Para obtener todas las ramas:

git checkout branch1 (in Big-repo) git subtree split -p dir1 -b dir1-branch1 git checkout branch2 (in Big-repo) git subtree split -p dir1 -b dir1-branch2 And push these branches to newly created repo.

¿Esto implica un mayor esfuerzo manual y estoy seguro de que podría haber una manera rápida de lograrlo?

¿¿¿Algunas ideas???


Este script hace el trabajo por mí:

#!/bin/bash set -e if [ -z "$3" ]; then echo "usage: $0 /full/path/to/repository path/to/splitfolder/from/repository/root new_origin" exit fi repoDir=$1 folder=$2 newOrigin=$3 cd $repoDir git checkout --detach git branch | grep --invert-match "*" | xargs git branch -D for remote in `git branch --remotes | grep --invert-match "/->"` do git checkout --track $remote git add -vA * git commit -vam "Changes from $remote" || true done git remote remove origin git filter-branch --prune-empty --subdirectory-filter $folder -- --all #prune old objects rm -rf .git/refs/original/* git reflog expire --all --expire-unreachable=0 git repack -A -d git prune #upload to new remote git remote add origin $newOrigin git push origin master for branch in `git branch | grep -v ''/*''` do git push origin $branch done