Pregunta Divide el gran repositorio de Git en muchos más pequeños


Después de convertir con éxito un repositorio SVN a Git, ahora tengo un repositorio de Git muy grande que quiero descomponer en varios repositorios más pequeños y mantener el historial.

Entonces, ¿alguien puede ayudar a romper un repositorio que podría verse así?

MyHugeRepo/
   .git/
   DIR_A/
   DIR_B/
   DIR_1/
   DIR_2/

En dos repositorios que se ven así:

MyABRepo/
   .git
   DIR_A/
   DIR_B/

My12Repo/
   .git
   DIR_1/
   DIR_2/

Intenté seguir instrucciones en esta pregunta anterior, pero no encaja realmente cuando trato de poner varios directorios en un repositorio separado (Separar (mover) el subdirectorio en un repositorio separado de Git)


76
2017-10-11 22:32


origen


Respuestas:


Esto configurará MyABRepo; puedes hacer My12Repo de manera similar, por supuesto.

git clone MyHugeRepo/ MyABRepo.tmp/
cd MyABRepo.tmp
git filter-branch --prune-empty --index-filter 'git rm --cached --ignore-unmatch DIR_1/* DIR_2/*' HEAD 

Una referencia a .git / refs / original / refs / heads / master permanece. Puedes eliminar eso con:

cd ..
git clone MyABRepo.tmp MyABRepo

Si todo fue bien, entonces puedes eliminar MyABRepo.tmp.


Si por alguna razón obtienes un error con respecto a .git-rewrite, puedes probar esto:

git clone MyHugeRepo/ MyABRepo.tmp/
cd MyABRepo.tmp
git filter-branch -d /tmp/git-rewrite.tmp --prune-empty --index-filter 'git rm --cached --ignore-unmatch DIR_1/* DIR_2/*' HEAD 
cd ..
git clone MyABRepo.tmp MyABRepo

Esto creará y usará /tmp/git-rewrite.tmp como un directorio temporal, en lugar de .git-rewrite. Naturalmente, puede sustituir cualquier camino que desee en lugar de /tmp/git-rewrite.tmp, siempre y cuando tenga permiso de escritura, y el directorio aún no existe.


71
2017-10-11 23:37



Podrías usar git filter-branch --index-filter con git rm --cached para eliminar los directorios no deseados de clones / copias de su repositorio original.

Por ejemplo:

trim_repo() { : trim_repo src dst dir-to-trim-out...
  : uses printf %q: needs bash, zsh, or maybe ksh
  git clone "$1" "$2" &&
  (
    cd "$2" &&
    shift 2 &&

    : mirror original branches &&
    git checkout HEAD~0 2>/dev/null &&
    d=$(printf ' %q' "$@") &&
    git for-each-ref --shell --format='
      o=%(refname:short) b=${o#origin/} &&
      if test -n "$b" && test "$b" != HEAD; then 
        git branch --force --no-track "$b" "$o"
      fi
    ' refs/remotes/origin/ | sh -e &&
    git checkout - &&
    git remote rm origin &&

    : do the filtering &&
    git filter-branch \
      --index-filter 'git rm --ignore-unmatch --cached -r -- '"$d" \
      --tag-name-filter cat \
      --prune-empty \
      -- --all
  )
}
trim_repo MyHugeRepo MyABRepo DIR_1 DIR_2
trim_repo MyHugeRepo My12Repo DIR_A DIR_B

Deberá eliminar manualmente las ramas o etiquetas innecesarias de cada repositorio (por ejemplo, si tiene una feature-x-for-AB rama, entonces probablemente quiera eliminar eso del repositorio "12").


9
2017-10-12 00:01



Aquí hay un script de ruby ​​que lo hará. https://gist.github.com/4341033


3
2017-12-19 22:26



El proyecto git_split es un script simple que hace exactamente lo que estás buscando. https://github.com/vangorra/git_split

Convierta los directorios de git en sus propios repositorios en su propia ubicación. Sin subárbol de negocios divertidos. Este script tomará un directorio existente en su repositorio de git y lo convertirá en un repositorio independiente propio. En el camino, se copiará durante todo el historial de cambios para el directorio que proporcionó.

./git_split.sh <src_repo> <src_branch> <relative_dir_path> <dest_repo>
        src_repo  - The source repo to pull from.
        src_branch - The branch of the source repo to pull from. (usually master)
        relative_dir_path   - Relative path of the directory in the source repo to split.
        dest_repo - The repo to push to.

3
2018-01-06 02:45



Gracias por sus respuestas, pero terminé simplemente copiando el repositorio dos veces y borrando los archivos que no quería de cada uno. Voy a utilizar la rama de filtro en una fecha posterior para eliminar todas las confirmaciones de los archivos eliminados, ya que ya están controlados por la versión en otro lugar.

cp -R MyHugeRepo MyABRepo
cp -R MyHugeRepo My12Repo

cd MyABRepo/
rm -Rf DIR_1/ DIR_2/
git add -A
git commit -a

Esto funcionó para lo que necesitaba.

EDITAR: Por supuesto, lo mismo se hizo en el My12Repo contra el directorio A y B. Esto me dio dos repositorios con idéntica historia hasta el punto en que eliminé los directorios no deseados.


0
2017-10-20 17:34