Lock 文件

repostack.lock.yaml 是自动生成的锁定文件,记录每个 repo 的精确 Git 状态。

作用

repostack.yaml 的关系:

文件作用类比
repostack.yaml声明 stack 包含哪些 repopackage.json
repostack.lock.yaml记录 repo 的精确 revisionpackage-lock.json

简单说:

  • repostack.yaml = "我想要什么"
  • repostack.lock.yaml = "实际是什么"

结构示例

version: 1
checksum: a1b2c3d4e5f67890
repos:
  foo:
    path: foo
    source: git@github.com:example-org/foo.git
    branch: main
    revision: a79cd2d8f1b2c3d4e5f678901234567890abcdef
  bar:
    path: bar
    source: git@github.com:example-org/bar.git
    branch: main
    revision: 123456789abcdef0123456789abcdef012345678

字段说明

字段说明
version锁定文件格式版本
checksum内容校验和(SHA-256 前 16 位),用于检测文件是否被意外修改
repos每个 repo 的锁定状态
repos.<name>.path本地路径(冗余,用于校验)
repos.<name>.source远程地址(冗余,用于校验)
repos.<name>.branch分支名称
repos.<name>.revision精确的 Git commit SHA

工作原理

生成时机

以下命令会自动更新 lock 文件:

  • repostack snapshot - 显式记录当前状态
  • repostack use - 添加 repo 后自动记录
  • repostack remove - 移除 repo 后自动记录
  • repostack sync - 同步完成后重新记录

校验机制

Lock 文件包含 SHA-256 校验和:

checksum: a1b2c3d4e5f67890

计算方式

取 lock 文件内容,排除 checksum 字段本身

将剩余字段(version + repos)按字母顺序排序

将排序后的对象转为 JSON 字符串

计算 SHA-256 哈希值

取前 16 位作为 checksum

验证时机

  • sync 命令读取 lock 文件时会重新计算并比对
  • 不匹配则报错,防止文件被意外修改

示例

假设 lock 文件内容(不含 checksum)为:

version: 1
repos:
  foo:
    path: foo
    source: git@github.com:example-org/foo.git
    branch: main
    revision: a79cd2d...

计算过程:

JSON: {"repos":{"foo":{"branch":"main","path":"foo","revision":"a79cd2d","source":"git@github.com:example-org/foo.git"}},"version":1}
SHA-256: a1b2c3d4e5f67890...
checksum: a1b2c3d4e5f67890  (前16位)

校验失败报错

Lock file checksum mismatch: expected a1b2c3d4..., got xxxxxxxxxxxxxxxx.
The lock file may have been corrupted or manually edited.

处理方法

如果确实需要修改,删除 checksum 字段后重新运行 snapshot

如果是意外损坏,从 Git 历史恢复 lock 文件

与 Git 的配合

推荐将 lock 文件提交到版本控制:

# 记录当前状态
repostack snapshot

# 提交到 Git
git add repostack.yaml repostack.lock.yaml
git commit -m "update stack"

这样可以通过 stack root 的 commit 历史来"时间旅行":

# 回到之前的 stack 状态
git checkout <commit>
repostack sync  # 各 repo 也回到当时的 revision

最佳实践

✅ 应该做

  • 提交到 Git:将 repostack.lock.yaml 加入版本控制
  • 定期 snapshot:重要变更前记录状态
  • 配合 sync 使用:切换分支或协作后运行 sync

❌ 不应该做

  • 不要手动编辑:如需修改,使用 use/remove 命令
  • 不要忽略:不要将 lock 文件加入 .gitignore
  • 不要依赖它做备份:lock 文件只记录 revision,不记录代码内容

常见问题

Q: 为什么 use/remove 也会自动 snapshot?

A: 为了保持 repostack.yamlrepostack.lock.yaml 始终同步。添加/移除 repo 后,lock 文件的内容定义已经变化,需要更新。

Q: Lock 文件冲突了怎么办?

A: 解决方式和普通代码冲突一样:

选择一方的版本

运行 repostack sync 确保本地状态匹配

如果需要,重新 snapshot 生成新的 lock

Q: 空仓库(无 commit)会怎样?

A: Revision 会显示 (no commits)sync 时不会尝试 checkout。

Q: 可以删除 lock 文件吗?

A: 可以,但会丢失精确的版本锁定。下次 sync 时 repo 会停留在当前 HEAD,而不是某个特定的历史版本。