- 文档
- 教程
【免费下载链接】training-kit
Open source courseware for Git and GitHub
本文围绕 GitHub Training Kit(本仓库,GitHub Professional Services 团队维护的开源培训材料)中的官方速查表文档展开,系统讲解从 Subversion(SVN)迁移到 Git 与 GitHub 的完整路径:既包括面向公网仓库的 GitHub Importer 自动迁移,也包括面向受限仓库的 SVN2Git 命令行工具,以及过渡期通过git svn桥接实现双向同步的实战方案。读完本文,你将掌握三条迁移路线的适用场景、关键命令与参数含义,并能借助文末的 SVN/Git 命令对照表快速完成团队的技术栈切换。
说明:本文对应仓库文档为 downloads/it/subversion-migration.md,其英文原版见 downloads/subversion-migration.md,西班牙语译本见 downloads/es_ES/subversion-migration.md。
迁移之前:理解 SVN 与 Git 的本质差异
从 Subversion 迁移到 Git,需要学习的不只是一组新命令,更是一次版本控制模型的范式转换。Subversion 是集中式版本控制系统:历史记录、分支和标签都保存在一个中央服务器上,客户端只持有工作副本。Git 则是分布式版本控制系统:正如本仓库的 git-guides/git-overview.md 所强调的,每一个与 Git 仓库协作的开发者都拥有该仓库的完整副本——每一个提交、每一个分支、每一个文件都在本地。
这种差异带来了一系列 Git 独有的能力:
- 分支廉价而轻量,可以放心地大量创建分支,作为安全的工作沙箱;
- 提交以 SHA 哈希存储,通过压缩文本文件实现极快的性能;
- 提交不可变,即使犯错也可以回滚分支指针或生成替代提交,让开发环境更安全;
- 天然支持多人并发,Git 能够处理合并冲突,允许多人同时修改同一文件。
速查表文档在总结部分明确指出:Subversion 与 Git 共享相似的词汇表,但相似之处往往仅限于命令名称,两者的行为与功能截然不同。理解这一点,是后续所有迁移决策的前提。
迁移路径一:GitHub Importer 自动迁移
对于可以通过互联网访问的项目,GitHub.com 提供了内置的Importer工具,用于从 Subversion、Team Foundation Server(TFS)、Mercurial 或托管在其他位置的 Git 版本控制项目进行自动迁移并创建新仓库。
迁移流程
整个过程非常简洁,速查表原文描述的步骤如下:
- 登录你的 GitHub 账户(如果尚未登录);
- 在 Importer 界面的 "repository" 字段中输入现有项目的版本控制仓库 URL;
- 启动转换。
GitHub 会自动检测源系统类型。根据检测到的版本控制系统,Importer 可能要求提供额外的迁移信息,其中最常见的是提供一个映射文件(mapping file),用于将 Subversion 用户名与 Git 提交中的作者字段(name 与 email)关联起来。由于 SVN 的提交只记录用户名,而 Git 提交需要作者姓名和邮箱,这份映射文件是保证迁移后提交历史"有主可查"的关键步骤。
适用边界
Importer 的适用前提是源仓库可被 GitHub 在线访问。如果你的 Subversion 仓库位于内网、存在访问限制或非公开,Importer 便无法触达,此时应转向下一条迁移路径。
迁移路径二:SVN2Git 命令行工具
当 Subversion 仓库存在访问限制或非公开、需要移植到 Git 时,速查表推荐的命令行工具是SVN2Git。与图形化的 Importer 相比,SVN2Git 在整个过程的每一步都提供可控性,适合需要精细操作的企业级迁移。
为什么需要专门的布局转换
Subversion 仓库的结构与 Git 仓库存在明显差异:SVN 通常在仓库内以trunk、branches、tags目录约定来组织开发主线、分支和标签,而 Git 的分支与标签是独立的引用对象。SVN2Git 的价值在于为传统布局和自定义布局都提供灵活的配置能力,从而保证迁移后生成的 Git 仓库在提交、分支和标签的组织上符合 Git 的社区最佳实践,覆盖项目的完整历史。
SVN2Git 的主要特性
速查表原文列出的核心特性包括:
- 转换所有 SVN 约定为传统 Git 结构:将
trunk变为默认分支、将branches/*映射为 Git 分支、将tags/*映射为 Git 标签; - 为 SVN 用户在 Git 提交中提供姓名与邮箱字段:解决 SVN 提交只含用户名、而 Git 提交需要作者与邮箱的问题(与 Importer 的映射文件作用类似,但在命令行层面以配置方式解决);
- 允许排除模式(exclusion patterns):精确控制哪些内容进入最终的 Git 仓库,例如排除历史中的构建产物或敏感文件。
过渡期桥接:利用 Git 对 SVN 的兼容能力
在正式迁移完成之前,很多团队会经历一段过渡期:Subversion 基础设施仍然保留,而成员们正在逐步熟悉本地 Git 仓库的交互方式、本地工作流和桌面应用。速查表的"过渡(Transizione)"章节正是为这一场景设计的。
此时,Git 内置的git svn桥接命令派上了用场:它允许用户与集中的 Subversion 仓库主机保持同步,同时享受本地 Git 命令行和图形客户端带来的全部优势——你可以在本地使用 Git 的分支、暂存、历史浏览能力,而底层数据仍然落在 SVN 服务器上。
获取 SVN 仓库为本地 Git 仓库
要将一个 Subversion 仓库完整下载为本地 Git 仓库,使用以下命令:
git svn clone [svn-repo-url] --stdlayout--stdlayout假定源仓库遵循标准的trunk/branches/tags目录布局。在执行克隆前,务必确认目标 Subversion 仓库的结构是否遵循标准布局。对于非传统的trunk、branches和tags位置,需要在svn clone时显式指定以下选项开关:
| 选项 | 作用 |
|---|---|
-T [trunk] | 指定替代的主干线来源约定(trunk 目录位置) |
-b [branches] | 指定替代的分支位置 |
-t [tags] | 指定替代的标签结构位置 |
例如,如果仓库使用mainline/作为主线目录、release/作为标签目录,可以写成git svn clone [svn-repo-url] -T mainline -b branches -t release。克隆操作完成后,你就可以像使用任何本地 Git 仓库一样,在命令行或图形客户端中进行各种本地 Git 操作。
将本地 Git 历史发布回 Subversion
过渡期内,本地 Git 仓库的提交历史可以通过一个命令发布回中央 Subversion 仓库:
git svn dcommitdcommit会将本地 Git 提交逐一转化为 SVN 提交,推送到 SVN 服务器。这里有一个重要的同步约束:如果 SVN 服务器上的历史包含本地 Git 仓库中尚不存在的提交,dcommit操作会被拒绝,直到你先用下面的命令把这些提交取回本地:
git svn rebasegit svn rebase会拉取 SVN 服务器上的新提交,并把本地尚未推送的提交重新放到这些新提交之后。务必牢记:这个操作会重写你的本地 Git 历史,提交标识符(commit ID)将会发生变化。这也是速查表特别提示的注意事项——一旦历史被重写,任何基于旧 commit ID 的引用都将失效,因此应在确认同步策略后再执行。
从语义上看,git svn dcommit与git svn rebase的组合,对应着纯 Git 世界中git push与git pull的职责,只不过数据的中转站是 SVN 服务器。
命令对照速查表:从 SVN 词汇到 Git 词汇
速查表文档以一张对照表总结了 SVN 与 Git 的词汇映射。这张表是迁移期最实用的随身参考,完整复现如下:
| SVN 命令 | Git 命令 | Git 中的行为 |
|---|---|---|
status | status | 报告工作树的状态 |
add | add | 每次提交前必须对每个路径执行 |
commit | commit | 将准备好的变更存入本地修订历史 |
rm、delete | rm | 准备在下一次提交中删除的路径 |
move | mv | 准备在下次提交中移动的内容 |
checkout | clone | 首次在本地获取项目的完整历史 |
branch | 为提交创建本地上下文 | |
merge | 合并分支历史并应用到工作树 | |
log | 列出当前分支的版本历史 | |
push | 将提交历史上传到 GitHub/集中式 Git 主机 | |
pull | 下载 GitHub 仓库历史并更新本地 | |
fetch | 仅下载 GitHub 仓库历史,不做其他操作 |
对照表解读与补充
status→status:名称相同,行为一致,都用于报告工作树/工作副本的状态。add→add:SVN 中add只登记新文件,Git 中add是每次提交前的必经步骤(暂存操作)。本仓库的 downloads/github-git-cheat-sheet.md 将其描述为"为版本化准备文件快照"。commit→commit:SVN 的提交直接写入中央服务器,Git 的提交只写入本地修订历史,需要后续push才能共享。rm/delete→rm:将路径标记为待删除,随下一次提交生效。move→mv:为移动/重命名的内容做好提交准备。checkout→clone:这是最容易混淆的一对。SVN 的checkout只拉取工作副本,而 Git 的clone会一次性在本地获取整个项目历史(所有文件、分支与提交),正如 git-guides/git-clone.md 所述:克隆通常只在项目开始时执行一次,之后即可在本地自由开发。- Git 独有的右侧命令:
branch(创建本地提交上下文)、merge(合并分支历史)、log(列出当前分支版本历史)、push(上传提交历史)、pull(下载并整合远程历史)、fetch(仅下载远程历史)——这些在 SVN 世界中要么不存在、要么语义完全不同,是迁移者需要重点建立的新心智模型。
迁移后最常用的 Git 命令速查
结合本仓库的 downloads/github-git-cheat-sheet.md 与git-guides系列,迁移完成后你很快就会高频使用以下命令:
git branch [branch-name]:创建新分支;git switch -c [branch-name]创建并切换分支;git add [file]:为文件创建快照,放入暂存区;git commit -m "[descriptive message]":将暂存快照永久写入版本历史;git push:将本地分支的所有提交上传到远程(git-guides/git-push.md 提醒:git push默认只推送当前检出的分支,推送前先git pull可减少远程合并冲突);git pull:将远程分支的新提交更新到本地工作分支,本质是git fetch+git merge的组合(见 git-guides/git-pull.md);git fetch:仅下载远程跟踪分支的历史,不触发合并,适合在预期冲突或离线前先行同步;git log:浏览项目文件的演进历史;git merge [branch]:将指定分支的历史合并进当前分支。
迁移完成后的落地建议
迁移不是终点,而是团队工作流升级的起点。基于速查表强调的"分布式 vs 集中式"差异,迁移后建议团队尽快建立以分支为中心的协作习惯:
- 以
main为生产基线,新功能一律在独立分支上开发(参考 git-guides/git-overview.md 描述的 Git 工作流:创建分支 → 修改并提交 → 推送分支 → 发起 Pull Request → 合并回main); - 先
git pull再git push,把远程冲突解决在本地; - 保留 SVN 时代的纪律性:提交信息规范、定期同步、及时清理已合并分支,这些好习惯在 Git 中同样重要;
- 对于仍在过渡期的仓库,维持
git svn桥接,直到所有成员都熟悉本地 Git 操作后再完成服务器的最终切换。
总结
从 Subversion 到 Git 的迁移,本质上是把版本控制模型从"集中式服务器"切换到"分布式副本"的思维升级。GitHub Training Kit 的这份速查表给出了三条清晰的路径:公网项目用GitHub Importer一键迁移,受限项目用SVN2Git精细转换,过渡期用git svn桥接实现双向同步。配合文末的 SVN/Git 命令对照表,团队可以在保持业务连续性的前提下,分阶段完成技术栈的平滑切换,最终享受到分布式版本控制带来的廉价分支、离线历史与高效协作能力。
- 文档
- 教程
【免费下载链接】training-kit
Open source courseware for Git and GitHub
相关推荐
GitHub training-kit 指南:Subversion(SVN)到 Git 的迁移与 `git svn` 平滑过渡实战
GitHub training kit 指南:Subversion(SVN)到 Git 的迁移与 git svn 平滑过渡实战 本篇基于 training ki
文档教程Subversion 迁移 Git 全指南:training-kit 中的 GitHub Importer、SVN2Git 与 git svn 桥接方案
Subversion 迁移 Git 全指南:training kit 中的 GitHub Importer、SVN2Git 与 git svn 桥接方案 本指南
文档教程Sapling Git 命令对照速查表:从 git 到 sl 的迁移实战指南
Sapling Git 命令对照速查表:从 git 到 sl 的迁移实战指南 本指南以 Sapling 官方文档《Git cheat sheet》为核心,系统性
开发工具CLI后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考