Snapshot 与 Sync
snapshot 和 sync 是 repostack 实现"时间旅行"的核心机制。
两个配置文件的关系
| 文件 | 作用 | 是否应提交到 Git |
|---|---|---|
repostack.yaml | 声明 stack 包含哪些 repo | ✅ 是 |
repostack.lock.yaml | 记录每个 repo 的精确 Git 状态 | ✅ 是 |
简单记忆:
repostack.yaml= "我想要什么"repostack.lock.yaml= "实际是什么"
关于 lock 文件的详细说明,参见 Lock 文件。
snapshot 做了什么
repostack snapshot
执行步骤:
读取当前 stack 中每个 repo 的:path - 本地路径source - 远程地址- 当前 branch
- 当前
HEAD revision
path - 本地路径source - 远程地址HEAD revision构建 lock 对象并计算 checksum(SHA-256)
将数据写入 repostack.lock.yaml
生成示例:
version: 1
checksum: a1b2c3d4e5f67890
repos:
foo:
path: foo
source: git@github.com:example-org/foo.git
branch: main
revision: a79cd2d8f1b2c3d4e5f678901234567890abcdef
自动 Snapshot
以下命令会自动更新 lock 文件,通常不需要手动运行 snapshot:
repostack use- 添加 repo 后自动 snapshotrepostack remove- 移除 repo 后自动 snapshotrepostack sync- 同步完成后自动 snapshot
sync 做了什么
repostack sync
执行步骤:
下载 - clone 本地缺失的 repo
读取 lock - 解析 repostack.lock.yaml
拉取 - 对每个 repo 执行 git fetch --all --tags
检出 - 如果 lock 有指定 revision,checkout 到该版本
记录 - 重新生成 lock 文件
Checksum 校验机制
lock 文件包含 SHA-256 校验和,用于检测文件是否被意外修改:
checksum: a1b2c3d4e5f67890
作用:
- 生成时计算 lock 内容(不含 checksum 本身)的 SHA-256 哈希,取前 16 位
sync命令读取时重新计算比对- 不匹配时报错,防止文件被意外修改
详细计算方式参见 Lock 文件。
如何处理错误:
如果确实需要修改,删除 checksum 字段后重新运行 snapshot
如果是意外损坏,从 Git 历史恢复 lock 文件
时间旅行工作流
推荐将 stack root 本身作为 Git 仓库:
# 1. 当前状态
cd ~/my-stack
repostack list
# foo @ main a79cd2d
# bar @ main 1234567
# 2. 记录状态
repostack snapshot
git add repostack.lock.yaml
git commit -m "checkpoint: before big refactor"
# 3. 继续开发...
# (在 foo 和 bar 中做各种修改、提交)
# 4. 需要回到之前的状态
git log --oneline
git checkout abc123 # 回到之前的 stack 状态
repostack sync # 各 repo 也回到当时的 revision
当前边界
snapshot只记录 commit,不记录未提交的修改(dirty 状态只会在list中显示)- 如果 repo checkout 到具体 revision,branch 会显示为
HEAD - lock 文件记录的是 Git revision 快照,不是完整环境锁定(不包含 node_modules 等)
常见问题
Q: 为什么 use/remove 会自动 snapshot?
A: 为了保持 repostack.yaml 和 repostack.lock.yaml 始终同步。添加/移除 repo 后,lock 文件的内容定义已经变化,需要更新。
Q: lock 文件冲突了怎么办?
A: 解决方式和普通代码冲突一样:
选择一方的版本
运行 repostack sync 确保本地状态匹配
如果需要,重新 snapshot 生成新的 lock
Q: 空仓库(无 commit)会怎样?
A: 会显示 (no commits),sync 时不会尝试 checkout。