23、Git迁移与备份:仓库迁移、备份策略、恢复操作、跨平台迁移

聊到Git迁移和备份,我脑子里第一个蹦出来的场景是:几年前帮一个团队把几十个仓库从自建的GitLab搬到企业版GitHub。那会儿网络不稳定,仓库又大,折腾了两天才搞定。嗯,从那以后,我对迁移这件事就特别上心。

说白了,Git迁移和备份就是两件事:把代码安全地挪个地方,以及万一出事了能原样恢复。你想想看,代码是公司的命根子,这活儿干不好,后果很严重。

核心原则:迁移和备份的本质是「完整保留提交历史、分支、标签」。不是简单地把文件拷过去,而是把整个Git对象库搬走。

Git 迁移与备份知识体系 Git 迁移与备份 仓库迁移 备份策略 恢复操作 跨平台迁移 镜像克隆 · 裸仓库 · 推送 完整备份 · 增量备份 · 定时 克隆恢复 · 裸仓库恢复 换行符 · 编码 · 权限 核心:完整保留提交历史、分支、标签

仓库迁移:换个地方住

仓库迁移,最常见的就是从一个Git服务器搬到另一个。比如从GitHub搬到GitLab,或者从自建服务器搬到云上。

最稳妥的方式:镜像克隆

我个人习惯用 --mirror 参数。这玩意儿会把所有东西都拉下来——分支、标签、引用,一个不落。

# 第一步:克隆裸仓库
git clone --mirror https://old-server.com/team/project.git

# 第二步:进入目录
cd project.git

# 第三步:添加新远程地址
git remote add new-origin https://new-server.com/team/project.git

# 第四步:推送所有内容
git push new-origin --mirror

小提示:--mirror 克隆出来的不是工作目录,而是裸仓库。你进去看会发现没有源码文件,只有 .git 里的那些对象。别慌,这是正常的。

我在项目中遇到过一种情况:旧服务器网络特别慢,一个仓库好几个G。这时候我会用 --depth 先浅克隆,但注意——浅克隆会丢失历史。所以如果要求完整历史,还是老老实实全量拉。

另一种方式:直接推裸仓库

如果你已经有裸仓库的备份文件,可以直接推过去:

# 在本地裸仓库目录中
git push --mirror https://new-server.com/team/project.git

这招特别适合离线迁移。先把裸仓库打包拷到U盘,到了新环境再推上去。

备份策略:别等出事了再后悔

备份这事儿,我吃过亏。有一次服务器硬盘坏了,才发现最近的备份是三个月前的。嗯,从那以后,我给自己定了个规矩:备份要自动化,要可验证

方案一:裸仓库备份(推荐)

裸仓库是Git的「完全体」,备份它最省心。

# 创建裸仓库备份
git clone --mirror https://server.com/team/project.git project-backup.git

# 打包压缩
tar -czf project-backup-2024-01-01.tar.gz project-backup.git/

方案二:git bundle 打包

我个人挺喜欢 git bundle 的。它把整个仓库打包成一个文件,方便传输和归档。

# 创建 bundle 文件
git bundle create project.bundle --all

# 从 bundle 恢复
git clone project.bundle project-restored/

重要:bundle 文件是二进制的,别用文本编辑器打开。我曾经看到有人试图用记事本打开,结果全是乱码,还以为是文件坏了。

方案三:增量备份

仓库太大,每天全量备份不现实。可以用 git fetch 做增量:

# 第一次:全量
git clone --mirror https://server.com/team/project.git project-backup.git

# 之后每天:增量
cd project-backup.git
git fetch --all

这招我用了好几年,每天定时跑个脚本,省时省力。

备份方式 优点 缺点 适用场景
裸仓库 完整、可恢复 占用空间大 全量备份、迁移
git bundle 单文件、易传输 增量麻烦 离线传输、归档
增量 fetch 省空间、快 依赖原始仓库 日常定时备份

恢复操作:从备份中重生

恢复操作,说白了就是备份的逆过程。但这里有个坑:恢复前一定要确认目标目录是空的,否则容易冲突。

从裸仓库恢复

# 解压备份
tar -xzf project-backup-2024-01-01.tar.gz

# 从裸仓库克隆出工作仓库
git clone project-backup.git project-restored/

从 bundle 恢复

# 直接克隆 bundle
git clone project.bundle project-restored/

# 或者先验证 bundle 完整性
git bundle verify project.bundle

警告:恢复后一定要验证!用 git log --oneline 看看提交历史是否完整,用 git branch -a 检查分支是否都在。我曾经恢复完才发现少了一个重要分支,就是因为备份时忘了加 --all 参数。

跨平台迁移:Windows、Linux、macOS 之间的坑

跨平台迁移,最头疼的不是Git本身,而是换行符文件权限

换行符问题

Windows 用 CRLF,Linux 和 macOS 用 LF。如果不处理,迁移后代码里全是 ^M 符号。

我建议在仓库根目录放一个 .gitattributes 文件:

# 设置文本文件的换行符
* text=auto

# 明确指定某些文件用 LF
*.sh text eol=lf
*.py text eol=lf

# 明确指定某些文件用 CRLF
*.bat text eol=crlf
*.ps1 text eol=crlf

文件权限问题

Linux 上的可执行权限,到了 Windows 就没了。Git 可以保存权限位,但需要设置:

# 查看文件权限
git ls-tree HEAD

# 设置可执行权限
git update-index --chmod=+x script.sh

路径大小写问题

Windows 和 macOS 默认不区分大小写,但 Linux 区分。这坑我踩过——在 macOS 上建了两个文件 Readme.mdREADME.md,推到 Linux 服务器上直接报错。

解决办法:在迁移前统一路径命名规范,或者设置 Git 大小写敏感:

# 让 Git 在 Windows/macOS 上也区分大小写
git config core.ignorecase false

我的经验:跨平台迁移前,先跑一遍 git fsck 检查仓库完整性。再跑 git gc 压缩一下对象库。这样能避免很多莫名其妙的问题。

好了,Git迁移与备份的核心内容就这些。记住一句话:迁移前备份,备份后验证,跨平台注意换行符和权限。做到这三点,基本不会出大问题。

公众号:蓝海资料掘金营,微信deep3321