当你需要将Git项目迁移到新位置、更换托管平台或彻底重置版本控制时,就很有可能需要这些知识。
项目迁移的需求比你想的要常见得多。比如你从 GitHub 搬到公司内网的 GitLab,或者将旧项目里的子模块拆分成独立服务,甚至是因为一不小心把密钥上传了,想清理历史记录重开一个干净的新仓库。这些场景下,你就需要用对 Git 的“迁移姿势”。
很多开发者觉得迁移麻烦,其实只要理解 Git 本质上是一个内容寻址的“版本快照系统”,你就会发现迁移不外乎两件事:“我要保留什么?”、“我要丢弃什么?”这篇指南就是围绕这两个问题展开,让你从容应对各种 Git 迁移需求。
对了,你可以根据下面的决策树,决定你想阅读的部分,实践过程中有疑问欢迎探讨。
迁移决策树
保留历史? → 用--mirror
克隆
只需最新代码? → 移除.git后重建
需要部分历史? →git filter-repo
完整迁移方案(保留历史记录)
如果你想把整个仓库搬家,不想丢掉任何东西(包括分支、Tag、历史提交、远程设置等),--mirror
是你最好的选择。它就像一张完整备份快照,把 .git
中的所有引用和配置都复制一份,适合对原始仓库做“全量克隆”。
这个方法尤其适合从一个平台搬到另一个平台,比如从 GitHub 搬到 Gitee 或 GitLab。注意,推送时也要用 --mirror
,否则有些引用(如远程分支)不会同步过去。如果原项目的默认分支是 master
,而新仓库默认使用 main
,也可以中途重命名。总之,这种方法是最“保险”的迁移方式,适合保守型开发者。
1 | # 1. 克隆原仓库(保留所有分支和标签) |
纯净迁移方案(不保留历史)
有时候,我们并不想背着历史包袱重新开始,尤其是当你意识到旧代码已经乱成一团,或者包含了不该泄露的敏感信息。这时,你可以选择删除 .git
目录后重建仓库。这种方式非常直接粗暴,也非常“轻量”:只保留代码内容,丢掉所有版本历史,就像从来没用过 Git 一样重新开始。
当然,这种方法的风险也在于你将彻底丢失所有变更记录、作者信息和 Tag。所以如果是团队项目,建议先沟通好再操作。如果你想只保留某一分支最近的提交,也可以用 git clone --depth 1
进行浅克隆,然后重新初始化。
1 | # 1. 解除当前版本控制(保留文件) |
高级迁移技巧
大型单体仓库逐渐拆分成微服务或子模块,是很多团队发展的必经阶段。这时候你可能就会想:我只关心某个子目录的内容,能不能把它独立成一个仓库,还保留它的提交历史?当然可以,这就要用上 Git 高级利器 —— git filter-repo
。filter-repo
可以非常高效地把某个目录及其历史提交“提取”出来,形成一个全新的独立仓库,不仅文件内容干净,连提交记录都只保留相关部分。比如把 src/module-a
提成一个新仓库,并作为根目录使用,就可以用 --subdirectory-filter
。它的效果比 filter-branch
快百倍,也更不容易出错。唯一要注意的是,它需要额外安装,建议在克隆出来的副本里操作,避免污染原始仓库。
迁移指定分支
1
git push new_remote local_branch:remote_branch
迁移子目录
1
git filter-repo --subdirectory-filter my-subdir
清理历史大文件
1
git filter-repo --strip-blobs-bigger-than 10M
迁移后必检项
验证分支/标签是否完整:
1
git branch -a && git tag -l
检查文件完整性:
1
git fsck --full
更新CI/CD配置:
- Jenkins/GitLab CI中的仓库地址
- Webhook设置
避坑指南
⚠️ 敏感信息处理
迁移前使用git secret scan
扫描密钥/密码
推荐工具:git-secrets
⚠️ LF/CRLF问题
这是 Git 世界里最容易被忽略、却最容易“把人整崩溃”的问题之一。如果你在 Mac 上开发,换行符是 LF,而 Windows 默认是 CRLF。于是你 clone 一份代码,结果一提交,全仓库变成了“修改”状态,其实只是换行不一致。
为了避免这种尴尬情况,Git 提供了 core.autocrlf 设置。Windows 用户推荐设置为 true,它会在 checkout 时把 LF 转成 CRLF,提交时再转回;macOS/Linux 用户建议设置为 input,提交时强转 LF,保持一致。除此之外,还建议在仓库根目录建一个 .gitattributes 文件,强制设置文件类型的换行行为。统一格式不仅能避免多人协作混乱,还能让你在 PR、diff 中更容易看出实际修改。
Windows用户迁移后执行:
1 | git config core.autocrlf input |
⚠️ 高危警告(使用前必读)
你知道吗?全球有数以万计的 Git 仓库曾经不小心泄露了密钥、数据库密码甚至生产环境的 API token。别以为“只是试试”,Git 会把你每一次 commit
的文件都记录在历史中,即使后面删除,历史里也还在。
为了防止“祸从提交起”,推荐在迁移前使用安全扫描工具:AWS 出品的 git-secrets
可以在你提交前实时检测敏感关键词,truffleHog
更是“暴力搜索”连编码过的 token 都能挖出来。如果发现确有泄露,可以配合 filter-repo
清除掉对应的文件和提交。这一步虽然繁琐,却能挽救整个项目的安全风险,强烈建议纳入你团队的代码审查流程中。
永久性删除
1
2- 所有提交历史、分支、标签将被不可恢复地删除!
- 操作前请确认已备份重要版本信息作用范围
1
2+ 仅在当前执行目录及其子目录生效
- 禁止在根目录(/)或家目录(~)运行!可能导致系统崩溃!敏感操作防护
1
2
3
4# 安全建议:先预览将被删除的目录
find . -type d -name ".git" | while read dir; do
echo "[高危] 即将删除: ${dir}"
done
附录:补充一个删除.git的安全方案(纯净版)
1 | #!/bin/bash |
最后,请务必需要注意,任何删除操作前,用
git bundle
创建完整备份包,可通过git clone backup.bundle
恢复历史**