如何将 svn:externals 转换为 git 标签

How to convert svn:externals to git tags

我正在努力转换一个相当大的 SVN 存储库。它是约 50 个项目,包括约 5 个不同的可交付产品(一些项目在所有产品之间共享,其他项目仅与几个产品共享,以及许多项目是特定产品所独有的)。这里有大约 15 年的代码历史(~16K svn 修订版)。

在转换为 SVN 后的早期,我们使用 SVN:externals 来标记我们的一些版本。我们的代码结构(结帐后在磁盘上)如下:

product1_root
  -> shared_project
  -> project_1
  -> project_2
  -> project_3
product2_root
  -> shared_project
  -> project_4
  -> project_5

SVN中的结构如下(b/t/tr) = standard branches/tags/trunk subdirs:

product1_root (b/t/tr)
shared_project (b/t/tr)
project_1 (b/t/tr)
project_2 (b/t/tr)
project_3 (b/t/tr)
product2_root (b/t/tr)
project_4 (b/t/tr)
project_5 (b/t/tr)

使用外部时,外部在 product1_root 和 product2_root 项目上分别设置为 shared/project2/3 和 shared/project4/5 中的 link,以便它们创建以上结构在磁盘上。因此,在发布时,只有 product1/2_root 项目收到标签(SVN 外部会自动拉取子项目的适当版本)。

我们后来摆脱了外部因素,转而明确标记所有项目并使用脚本将它们全部拉出来进行构建。

有没有办法在迁移过程中将标签从 product1_root 传播到 project_1、project_2、project_3 和 shared_project,以便它们匹配新 git 存储库中的其余历史记录。

或者我是否应该考虑尝试将此作为迁移前任务或 post 迁移任务来解决?

我看过很多不同的工具,它们似乎要么完全忽略 svn:externals,要么尝试将它们转换为子模块。

我终于明白了。请记住,我的 svn:externals 设置为指向回购协议中的特定挂钩(不是头部),因此如果您不在同一条船上,这可能不起作用。

此外,您从 SVN 到 git 的迁移必须按时间顺序完成,因为 SVN 中的修订历史必须按顺序处理。以下两个命令将执行此操作 (source):

git svn init [SVN repo url] --stdlayout --prefix=svn/
git svn fetch

这假设您有一个标准的 SVN 存储库布局 (branches/tags/trunk)。如果您的不同,则需要修改上述命令。上面的命令还为所有内容加上 svn/ 前缀,只是为了表明这些内容是从 svn 导入的,而不是本地 git 创建的内容(以备将来需要时参考)。

完成后(从我的 16K 修订版 SVN 存储库中提取单个项目大约需要 90 分钟)。然后,您可以在 SVN 存储库中查找 svn:externals 标记的创建日期,并使用以下命令找出与您的项目相关的适当 git 提交:

git log --before='CCYY-MM-DD' -1

输出将采用以下格式:

commit a22182ca563928b4de2143ff98dd0362f9eca36d
Author: <author>
Date:   Wed Oct 31 21:58:01 2012 +0000

<Commit comment>

最后,获取提交哈希的前几个字符并在 git:

中创建您的标签
git tag -a v6.1.1.3 a22182 -m "manually creating git tag for svn:externals based tag"

验证您的 git 存储库和 SVN 存储库中的标签是否相同,然后继续进行其余的转换。