Разделить большой хранилище Git на многие более мелкие
После успешной конвертации SVN-репозитория в Git у меня теперь есть очень большой репозиторий Git, который я хочу разбить на несколько меньших репозиториев и сохранить историю.
Итак, может кто-то помочь с разбивкой репо, которое может выглядеть так:
MyHugeRepo/
.git/
DIR_A/
DIR_B/
DIR_1/
DIR_2/
В два репозитория, которые выглядят следующим образом:
MyABRepo/
.git
DIR_A/
DIR_B/
My12Repo/
.git
DIR_1/
DIR_2/
Я пробовал следующие указания в этом предыдущем вопросе, но это не очень подходит при попытке поместить несколько каталогов в отдельный репозиторий (подкаталог Detach (move) в отдельный Git репозиторий).
Ответы
Ответ 1
Это установит MyABRepo; вы тоже можете сделать My12Repo, конечно.
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
Относится ссылка на .git/refs/original/refs/heads/master. Вы можете удалить это с помощью:
cd ..
git clone MyABRepo.tmp MyABRepo
Если все пойдет хорошо, вы можете удалить MyABRepo.tmp.
Если по какой-то причине вы получите сообщение об ошибке .git-rewrite, вы можете попробовать следующее:
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
Это создаст и использует /tmp/ git-rewrite.tmp в качестве временного каталога вместо .git-rewrite
.
Естественно, вы можете заменить любой путь, а не /tmp/git-rewrite.tmp
, если у вас есть разрешение на запись, а каталог еще не существует.
Ответ 2
Вы можете использовать git filter-branch --index-filter
с git rm --cached
для удаления нежелательных каталогов из клонов/копий исходного хранилища.
Например:
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' "[email protected]") &&
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
Вам нужно будет вручную удалить все репозитории ненужных ветвей или тегов (например, если у вас есть ветка feature-x-for-AB, то вы, вероятно, захотите удалить ее из репозитория "12" ).
Ответ 3
Вот рубин script, который сделает это.
https://gist.github.com/4341033
Ответ 4
Проект git_split - это простой script, который делает именно то, что вы ищете. https://github.com/vangorra/git_split
Поверните каталоги git в свои собственные репозитории в своем собственном расположении. Нет поддерева смешного дела. Этот script будет использовать существующий каталог в вашем репозитории git и превратить этот каталог в самостоятельный собственный репозиторий. По пути он скопирует всю историю изменений для предоставленного вами каталога.
./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.
Ответ 5
Спасибо за ваши ответы, но в итоге я просто копировал репозиторий дважды, а затем удалял файлы, которые я не хотел от них. Я собираюсь использовать ветвь фильтра позже, чтобы вычеркнуть все коммиты для удаленных файлов, так как они уже контролируются версией в другом месте.
cp -R MyHugeRepo MyABRepo
cp -R MyHugeRepo My12Repo
cd MyABRepo/
rm -Rf DIR_1/ DIR_2/
git add -A
git commit -a
Это работало на то, что мне нужно.
EDIT: Конечно, то же самое было сделано в My12Repo против каталога A и B. Это дало мне два репозитория с одинаковой историей вплоть до того, что я удалил нежелательные каталоги.