87 votes

Divisez un grand référentiel Git en plusieurs plus petits

Après le succès de la conversion d'un dépôt SVN à Git, j'ai maintenant un très grand dépôt Git que je veux décomposer en plusieurs petits dépôts et de maintenir l'histoire.

Donc, quelqu'un peut aider avec la coupure des pensions qui pourrait ressembler à ceci:

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

Dans les deux référentiels qui ressemblent à ceci:

MyABRepo/
   .git
   DIR_A/
   DIR_B/

My12Repo/
   .git
   DIR_1/
   DIR_2/

J'ai essayé en suivant les instructions de cette question précédente, mais il n'a pas vraiment d'ajustement lors de la tentative de placer plusieurs répertoires dans un repo (http://stackoverflow.com/questions/359424/detach-subdirectory-into-separate-git-repository).

80voto

unutbu Points 222216

Cela va de l'installation MyABRepo; vous pouvez faire My12Repo de même bien sûr.

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 

Une référence pour .git/refs/original/refs/heads/master reste. Vous pouvez le retirer avec:

cd ..
git clone MyABRepo.tmp MyABRepo

Si tout va bien, vous pouvez alors retirer MyABRepo.tmp.


Si pour une raison quelconque, vous obtenez un message d'erreur concernant .git-réécrire, vous pouvez essayer ceci:

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

Cela permettra de créer et d'utiliser /tmp/git-réécriture.tmp comme un répertoire temporaire, au lieu de .git-rewrite. Naturellement, vous pouvez remplacer n'importe quel chemin d'accès que vous souhaitez à la place de /tmp/git-rewrite.tmp, aussi longtemps que vous avez la permission d'écriture, et le répertoire n'existe pas déjà.

10voto

Chris Johnsen Points 50064

Vous pouvez utiliser git filter-branch --index-filter avec git rm --cached pour supprimer les répertoires non désirés des clones / copies de votre référentiel d'origine.

Par exemple:

 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
 

Vous devrez supprimer manuellement les branches ou les balises inutiles de chaque référentiel (par exemple, si vous aviez une branche feature-x-for-AB , vous souhaiterez probablement la supprimer du référentiel "12").

4voto

EnabrenTane Points 5262

Voici un script ruby qui le fera. https://gist.github.com/4341033

1voto

MikeM Points 262

Merci pour vos réponses mais j'ai fini par copier le référentiel deux fois puis supprimer les fichiers, je n'ai pas envie de chacun. Je vais utiliser le filtre-branche à une date ultérieure à dépouiller tous les commits pour les fichiers supprimés car ils sont déjà la version contrôlée ailleurs.

cp -R MyHugeRepo MyABRepo
cp -R MyHugeRepo My12Repo

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

Il a travaillé pour ce dont j'avais besoin.

EDIT: bien sûr, la même chose a été fait dans la My12Repo contre A et B répertoire. Cela m'a donné deux repos à l'identique de l'histoire jusqu'au point que j'ai supprimé les indésirables répertoires.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X