将大型 Git 存储库拆分为许多较小的存储库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3910412/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Split large Git repository into many smaller ones
提问by MikeM
After successfully converting an SVN repository to Git, I now have a very large Git repository that I want to break down into multiple smaller repositories and maintain history.
成功将 SVN 存储库转换为 Git 后,我现在有一个非常大的 Git 存储库,我想将其分解为多个较小的存储库并维护历史记录。
So, can someone help with breaking up a repo that might look like this:
那么,有人可以帮助分解可能如下所示的回购协议:
MyHugeRepo/
.git/
DIR_A/
DIR_B/
DIR_1/
DIR_2/
Into two repositories that look like this:
进入两个看起来像这样的存储库:
MyABRepo/
.git
DIR_A/
DIR_B/
My12Repo/
.git
DIR_1/
DIR_2/
I've tried following directions in this previous question but it doesn't really fit when trying to put multiple directories into a separate repo (Detach (move) subdirectory into separate Git repository).
我已经尝试按照上一个问题中的说明进行操作,但是在尝试将多个目录放入单独的存储库(将子目录分离 (移动) 到单独的 Git 存储库中)时,它并不真正适合。
回答by unutbu
This will setup MyABRepo; you can do My12Repo similarly of course.
这将设置 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
A reference to .git/refs/original/refs/heads/master remains. You can remove that up with:
对 .git/refs/original/refs/heads/master 的引用仍然存在。你可以删除它:
cd ..
git clone MyABRepo.tmp MyABRepo
If all went well you can then remove MyABRepo.tmp.
如果一切顺利,您可以删除 MyABRepo.tmp。
If for some reason you get an error regarding .git-rewrite, you can try this:
如果由于某种原因你收到关于 .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
This will create and use /tmp/git-rewrite.tmp as a temporary directory, instead of .git-rewrite
.
Naturally, you can substitute any path you wish instead of /tmp/git-rewrite.tmp
, so long as you have write permission, and the directory does not already exist.
这将创建并使用 /tmp/git-rewrite.tmp 作为临时目录,而不是.git-rewrite
. 当然,您可以替换任何您希望的路径而不是/tmp/git-rewrite.tmp
,只要您有写权限,并且该目录不存在。
回答by Chris Johnsen
You could use git filter-branch --index-filter
with git rm --cached
to delete the unwanted directories from clones/copies of your original repository.
您可以使用git filter-branch --index-filter
withgit rm --cached
从原始存储库的克隆/副本中删除不需要的目录。
For example:
例如:
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
You will need to manually delete each repository's unneeded branches or tags (e.g. if you had a feature-x-for-ABbranch, then you probably want to delete that from the “12” repository).
您将需要手动删除每个存储库不需要的分支或标签(例如,如果您有一个feature-x-for-AB分支,那么您可能希望从“12”存储库中删除它)。
回答by vangorra
The git_split project is a simple script that does exactly what you are looking for. https://github.com/vangorra/git_split
git_split 项目是一个简单的脚本,它完全符合您的要求。https://github.com/vangorra/git_split
Turn git directories into their very own repositories in their own location. No subtree funny business. This script will take an existing directory in your git repository and turn that directory into an independent repository of its own. Along the way, it will copy over the entire change history for the directory you provided.
将 git 目录变成他们自己位置的自己的存储库。没有子树有趣的业务。此脚本将在您的 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.
回答by EnabrenTane
Here is a ruby script that will do it. https://gist.github.com/4341033
这是一个可以做到这一点的 ruby 脚本。 https://gist.github.com/4341033
回答by MikeM
Thanks for your answers but I ended up just copying the repository twice then deleting the files I didn't want from each. I am going to use the filter-branch at a later date to strip out all the commits for the deleted files since they are already version controlled elsewhere.
感谢您的回答,但我最终只是复制了存储库两次,然后删除了我不想要的文件。稍后我将使用 filter-branch 去除已删除文件的所有提交,因为它们已经在其他地方进行了版本控制。
cp -R MyHugeRepo MyABRepo
cp -R MyHugeRepo My12Repo
cd MyABRepo/
rm -Rf DIR_1/ DIR_2/
git add -A
git commit -a
This worked for what I needed.
这对我所需要的有用。
EDIT: Of course, the same thing was done in the My12Repo against the A and B directory. This gave me two repos with identical history up to the point I deleted the unwanted directories.
编辑:当然,在 My12Repo 中针对 A 和 B 目录做了同样的事情。这给了我两个具有相同历史记录的存储库,直到我删除了不需要的目录。