Diviser le grand dépôt Git en plusieurs plus petits
après avoir converti avec succès un dépôt SVN en git, j'ai maintenant un très grand dépôt Git que je veux décomposer en plusieurs dépôts plus petits et maintenir l'histoire.
alors, quelqu'un peut-il aider à briser une pension qui pourrait ressembler à ceci:
MyHugeRepo/
.git/
DIR_A/
DIR_B/
DIR_1/
DIR_2/
dans deux dépôts qui ressemblent à ceci:
MyABRepo/
.git
DIR_A/
DIR_B/
My12Repo/
.git
DIR_1/
DIR_2/
j'ai essayé de suivre les directions dans cette question précédente, mais il n'est pas vraiment convient lorsque vous essayez de mettre plusieurs répertoires dans un rapport séparé ( Detach (move) subdirectory dans le dépôt git séparé ).
5 réponses
cela va configurer MyABRepo; vous pouvez faire My12Repo de la même façon 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 .git/refs/original/refs/heads/master reste. Vous pouvez supprimer cela avec:
cd ..
git clone MyABRepo.tmp MyABRepo
si tout s'est bien passé, vous pouvez alors enlever MyABRepo.tmp.
Si pour une raison quelconque, vous obtenez un message d'erreur concernant .git-rewrite, 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 créera et de l'utilisation /tmp/git-réécriture.tmp en tant que répertoire temporaire, au lieu de .git-rewrite
.
Naturellement, vous pouvez substituer n'importe quel chemin que vous voulez au lieu de /tmp/git-rewrite.tmp
, tant que vous avez la permission d'écrire, et que le répertoire n'existe pas déjà.
vous pouvez utiliser git filter-branch --index-filter
avec git rm --cached
pour supprimer les répertoires indésirables des clones/copies de votre dépôt original.
par exemple:
trim_repo() { : trim_repo src dst dir-to-trim-out...
: uses printf %q: needs bash, zsh, or maybe ksh
git clone "" "" &&
(
cd "" &&
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 étiquettes non nécessaires de chaque dépôt (par exemple, si vous aviez une branche -X-for-AB , vous voudrez probablement supprimer cela du dépôt" 12").
voici un script ruby qui le fera. https://gist.github.com/4341033
le projet git_split est un script simple qui fait exactement ce que vous recherchez. https://github.com/vangorra/git_split
transforment les répertoires git en leurs propres dépôts dans leur propre emplacement. Pas de sous-arbre drôle d'affaires. Ce script prendra un répertoire existant dans votre dépôt git et le transformera en un dépôt indépendant. En cours de route, il copiera sur l'ensemble de l'histoire du changement répertoire que vous avez fourni.
./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.
Merci pour vos réponses mais j'ai fini par copier le dépôt deux fois puis supprimer les fichiers que je ne voulais pas de chacun. Je vais utiliser la branche filter à une date ultérieure pour supprimer toutes les propagations pour les fichiers supprimés car ils sont déjà contrôlés ailleurs.
cp -R MyHugeRepo MyABRepo
cp -R MyHugeRepo My12Repo
cd MyABRepo/
rm -Rf DIR_1/ DIR_2/
git add -A
git commit -a
ça a marché 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 les repos avec une histoire identique jusqu'au point où j'ai supprimé les répertoires indésirables.