我有一个Git存储库,其中包含许多子目录.现在我发现其中一个子目录与另一个子目录无关,应该分离到一个单独的存储库.
如何在将文件的历史记录保存在子目录中的同时执行此操作?
我想我可以制作一个克隆并删除每个克隆的不需要的部分,但我想这会给我一个完整的树,当检查旧版本等.这可能是可以接受的,但我宁愿能够假装两个存储库没有共享历史记录.
为了说清楚,我有以下结构:
XYZ/
.git/
XY1/
ABC/
XY2/
Run Code Online (Sandbox Code Playgroud)
但我想这样做:
XYZ/
.git/
XY1/
XY2/
ABC/
.git/
ABC/
Run Code Online (Sandbox Code Playgroud) 我们的Git存储库最初是作为单个怪物SVN存储库的一部分开始的,其中每个项目都有自己的树,如下所示:
project1/branches
/tags
/trunk
project2/branches
/tags
/trunk
Run Code Online (Sandbox Code Playgroud)
显然,将文件从一个文件移动到另一个文件非常容易svn mv.但在Git中,每个项目都在自己的存储库中,今天我被要求将子目录从中移动project2到project1.我做了这样的事情:
$ git clone project2
$ cd project2
$ git filter-branch --subdirectory-filter deeply/buried/java/source/directory/A -- --all
$ git remote rm origin # so I don't accidentally the repo ;-)
$ mkdir -p deeply/buried/different/java/source/directory/B
$ for f in *.java; do
> git mv $f deeply/buried/different/java/source/directory/B
> done
$ git commit -m "moved files to new subdirectory"
$ cd ..
$
$ git clone project1
$ cd project1
$ …Run Code Online (Sandbox Code Playgroud) 我们当前的repo有成千上万的提交,一个新的克隆传输几乎一堆数据(有很多jar文件已经被删除了历史).我们希望通过创建一个新的repo来缩小此大小,该repo仅保留repo中当前活动的文件的完整历史记录,或者可能只修改当前repo以清除已删除的文件历史记录.但我不确定如何在实际庄园中做到这一点.
for del in `cat deleted.txt`
do
git filter-branch --index-filter "git rm --cached --ignore-unmatch $del" --prune-empty -- --all
# The following seems to be necessary every time
# because otherwise git won't overwrite refs/original
git reset --hard
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git reflog expire --expire=now --all
git gc --aggressive --prune=now
done;
Run Code Online (Sandbox Code Playgroud)
但鉴于我们在历史上有数以万计的已删除文件和成千上万的提交,运行脚本将需要一个永恒的时间.2小时前我开始运行这个只删除一个文件,filter-branch命令仍在运行,它一次一个地进行40,000多次提交,这是一个带有SSD驱动器的新Macbook pro.
我还阅读了https://help.github.com/articles/remove-sensitive-data页面,但这仅适用于删除单个文件.
有没有人能够做到这一点?我真的想保留当前跟踪文件的历史记录,如果我们无法保留历史记录,我不确定节省空间的好处是否值得创建一个新的回购.