【发布时间】:2013-07-26 16:16:09
【问题描述】:
场景如下:
我有一个大型 CVS 存储库,我想将其转换为 14 个不同的 git 存储库。
该过程的cvs2git 部分很好,并导致一个大型存储库 repo.git。
对于 14 个 git 存储库中的每一个,我都克隆了主存储库并运行以下命令:
git filter-branch -d /tmp/rep --tag-name-filter cat --prune-empty --subdirectory-filter "sub/directory" -- --all
但是,在执行此命令之前,我必须为某些 git 存储库执行另一个 git filter-branch 命令,因为我必须重写提交才能将文件从一个目录移动到另一个目录。 --tree-filter 是我使用的选项。以下是执行的命令行示例:
script_tree_filter="if test -f rep/to/my/file && test -d another/rep ; then echo Moving my file ; mv rep/to/my/file another/rep; fi"
git filter-branch -d /tmp/rep --tag-name-filter cat --prune-empty --tree-filter '$script_tree_filter' -- --all
在过程结束时(14500 次提交:大约需要 1 小时!)我清理了 refs 并使用git gc:
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git reflog expire --expire=now --all
git gc --prune=now
最后我得到了一个大小为 1.2Go 的存储库(这显然还是太大了),通过查看提交,我可以看到很多旧的仍然存在。它们涉及在--subdirectory-filter 命令之后不应再出现的文件和目录。
在提交的历史中,不想要的提交和好的提交之间存在不连续性,如 gitk --all 所示:
我很确定这些提交仍然存在,因为它们上有一些标签。如果是这种情况,是否可以在不删除良好提交的情况下删除这些标签?
如果标签不是原因,有什么想法吗?
更多信息,refs目录(在subdirectory-filter获取的git仓库中)的内容为空:
$ ls -R refs/
refs/:
heads original tags
refs/heads:
refs/original:
refs
refs/original/refs:
heads tags
refs/original/refs/heads:
refs/original/refs/tags:
refs/tags:
我发现分支和标签都列在了git仓库的packed-refs文件中:
d0c675d8f198ce08bb68f368b6ca83b5fea70a2b refs/tags/v03-rev-04
95c3f91a4e92e9bd11573ff4bb8ed4b61448d8f7 refs/tags/v03-rev-05
文件中列出了817个标签和219个分支。
【问题讨论】:
-
git gc会将标签引用打包到 .git/packed-refs 中,因此是空目录。我不确定为什么标签会指向旧的提交,因为每个过滤器分支操作都使用--tag-name-filter.... -
你按照本帖的4条命令清理了吗? stackoverflow.com/a/7966852/11343
-
除了
reset hard,我执行了我的问题中提到的其他 3 个命令(rm -rf .git/refs/original/的编写方式不同,因为我有一个裸存储库)。我没有使用gc的--agressive选项,但我不能尝试(我认为它不会改变任何东西)。 -
所以您问题中的
ls登录不是最新的,是吗?里面有refs/original的东西。另外请在您的 cmets 中使用@user,否则我们不会收到通知 -
@CharlesB
ls日志是最新的:refs/original 中的所有目录都是空的(使用命令update-ref -d)。
标签: git tree git-filter-branch disconnected