工作中难免遇到这种情况:你想用Git的强大功能,但团队还在用水晶球(Subversion)、水银(Mercurial)甚至更古老的版本控制系统(VCS)?
别慌!本章就像Git的“万能转换器”,教你两种核心技能:一是把Git当其他VCS的客户端(本地用Git,远程用其他系统),二是把其他VCS的项目完整迁移到Git,不丢任何历史记录~ 初学者也能轻松上手,从此告别“被迫适应旧系统”的痛苦!
🤝 Git作为客户端 - 本地用Git,远程连其他VCS
git svn
git-remote-hg
Git Fusion
git-tfs
1. Git + Subversion - 最常用的跨系统组合 📌
Subversion(SVN)是老牌集中式VCS,很多老项目还在使用。用
git svn
可以让你本地用Git的分支、合并功能,远程推送到SVN服务器,无缝融入SVN团队。
核心操作流程
# 1. 克隆SVN仓库到本地(转为Git仓库)
# -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不兼容)
💡 实用场景:团队还在用SVN,但你想享受Git的本地分支、暂存区功能?用git svn偷偷“开挂”,队友完全看不出你用的是Git~
2. Git + Mercurial - 分布式VCS互通 🔄
Mercurial(Hg)和Git同为分布式VCS,功能相似。用
git-remote-hg
可以让Git作为Hg的客户端,双向同步。
# 1. 安装git-remote-hg(依赖Python和Mercurial客户端)
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变更集
# git-p4 快速入门
# 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互通:
# 1. 安装git-tfs(需先安装Visual Studio或TFS SDK)
# 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-tfs仅支持Windows环境,跨平台可用
git-tf
(功能较简化,不支持分支)
🚚 迁移到Git - 彻底告别旧VCS,历史不丢失
SVN迁移
Mercurial迁移
Perforce迁移
自定义迁移
1. SVN迁移到Git - 完整保留历史 📜
迁移不是简单克隆,需要清理作者信息、转换标签/分支,确保Git仓库干净可用。
# 步骤1:准备作者映射文件(SVN用户名→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 # 推送所有标签
💡 关键:—no-metadata 会移除Git提交中的git-svn-id,让Git仓库更干净;作者映射确保提交记录的作者信息正确。
2. Mercurial迁移到Git - 分布式VCS无缝转换 🔄
Hg和Git模型相似,迁移工具
hg-fast-export
能完整保留分支、标签和历史。
# 步骤1:克隆Hg仓库和迁移工具
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
。
# 示例:迁移按日期备份的文件夹(back_2024_01_01, back_2024_01_02...)
# 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远程时使用):
# 创建作者映射文件author-map.txt,格式:旧邮箱 新姓名 <新邮箱>
# 示例: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
⚠️ 警告:此操作会修改所有提交的SHA-1,仅在迁移后、未分享Git仓库时使用!
场景3:迁移SVN时,标签显示为分支,如何修复?
SVN的标签是目录拷贝,git svn默认转为远程分支,迁移后需手动转为Git标签:
# 查看所有SVN标签(此时是分支)
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的操作命令、迁移步骤、避坑指南,还有作者映射、标签转换等实用脚本,让你遇到跨系统问题直接翻手册就能解决~