在 cvs2git 迁移中删除早于 x 的历史记录

Drop history older than x on cvs2git Migration

我们计划将我们最后一个大型 CVS 存储库迁移到 Git 存储库中。

对于迁移,我们使用 svn2git 的 cvs2git。因为这个 CVS 存储库已经增长了 ~ 12 年,它有 31GB 的数据。

我找不到任何解决方案来删除所有早于指定时间段(例如 2 年)的历史记录。

你知道其中一个 tool/command/resolution 吗?:

谢谢和问候, 安德烈亚斯

Dmitry Oksenchuk 建议的解决方案: 编辑移植后,我写了一个 BASH 脚本 tp clean up messed up tags and branches:

#!/bin/bash

NEW_ROOT_REF=
git tag --contains $NEW_ROOT_REF | sort  > TAGS_TO_KEEP.tmp
echo "Keep Tags:"
cat TAGS_TO_KEEP.tmp | wc -w

git branch --contains $NEW_ROOT_REF | sort  > BRANCHES_TO_KEEP.tmp
echo "Keep Branches:"
cat BRANCHES_TO_KEEP.tmp | wc -w

git tag -l | sort > TAGS_ALL.tmp
echo "All Tags:"
cat TAGS_ALL.tmp | wc -w

git branch -l | sort > BRANCHES_ALL.tmp
echo "All Branchess:"
cat BRANCHES_ALL.tmp | wc -w

# Remove tags
COUNTER=0
for drop in `comm TAGS_ALL.tmp TAGS_TO_KEEP.tmp -23`; do
        git tag -d $drop
        COUNTER=$[$COUNTER +1]
done
echo "Dropped tags: $COUNTER"

# Remove branches
COUNTER=0
for drop in `comm BRANCHES_ALL.tmp BRANCHES_TO_KEEP.tmp -23`; do
        git branch -D $drop
        COUNTER=$[$COUNTER +1]
done
echo "Dropped branches: $COUNTER"

# Clean up
rm TAGS_ALL.tmp TAGS_TO_KEEP.tmp BRANCHES_ALL.tmp BRANCHES_TO_KEEP.tmp

在结构良好的 Git 回购历史深度通常不是问题。在 linux 回购中有超过 500k 的提交并且它工作正常。今年我们将一个 ~15 年前的 CVS 存储库(5GB ,v 文件)迁移到 Git。 Git 存储库占用约 200MB 并包含约 70k 次提交。

我们面临两个主要问题:二进制文件和标签数量。

二进制文件

在 CVS 中,二进制文件的所有修订都存储在服务器上,只有当前修订才会在结帐时传输。所以在 CVS 中存储二进制文件完全不是问题,你只需要在服务器上有足够的磁盘 space 即可。 Git 情况不同。当您克隆 Git 存储库时,二进制文件的所有修订都会传输到您的本地克隆。即使文件在最近的提交中不存在,它的所有历史修订都在您的本地存储库中。通过从历史记录中删除不需要的二进制文件,我们设法将 Git 存储库的大小从 ~700MB 缩小到 ~200MB。这里的重点是根据 Git 中的文件大小而不是 CVS 中的文件大小做出决定。 Git 使用 zlib 压缩和 delta 压缩打包对象,因此同一文件的历史记录在 Git 和 CVS 中可以占用完全不同的磁盘 space。您可以在 Git 扩展中使用 "Find large files" 插件。

标签数量

我们在 CVS 存储库中有超过 20k 个构建标签。对于如此多的标签,Git 扩展和源代码树都工作得非常慢(尤其是当它们需要将所有标签加载到下拉列表中时)。 git push 与 Git 1.9.5 也非常慢,因为 Git 2.3.0 中的性能回归 fixed。目前在 Git 我们只保留最近 2 年的构建标签(~7k 标签)定期归档旧标签。

删除旧历史

如果您仍然需要它,在 Git 中删除旧历史记录比在 CVS 中或在迁移过程中更容易和更安全。

  1. grafts 文件中设置新的根提交:echo %commit_hash% >.git/info/grafts
  2. 删除所有不包含该提交的标签和分支(参见 git tag --containsgit branch --contains
  3. 重写提交图:git filter-branch --tag-name-filter cat -- --all

或者,您也可以解析 git-dump.dat 文件(cvs2git 的输出 git 快速导入格式)并从那里删除旧的提交、标签和分支。