Isolated workspaces for repo-managed multi-repository projects using git worktree + symlink
Project description
repoworktree
为 repo 管理的多仓库项目创建隔离工作空间。基于 git worktree + symlink,支持从全 symlink(零开销只读)到全 worktree(完全隔离)的连续光谱。
全 symlink (只读) 全 worktree (完全隔离)
│ rwt create /tmp/ws rwt create /tmp/ws --all │
│ ◄── rwt promote / demote 动态切换 ──► │
└──────────────────────────────────────────────────────────┘
安装
Python 3.10+,无第三方依赖。
pip install repoworktree
快速开始
# 创建工作空间,指定需要修改的仓库
rwt create /tmp/ws-agent1 -w nuttx,apps -n "fix-serial-driver"
# 在工作空间中开发
cd /tmp/ws-agent1
source envsetup.sh && lunch && m # 构建正常工作
# 开发中发现需要修改更多仓库
rwt promote frameworks/system/core
# 完成后不再需要修改的仓库降级回 symlink
rwt demote frameworks/system/core
# 销毁工作空间
rwt destroy /tmp/ws-agent1
命令参考
rwt create — 创建工作空间
rwt create <path> [options]
| 选项 | 说明 |
|---|---|
<path> |
工作空间目标路径 |
-n, --name |
工作空间名称(默认:目录名) |
-w, --worktree |
逗号分隔的子仓库路径,创建为 git worktree |
--all |
所有子仓库都创建 git worktree |
-s, --source |
主 repo checkout 路径(默认:自动检测 .repo/) |
--pin |
锁定版本,格式 repo=version[,repo=version,...] |
-b, --branch |
为 worktree 创建命名分支而非 detached HEAD |
示例:
# 全 symlink 只读(极端 A)
rwt create /tmp/ws-readonly
# 典型用法:修改少量仓库
rwt create /tmp/ws-agent1 -w nuttx,apps -n "fix-serial-driver"
# 修改嵌套子仓库
rwt create /tmp/ws-bt -w nuttx,apps/system/adb
# 父子仓库同时修改
rwt create /tmp/ws-dev -w apps,apps/system/adb
# 全 worktree 完全隔离(极端 B)
rwt create /tmp/ws-full --all
# 锁定版本 + 命名分支
rwt create /tmp/ws-stable -w nuttx --pin nuttx=v12.0.0 -b feature/new-driver
rwt destroy — 销毁工作空间
rwt destroy <path|name> [-f]
| 选项 | 说明 |
|---|---|
<path|name> |
工作空间路径或名称 |
-f, --force |
强制销毁,即使有未提交修改 |
rwt destroy /tmp/ws-agent1
rwt destroy fix-serial-driver # 按名称
rwt destroy /tmp/ws-dirty -f # 丢弃未提交修改
rwt promote — 提升子仓库为可写 worktree
在工作空间内执行,将 symlink 的子仓库动态提升为 git worktree。
rwt promote <repo_path> [options]
| 选项 | 说明 |
|---|---|
<repo_path> |
子仓库路径(如 nuttx、frameworks/system/core) |
--pin |
checkout 到指定版本 |
-b, --branch |
创建命名分支 |
cd /tmp/ws-agent1
rwt promote vendor/xiaomi/miwear
rwt promote frameworks/system/core --pin abc1234
rwt promote nuttx -b fix/uart-bug
promote 自动处理嵌套情况:
- 顶层 symlink → 直接替换为 worktree
- 深层嵌套(如
frameworks/system/core)→ 自动拆解父级 symlink 为真实目录 + symlink 混合结构 - 父仓库已有子 worktree → 临时移除子 worktree,创建父 worktree,再恢复子 worktree
rwt demote — 降级 worktree 为只读 symlink
rwt demote <repo_path> [-f]
| 选项 | 说明 |
|---|---|
<repo_path> |
子仓库路径 |
-f, --force |
强制降级,丢弃未提交修改 |
rwt demote apps
rwt demote apps -f # 丢弃修改
demote 自动处理:
- 有子 worktree 时保留子 worktree,父目录重建为真实目录 + symlink 结构
- 无子 worktree 时向上合并,尽可能将父目录恢复为 symlink
rwt list — 列出所有工作空间
rwt list [-s <source>] [--json]
rwt status — 查看工作空间详情
rwt status [<path|name>] [--json]
rwt sync — 同步工作空间
rwt sync [--rebase]
主仓库 repo sync 后,symlink 自动跟随更新。worktree 需要手动 sync:
| 子仓库状态 | 默认行为 | --rebase 行为 |
|---|---|---|
| symlink | 自动跟随 | 同左 |
| worktree, pinned | 跳过 | 跳过 |
| worktree, 有本地修改 | 跳过,报告 | 跳过,报告 |
| worktree, 有本地 commit | 跳过,报告 | rebase 到最新 |
| worktree, clean | 更新到主仓库 HEAD | 同左 |
rwt pin / rwt unpin — 版本锁定
rwt pin <repo_path> [<version>]
rwt unpin <repo_path>
rwt export — 导出变更
rwt export [--format patch|bundle] [-o <dir>]
典型场景
多 agent 并行开发
# 两个 agent 同时修改 nuttx,互不影响
rwt create /tmp/ws-agent1 -w nuttx -n "agent1-serial-fix"
rwt create /tmp/ws-agent2 -w nuttx -n "agent2-spi-driver"
开发过程中动态调整
# 初始只修改 nuttx
rwt create /tmp/ws-dev -w nuttx
cd /tmp/ws-dev
# 发现需要修改 apps/system/adb
rwt promote apps/system/adb
# 又需要修改 apps 本身
rwt promote apps
# apps 改完了,降级回 symlink
rwt demote apps
导出变更到主目录
cd /tmp/ws-agent1/nuttx
git push origin HEAD:refs/for/main # 直接推送到 Gerrit
工作空间结构
/tmp/ws-agent1/
├── .workspace.json # 工作空间元数据
├── nuttx/ # git worktree(可写)
├── apps/ # 真实目录(内部有 worktree 后代)
│ ├── system/
│ │ ├── adb/ # git worktree(可写)
│ │ └── core/ # symlink → source(只读)
│ └── benchmarks/ # symlink → source(只读)
├── build/ # symlink → source(只读)
├── frameworks/ # symlink → source(只读)
├── build.sh # symlink(保持原始相对链接)
└── CLAUDE.md # symlink → source
原理
- symlink 子仓库:零开销,直接指向主 checkout 的对应目录,只读(修改会影响主目录)
- worktree 子仓库:通过
git worktree add创建独立工作副本,有自己的 HEAD、index、工作树,完全隔离 - 嵌套仓库:repo 管理的项目中存在父子仓库(如
apps/和apps/system/adb/是独立 git 仓库)。当子仓库需要 worktree 时,父级 symlink 被拆解为真实目录 + symlink 混合结构,只在通往 worktree 的路径上创建真实目录 - 元数据:
.workspace.json记录工作空间配置,主目录的.workspaces.json索引所有工作空间
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file repoworktree-0.1.0.tar.gz.
File metadata
- Download URL: repoworktree-0.1.0.tar.gz
- Upload date:
- Size: 57.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b6866298d81813a32df86372f5303eb3c7d80a1e2700cc31484352cdd97dd04
|
|
| MD5 |
2c01949948e1ee6adb1456c9f253ce26
|
|
| BLAKE2b-256 |
a2e66d50068159645246b98cf90f2508eb7878144473d901128f192dff58696e
|
Provenance
The following attestation bundles were made for repoworktree-0.1.0.tar.gz:
Publisher:
publish.yml on XuNeo/repoworktree
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repoworktree-0.1.0.tar.gz -
Subject digest:
1b6866298d81813a32df86372f5303eb3c7d80a1e2700cc31484352cdd97dd04 - Sigstore transparency entry: 976371946
- Sigstore integration time:
-
Permalink:
XuNeo/repoworktree@39b74a06a15735385b282db786b04e27691bac6a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/XuNeo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@39b74a06a15735385b282db786b04e27691bac6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file repoworktree-0.1.0-py3-none-any.whl.
File metadata
- Download URL: repoworktree-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b94c65665a4e9bfd4663b8c50f454e6ee44f0dce8597ac82df213c9fc95c080
|
|
| MD5 |
0f4c3aff4f1f4d2ce46abe1b5dcf0502
|
|
| BLAKE2b-256 |
6abed36a058123cbb590d67b6336995e630afa522e361b0e6fbaea55887d742d
|
Provenance
The following attestation bundles were made for repoworktree-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on XuNeo/repoworktree
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repoworktree-0.1.0-py3-none-any.whl -
Subject digest:
1b94c65665a4e9bfd4663b8c50f454e6ee44f0dce8597ac82df213c9fc95c080 - Sigstore transparency entry: 976371951
- Sigstore integration time:
-
Permalink:
XuNeo/repoworktree@39b74a06a15735385b282db786b04e27691bac6a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/XuNeo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@39b74a06a15735385b282db786b04e27691bac6a -
Trigger Event:
release
-
Statement type: