没有个人 Git 仓库时,怎么维护自己的内部小项目
给自己用的脚本、本地知识库、AI 工具的 Skill,或尚未进入团队工程体系的内部资料,往往需要长期维护,却不适合直接放进现有业务仓库。
有获准的私有 Git 仓库时,可以直接用它保留提交历史、分支、作者信息和变更差异,也方便多设备同步。
但现实里经常会遇到两个限制:
- 公司内网有 GitLab,但普通员工不能创建个人仓库。
- 由于合规、保密或数据边界要求,项目不能放到公网 GitHub / Gitee,即使是私有仓库也不合适。
如果公司允许把这些资料存入企业飞书,可以在本地继续按项目维护,再把备份文件放到飞书云盘或文档附件里。存储位置是否获准、谁能访问,需要先确认;不能因为服务在公司内部使用,就默认所有资料都适合上传。
这条路线可以先解决备份和离线分发:电脑坏了能恢复,换设备能迁移,别人需要时能拿到一份明确版本,多次更新时也能沿用同一个远端文件位置。
先分清想保存什么
先确定远端要保存什么:普通目录快照、指定提交的文件,还是包含历史的 Git 仓库备份。
如果只是想把当前目录保存下来,普通 zip 就够。如果项目已经用 Git 管理,而且只需要交付当前版本,可以用 git archive。如果希望连提交历史一起保留,后续还能 clone 成一个可继续开发的仓库,就应该用 git bundle。
方案一:zip,最直接的目录压缩
zip 是最普通的压缩方式。
它的特点是简单:不要求项目本身是 Git 仓库,也不要求有提交历史。只要目录存在,就可以压缩。
在 macOS 或 Linux 上,可以这样生成:
zip -r project-backup.zip project-folder -x 'project-folder/.git/*'
也可以直接在 Finder 里右键目录,选择压缩。
拿到 zip 文件的人不需要知道 Git,直接解压就能看到目录。
它的缺点也很明显:默认会把目录里的内容都放进去。上面的命令显式排除了 .git/,只保存目录中的文件;它不会读取 .gitignore。如果项目里有 node_modules、构建产物、缓存、大文件或临时日志,还需要另外用 zip -x 排除。规则一多,就会变得不如 Git 自己的忽略机制清楚。
因此 zip 更适合这些情况:
- 目录不是 Git 仓库。
- 内容规模不大。
- 解压后能直接使用比保留提交历史更重要。
- 目录里没有太多需要排除的缓存和依赖目录。
如果只是备份一个本地资料夹、一个 Markdown 知识库、一个没有 Git 管理的小工具目录,zip 是成本最低的方案。
方案二:git archive,打包当前提交里的项目内容
如果项目已经用 Git 管理,但远端只需要一份「当前版本源码」,可以用 git archive。
常用命令是:
git archive --format=zip --output project-snapshot.zip HEAD
它打包的是 HEAD 提交里的文件,不会带上未跟踪的依赖目录、缓存或日志。但 .gitignore 不会替它过滤已经提交的文件:如果敏感文件早已进入提交,它仍可能被打包。需要排除已跟踪的交付外文件时,可以在 .gitattributes 中配置 export-ignore。
这里要注意一个细节:git archive 打包的是某个提交,不是当前工作区。已经修改但还没提交的内容不会进入 HEAD 生成的压缩包。打包前最好先看一眼:
git status --short
如果有需要进入快照的改动,先提交,再执行 git archive。
不过 git archive 生成的是源码快照,不包含 .git/,也不包含提交历史。别人解压后能看到文件,但不能继续查看原来的 commit、branch 和 author 记录。
它适合这些情况:
- 项目已经是 Git 仓库。
- 远端只需要当前版本,不需要历史。
- 希望只交付指定提交里的文件,不带未跟踪内容。
- 接收方更希望直接解压,而不是执行
git clone。
把它理解成「Git 管理下的干净 zip」会比较准确。
方案三:git bundle,把 Git 仓库本身打成一个文件
如果想保留 Git 提交历史,git bundle 更合适。
常用命令是:
git bundle create project-backup.bundle --all
--all 会纳入当前仓库的 refs 及其可达历史,包括分支和 tag。这个文件不是普通 zip,不能直接双击解压查看源码,但 Git 可以从中读取对象和历史。
和 git archive 一样,bundle 不保存未提交的工作区改动。本地配置和 hooks 也不在备份范围内;它不是整个 .git 目录的复制。Git 的 bundle 文档明确区分了引用、可达提交和其他本地状态。打包前先检查工作区,把需要保留的项目改动提交,不能为了备份顺手提交凭证或缓存。
生成后先检查文件:
git bundle verify project-backup.bundle
这会检查 bundle 的格式和前置提交要求。要确认自己真能恢复,还应在一个新的临时目录里 clone,检查文件、分支和 tag;不要在原项目目录上直接覆盖。
还原时用 git clone:
git clone project-backup.bundle project-folder
这样还原出来的是一个正常 Git 工作目录,可以继续看提交历史、创建新提交、切分支。
如果有同事协助开发,只要他们的提交已经进入这个仓库历史,bundle 里也会保留对应的 author 和 commit 信息。它保存的是 Git 历史,不只是文件结果。
git bundle 适合这些情况:
- 项目已经用 Git 管理。
- 提交历史有价值。
- 未来可能要在另一台设备上继续开发。
- 希望保留分支、tag、author 和 commit 记录。
- 接收方可以接受用
git clone还原。
如果希望在另一台机器继续维护已有 Git 历史,我会选 git bundle --all,同时另行处理确实需要迁移的本地配置。
三种方式怎么选
有没有 Git、要不要保留历史,决定了使用哪种文件:
| 方式 | 是否需要 Git 仓库 | 是否保留提交历史 | 接收方怎么还原 | 适合场景 |
|---|---|---|---|---|
zip |
不需要 | 不保留 | 直接解压 | 普通目录、资料夹、小规模文件 |
git archive |
需要 | 不保留 | 直接解压 | 干净源码快照、交付当前版本 |
git bundle |
需要 | 保留 | git clone |
仓库备份、多设备迁移、保留历史 |
交付前也要说明文件代表的是目录快照、提交快照还是 Git 历史备份,避免接收方拿到 bundle 后不知道怎样打开。
远端放到哪里
备份文件生成后,还需要一个获准使用、便于持续更新的远端位置。
如果内容适合让多人看到,可以把备份文件附在相关飞书文档中,说明项目用途、恢复方法和更新规则。读者从同一篇文档就能找到背景和对应版本。
如果内容主要给自己备份,飞书云盘更轻。它默认更像个人文件存储,适合放一些还没有团队化的小项目、个人工具、草稿知识库和 AI 工作流资产。
如果这个目录只用来保存最新备份,可以按项目名和日期命名。例如:
project-name-2026-05-29.bundle
project-name-2026-05-29.zip
项目更新后,先生成并校验新文件,再更新远端。替换前还要确认旧文件属于这个项目、当前账号有权限操作,而且新备份已在本地保留。
需要恢复旧状态时,就不能只留最新文件。可以按实际恢复需要保留近期版本或周备份,不要把「目录整洁」放在可恢复性前面。
重复备份可以自动生成并校验,但要区分脚本的运行目录、单次执行限制和旧文件保留策略。完整内容见自动生成备份的脚本弹窗。
AI 工作流资产的备份选择
AI 工具里的 Skill、规则、个人知识库就是这类问题的典型例子。
它们不是业务项目,但会越来越重要。比如一套文档整理 Skill、一组前端排障规则、一批 Markdown 知识库,可能在很多项目里反复提供帮助。
这些内容只留在本机,电脑坏了就难恢复;放到公网仓库,又可能不符合内部资料的存储要求。没有获准的个人仓库时,可以按前面的方法保存本地版本,再通过获准的文件存储入口备份。
这时可以这样处理:
- 本地目录继续用 Git 管理,认真写 commit。
- 定期用
git bundle create xxx.bundle --all备份引用和提交历史,并检查恢复结果。 - 把 bundle 上传到飞书云盘或附到飞书文档里。
- 校验新 bundle 后更新远端;是否只留最新版,按前面的恢复需求决定。
如果只是想给别人一份当前资料,不需要历史,可以额外生成 git archive 版本。别人直接解压就能看 Markdown,不需要理解 bundle。
我会为自己保留 bundle,需要给别人一份可直接阅读的 Markdown 时,再生成 archive。
总结
没有获准的个人远端仓库,仍可以在本地用 Git 维护项目,再把备份放到获准的文件存储中。普通 zip 保存目录文件,git archive 保存指定提交的源码快照,git bundle --all 保存引用及其可达历史;要换设备继续开发并保留历史,bundle 更合适,但未提交改动、本地配置和 hooks 仍需分别处理。
备份是否可用,要看校验和恢复结果;保留多少远端版本,则取决于恢复需求。先生成并检查新文件,再按权限和保留规则更新远端,不能用目录整洁代替可恢复性。
「压缩包 + 飞书」提供的是备份和离线分发,不是 Git 服务。接收方能恢复指定版本或历史,但附件不会替团队管理分支权限、合并冲突,也没有在线 review、issue 和 CI。
低频维护时,先做好本地版本管理、获准的远端存储和恢复检查。多人开始频繁交换改动后,就该申请正式团队仓库,不能继续靠替换同一个附件协调开发。
自动生成备份的脚本
可以把生成过程脚本化
重复备份时,可以把生成和校验写进脚本。
比如一个 Git 管理的小项目,可以写一个本地备份脚本:
#!/usr/bin/env bash
set -euo pipefail
project_name="project-name"
stamp="$(date +%Y-%m-%d-%H%M%S)"
output_dir="$HOME/code"
backup_file="$output_dir/${project_name}-${stamp}.bundle"
if [[ -e "$backup_file" ]]; then
printf '备份文件已存在:%s\n' "$backup_file" >&2
exit 1
fi
git bundle create "$backup_file" --all
git bundle verify "$backup_file"
如果只是普通目录,也可以用 zip:
#!/usr/bin/env bash
set -euo pipefail
project_name="project-name"
stamp="$(date +%Y-%m-%d-%H%M%S)"
output_dir="$HOME/code"
backup_file="$output_dir/${project_name}-${stamp}.zip"
if [[ -e "$backup_file" ]]; then
printf '备份文件已存在:%s\n' "$backup_file" >&2
exit 1
fi
zip -r "$backup_file" "$project_name" -x "$project_name/.git/*"
unzip -t "$backup_file"
bundle 脚本要从 Git 仓库内运行;zip 示例要从包含 project-name 的父目录运行。output_dir 需要事先存在,zip 校验还需要 unzip。
脚本先生成新文件,再校验,不删除旧文件;遇到已存在的目标文件就退出。时间到秒用于区分同一天的多次备份,定期清理仍需按项目和保留规则处理。生成或校验失败时,上一份备份应该仍在。
这些是手动单次运行的示例,不支持并发。存在性检查与写文件不是一个原子动作;要做并行备份,需要隔离各次输出目录并设计发布、保留和失败清理流程。
如果还想更进一步,可以把「上传到飞书云盘并替换旧文件」也工具化。这个步骤依赖当前账号、登录态和飞书页面能力,自动化前要确认权限边界和误删恢复机制。对于确定只保留最新备份的目录,删除旧文件再上传新文件是可以接受的;对于多人共用或不可恢复资料,就不应该默认自动删除。