工作中难免遇到这种情况:你想用 Git 的强大功能,但团队还在用水晶球(Subversion)、水银(Mercurial)甚至更古老的版本控制系统(VCS)?
别慌!本章就像 Git 的“万能转换器”,教你两种核心技能:一是把 Git 当其他 VCS 的客户端(本地用 Git,远程用其他系统),二是把其他 VCS 的项目完整迁移到 Git,不丢任何历史记录~ 初学者也能轻松上手,从此告别“被迫适应旧系统”的痛苦!
git-remote-hg
Git Fusion
git-tfs
1. Git + Subversion – 最常用的跨系统组合 📌
Subversion(SVN)是老牌集中式 VCS,很多老项目还在使用。用 git svn 可以让你本地用 Git 的分支、合并功能,远程推送到 SVN 服务器,无缝融入 SVN 团队。
核心操作流程
# -s 表示 SVN 是标准布局(trunk/branches/tags),非标准用 -T trunk -b branches -t tags
git svn clone https://svn.example.com/project -s my-git-repo# 2. 进入本地仓库,正常用 Git 操作(分支、提交等)
cd my-git-repo
git checkout -b feature-1 # 创建本地分支
# 编辑文件 …
git add .
git commit -m “ 实现功能 1 ” # 本地 Git 提交,未同步到 SVN
# 3. 拉取 SVN 服务器的最新更新(类似 git pull)
git svn rebase # 拉取并变基,保持历史线性(SVN 不支持合并提交)
# 4. 推送本地 Git 提交到 SVN 服务器(类似 git push)
git svn dcommit # 每个 Git 提交会转为一个 SVN 提交
# 5. 其他常用命令
git svn log # 查看 SVN 风格的日志
git svn blame # 查看文件每行的修改记录(类似 svn annotate)
git svn info # 查看 SVN 服务器信息(类似 svn info)
关键注意事项
- SVN 是线性历史,
git svn不建议本地合并分支,尽量用rebase保持历史线性 dcommit会修改 Git 提交的 SHA-1(添加 git-svn-id),不要同时推送到 Git 远程仓库- 拉取更新必须用
git svn rebase,不能用git pull(会产生合并提交,SVN 不兼容)
2. Git + Mercurial – 分布式 VCS 互通 🔄
Mercurial(Hg)和 Git 同为分布式 VCS,功能相似。用 git-remote-hg 可以让 Git 作为 Hg 的客户端,双向同步。
curl -o ~/bin/git-remote-hg https://raw.githubusercontent.com/felipec/git-remote-hg/master/git-remote-hg
chmod +x ~/bin/git-remote-hg # 确保~/bin 在 PATH 中
pip install mercurial # 安装 Python 依赖# 2. 克隆 Hg 仓库到本地(Git 仓库)
git clone hg::https://hg.example.com/project my-git-repo
# 3. 本地 Git 操作(提交、分支等)
git checkout -b bugfix
# 编辑文件 …
git commit -m “ 修复 bug”
# 4. 拉取 Hg 服务器更新
git fetch origin
# 5. 推送 Git 提交到 Hg 服务器
git push origin master
特点:Hg 和 Git 都是分布式,支持合并提交,互通体验比 SVN 好,几乎和操作 Git 远程仓库一致。
3. Git + Perforce – 企业级 VCS 适配 🏢
Perforce 是企业常用的集中式 VCS,有两种 Git 互通方案:
- Git Fusion:Perforce 官方提供的服务器端工具,将 Perforce 仓库暴露为 Git 仓库,支持双向同步,体验最接近原生 Git
- git-p4:客户端工具,无需服务器配置,本地将 Git 提交转为 Perforce 变更集
# 1. 配置 Perforce 连接信息
export P4PORT=perforce.example.com:1666
export P4USER=your-username# 2. 克隆 Perforce 仓库到本地 Git 仓库
git p4 clone //depot/project/main my-git-repo
# 3. 本地 Git 提交后,推送至 Perforce
git p4 rebase # 拉取 Perforce 最新更新
git p4 submit # 推送本地提交到 Perforce
4. Git + TFS – Windows 环境适配 🪟
TFS(Team Foundation Server)是微软的协作套件,其版本控制部分为 TFVC。Windows 用户可用 git-tfs 实现 Git 与 TFVC 互通:
# 2. 克隆 TFVC 仓库
git tfs clone –with-branches https://tfs.example.com/DefaultCollection $/project/Trunk my-git-repo# 3. 本地 Git 操作后,同步到 TFVC
git tfs fetch # 拉取 TFVC 更新
git rebase tfs/default # 变基保持线性
git tfs rcheckin # 推送 Git 提交到 TFVC(每个 Git 提交转为 TFVC 变更集)
git-tf(功能较简化,不支持分支)Mercurial 迁移
Perforce 迁移
自定义迁移
1. SVN 迁移到 Git – 完整保留历史 📜
迁移不是简单克隆,需要清理作者信息、转换标签 / 分支,确保 Git 仓库干净可用。
# 先导出 SVN 的所有作者
svn log –xml https://svn.example.com/project | grep author | sort -u | \
perl -pe ‘s/.*>(.*?)<.*/$1 = /’ > users.txt
# 编辑 users.txt,补充 Git 作者信息,格式:svn-user = Git Name <email@example.com># 步骤 2:克隆 SVN 仓库(完整历史),应用作者映射
git svn clone https://svn.example.com/project -s \
–authors-file=users.txt –no-metadata my-git-repo
# 步骤 3:清理 Git 仓库(转换 SVN 标签和分支)
cd my-git-repo
# 转换 SVN 标签为 Git 标签(原标签是远程分支)
cp -Rf .git/refs/remotes/origin/tags/* .git/refs/tags/
rm -Rf .git/refs/remotes/origin/tags
# 转换 SVN 分支为 Git 本地分支
cp -Rf .git/refs/remotes/origin/* .git/refs/heads/
rm -Rf .git/refs/remotes/origin
# 删除多余的 trunk 分支(Git 默认用 master)
git branch -d trunk
# 步骤 4:推送到新的 Git 服务器
git remote add origin git@git.example.com:project.git
git push origin –all # 推送所有分支
git push origin –tags # 推送所有标签
2. Mercurial 迁移到 Git – 分布式 VCS 无缝转换 🔄
Hg 和 Git 模型相似,迁移工具 hg-fast-export 能完整保留分支、标签和历史。
hg clone https://hg.example.com/project /tmp/hg-repo # 克隆 Hg 仓库
git clone https://repo.or.cz/r/fast-export.git /tmp/fast-export # 克隆迁移工具# 步骤 2:准备作者映射文件(可选,清理 Hg 作者信息)
cd /tmp/hg-repo
hg log | grep user: | sort | uniq | sed ‘s/user: *//’ > /tmp/authors.txt
# 编辑 authors.txt:hg-user = Git Name <email@example.com>
# 步骤 3:创建新 Git 仓库,执行迁移
mkdir /tmp/git-repo && cd /tmp/git-repo
git init
/tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors.txt
# 步骤 4:推送到 Git 服务器
git remote add origin git@git.example.com:project.git
git push origin –all –tags
3. Perforce/TFS 迁移到 Git – 企业级项目迁移 🏢
- Perforce 迁移 :用
git p4 clone --detect-branches //depot/project@all克隆完整历史,然后清理 git-p4 标记(用 git filter-branch 删除[git-p4:] 信息) - TFS 迁移:用
git tfs clone --with-branches --authors=authors.txt克隆,然后用git filter-branch清理 git-tfs-id 标记
4. 自定义迁移 – 适配小众 VCS 或特殊场景 🛠️
如果是小众 VCS(如 CVS)或自定义备份目录(如按日期备份的文件夹),可用 Git 的 fast-import 工具自定义迁移脚本。
核心思路:读取旧系统的每个版本快照,生成 Git 能识别的指令,通过管道传给 git fast-import。
# 1. 编写迁移脚本(Ruby 示例,核心是输出 fast-import 指令)
# 脚本逻辑:遍历每个备份目录,生成 Git 提交,链接历史
# 2. 执行迁移
mkdir my-git-repo && cd my-git-repo
git init
ruby migrate-script.rb /path/to/backup-dirs | git fast-import
# 3. 检出文件
git reset –hard master
fast-import 支持批量导入大量提交,比逐个 git commit 高效 10 倍,适合超大型项目迁移。场景 1:团队混合使用 Git 和 SVN,如何协作?
核心原则:以 SVN 为中心,所有协作通过 SVN 服务器,Git 用户用 git svn 同步。
- Git 用户:本地用 Git 分支开发,提交后
git svn rebase + dcommit同步到 SVN - SVN 用户:正常用 SVN 提交,Git 用户通过
git svn rebase拉取更新 - 禁止:Git 用户直接推送到其他 Git 远程仓库(会导致 SHA- 1 不一致)
场景 2:迁移后发现历史作者信息错误,如何修正?
用 git filter-branch 批量修改提交的作者信息(迁移后未推送到 Git 远程时使用):
# 示例:old@example.com 新姓名 <new@example.com># 执行批量修改
git filter-branch –env-filter ‘
map=$(cat author-map.txt)
while IFS= read -r line; do
old_email=$(echo $line | awk “{print \$1}”)
new_name=$(echo $line | awk “{print \$2}”)
new_email=$(echo $line | awk “{print \$3}”)
if [“$GIT_AUTHOR_EMAIL” = “$old_email”]; then
export GIT_AUTHOR_NAME=”$new_name”
export GIT_AUTHOR_EMAIL=”$new_email”
export GIT_COMMITTER_NAME=”$new_name”
export GIT_COMMITTER_EMAIL=”$new_email”
fi
done <<< “$map” ‘ –tag-name-filter cat — –all
场景 3:迁移 SVN 时,标签显示为分支,如何修复?
SVN 的标签是目录拷贝,git svn 默认转为远程分支,迁移后需手动转为 Git 标签:
git branch -r | grep tags/# 批量将分支转为 Git 标签
for tag in $(git branch -r | grep tags/ | sed ‘s/origin\/tags\///’); do
git tag $tag origin/tags/$tag
git branch -r -d origin/tags/$tag
done
# 推送标签到 Git 服务器
git push origin –tags
常见坑与解决方案
- 坑 1:git svn dcommit 失败,提示“文件过时” → 先执行
git svn rebase拉取最新更新,解决冲突后再 dcommit - 坑 2:迁移后 Git 仓库体积过大 → 执行
git gc --aggressive优化仓库,删除冗余对象 - 坑 3:Mercurial 迁移后分支丢失 → 克隆 Hg 仓库时确保用
hg clone --mirror获取完整分支,迁移时用--with-branches - 坑 4:迁移后提交时间不对 → 迁移工具默认保留原提交时间,若异常,检查系统时区设置,或用
git filter-branch修正
- 跨系统协作:用 git svn(SVN)、git-remote-hg(Hg)、git-p4(Perforce)等工具,本地享受 Git 功能,远程适配旧 VCS
- 迁移核心:保留完整历史(提交、分支、标签)、清理冗余信息(如 git-svn-id)、修正作者信息
- 关键原则:集中式 VCS(SVN/Perforce/TFVC)需保持历史线性,避免合并提交;分布式 VCS(Hg)迁移体验更平滑
- 避坑重点:迁移后先在本地验证(日志、分支、标签),再推送到 Git 服务器;修改历史的操作(filter-branch)仅在本地仓库执行
要不要我帮你整理一份Git 跨系统协作 & 迁移速查手册?包含各 VCS 的操作命令、迁移步骤、避坑指南,还有作者映射、标签转换等实用脚本,让你遇到跨系统问题直接翻手册就能解决~