我的仓库中有几个子树(例如./sub1/
,,./sub2/
..),我想将它们提取到单独的仓库中,保持提交历史和相同的目录结构,即一个新的仓库sub1
应该有./sub1/
来自主仓库的子树。我怎样才能做到这一点?
问问题
942 次
1 回答
5
您可以将 git 的过滤器分支与子树过滤器一起使用。
以下是步骤:
克隆工作副本。此操作将更改本地 repo,因此我们必须首先有一个工作副本。你可以像下面那样做一个 git clone 或者只是复制它。
git clone --no-hardlinks <original repository> <working copy>
使用子树过滤器。
cd <working copy> git filter-branch --subdirectory-filter <subdir path to be splited> --prune-empty --tag-name-filter cat -- --all # reset current working directory git reset --hard
我们已经完成了我们的任务,最好做一些清理工作,因为很多旧对象变得无法访问。
删除旧遥控器
git remote rm origin
删除旧的 reflog
# clean unneeded reflog in order to free space refbak=$(git for-each-ref --format="%(refname)" refs/original/) if [ -n "$refbak" ];then echo -n $refbak | xargs -n 1 git update-ref -d fi git reflog expire --expire=now --all
重新打包并压缩 repo
# prune loose objects git gc --aggressive --prune=now
这将使回购结构从
repo/
|-- sub1/
|-- sub11
|-- sub12
|-- sub2
至
repo/
|-- sub11
|-- sub12
但是,看起来你希望它变成
repo/
|-- sub1/
|-- sub11
|-- sub12
然后,还需要做一个步骤,用 index-filter 重写 git commit 历史。
# replace <subdir path> with the actual subdir path, for this case, it should be "sub1"
git filter-branch --index-filter 'git ls-files -s | sed "s-\t-&<subdir path>/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD
于 2012-10-10T11:41:06.327 回答