我有一个存储库,我想将其目录之一分离到一个新的存储库中。This是一个完美的起点,但是有一个警告:我想要分离的目录在某个时候被重命名。如果我按照该帖子中的解决方案使用目录的新名称,那么我似乎会丢失重命名之前的历史记录。有什么想法可以调整以使其在这种情况下发挥作用吗?
git filter-branch
可以对提交范围进行操作;所以我们能做的就是分别过滤“之前”和“之后”,然后使用移植将它们粘在一起:
git branch rename $COMMIT_ID_OF_RENAME
git branch pre-rename rename~
## First filter all commits up to rename, but not rename itself
git filter-branch --subdirectory-filter $OLDNAME pre-rename
## Add a graft, so our rename rev comes after the processed pre-rename revs
echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts
## The first filter-branch left a refs backup directory. Move it away so the
## next filter-branch doesn't complain
mv .git/refs/original .git/refs/original0
## Now filter the rest
git filter-branch --subdirectory-filter $NEWNAME master ^pre-rename
## The graft is now baked into the branch, so we don't need it anymore
rm .git/info/grafts
如果您需要过滤多个分支或标签,这会稍微复杂一些;重命名之前的分支可以包含在第一个过滤器分支中,而之后的分支必须包含在重命名之前^rename
在第二个过滤器分支中。
另一种选择是添加索引过滤器(或树过滤器)来检查旧目录和新目录,并保留存在的目录。
由于您尚未提供测试存储库,因此这里有一个针对此场景的快速健全性检查脚本:
#!/bin/bash
set -u
set -e
set -x
rm -rf .git x y foo
git init
mkdir x
echo initial > x/foo
git add x/foo
git commit -m 'test commit 1'
echo tc2 >> x/foo
git commit -a -m 'test commit 2'
mv x y
git rm x/foo
git add y/foo
git commit -a -m 'test rename'
git branch rename HEAD
echo post rename >> y/foo
git commit -a -m 'test post rename'
git branch pre-rename rename~
git filter-branch --subdirectory-filter x pre-rename
echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts
mv .git/refs/original .git/refs/original0
git filter-branch --subdirectory-filter y master ^pre-rename
rm .git/info/grafts
git log -u
如果此过程对您不起作用,那么您的存储库历史记录中可能存在您尚未描述的其他奇怪情况,例如隐藏在历史记录中的另一个重命名。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)