为啥 `git svn clone` 不能转换所有的 SVN 分支?

Posted

技术标签:

【中文标题】为啥 `git svn clone` 不能转换所有的 SVN 分支?【英文标题】:Why does `git svn clone` not convert all SVN branches?为什么 `git svn clone` 不能转换所有的 SVN 分支? 【发布时间】:2021-10-06 07:30:26 【问题描述】:

我有一个 SVN 存储库,我正在使用 git svn 将其转换为 Git 存储库。该过程不会始终如一地将 SVN 分支转换为 Git 分支,我正在尝试找出原因。

我从svn_source/ 目录中的 SVN 存储库开始。这是一个适当的回购,而不是工作副本。如果我将工作副本签入svn_wc/,我可以明确列出其分支:

~$ svn checkout file://~/svn_source/ ~/svn_wc/
~$ cd svn_wc/
~/svn-wc$ ls -A1h branches/
1.0
1.1
1.2
1.3
2.0
3.0
3.0-alpha
3.0-beta
3.1-test

当我随后使用git svn clone 将 SVN 存储库(不是工作副本)克隆到完整的 Git 存储库中时,

~$ git svn clone --stdlayout --no-metadata file://~/svn_source/  ~/git_full/

~/git_full/.git/refs/remotes/origin/下只有三个SVN分支被转换为远程分支引用:

~/git_full/.git$ tree refs/     
refs/
├── heads/
│   └── master
├── remotes/
│   └── origin/
│       ├── 2.0
│       ├── 3.0-beta
│       ├── tags/
│       └── 3.1-test
└── tags/

5 directories, 4 files

为什么只有这三个被转换?我已经运行了三次git svn clone,而且总是这些。据我所知,它们并没有什么特别之处。

【问题讨论】:

请显示git show-ref 的输出而不是tree refs/。 Git 不仅将分支存储在.git/refs 之下的文件中,而且还存储在其他地方。 git show-ref 将所有预期的分支显示为<hash> refs/remotes/origin/<branchname> 行。所以我猜git svn clone 正在克隆每个 SVN 分支。知道为什么这三个分支可能会被挑出来明确地放在.git/refs/ 中吗? 查看我的答案加:“旧”分支已被打包到一个文件中,因为它们在最新的 SVN 修订版中没有更改。较新的分支在最新版本中更新得更频繁,因此(尚未)打包。 【参考方案1】:

您的tree refs/ 命令可能不会显示所有引用,因为 git 最终会将它们打包到文件 .git/packed-refs 中。这在git pack-refs 手册中有说明:

传统上,分支和标签的提示(统称为 refs) 每个引用存储一个文件在 $GIT_DIR/refs 下的(子)目录中 目录。虽然许多分支提示往往会经常更新,但大多数标签 并且一些分支提示永远不会更新。当一个存储库有数百个 或数千个标签,这种每个引用一个文件的格式都浪费存储空间 并损害性能。

要显示所有内容,请使用 git show-refgit for-each-ref

【讨论】:

以上是关于为啥 `git svn clone` 不能转换所有的 SVN 分支?的主要内容,如果未能解决你的问题,请参考以下文章

Git-svn clone

Windows 下的 git svn clone large repo:内存不足 - 不是大文件问题

在 git svn clone/fetch 期间避免“警告:有太多无法访问的松散对象”

SVN迁移到Git的过程(+ 一些技巧)

svn info对应git啥命令

SVN 向 GIT 进行转换如何拉取所有提交记录