我在子目录中有一个存储库,现在我想拥有父目录也在版本控制下,但保留当前的存储库历史记录。
所以用下面的树:
a/b/c
c
目前拥有一个存储库,但我想在a
中拥有一个存储库,并在c
中包含所有历史。
我敢肯定有一种方法可以做到这一点,也许是一些git filter-branch
?我不想使用子模块,我想有一个单一的存储库在最后。
您需要的是创建新的外部存储库,并使用子树合并合并内部存储库。在这个页面的底部有一个快速的如何做…你应该暂时将c移出a/b,这些指令期望c树在最终位置还不存在。
如果你想让c在过去的历史记录中嵌套(并且可以使用更改的sha1s),请使用filter-branch代替:
git filter-branch --index-filter
'git ls-files -s | sed "s#t#&a/b/c/#" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new
git update-index --index-info &&
mv -T "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' -- --all
你有一个选择:
您可以简单地将当前结构移动到将成为新结构的地方。然后把整个回购往上一层。git add -A
将添加所有的更改,这是一堆删除和新文件添加。git status
将显示它们是移动的。每个对象都存储一次,无论它在什么路径上,所以这不会是一个昂贵的操作。这是最简单的选择。此时,您还可以放入其他高级目录。
while in c:
mkdir b
cd b
mkdir c
mv <all other objects from top level> c
git add -A
git commit -m "moved everything"
mv c a
# clean up
git会判断一个文件是否被移动,如果你正在进行合并,它会帮助你。
或者,如果你喜欢,你可以使用过滤器分支来改变历史记录,但是你所有的提交都有不同的SHA1s。这可能是不希望的。
一个简单的mv不行吗?所有的'c'只会显示为一个重命名。
类似这样:(请不要剪切和粘贴,因为我还没有尝试过这个…只要抓住要点…)
cp -r /someroot/a/b/c /tmp/tmproot/c # make a full backup of the given repository
rm -Rf /someroot/a/b/c # completely remove c, leaving only a/b
mv -r /someroot/a /tmp/tmproot # moves a/b to the repository
cd /tmp/tmproot
git mv -r c a/b # git-moves c into a/b, so all history of c is retained
现在您的/tmp/tmproot目录应该有一个/b/c,并保留了c的历史记录
rm /someroot
mv -Rf /tmp/tmproot /someroot # replace the old rep with your new one
现在添加所有内容并提交