From 09f778850cb5ae642b3e5460a59b907b52a20751 Mon Sep 17 00:00:00 2001 From: lambda610 Date: Fri, 6 Mar 2026 00:28:21 +0800 Subject: [PATCH 1/6] feat: add jujutsu skill for jj-enabled projects --- skills/jujutsu/SKILL.md | 144 ++++++++++++++++++++++++++ skills/jujutsu/references/commands.md | 89 ++++++++++++++++ skills/jujutsu/references/pitfalls.md | 139 +++++++++++++++++++++++++ skills/jujutsu/references/revsets.md | 93 +++++++++++++++++ 4 files changed, 465 insertions(+) create mode 100644 skills/jujutsu/SKILL.md create mode 100644 skills/jujutsu/references/commands.md create mode 100644 skills/jujutsu/references/pitfalls.md create mode 100644 skills/jujutsu/references/revsets.md diff --git a/skills/jujutsu/SKILL.md b/skills/jujutsu/SKILL.md new file mode 100644 index 0000000..5d6ae51 --- /dev/null +++ b/skills/jujutsu/SKILL.md @@ -0,0 +1,144 @@ +--- +name: jujutsu +description: Use Jujutsu (jj) for version control in jj-enabled projects. Applies when the project uses jj (has .jj/ directory, README specifies jj, or user requests jj). +--- + +# Jujutsu 使用指南 + +Jujutsu (jj) 是新一代分布式版本控制工具,兼容 Git 仓库但用法有根本差异。 + +## 何时使用 + +**仅在明确使用 jj 的项目中使用此 skill。** 判断方法: +- 存在 `.jj/` 目录 +- 项目 README 明确要求用 jj +- 用户明确指定用 jj + +对于普通 Git 项目,使用标准的 Git 工具。 + +## 心智模型(与 Git 的根本差异) + +### ❌ 不要按 Git 思维操作 + +| Git 思维 | 问题 | +|---------|------| +| `git add` → `git commit` | jj 无暂存区,不需要 add | +| commit 后不能改 | jj 的 commit 可随时修改 | +| 用 branch 管理分支 | jj 用 bookmarks,是轻量指针 | +| stash 暂存改动 | jj 用 shelf 或直接新建 change | +| 冲突必须立即解决 | jj 先继续工作,之后再解决 | + +### ✅ 正确的心智模型 + +1. **自动追踪** — jj 自动追踪所有修改,无需 `git add` +2. **可变提交** — commit 是可编辑的"change",随时可修改 +3. **操作可撤销** — 几乎所有操作都能用 `jj undo` 撤销 +4. **Bookmarks** — 轻量标记,不是 Git branch 的完全等价物 +5. **Revsets** — 强大的查询语法,能表达复杂条件 + +## 常用命令速查 + +```bash +# 查看状态 +jj st # 当前变更 +jj log # 历史(按时间倒序) +jj log --graph # 图形化历史 + +# 操作变更 +jj diff # 查看当前变更 +jj describe # 修改提交信息 +jj commit -m "message" # 提交(会自动包含所有修改) +jj squash # 合并到父提交 +jj restore # 撤销文件修改 + +# Bookmarks(类似 branch) +jj bookmark list # 列出 bookmarks +jj bookmark create # 创建 bookmark +jj bookmark delete # 删除 bookmark +jj bookmark move --to # 移动 bookmark + +# 分支/工作流 +jj new # 创建新 change +jj new # 基于某提交创建新 change +jj co # 切换到 bookmark +jj rebase -b -o # 变基 + +# 远程操作 +jj git fetch # 拉取 +jj git push # 推送 +jj git push --bookmark # 推送特定 bookmark + +# 撤销 +jj undo # 撤销上一次操作 +jj op log # 查看操作日志 +``` + +## 常见工作流 + +### 日常提交 +```bash +# 1. 查看变更 +jj st +jj diff + +# 2. 提交(无需 add) +jj commit -m "feat: add new feature" + +# 3. 查看历史 +jj log +``` + +### 修改历史提交 +```bash +# 修改当前提交的描述 +jj describe -m "new message" + +# 把当前变更合并到上一个提交 +jj squash + +# 拆分当前提交(需要用 jj diffedit) +jj split +``` + +### 处理冲突 +```bash +# 1. 冲突时 jj 不会中断,会创建一个 conflicted change +# 2. 解决文件冲突后 +jj resolve + +# 3. 确认解决完毕 +jj st + +# 4. 继续提交或 squash +jj squash +``` + +### 与远程同步 +```bash +# 拉取远程变更 +jj git fetch + +# 如果有冲突,创建新 change 再处理 +jj new /main + +# 推送 +jj git push +``` + +## 注意事项 + +1. **不要用 `git add`** — jj 自动追踪,add 反而可能造成混淆 +2. **不要用 `git checkout `** — 用 `jj restore ` +3. **不要用 `git stash`** — 用 `jj shelf` 或新建 change +4. **`jj commit` 会包含所有修改** — 不需要 `-a` 之类 flag +5. **冲突不阻塞** — 可以继续工作,稍后再解决 + +## 获取帮助 + +```bash +jj help +jj help +jj log --help # 查看 revset 语法 +``` + +更多命令对照:见 `references/commands.md` diff --git a/skills/jujutsu/references/commands.md b/skills/jujutsu/references/commands.md new file mode 100644 index 0000000..7e5940a --- /dev/null +++ b/skills/jujutsu/references/commands.md @@ -0,0 +1,89 @@ +# 命令对照表(带解释) + +> 对比 Git 命令,理解为什么不同。 + +## 基础操作 + +| Git | Jujutsu | 说明 | +|-----|---------|------| +| `git status` | `jj st` | 查看当前工作状态 | +| `git diff` | `jj diff` | 查看未提交的修改 | +| `git diff HEAD` | `jj diff` | 同上,jj 默认比较 HEAD | +| `git diff ..` | `jj diff -r --to ` | 比较两个提交 | +| `git add` | ❌ 不需要 | jj 自动追踪所有修改 | +| `git commit` | `jj commit -m "msg"` | 提交当前所有变更 | +| `git commit -a` | `jj commit` | 同上,jj 不需要 -a | +| `git commit --amend` | `jj squash @` | 把变更合并到当前提交 | +| `git restore ` | `jj restore ` | 撤销文件修改 | +| `git checkout -- ` | `jj restore ` | 同上 | + +## 历史查看 + +| Git | Jujutsu | 说明 | +|-----|---------|------| +| `git log` | `jj log` | 查看历史(默认显示当前 change) | +| `git log --oneline` | `jj log -r ::@` | 简洁格式 | +| `git log --graph` | `jj log --graph` | 图形化(jj 更美观) | +| `git log --all` | `jj log -r 'all()'` | 查看所有 bookmark | +| `git show ` | `jj show ` | 查看提交详情 | +| `git blame ` | `jj file annotate ` | 查看文件每行最后修改 | + +## 分支操作(Bookmarks) + +| Git | Jujutsu | 说明 | +|-----|---------|------| +| `git branch` | `jj bookmark list` | 列出分支 | +| `git branch ` | `jj bookmark create ` | 创建分支 | +| `git branch -d ` | `jj bookmark delete ` | 删除分支 | +| `git checkout ` | `jj co ` | 切换分支 | +| `git checkout -b ` | `jj new ` | 创建并切换 | +| `git branch -f ` | `jj bookmark move --to ` | 移动分支 | + +**注意**:jj 的 bookmarks 是轻量指针,不是 Git branch 的完全等价物。 + +## 变基与合并 + +| Git | Jujutsu | 说明 | +|-----|---------|------| +| `git merge ` | `jj new @ ` | 合并(创建新 change) | +| `git rebase ` | `jj rebase -b -o ` | 变基 | +| `git rebase --onto B A^ ` | `jj rebase -s A -o B` | 变基到新基础 | +| `git rebase -i` | `jj rebase -r` | 交互式变基 | + +## 远程操作 + +| Git | Jujutsu | 说明 | +|-----|---------|------| +| `git fetch` | `jj git fetch` | 拉取 | +| `git pull` | `jj git fetch` (+ `jj new`) | 拉取后创建新 change | +| `git push` | `jj git push` | 推送 | +| `git push ` | `jj git push --bookmark ` | 推送特定 bookmark | +| `git remote add ` | `jj git remote add ` | 添加远程 | + +## 暂存与撤销 + +| Git | Jujutsu | 说明 | +|-----|---------|------| +| `git stash` | `jj shelf` | 暂存当前变更 | +| `git stash pop` | `jj shelf unapply` | 恢复暂存 | +| `git reset --hard` | `jj abandon` | 放弃当前 change | +| `git reset --soft HEAD~` | `jj squash --from @-` | 保留修改并新建 change | +| `git cherry-pick ` | `jj duplicate -o @` | 复制提交 | + +## 撤销操作 + +| Git | Jujutsu | 说明 | +|-----|---------|------| +| `git reflog` | `jj op log` | 查看操作日志 | +| `git reset --hard ` | `jj undo` | 撤销上一次操作 | + +**jj 的 `jj undo` 比 Git 的 reset 更强大**,可以撤销几乎任何操作。 + +## 文件操作 + +| Git | Jujutsu | 说明 | +|-----|---------|------| +| `git ls-files` | `jj file list` | 列出跟踪的文件 | +| `git rm ` | `jj file delete ` | 删除文件 | +| `git rm --cached ` | `jj file untrack ` | 取消跟踪 | +| `git rev-parse --show-toplevel` | `jj workspace root` | 仓库根目录 | diff --git a/skills/jujutsu/references/pitfalls.md b/skills/jujutsu/references/pitfalls.md new file mode 100644 index 0000000..f2c2f02 --- /dev/null +++ b/skills/jujutsu/references/pitfalls.md @@ -0,0 +1,139 @@ +# 常见错误与陷阱 + +> Agent 容易犯的错误,按严重程度排序。 + +## 🔴 严重错误 + +### 用 `git add` + +**错误**:想暂存文件时用 `git add` + +**问题**:jj 没有暂存区概念,`git add` 不会生效(除非在 git 兼容模式) + +**正确做法**: +```bash +# jj 自动追踪所有修改,直接提交即可 +jj commit -m "message" + +# 如果只想提交部分文件,用 jj split 或 jj diffedit +jj diffedit -r @ +``` + +### 用 `git checkout` 切换分支 + +**错误**:用 `git checkout ` 切换分支 + +**问题**:jj 用 `jj co` 或 `jj edit` + +**正确做法**: +```bash +jj co +# 或 +jj edit +``` + +### 用 `git stash` 暂存 + +**错误**:用 `git stash` 暂存改动 + +**问题**:jj 用 shelf + +**正确做法**: +```bash +# 暂存当前改动 +jj shelf + +# 恢复暂存 +jj shelf unapply + +# 查看暂存列表 +jj shelf list +``` + +## 🟠 易错操作 + +### `jj new` 不带参数 + +**误解**:`jj new` 等于 `git checkout -b` + +**正确**:`jj new` 基于当前 `@` 创建新 change,不带 bookmark 名 + +```bash +# 创建新 change(无 bookmark) +jj new + +# 创建并设置 bookmark +jj new -b + +# 基于某提交创建 +jj new +``` + +### `jj rebase` 参数顺序 + +**误解**:先写源后写目标(像 git 那样) + +**正确**:jj 用 `-b` 指定要移动的 bookmark,`-o` 指定目标位置 + +```bash +# 错误 +jj rebase A B # ❌ + +# 正确 +jj rebase -b A -o B # ✅ 把 A 变基到 B 上 +``` + +### 冲突后继续操作 + +**误解**:遇到冲突必须解决才能继续 + +**正确**:jj 允许先继续工作,稍后再解决冲突 + +```bash +# 冲突后,先查看状态 +jj st + +# 创建新 change 继续工作(冲突会保留在原 change) +jj new + +# 之后回到冲突的 change,解决后再 squash +jj co +# 解决冲突文件 +jj resolve +jj squash +``` + +## 🟡 小问题 + +### 忘记 `-m` 参数 + +**问题**:`jj commit` 不带 `-m` 会打开编辑器 + +**建议**:习惯用 `jj commit -m "message"` + +### 混淆 bookmarks 和 changes + +- **Bookmark**:类似 Git branch,是指向提交的指针 +- **Change**:jj 的核心概念,是可编辑的提交 + +``` +@ → 当前工作的 change +HEAD → 当前 checkout 的 bookmark 指向的提交 +``` + +### 用 Git 命令 + +**提醒**:在 jj 项目中尽量用 jj 命令。虽然 jj 兼容 git 操作,但: +- `jj git init` 初始化 `.jj/` 目录 +- `jj git clone` 正确设置 jj 环境 +- 直接用 `git init` 可能导致 jj 无法识别 + +## 检查清单 + +操作前快速检查: +- [ ] 不要用 `git add` +- [ ] 用 `jj commit` 而不是 `git commit` +- [ ] 用 `jj co` 而不是 `git checkout` +- [ ] 用 `jj bookmark` 而不是 `git branch` +- [ ] 用 `jj rebase -b -o` 而不是 `git rebase` +- [ ] 用 `jj shelf` 而不是 `git stash` diff --git a/skills/jujutsu/references/revsets.md b/skills/jujutsu/references/revsets.md new file mode 100644 index 0000000..6199e3e --- /dev/null +++ b/skills/jujutsu/references/revsets.md @@ -0,0 +1,93 @@ +# Revset 查询语法 + +Revset 是 jj 强大的查询语法,能精确定位提交。 + +## 基本语法 + +```bash +jj log -r +``` + +## 常用查询 + +| Revset | 含义 | +|--------|------| +| `@` | 当前工作 change | +| `@-` | 当前 change 的父提交 | +| `@--` | 祖父提交 | +| `main` | bookmark 名为 main 的提交 | +| `HEAD` | HEAD 指向的提交 | +| `root` | 仓库根提交 | + +## 运算符 + +| 运算符 | 含义 | 示例 | +|--------|------|------| +| `::` | 祖先范围 | `main::` = main 的所有后代 | +| `..` | 包含范围 | `main..main~5` | +| `|` | 并集 | `main | feature` | +| `&` | 交集 | `main & @` | +| `-` | 差集 | `@ - main` | +| `+` | 并集(同 `\|`) | | +| `::` | 子孙 | `A::B` = A 到 B 之间的提交 | + +## 常见用法 + +```bash +# 当前分支的历史 +jj log -r @::@- + +# 所有未推送的提交 +jj log -r '@..@|bookmarks(@)..' + +# 某个 bookmark 的历史 +jj log -r main::main + +# 最近 5 个提交 +jj log -r @--.. + +# 包含某个文件的提交 +jj log -r "file(path/to/file)" + +# 在某日期之后的提交 +jj log -r "date(2024-01-01).." + +# 作者包含某字符串的提交 +jj log -r "author(yelo)" +``` + +## 谓词 + +| 谓词 | 用法 | 说明 | +|------|------|------| +| `date()` | `date(2024-01-01)` | 日期 | +| `author()` | `author(yelo)` | 作者 | +| `committer()` | `committer(bot)` | 提交者 | +| `file()` | `file(src/main.rs)` | 包含某文件 | +| `description()` | `description(feat)` | 描述包含 | +| `empty()` | `empty()` | 空提交(无文件变更) | +| `public()` | `public()` | 已推送的提交 | + +## 快捷方式 + +| 快捷 | 展开 | +|-------|------| +| `@~n` | `@-n`,即第 n 个祖先 | +| `@^` | `@-`,即父提交 | +| `main~3` | main 的第 3 个祖先 | + +## 示例 + +```bash +# 查看当前 change 的祖先链 +jj log -r @::@- + +# 查看 feature 分支独有的提交 +jj log -r "feature - main" + +# 查看最近一周的提交 +jj log -r "date(-7d).." + +# 查看两个 bookmark 之间的差异 +jj diff -r main..feature +``` From 65287b55cc0a15e47531942ac365803754fb2eda Mon Sep 17 00:00:00 2001 From: lambda610 Date: Fri, 6 Mar 2026 01:11:45 +0800 Subject: [PATCH 2/6] fix: correct jujutsu commands based on official docs --- skills/jujutsu/SKILL.md | 152 +++++++++++++++++++------- skills/jujutsu/references/commands.md | 76 ++++++++----- skills/jujutsu/references/pitfalls.md | 132 +++++++++++++--------- skills/jujutsu/references/revsets.md | 108 ++++++++++++------ 4 files changed, 313 insertions(+), 155 deletions(-) diff --git a/skills/jujutsu/SKILL.md b/skills/jujutsu/SKILL.md index 5d6ae51..7661bb1 100644 --- a/skills/jujutsu/SKILL.md +++ b/skills/jujutsu/SKILL.md @@ -22,46 +22,49 @@ Jujutsu (jj) 是新一代分布式版本控制工具,兼容 Git 仓库但用 | Git 思维 | 问题 | |---------|------| -| `git add` → `git commit` | jj 无暂存区,不需要 add | -| commit 后不能改 | jj 的 commit 可随时修改 | +| `git add` | jj 无暂存区,不需要 add | +| commit 后不能改 | jj 的 commit 是可编辑的 change | | 用 branch 管理分支 | jj 用 bookmarks,是轻量指针 | -| stash 暂存改动 | jj 用 shelf 或直接新建 change | -| 冲突必须立即解决 | jj 先继续工作,之后再解决 | +| `git stash` 暂存 | 用 `jj new @-` 或 `jj shelf` | +| 冲突必须立即解决 | jj 冲突可延迟处理 | ### ✅ 正确的心智模型 1. **自动追踪** — jj 自动追踪所有修改,无需 `git add` 2. **可变提交** — commit 是可编辑的"change",随时可修改 3. **操作可撤销** — 几乎所有操作都能用 `jj undo` 撤销 -4. **Bookmarks** — 轻量标记,不是 Git branch 的完全等价物 +4. **Bookmarks** — 轻量标记,类似 Git branch 但有 tracked 概念 5. **Revsets** — 强大的查询语法,能表达复杂条件 +6. **无 checkout** — 用 `jj new` 或 `jj edit` 切换 ## 常用命令速查 ```bash # 查看状态 -jj st # 当前变更 -jj log # 历史(按时间倒序) +jj st # 当前变更(相当于 git status) +jj log # 历史 jj log --graph # 图形化历史 -# 操作变更 +# 操作变更(无需 add) jj diff # 查看当前变更 -jj describe # 修改提交信息 -jj commit -m "message" # 提交(会自动包含所有修改) -jj squash # 合并到父提交 -jj restore # 撤销文件修改 +jj describe # 修改提交信息 +jj commit -m "message" # 提交(自动包含所有修改) +jj squash # 合并到父提交(类似 git commit --amend) +jj restore # 撤销文件修改 -# Bookmarks(类似 branch) +# 注意:没有 jj co 或 jj checkout! +# 切换到某 bookmark:用 jj new +# 编辑某 commit:用 jj edit + +# Bookmarks(类似 branch,但不同) jj bookmark list # 列出 bookmarks -jj bookmark create # 创建 bookmark +jj bookmark create -r # 创建 bookmark jj bookmark delete # 删除 bookmark -jj bookmark move --to # 移动 bookmark +jj bookmark move --to # 移动 bookmark -# 分支/工作流 -jj new # 创建新 change -jj new # 基于某提交创建新 change -jj co # 切换到 bookmark -jj rebase -b -o # 变基 +# 变基 +jj rebase -b -o # 移动 bookmark 及其指向的 commit +jj rebase -s -o # 移动 commit 及其后代 # 远程操作 jj git fetch # 拉取 @@ -81,7 +84,7 @@ jj op log # 查看操作日志 jj st jj diff -# 2. 提交(无需 add) +# 2. 提交(无需 add!) jj commit -m "feat: add new feature" # 3. 查看历史 @@ -96,49 +99,118 @@ jj describe -m "new message" # 把当前变更合并到上一个提交 jj squash -# 拆分当前提交(需要用 jj diffedit) -jj split +# 把变更 squash 到指定提交 +jj squash --into +``` + +### 创建新分支(在某 bookmark 上开始工作) +```bash +# 相当于 git checkout -b topic main +jj new main +jj bookmark create topic +# 或者一步到位: +jj new main -b topic +``` + +### 变基 +```bash +# 移动 bookmark A 到 B 上(类似 git rebase) +jj rebase -b A -o B + +# 移动 commit 及其后代到新基础 +jj rebase -s -o ``` ### 处理冲突 ```bash -# 1. 冲突时 jj 不会中断,会创建一个 conflicted change -# 2. 解决文件冲突后 -jj resolve +# 1. 冲突不会中断操作,会创建 conflicted change +# 2. 创建新 commit 来解决冲突 +jj new -# 3. 确认解决完毕 -jj st +# 3. 解决文件中的冲突标记 +# 编辑文件... + +# 4. 标记已解决 +jj resolve -# 4. 继续提交或 squash +# 5. squash 到原提交 jj squash ``` +### 临时保存当前工作 +```bash +# 相当于 git stash:创建兄弟 commit +jj new @- + +# 恢复:用 jj edit 回到之前的 commit +``` + ### 与远程同步 ```bash -# 拉取远程变更 +# 拉取 jj git fetch -# 如果有冲突,创建新 change 再处理 -jj new /main +# 如果有远程更新,先 fetch +jj git fetch # 推送 jj git push ``` +## 关键命令对照 + +| Git | Jujutsu | 说明 | +|-----|---------|------| +| `git status` | `jj st` | | +| `git diff` | `jj diff` | | +| `git add` | ❌ 不需要 | jj 自动追踪 | +| `git commit` | `jj commit -m "msg"` | | +| `git commit --amend` | `jj squash` | | +| `git checkout ` | `jj new ` | **没有 jj co!** | +| `git checkout -b ` | `jj new -b ` | | +| `git branch` | `jj bookmark list` | | +| `git merge A` | `jj new @ A` | | +| `git rebase B A` | `jj rebase -b A -o B` | | +| `git stash` | `jj new @-` | | +| `git reset --hard` | `jj abandon` | | +| `git reset --soft HEAD~` | `jj squash --from @-` | | + +**注意**:jj 没有 `jj co` 或 `jj checkout` 命令! + ## 注意事项 -1. **不要用 `git add`** — jj 自动追踪,add 反而可能造成混淆 -2. **不要用 `git checkout `** — 用 `jj restore ` -3. **不要用 `git stash`** — 用 `jj shelf` 或新建 change -4. **`jj commit` 会包含所有修改** — 不需要 `-a` 之类 flag -5. **冲突不阻塞** — 可以继续工作,稍后再解决 +1. **不要用 `git add`** — jj 自动追踪 +2. **不要用 `jj co`** — 用 `jj new` 或 `jj edit` +3. **`jj commit` 自动包含所有修改** — 不需要 `-a` +4. **冲突不阻塞** — 可以继续工作,稍后再解决 +5. **`jj new` 创建的是 change** — 是可编辑的空 commit +6. **Bookmarks 有 tracked 概念** — 类似 Git 的 upstream + +## Revset 快速参考 + +```bash +# 常用符号 +@ # 当前 working-copy commit +@- # 父提交 +root() # 根提交 +bookmarks() # 所有 bookmark + +# 运算符 +:: # 祖先(包含自己) +.. # 不包含祖先 +~ # 差集 +| # 并集 +& # 交集 + +# 示例 +jj log -r ::@ # 当前 commit 的祖先链 +jj log -r 'all()' # 所有可见 commit +jj log -r main.. # main 分支后的 commit +``` ## 获取帮助 ```bash jj help jj help -jj log --help # 查看 revset 语法 ``` - -更多命令对照:见 `references/commands.md` diff --git a/skills/jujutsu/references/commands.md b/skills/jujutsu/references/commands.md index 7e5940a..33915c8 100644 --- a/skills/jujutsu/references/commands.md +++ b/skills/jujutsu/references/commands.md @@ -1,6 +1,6 @@ # 命令对照表(带解释) -> 对比 Git 命令,理解为什么不同。 +> 基于官方文档:https://www.jj-vcs.dev/latest/git-command-table/ ## 基础操作 @@ -9,11 +9,11 @@ | `git status` | `jj st` | 查看当前工作状态 | | `git diff` | `jj diff` | 查看未提交的修改 | | `git diff HEAD` | `jj diff` | 同上,jj 默认比较 HEAD | -| `git diff ..` | `jj diff -r --to ` | 比较两个提交 | +| `git diff ..` | `jj diff -r A..B` | 比较两个提交 | | `git add` | ❌ 不需要 | jj 自动追踪所有修改 | | `git commit` | `jj commit -m "msg"` | 提交当前所有变更 | | `git commit -a` | `jj commit` | 同上,jj 不需要 -a | -| `git commit --amend` | `jj squash @` | 把变更合并到当前提交 | +| `git commit --amend` | `jj squash` | 把当前变更合并到父提交 | | `git restore ` | `jj restore ` | 撤销文件修改 | | `git checkout -- ` | `jj restore ` | 同上 | @@ -21,53 +21,59 @@ | Git | Jujutsu | 说明 | |-----|---------|------| -| `git log` | `jj log` | 查看历史(默认显示当前 change) | +| `git log` | `jj log` | 查看历史 | | `git log --oneline` | `jj log -r ::@` | 简洁格式 | -| `git log --graph` | `jj log --graph` | 图形化(jj 更美观) | -| `git log --all` | `jj log -r 'all()'` | 查看所有 bookmark | +| `git log --graph` | `jj log --graph` | 图形化 | +| `git log --all` | `jj log -r 'all()'` | 查看所有 | | `git show ` | `jj show ` | 查看提交详情 | -| `git blame ` | `jj file annotate ` | 查看文件每行最后修改 | +| `git blame ` | `jj file annotate ` | 文件注解 | -## 分支操作(Bookmarks) +## ⚠️ 分支操作(关键区别!) | Git | Jujutsu | 说明 | |-----|---------|------| -| `git branch` | `jj bookmark list` | 列出分支 | -| `git branch ` | `jj bookmark create ` | 创建分支 | -| `git branch -d ` | `jj bookmark delete ` | 删除分支 | -| `git checkout ` | `jj co ` | 切换分支 | -| `git checkout -b ` | `jj new ` | 创建并切换 | -| `git branch -f ` | `jj bookmark move --to ` | 移动分支 | - -**注意**:jj 的 bookmarks 是轻量指针,不是 Git branch 的完全等价物。 +| `git checkout ` | `jj new ` | **没有 jj co!** | +| `git checkout -b ` | `jj new -b ` | 创建并切换 | +| `git branch` | `jj bookmark list` | 列出 | +| `git branch ` | `jj bookmark create ` | 创建 | +| `git branch -d ` | `jj bookmark delete ` | 删除 | +| `git branch -f ` | `jj bookmark move --to ` | 移动 | + +**关键点**: +- jj 没有 `jj co` 或 `jj checkout` 命令! +- 用 `jj new ` 创建新 change 并切换到它 +- 用 `jj edit ` 在 working copy 中编辑某 commit ## 变基与合并 | Git | Jujutsu | 说明 | |-----|---------|------| -| `git merge ` | `jj new @ ` | 合并(创建新 change) | -| `git rebase ` | `jj rebase -b -o ` | 变基 | -| `git rebase --onto B A^ ` | `jj rebase -s A -o B` | 变基到新基础 | -| `git rebase -i` | `jj rebase -r` | 交互式变基 | +| `git merge ` | `jj new @ A` | 合并(创建新 change) | +| `git rebase ` | `jj rebase -b A -o B` | 移动 bookmark | +| `git rebase --onto B A^ ` | `jj rebase -s A -o B` | 移动 commit 及后代 | + +**关键区别**: +- `-b` = 移动 bookmark 指向的 commit +- `-s` = 移动指定 commit 及其所有后代 ## 远程操作 | Git | Jujutsu | 说明 | |-----|---------|------| | `git fetch` | `jj git fetch` | 拉取 | -| `git pull` | `jj git fetch` (+ `jj new`) | 拉取后创建新 change | +| `git pull` | `jj git fetch` (+ `jj new`) | | | `git push` | `jj git push` | 推送 | -| `git push ` | `jj git push --bookmark ` | 推送特定 bookmark | -| `git remote add ` | `jj git remote add ` | 添加远程 | +| `git push ` | `jj git push --bookmark ` | | +| `git remote add` | `jj git remote add` | | ## 暂存与撤销 | Git | Jujutsu | 说明 | |-----|---------|------| -| `git stash` | `jj shelf` | 暂存当前变更 | -| `git stash pop` | `jj shelf unapply` | 恢复暂存 | +| `git stash` | `jj new @-` | 暂存到兄弟 commit | +| `git stash pop` | `jj edit ` | 恢复 | | `git reset --hard` | `jj abandon` | 放弃当前 change | -| `git reset --soft HEAD~` | `jj squash --from @-` | 保留修改并新建 change | +| `git reset --soft HEAD~` | `jj squash --from @-` | 保留修改 | | `git cherry-pick ` | `jj duplicate -o @` | 复制提交 | ## 撤销操作 @@ -77,13 +83,23 @@ | `git reflog` | `jj op log` | 查看操作日志 | | `git reset --hard ` | `jj undo` | 撤销上一次操作 | -**jj 的 `jj undo` 比 Git 的 reset 更强大**,可以撤销几乎任何操作。 +**jj 的 `jj undo` 更强大** — 可以撤销几乎任何操作! ## 文件操作 | Git | Jujutsu | 说明 | |-----|---------|------| -| `git ls-files` | `jj file list` | 列出跟踪的文件 | -| `git rm ` | `jj file delete ` | 删除文件 | -| `git rm --cached ` | `jj file untrack ` | 取消跟踪 | +| `git ls-files` | `jj file list` | 列出文件 | +| `git rm ` | `jj file delete ` | 删除 | +| `git rm --cached ` | `jj file untrack ` | 取消跟踪(需匹配 ignore pattern) | | `git rev-parse --show-toplevel` | `jj workspace root` | 仓库根目录 | + +## 高级操作 + +| Git | Jujutsu | 说明 | +|-----|---------|------| +| `git add -p` | `jj split` | 交互式拆分 | +| `git rebase -i` | `jj rebase -r` | 交互式变基 | +| | `jj absorb` | 自动吸收修改到之前的 commit | +| | `jj diffedit` | 交互式编辑某 commit 的 diff | +| | `jj describe` | 修改 commit 信息 | diff --git a/skills/jujutsu/references/pitfalls.md b/skills/jujutsu/references/pitfalls.md index f2c2f02..26043f0 100644 --- a/skills/jujutsu/references/pitfalls.md +++ b/skills/jujutsu/references/pitfalls.md @@ -1,6 +1,6 @@ # 常见错误与陷阱 -> Agent 容易犯的错误,按严重程度排序。 +> 基于官方文档,Agent 容易犯的错误。 ## 🔴 严重错误 @@ -8,50 +8,80 @@ **错误**:想暂存文件时用 `git add` -**问题**:jj 没有暂存区概念,`git add` 不会生效(除非在 git 兼容模式) +**问题**:jj 没有暂存区概念,`git add` 不会生效 **正确做法**: ```bash # jj 自动追踪所有修改,直接提交即可 jj commit -m "message" -# 如果只想提交部分文件,用 jj split 或 jj diffedit -jj diffedit -r @ +# 如果只想提交部分文件,用 jj split +jj split file1 file2 ``` -### 用 `git checkout` 切换分支 +### 用 `jj co` 或 `jj checkout` 切换 -**错误**:用 `git checkout ` 切换分支 +**错误**:用 `jj co ` 或 `jj checkout` -**问题**:jj 用 `jj co` 或 `jj edit` +**问题**:jj 根本没有这两个命令! **正确做法**: ```bash -jj co -# 或 -jj edit +# 创建新 change 在 bookmark 上(相当于 checkout -b) +jj new main + +# 创建新 change 并设置 bookmark +jj new main -b myfeature + +# 编辑现有 commit +jj edit ``` ### 用 `git stash` 暂存 -**错误**:用 `git stash` 暂存改动 +**错误**:用 `git stash` -**问题**:jj 用 shelf +**问题**:jj 没有 stash,用 `jj new @-` 创建兄弟 commit **正确做法**: ```bash -# 暂存当前改动 -jj shelf +# 临时保存当前工作(创建兄弟 commit) +jj new @- + +# 恢复:用 jj edit 回到原 commit +jj edit <原commit> +``` + +### 用 `git merge` -# 恢复暂存 -jj shelf unapply +**错误**:用 `jj merge` -# 查看暂存列表 -jj shelf list +**问题**:jj 没有 merge 命令 + +**正确做法**: +```bash +# 合并 A 到当前 commit +jj new @ A ``` ## 🟠 易错操作 +### 混淆 `-b` 和 `-s` 在 rebase + +**误解**:`-b` 移动单个 commit + +**正确**: +- `-b `:移动 bookmark 指向的 commit(不包含后代) +- `-s `:移动 commit 及其所有后代 + +```bash +# 错误 +jj rebase -b A -o B # 移动 A(不含后代) + +# 正确(移动 A 及其后代) +jj rebase -s A -o B +``` + ### `jj new` 不带参数 **误解**:`jj new` 等于 `git checkout -b` @@ -69,38 +99,37 @@ jj new -b jj new ``` -### `jj rebase` 参数顺序 +### 冲突后不知如何继续 -**误解**:先写源后写目标(像 git 那样) +**误解**:遇到冲突必须立即解决 -**正确**:jj 用 `-b` 指定要移动的 bookmark,`-o` 指定目标位置 +**正确**:jj 允许先继续工作,稍后再解决 ```bash -# 错误 -jj rebase A B # ❌ +# 冲突后,jj 会创建 conflicted change +# 可以继续创建新 commit +jj new -# 正确 -jj rebase -b A -o B # ✅ 把 A 变基到 B 上 +# 之后回到冲突 commit 解决 +jj new +# 解决文件中的冲突 +jj resolve +jj squash ``` -### 冲突后继续操作 +### 用 `jj file untrack` 但不设置 ignore -**误解**:遇到冲突必须解决才能继续 +**错误**:直接 `jj file untrack` -**正确**:jj 允许先继续工作,稍后再解决冲突 +**问题**:文件必须匹配 ignore pattern 才能 untrack +**正确做法**: ```bash -# 冲突后,先查看状态 -jj st - -# 创建新 change 继续工作(冲突会保留在原 change) -jj new +# 1. 先添加到 .gitignore +echo "file.txt" >> .gitignore -# 之后回到冲突的 change,解决后再 squash -jj co -# 解决冲突文件 -jj resolve -jj squash +# 2. 再 untrack +jj file untrack file.txt ``` ## 🟡 小问题 @@ -114,26 +143,27 @@ jj squash ### 混淆 bookmarks 和 changes - **Bookmark**:类似 Git branch,是指向提交的指针 -- **Change**:jj 的核心概念,是可编辑的提交 +- **Change**:jj 核心概念,是可编辑的提交 +- **Working-copy commit**:当前工作目录的 commit(@ 符号) -``` -@ → 当前工作的 change -HEAD → 当前 checkout 的 bookmark 指向的提交 -``` +### 在 Git 项目中直接用 `git init` -### 用 Git 命令 +**问题**:应该用 `jj git init` -**提醒**:在 jj 项目中尽量用 jj 命令。虽然 jj 兼容 git 操作,但: -- `jj git init` 初始化 `.jj/` 目录 -- `jj git clone` 正确设置 jj 环境 -- 直接用 `git init` 可能导致 jj 无法识别 +**正确**: +```bash +jj git init +# 或 +jj git clone +``` ## 检查清单 操作前快速检查: - [ ] 不要用 `git add` +- [ ] 不要用 `jj co` 或 `jj checkout` - [ ] 用 `jj commit` 而不是 `git commit` -- [ ] 用 `jj co` 而不是 `git checkout` - [ ] 用 `jj bookmark` 而不是 `git branch` -- [ ] 用 `jj rebase -b -o` 而不是 `git rebase` -- [ ] 用 `jj shelf` 而不是 `git stash` +- [ ] 用 `jj new @ A` 而不是 `git merge` +- [ ] 用 `jj rebase -b` 或 `-s` 变基 +- [ ] 用 `jj new @-` 暂存而不是 `git stash` diff --git a/skills/jujutsu/references/revsets.md b/skills/jujutsu/references/revsets.md index 6199e3e..105ff02 100644 --- a/skills/jujutsu/references/revsets.md +++ b/skills/jujutsu/references/revsets.md @@ -1,5 +1,7 @@ # Revset 查询语法 +> 基于官方文档:https://www.jj-vcs.dev/latest/revsets/ + Revset 是 jj 强大的查询语法,能精确定位提交。 ## 基本语法 @@ -8,34 +10,69 @@ Revset 是 jj 强大的查询语法,能精确定位提交。 jj log -r ``` -## 常用查询 +## 常用符号 -| Revset | 含义 | -|--------|------| -| `@` | 当前工作 change | -| `@-` | 当前 change 的父提交 | +| 符号 | 含义 | +|------|------| +| `@` | 当前 working-copy commit | +| `@-` | 当前 commit 的父提交 | | `@--` | 祖父提交 | | `main` | bookmark 名为 main 的提交 | | `HEAD` | HEAD 指向的提交 | -| `root` | 仓库根提交 | +| `root()` | 仓库根提交(虚拟 commit,hash 全为 0) | ## 运算符 | 运算符 | 含义 | 示例 | |--------|------|------| -| `::` | 祖先范围 | `main::` = main 的所有后代 | -| `..` | 包含范围 | `main..main~5` | -| `|` | 并集 | `main | feature` | +| `::` | 祖先范围(包含自己) | `main::` = main 的所有后代 | +| `..` | 不包含祖先 | `main..main~5` | +| `|` | 并集 | `main \| feature` | | `&` | 交集 | `main & @` | -| `-` | 差集 | `@ - main` | -| `+` | 并集(同 `\|`) | | -| `::` | 子孙 | `A::B` = A 到 B 之间的提交 | +| `~` | 差集 | `@ ~ main` | +| `-` | 父母(单数) | `@-` = 父提交 | +| `+` | 子孙(单数) | | + +## 范围运算符 + +| 运算符 | 含义 | +|--------|------| +| `x::y` | x 到 y 之间的后代(包含 x 和 y) | +| `x..y` | x 到 y 之间的祖先(不包含 x 的祖先) | +| `::x` | x 的所有祖先 | +| `x::` | x 的所有后代 | + +**注意**:`..` 在左边时不分配(不同于 `|`): +- `(A | B)..` = `A.. & B..`(交集) +- `A.. | B..` = 并集 + +## 函数 + +| 函数 | 用法 | 说明 | +|------|------|------| +| `all()` | `all()` | 所有可见 commit | +| `none()` | `none()` | 空集 | +| `bookmarks()` | `bookmarks()` | 所有本地 bookmark | +| `bookmarks(pattern)` | `bookmarks("main")` | 匹配 pattern 的 bookmark | +| `remote_bookmarks()` | `remote_bookmarks()` | 所有远程 bookmark | +| `visible_heads()` | `visible_heads()` | 所有可见 head | +| `parents(x)` | `parents(@)` | x 的父母 | +| `children(x)` | `children(@)` | x 的子孙 | +| `ancestors(x)` | `ancestors(@)` | x 的祖先 | +| `descendants(x)` | `descendants(@)` | x 的后代 | +| `first_parent(x)` | `first_parent(@)` | 只取第一个父母 | +| `latest(x)` | `latest(@, 5)` | 最近 N 个 | +| `merges()` | `merges()` | 合并提交 | +| `file(path)` | `file("src/main.rs")` | 包含某文件的 commit | +| `author(name)` | `author("yelo")` | 作者匹配 | +| `description(text)` | `description("feat")` | 描述包含 | +| `date(expr)` | `date(2024-01-01)` | 日期 | ## 常见用法 ```bash # 当前分支的历史 -jj log -r @::@- +jj log -r ::@ # 所有未推送的提交 jj log -r '@..@|bookmarks(@)..' @@ -44,50 +81,53 @@ jj log -r '@..@|bookmarks(@)..' jj log -r main::main # 最近 5 个提交 -jj log -r @--.. +jj log -r latest(@, 5) # 包含某个文件的提交 -jj log -r "file(path/to/file)" +jj log -r 'file(path/to/file)' # 在某日期之后的提交 -jj log -r "date(2024-01-01).." +jj log -r 'date(2024-01-01)..' # 作者包含某字符串的提交 -jj log -r "author(yelo)" -``` +jj log -r 'author(yelo)' -## 谓词 +# 合并提交 +jj log -r 'merges()' -| 谓词 | 用法 | 说明 | -|------|------|------| -| `date()` | `date(2024-01-01)` | 日期 | -| `author()` | `author(yelo)` | 作者 | -| `committer()` | `committer(bot)` | 提交者 | -| `file()` | `file(src/main.rs)` | 包含某文件 | -| `description()` | `description(feat)` | 描述包含 | -| `empty()` | `empty()` | 空提交(无文件变更) | -| `public()` | `public()` | 已推送的提交 | +# 空提交(无文件变更) +jj log -r 'empty()' + +# 可变 commits(本地修改过的) +jj log -r 'mutable()' +``` ## 快捷方式 | 快捷 | 展开 | |-------|------| -| `@~n` | `@-n`,即第 n 个祖先 | -| `@^` | `@-`,即父提交 | +| `@~n` | `@-n`,第 n 个祖先 | +| `@^` | `@-`,父提交 | | `main~3` | main 的第 3 个祖先 | ## 示例 ```bash -# 查看当前 change 的祖先链 -jj log -r @::@- +# 查看当前 commit 的祖先链 +jj log -r ::@ # 查看 feature 分支独有的提交 -jj log -r "feature - main" +jj log -r 'feature - main' # 查看最近一周的提交 -jj log -r "date(-7d).." +jj log -r 'date(-7d)..' # 查看两个 bookmark 之间的差异 jj diff -r main..feature + +# 查看某个人的所有提交 +jj log -r 'author(yelo)' + +# 查看所有 bookmark 的最新位置 +jj log -r 'bookmarks()' ``` From 39313eeb4db999d0fea8f6b1604b3dcedc505ec8 Mon Sep 17 00:00:00 2001 From: lambda610 Date: Fri, 6 Mar 2026 01:30:39 +0800 Subject: [PATCH 3/6] feat: add advanced topics - colocated workspaces, multiple remotes, divergent changes, filesets --- skills/jujutsu/SKILL.md | 58 ++++-- skills/jujutsu/references/advanced.md | 276 ++++++++++++++++++++++++++ skills/jujutsu/references/commands.md | 4 +- skills/jujutsu/references/pitfalls.md | 48 ++++- 4 files changed, 367 insertions(+), 19 deletions(-) create mode 100644 skills/jujutsu/references/advanced.md diff --git a/skills/jujutsu/SKILL.md b/skills/jujutsu/SKILL.md index 7661bb1..b126573 100644 --- a/skills/jujutsu/SKILL.md +++ b/skills/jujutsu/SKILL.md @@ -27,6 +27,7 @@ Jujutsu (jj) 是新一代分布式版本控制工具,兼容 Git 仓库但用 | 用 branch 管理分支 | jj 用 bookmarks,是轻量指针 | | `git stash` 暂存 | 用 `jj new @-` 或 `jj shelf` | | 冲突必须立即解决 | jj 冲突可延迟处理 | +| checkout 切换分支 | 用 `jj new` 或 `jj edit`(无 checkout) | ### ✅ 正确的心智模型 @@ -36,6 +37,33 @@ Jujutsu (jj) 是新一代分布式版本控制工具,兼容 Git 仓库但用 4. **Bookmarks** — 轻量标记,类似 Git branch 但有 tracked 概念 5. **Revsets** — 强大的查询语法,能表达复杂条件 6. **无 checkout** — 用 `jj new` 或 `jj edit` 切换 +7. **冲突不阻塞** — 冲突记录在 commit 中,可稍后解决 + +## 核心概念 + +### Change vs Commit + +- **Commit**:文件的快照 + 元数据(作者、日期、父提交) +- **Change**:commit 的演化历史,用 change ID 标识(类似 Gerrit 的 Change-Id) +- **Working-copy commit**:当前工作目录对应的 commit(@ 符号) + +### Change ID vs Commit ID + +- **Change ID**:jj 特有,16 字节随机生成,格式如 `kntqzsqt`,会保持不变 +- **Commit ID**:Git 兼容的提交哈希,会随内容变化 + +### Bookmark vs Branch + +- **Bookmark**:指向 commit 的命名指针,类似 Git branch +- **无"当前 bookmark"** — jj 没有活跃分支的概念 +- **Tracked bookmark**:跟踪远程同名 bookmark + +### Colocated Workspaces + +jj 和 git 可共存于同一目录: +- `.jj/` + `.git/` 共存 +- jj 和 git 命令可混用 +- jj 自动 import/export 到 git ## 常用命令速查 @@ -61,6 +89,7 @@ jj bookmark list # 列出 bookmarks jj bookmark create -r # 创建 bookmark jj bookmark delete # 删除 bookmark jj bookmark move --to # 移动 bookmark +jj bookmark track --remote= # 跟踪远程 bookmark # 变基 jj rebase -b -o # 移动 bookmark 及其指向的 commit @@ -74,6 +103,10 @@ jj git push --bookmark # 推送特定 bookmark # 撤销 jj undo # 撤销上一次操作 jj op log # 查看操作日志 + +# 多远程 +jj config set --repo git.fetch '["upstream", "origin"]' +jj bookmark track main # 跟踪远程 bookmark ``` ## 常见工作流 @@ -103,7 +136,7 @@ jj squash jj squash --into ``` -### 创建新分支(在某 bookmark 上开始工作) +### 创建新分支 ```bash # 相当于 git checkout -b topic main jj new main @@ -145,16 +178,17 @@ jj new @- # 恢复:用 jj edit 回到之前的 commit ``` -### 与远程同步 -```bash -# 拉取 -jj git fetch +### Divergent Changes(分叉变化) -# 如果有远程更新,先 fetch -jj git fetch +当同一 change ID 有多个可见 commit 时: +```bash +# 查看 +jj log # 显示 divergent 标记 -# 推送 -jj git push +# 解决策略 +jj abandon # 放弃一个 +jj metaedit --update-change-id # 生成新 change ID +jj squash --from --into # 合并两个 ``` ## 关键命令对照 @@ -173,9 +207,7 @@ jj git push | `git rebase B A` | `jj rebase -b A -o B` | | | `git stash` | `jj new @-` | | | `git reset --hard` | `jj abandon` | | -| `git reset --soft HEAD~` | `jj squash --from @-` | | - -**注意**:jj 没有 `jj co` 或 `jj checkout` 命令! +| `git reflog` | `jj op log` | | ## 注意事项 @@ -214,3 +246,5 @@ jj log -r main.. # main 分支后的 commit jj help jj help ``` + +更多内容:见 `references/` 目录 diff --git a/skills/jujutsu/references/advanced.md b/skills/jujutsu/references/advanced.md new file mode 100644 index 0000000..7f2c537 --- /dev/null +++ b/skills/jujutsu/references/advanced.md @@ -0,0 +1,276 @@ +# 高级主题 + +> 基于官方文档的补充内容 + +## Colocated Workspaces(共存工作区) + +jj 和 git 可以共存于同一目录,方便迁移和混用工具。 + +### 创建 + +```bash +# 新建共存工作区(默认行为) +jj git init +# 或 +jj git clone + +# 禁用共存 +jj git init --no-colocate +jj git clone --no-colocate +``` + +### 混用 jj 和 git + +```bash +# 在共存工作区中可以: +jj st +git status # 也可以用,但可能显示"detached HEAD" + +# jj 命令会自动 import/export 到 git +# 但建议主要用 jj,git 只做只读操作 +``` + +### 切换共存状态 + +```bash +# 查看当前状态 +jj git colocation status + +# 启用共存 +jj git colocation enable + +# 禁用共存 +jj git colocation disable +``` + +### 注意事项 + +- jj 命令会频繁自动 import/export,可能导致分支冲突 +- 大型仓库中 jj 会变慢(每次命令都执行 git import) +- 有冲突文件时 Git 工具可能出问题 + +## Multiple Remotes(多远程) + +### 典型工作流 + +#### Fork 工作流(贡献上游) + +```bash +# 1. 配置同时从多个 remote 拉取 +jj config set --repo git.fetch '["upstream", "origin"]' + +# 2. 推送只用 origin +jj config set --repo git.push origin + +# 3. 跟踪远程 bookmark +jj bookmark track main # 跟踪 origin/main +jj bookmark track main --remote=upstream # 也跟踪 upstream + +# 4. 设置 trunk(作为 immutable 基础) +jj config set --repo 'revset-aliases."trunk()"' main@upstream +``` + +#### 集成工作流(独立仓库) + +```bash +# 1. 只从 origin 拉取和推送 +jj config set --repo git.fetch '["origin"]' + +# 2. 只跟踪 origin +jj bookmark track main --remote=origin +jj bookmark untrack main --remote=upstream + +# 3. 设置 trunk 为 origin +jj config set --repo 'revset-aliases."trunk()"' main@origin +``` + +### Remote Bookmarks 引用 + +```bash +# 引用远程 bookmark +main@origin # origin 上的 main +main@upstream # upstream 上的 main + +# 在新远程上创建 +jj new main@upstream +``` + +## Divergent Changes(分叉变化) + +当同一 change ID 有多个可见 commit 时发生。 + +### 原因 + +1. 本地和远程同时修改了同一个 change +2. 从不同 workspace 操作同一 change +3. 并发操作导致 + +### 识别 + +```bash +jj log +# 显示: +# mzvwutvl/0 ... (divergent) +# mzvwutvl/1 ... (divergent) +``` + +### 解决策略 + +#### 1. 放弃一个 + +```bash +# 放弃不需要的版本 +jj abandon +``` + +#### 2. 生成新 change ID + +```bash +# 为一个 commit 生成新的 change ID +jj metaedit --update-change-id +``` + +#### 3. 合并内容 + +```bash +# 把一个 squash 到另一个 +jj squash --from --into +``` + +#### 4. 忽略 + +如果不影响工作,可以暂时不管。 + +## Operation Log(操作日志) + +jj 记录每次修改仓库的操作,比 Git 的 reflog 更强大。 + +### 查看 + +```bash +# 操作列表 +jj op log + +# 带 diff 的操作历史 +jj op log -p +``` + +### 撤销 + +```bash +# 撤销上一次操作 +jj undo + +# 撤销到特定操作 +jj undo --at-operation +``` + +### 恢复到之前状态 + +```bash +# 恢复整个仓库到某操作时的状态 +jj op restore --at-operation +``` + +### 时光倒流 + +```bash +# 在某个操作的状态下运行命令(不修改) +jj --at-operation log +``` + +## Conflict 深入 + +### 冲突类型 + +1. **文件冲突**:同一文件同一位置被不同修改 +2. **Bookmark 冲突**:本地和远程 bookmark 移动冲突 +3. **Change 分叉**:同一 change ID 多个可见 commit + +### 冲突解决 + +```bash +# 1. 创建新 commit 在冲突 commit 上 +jj new + +# 2. 编辑文件解决冲突 +# 编辑冲突标记... + +# 3. 标记解决 +jj resolve + +# 4. 如果有多个冲突文件,全部解决后 +jj squash +``` + +### 冲突标记风格 + +可配置(默认 "diff"): +```bash +# diff 风格(默认) +jj config set --user ui.conflict-marker-style diff + +# snapshot 风格 +jj config set --user ui.conflict-marker-style snapshot + +# git 风格 +jj config set --user ui.conflict-marker-style git +``` + +## Filesets(文件集) + +类似 revset 但用于文件选择。 + +### 语法 + +```bash +# 文件路径 +jj diff file.txt + +# glob 模式 +jj diff 'glob:*.rs' + +# cwd 前缀 +jj diff 'cwd:src/' + +# root 前缀 +jj diff 'root:src/' + +# 组合 +jj diff 'src ~ glob:**/test*.rs' +jj diff 'glob:*.rs | glob:*.md' +``` + +### 使用场景 + +```bash +# 拆分时只选部分文件 +jj split 'glob:*.rs' + +# 查看特定目录差异 +jj diff 'root:src/' +``` + +## 配置示例 + +### 用户配置 + +```toml +[user] +name = "Your Name" +email = "your@email.com" + +[ui] +color = "auto" +default-command = ["log", "--reversed"] + +[diff] +color-words.max-inline-alternation = 3 +``` + +### 自动签名 + +```toml +[signing] +behavior = "inline" +``` diff --git a/skills/jujutsu/references/commands.md b/skills/jujutsu/references/commands.md index 33915c8..b7a56e4 100644 --- a/skills/jujutsu/references/commands.md +++ b/skills/jujutsu/references/commands.md @@ -53,7 +53,7 @@ | `git rebase --onto B A^ ` | `jj rebase -s A -o B` | 移动 commit 及后代 | **关键区别**: -- `-b` = 移动 bookmark 指向的 commit +- `-b` = 移动 bookmark 指向的 commit(不包含后代) - `-s` = 移动指定 commit 及其所有后代 ## 远程操作 @@ -65,6 +65,7 @@ | `git push` | `jj git push` | 推送 | | `git push ` | `jj git push --bookmark ` | | | `git remote add` | `jj git remote add` | | +| `git branch -u /` | `jj bookmark track --remote=` | 跟踪远程 | ## 暂存与撤销 @@ -103,3 +104,4 @@ | | `jj absorb` | 自动吸收修改到之前的 commit | | | `jj diffedit` | 交互式编辑某 commit 的 diff | | | `jj describe` | 修改 commit 信息 | +| | `jj evolog` | 查看 change 的演化历史 | diff --git a/skills/jujutsu/references/pitfalls.md b/skills/jujutsu/references/pitfalls.md index 26043f0..72c0382 100644 --- a/skills/jujutsu/references/pitfalls.md +++ b/skills/jujutsu/references/pitfalls.md @@ -132,6 +132,33 @@ echo "file.txt" >> .gitignore jj file untrack file.txt ``` +### 混淆 bookmarks 和 changes + +**误解**:bookmark 就是 branch + +**正确**: +- **Bookmark**:类似 Git branch,是指向提交的指针 +- **Change**:jj 核心概念,是可编辑的提交 +- **Working-copy commit**:当前工作目录的 commit(@ 符号) +- **无"当前 bookmark"** — jj 没有活跃分支的概念 + +### 忽略 divergent changes + +**误解**:只要用 change ID 就不会有歧义 + +**正确**:如果 change ID 分叉了,需要用 commit ID 或带偏移的 change ID + +```bash +# 分叉的 change ID +jj log # 显示为 xyz/0, xyz/1 + +# 用 commit ID 指定 +jj edit + +# 或用带偏移的 change ID +jj edit xyz/0 +``` + ## 🟡 小问题 ### 忘记 `-m` 参数 @@ -140,12 +167,6 @@ jj file untrack file.txt **建议**:习惯用 `jj commit -m "message"` -### 混淆 bookmarks 和 changes - -- **Bookmark**:类似 Git branch,是指向提交的指针 -- **Change**:jj 核心概念,是可编辑的提交 -- **Working-copy commit**:当前工作目录的 commit(@ 符号) - ### 在 Git 项目中直接用 `git init` **问题**:应该用 `jj git init` @@ -157,6 +178,20 @@ jj git init jj git clone ``` +### 混淆 tracked vs untracked bookmarks + +**误解**:fetch 后自动跟踪 + +**正确**: +```bash +# 默认只跟踪 origin 的 main +# 其他需要手动 track +jj bookmark track --remote= + +# 查看tracked +jj bookmark list --tracked +``` + ## 检查清单 操作前快速检查: @@ -167,3 +202,4 @@ jj git clone - [ ] 用 `jj new @ A` 而不是 `git merge` - [ ] 用 `jj rebase -b` 或 `-s` 变基 - [ ] 用 `jj new @-` 暂存而不是 `git stash` +- [ ] 分叉的 change ID 需要用 commit ID 明确指定 From 79401faec89d748f2ed8fd4781415f17ba86a613 Mon Sep 17 00:00:00 2001 From: lambda610 Date: Fri, 6 Mar 2026 01:43:23 +0800 Subject: [PATCH 4/6] fix: correct checkout/edit/new commands and rebase options --- skills/jujutsu/SKILL.md | 66 +++++++++++++++++---------- skills/jujutsu/references/commands.md | 18 ++++---- skills/jujutsu/references/pitfalls.md | 14 ++++-- 3 files changed, 62 insertions(+), 36 deletions(-) diff --git a/skills/jujutsu/SKILL.md b/skills/jujutsu/SKILL.md index b126573..d73facc 100644 --- a/skills/jujutsu/SKILL.md +++ b/skills/jujutsu/SKILL.md @@ -25,9 +25,9 @@ Jujutsu (jj) 是新一代分布式版本控制工具,兼容 Git 仓库但用 | `git add` | jj 无暂存区,不需要 add | | commit 后不能改 | jj 的 commit 是可编辑的 change | | 用 branch 管理分支 | jj 用 bookmarks,是轻量指针 | -| `git stash` 暂存 | 用 `jj new @-` 或 `jj shelf` | +| `git stash` 暂存 | 用 `jj new @-` | | 冲突必须立即解决 | jj 冲突可延迟处理 | -| checkout 切换分支 | 用 `jj new` 或 `jj edit`(无 checkout) | +| checkout 切换 | 用 `jj edit`(无 checkout) | ### ✅ 正确的心智模型 @@ -36,7 +36,7 @@ Jujutsu (jj) 是新一代分布式版本控制工具,兼容 Git 仓库但用 3. **操作可撤销** — 几乎所有操作都能用 `jj undo` 撤销 4. **Bookmarks** — 轻量标记,类似 Git branch 但有 tracked 概念 5. **Revsets** — 强大的查询语法,能表达复杂条件 -6. **无 checkout** — 用 `jj new` 或 `jj edit` 切换 +6. **无 checkout** — 用 `jj edit` 切换到某 commit 7. **冲突不阻塞** — 冲突记录在 commit 中,可稍后解决 ## 核心概念 @@ -56,7 +56,7 @@ Jujutsu (jj) 是新一代分布式版本控制工具,兼容 Git 仓库但用 - **Bookmark**:指向 commit 的命名指针,类似 Git branch - **无"当前 bookmark"** — jj 没有活跃分支的概念 -- **Tracked bookmark**:跟踪远程同名 bookmark +- **Tracked bookmark**:自动跟踪远程同名 bookmark ### Colocated Workspaces @@ -80,11 +80,17 @@ jj commit -m "message" # 提交(自动包含所有修改) jj squash # 合并到父提交(类似 git commit --amend) jj restore # 撤销文件修改 -# 注意:没有 jj co 或 jj checkout! -# 切换到某 bookmark:用 jj new -# 编辑某 commit:用 jj edit +# ⚠️ 没有 checkout! +# 切换到某 commit 编辑:用 jj edit +# 创建新 change:用 jj new -# Bookmarks(类似 branch,但不同) +# 创建与切换 +jj new # 创建新 empty change(当前 @ 的子提交) +jj new # 基于某 revision 创建新 change +jj new -b # 创建新 change 并设置 bookmark +jj edit # 切换到某 commit 进行编辑(类似 checkout) + +# Bookmarks jj bookmark list # 列出 bookmarks jj bookmark create -r # 创建 bookmark jj bookmark delete # 删除 bookmark @@ -92,8 +98,9 @@ jj bookmark move --to # 移动 bookmark jj bookmark track --remote= # 跟踪远程 bookmark # 变基 -jj rebase -b -o # 移动 bookmark 及其指向的 commit +jj rebase -b -o # 移动整个分支 jj rebase -s -o # 移动 commit 及其后代 +jj rebase -r -o # 只移动指定 commit # 远程操作 jj git fetch # 拉取 @@ -105,8 +112,8 @@ jj undo # 撤销上一次操作 jj op log # 查看操作日志 # 多远程 -jj config set --repo git.fetch '["upstream", "origin"]' -jj bookmark track main # 跟踪远程 bookmark +jj config set --user git.fetch '["upstream", "origin"]' +jj bookmark track main --remote=origin # 跟踪 origin/main ``` ## 常见工作流 @@ -136,22 +143,30 @@ jj squash jj squash --into ``` +### 编辑现有 commit(类似 git checkout) +```bash +# 切换到某 commit 进行编辑 +jj edit + +# 之后的所有修改都会 amend 这个 commit +``` + ### 创建新分支 ```bash -# 相当于 git checkout -b topic main -jj new main -jj bookmark create topic -# 或者一步到位: +# 创建新 change 并设置 bookmark jj new main -b topic ``` ### 变基 ```bash -# 移动 bookmark A 到 B 上(类似 git rebase) -jj rebase -b A -o B +# 移动整个分支(包含所有后代) +jj rebase -b topic -o main -# 移动 commit 及其后代到新基础 +# 移动单个 commit 及其后代 jj rebase -s -o + +# 只移动单个 commit(不包含后代) +jj rebase -r -o ``` ### 处理冲突 @@ -200,19 +215,24 @@ jj squash --from --into # 合并两个 | `git add` | ❌ 不需要 | jj 自动追踪 | | `git commit` | `jj commit -m "msg"` | | | `git commit --amend` | `jj squash` | | -| `git checkout ` | `jj new ` | **没有 jj co!** | -| `git checkout -b ` | `jj new -b ` | | +| `git checkout ` | `jj edit ` | **切换到某 commit 编辑** | +| `git checkout -b ` | `jj new -b ` | 创建并设置 bookmark | | `git branch` | `jj bookmark list` | | -| `git merge A` | `jj new @ A` | | -| `git rebase B A` | `jj rebase -b A -o B` | | +| `git switch ` | `jj new ` | **创建新 change** | +| `git merge A` | `jj new @ A` | 创建 merge commit | +| `git rebase A B` | `jj rebase -s A -o B` | A 及其后代移到 B 上 | | `git stash` | `jj new @-` | | | `git reset --hard` | `jj abandon` | | | `git reflog` | `jj op log` | | +**注意**: +- `jj new` **不是** `git checkout`,而是创建新 change +- `jj edit` 才是类似"切换到某 commit"的命令 + ## 注意事项 1. **不要用 `git add`** — jj 自动追踪 -2. **不要用 `jj co`** — 用 `jj new` 或 `jj edit` +2. **没有 checkout** — 用 `jj edit` 切换,用 `jj new` 创建 3. **`jj commit` 自动包含所有修改** — 不需要 `-a` 4. **冲突不阻塞** — 可以继续工作,稍后再解决 5. **`jj new` 创建的是 change** — 是可编辑的空 commit diff --git a/skills/jujutsu/references/commands.md b/skills/jujutsu/references/commands.md index b7a56e4..4207ad8 100644 --- a/skills/jujutsu/references/commands.md +++ b/skills/jujutsu/references/commands.md @@ -32,8 +32,9 @@ | Git | Jujutsu | 说明 | |-----|---------|------| -| `git checkout ` | `jj new ` | **没有 jj co!** | -| `git checkout -b ` | `jj new -b ` | 创建并切换 | +| `git checkout ` | `jj edit ` | **切换到某 commit 编辑** | +| `git checkout -b ` | `jj new -b ` | 创建并设置 bookmark | +| `git switch ` | `jj new ` | 创建新 change | | `git branch` | `jj bookmark list` | 列出 | | `git branch ` | `jj bookmark create ` | 创建 | | `git branch -d ` | `jj bookmark delete ` | 删除 | @@ -41,20 +42,21 @@ **关键点**: - jj 没有 `jj co` 或 `jj checkout` 命令! -- 用 `jj new ` 创建新 change 并切换到它 -- 用 `jj edit ` 在 working copy 中编辑某 commit +- 用 `jj edit ` 切换到某 commit 进行编辑(类似 checkout) +- 用 `jj new` 创建新 change(不是切换!) ## 变基与合并 | Git | Jujutsu | 说明 | |-----|---------|------| -| `git merge ` | `jj new @ A` | 合并(创建新 change) | -| `git rebase ` | `jj rebase -b A -o B` | 移动 bookmark | -| `git rebase --onto B A^ ` | `jj rebase -s A -o B` | 移动 commit 及后代 | +| `git merge ` | `jj new @ A` | 合并(创建新 merge commit) | +| `git rebase A B` | `jj rebase -s A -o B` | A 及其后代移到 B 上 | +| `git rebase --onto B A^ ` | `jj rebase -s A -o B` | 同上 | **关键区别**: -- `-b` = 移动 bookmark 指向的 commit(不包含后代) +- `-b` = 移动整个分支(包含祖先,不含 destination 的祖先) - `-s` = 移动指定 commit 及其所有后代 +- `-r` = 只移动指定的 commit(不含后代) ## 远程操作 diff --git a/skills/jujutsu/references/pitfalls.md b/skills/jujutsu/references/pitfalls.md index 72c0382..34bd2e9 100644 --- a/skills/jujutsu/references/pitfalls.md +++ b/skills/jujutsu/references/pitfalls.md @@ -71,15 +71,19 @@ jj new @ A **误解**:`-b` 移动单个 commit **正确**: -- `-b `:移动 bookmark 指向的 commit(不包含后代) +- `-b `:移动整个分支(包含祖先,不含 destination 的祖先) - `-s `:移动 commit 及其所有后代 +- `-r `:只移动指定的 commit(不含后代) ```bash -# 错误 -jj rebase -b A -o B # 移动 A(不含后代) - -# 正确(移动 A 及其后代) +# 移动 A 及其后代 jj rebase -s A -o B + +# 移动整个分支 +jj rebase -b bookmark -o main + +# 只移动单个 commit +jj rebase -r A -o B ``` ### `jj new` 不带参数 From 9e5eff878d68636391c02bb5fed93b84930767ff Mon Sep 17 00:00:00 2001 From: lambda610 Date: Fri, 6 Mar 2026 01:47:47 +0800 Subject: [PATCH 5/6] docs: translate jujutsu skill to English --- skills/jujutsu/SKILL.md | 315 +++++++++++++------------- skills/jujutsu/references/advanced.md | 206 ++++++++--------- skills/jujutsu/references/commands.md | 212 ++++++++--------- skills/jujutsu/references/pitfalls.md | 192 ++++++++-------- 4 files changed, 462 insertions(+), 463 deletions(-) diff --git a/skills/jujutsu/SKILL.md b/skills/jujutsu/SKILL.md index d73facc..00737c5 100644 --- a/skills/jujutsu/SKILL.md +++ b/skills/jujutsu/SKILL.md @@ -3,268 +3,267 @@ name: jujutsu description: Use Jujutsu (jj) for version control in jj-enabled projects. Applies when the project uses jj (has .jj/ directory, README specifies jj, or user requests jj). --- -# Jujutsu 使用指南 +# Jujutsu Usage Guide -Jujutsu (jj) 是新一代分布式版本控制工具,兼容 Git 仓库但用法有根本差异。 +Jujutsu (jj) is a next-generation distributed version control system written in Rust, compatible with fundamentally different usage with Git repositories but patterns. -## 何时使用 +## When to Use -**仅在明确使用 jj 的项目中使用此 skill。** 判断方法: -- 存在 `.jj/` 目录 -- 项目 README 明确要求用 jj -- 用户明确指定用 jj +**Only use this skill for projects that explicitly use jj.** How to identify: +- Has a `.jj/` directory +- Project README explicitly requires jj +- User explicitly specifies jj -对于普通 Git 项目,使用标准的 Git 工具。 +For regular Git projects, use standard Git tools. -## 心智模型(与 Git 的根本差异) +## Mental Model (Fundamental Differences from Git) -### ❌ 不要按 Git 思维操作 +### ❌ Don't Think in Git Terms -| Git 思维 | 问题 | -|---------|------| -| `git add` | jj 无暂存区,不需要 add | -| commit 后不能改 | jj 的 commit 是可编辑的 change | -| 用 branch 管理分支 | jj 用 bookmarks,是轻量指针 | -| `git stash` 暂存 | 用 `jj new @-` | -| 冲突必须立即解决 | jj 冲突可延迟处理 | -| checkout 切换 | 用 `jj edit`(无 checkout) | +| Git Thinking | Problem | +|--------------|---------| +| `git add` | jj has no staging area, don't need add | +| Commits can't be changed | jj commits are editable "changes" | +| Use branches | jj uses bookmarks, lightweight pointers | +| `git stash` | Use `jj new @-` instead | +| Conflicts must be resolved immediately | jj conflicts can be deferred | -### ✅ 正确的心智模型 +### ✅ Correct Mental Model -1. **自动追踪** — jj 自动追踪所有修改,无需 `git add` -2. **可变提交** — commit 是可编辑的"change",随时可修改 -3. **操作可撤销** — 几乎所有操作都能用 `jj undo` 撤销 -4. **Bookmarks** — 轻量标记,类似 Git branch 但有 tracked 概念 -5. **Revsets** — 强大的查询语法,能表达复杂条件 -6. **无 checkout** — 用 `jj edit` 切换到某 commit -7. **冲突不阻塞** — 冲突记录在 commit 中,可稍后解决 +1. **Auto-tracking** — jj tracks all changes automatically, no `git add` needed +2. **Mutable commits** — commits are editable "changes", can be modified anytime +3. **Undoable operations** — almost all operations can be undone with `jj undo` +4. **Bookmarks** — lightweight pointers, similar to Git branches but with tracked concept +5. **Revsets** — powerful query syntax for complex conditions +6. **No checkout** — use `jj edit` to switch to a commit +7. **Non-blocking conflicts** — conflicts are recorded in commits, can be resolved later -## 核心概念 +## Core Concepts ### Change vs Commit -- **Commit**:文件的快照 + 元数据(作者、日期、父提交) -- **Change**:commit 的演化历史,用 change ID 标识(类似 Gerrit 的 Change-Id) -- **Working-copy commit**:当前工作目录对应的 commit(@ 符号) +- **Commit**: Snapshot of files + metadata (author, date, parents) +- **Change**: Evolution history of a commit, identified by change ID (similar to Gerrit's Change-Id) +- **Working-copy commit**: The commit corresponding to the current working directory (@ symbol) ### Change ID vs Commit ID -- **Change ID**:jj 特有,16 字节随机生成,格式如 `kntqzsqt`,会保持不变 -- **Commit ID**:Git 兼容的提交哈希,会随内容变化 +- **Change ID**: Unique to jj, 16 bytes randomly generated, format like `kntqzsqt`, remains unchanged +- **Commit ID**: Git-compatible commit hash, changes with content ### Bookmark vs Branch -- **Bookmark**:指向 commit 的命名指针,类似 Git branch -- **无"当前 bookmark"** — jj 没有活跃分支的概念 -- **Tracked bookmark**:自动跟踪远程同名 bookmark +- **Bookmark**: Named pointer to a commit, similar to Git branch +- **No "current bookmark"** — jj has no concept of active branch +- **Tracked bookmark**: Automatically tracks remote bookmark of the same name ### Colocated Workspaces -jj 和 git 可共存于同一目录: -- `.jj/` + `.git/` 共存 -- jj 和 git 命令可混用 -- jj 自动 import/export 到 git +jj and git can coexist in the same directory: +- `.jj/` + `.git/` coexist +- jj and git commands can be mixed +- jj automatically imports/exports to git -## 常用命令速查 +## Quick Command Reference ```bash -# 查看状态 -jj st # 当前变更(相当于 git status) -jj log # 历史 -jj log --graph # 图形化历史 - -# 操作变更(无需 add) -jj diff # 查看当前变更 -jj describe # 修改提交信息 -jj commit -m "message" # 提交(自动包含所有修改) -jj squash # 合并到父提交(类似 git commit --amend) -jj restore # 撤销文件修改 - -# ⚠️ 没有 checkout! -# 切换到某 commit 编辑:用 jj edit -# 创建新 change:用 jj new - -# 创建与切换 -jj new # 创建新 empty change(当前 @ 的子提交) -jj new # 基于某 revision 创建新 change -jj new -b # 创建新 change 并设置 bookmark -jj edit # 切换到某 commit 进行编辑(类似 checkout) +# Status +jj st # Current changes (like git status) +jj log # History +jj log --graph # Graph view + +# Working with changes (no add needed) +jj diff # View current changes +jj describe # Edit commit message +jj commit -m "message" # Commit (auto-includes all changes) +jj squash # Squash into parent (like git commit --amend) +jj restore # Discard file changes + +# ⚠️ No checkout! +# Switch to edit a commit: jj edit +# Create new change: jj new + +# Creation and switching +jj new # Create new empty change (child of current @) +jj new # Create new change based on revision +jj new -b # Create new change and set bookmark +jj edit # Switch to a commit for editing (like checkout) # Bookmarks -jj bookmark list # 列出 bookmarks -jj bookmark create -r # 创建 bookmark -jj bookmark delete # 删除 bookmark -jj bookmark move --to # 移动 bookmark -jj bookmark track --remote= # 跟踪远程 bookmark - -# 变基 -jj rebase -b -o # 移动整个分支 -jj rebase -s -o # 移动 commit 及其后代 -jj rebase -r -o # 只移动指定 commit - -# 远程操作 -jj git fetch # 拉取 -jj git push # 推送 -jj git push --bookmark # 推送特定 bookmark - -# 撤销 -jj undo # 撤销上一次操作 -jj op log # 查看操作日志 - -# 多远程 +jj bookmark list # List bookmarks +jj bookmark create -r # Create bookmark +jj bookmark delete # Delete bookmark +jj bookmark move --to # Move bookmark +jj bookmark track --remote= # Track remote bookmark + +# Rebase +jj rebase -b -o # Move entire branch +jj rebase -s -o # Move commit and descendants +jj rebase -r -o # Move only specified commit + +# Remote operations +jj git fetch # Fetch +jj git push # Push +jj git push --bookmark # Push specific bookmark + +# Undo +jj undo # Undo last operation +jj op log # View operation log + +# Multiple remotes jj config set --user git.fetch '["upstream", "origin"]' -jj bookmark track main --remote=origin # 跟踪 origin/main +jj bookmark track main --remote=origin # Track origin/main ``` -## 常见工作流 +## Common Workflows -### 日常提交 +### Daily Commit ```bash -# 1. 查看变更 +# 1. View changes jj st jj diff -# 2. 提交(无需 add!) +# 2. Commit (no add!) jj commit -m "feat: add new feature" -# 3. 查看历史 +# 3. View history jj log ``` -### 修改历史提交 +### Modifying Historical Commits ```bash -# 修改当前提交的描述 +# Edit current commit message jj describe -m "new message" -# 把当前变更合并到上一个提交 +# Squash current changes into parent jj squash -# 把变更 squash 到指定提交 +# Squash into specific commit jj squash --into ``` -### 编辑现有 commit(类似 git checkout) +### Editing Existing Commit (like git checkout) ```bash -# 切换到某 commit 进行编辑 +# Switch to a commit for editing jj edit -# 之后的所有修改都会 amend 这个 commit +# All subsequent changes will amend this commit ``` -### 创建新分支 +### Creating New Branch ```bash -# 创建新 change 并设置 bookmark +# Create new change and set bookmark jj new main -b topic ``` -### 变基 +### Rebase ```bash -# 移动整个分支(包含所有后代) +# Move entire branch (with all descendants) jj rebase -b topic -o main -# 移动单个 commit 及其后代 +# Move single commit and descendants jj rebase -s -o -# 只移动单个 commit(不包含后代) +# Move only single commit (no descendants) jj rebase -r -o ``` -### 处理冲突 +### Handling Conflicts ```bash -# 1. 冲突不会中断操作,会创建 conflicted change -# 2. 创建新 commit 来解决冲突 +# 1. Conflicts don't block; creates conflicted change +# 2. Create new commit to resolve jj new -# 3. 解决文件中的冲突标记 -# 编辑文件... +# 3. Resolve conflict markers in files +# Edit files... -# 4. 标记已解决 +# 4. Mark as resolved jj resolve -# 5. squash 到原提交 +# 5. Squash into original jj squash ``` -### 临时保存当前工作 +### Temporarily Stashing Work ```bash -# 相当于 git stash:创建兄弟 commit +# Like git stash: create sibling commit jj new @- -# 恢复:用 jj edit 回到之前的 commit +# Restore: jj edit to go back ``` -### Divergent Changes(分叉变化) +### Divergent Changes -当同一 change ID 有多个可见 commit 时: +When a change ID has multiple visible commits: ```bash -# 查看 -jj log # 显示 divergent 标记 +# View +jj log # Shows divergent label -# 解决策略 -jj abandon # 放弃一个 -jj metaedit --update-change-id # 生成新 change ID -jj squash --from --into # 合并两个 +# Resolution strategies +jj abandon # Abandon one +jj metaedit --update-change-id # Generate new change ID +jj squash --from --into # Merge both ``` -## 关键命令对照 +## Key Command Mapping -| Git | Jujutsu | 说明 | -|-----|---------|------| +| Git | Jujutsu | Notes | +|-----|---------|-------| | `git status` | `jj st` | | | `git diff` | `jj diff` | | -| `git add` | ❌ 不需要 | jj 自动追踪 | +| `git add` | ❌ Not needed | jj auto-tracks | | `git commit` | `jj commit -m "msg"` | | | `git commit --amend` | `jj squash` | | -| `git checkout ` | `jj edit ` | **切换到某 commit 编辑** | -| `git checkout -b ` | `jj new -b ` | 创建并设置 bookmark | +| `git checkout ` | `jj edit ` | **Switch to edit commit** | +| `git checkout -b ` | `jj new -b ` | Create and set bookmark | | `git branch` | `jj bookmark list` | | -| `git switch ` | `jj new ` | **创建新 change** | -| `git merge A` | `jj new @ A` | 创建 merge commit | -| `git rebase A B` | `jj rebase -s A -o B` | A 及其后代移到 B 上 | +| `git switch ` | `jj new ` | **Create new change** | +| `git merge A` | `jj new @ A` | Create merge commit | +| `git rebase A B` | `jj rebase -s A -o B` | A and descendants onto B | | `git stash` | `jj new @-` | | | `git reset --hard` | `jj abandon` | | | `git reflog` | `jj op log` | | -**注意**: -- `jj new` **不是** `git checkout`,而是创建新 change -- `jj edit` 才是类似"切换到某 commit"的命令 +**Note**: +- `jj new` is **NOT** `git checkout` — it creates a new change +- `jj edit` is the command for "switching to a commit" -## 注意事项 +## Important Notes -1. **不要用 `git add`** — jj 自动追踪 -2. **没有 checkout** — 用 `jj edit` 切换,用 `jj new` 创建 -3. **`jj commit` 自动包含所有修改** — 不需要 `-a` -4. **冲突不阻塞** — 可以继续工作,稍后再解决 -5. **`jj new` 创建的是 change** — 是可编辑的空 commit -6. **Bookmarks 有 tracked 概念** — 类似 Git 的 upstream +1. **Don't use `git add`** — jj auto-tracks +2. **No checkout** — use `jj edit` to switch, `jj new` to create +3. **`jj commit` auto-includes all changes** — no `-a` needed +4. **Conflicts don't block** — can continue working, resolve later +5. **`jj new` creates a change** — editable empty commit +6. **Bookmarks have tracked concept** — like Git's upstream -## Revset 快速参考 +## Revset Quick Reference ```bash -# 常用符号 -@ # 当前 working-copy commit -@- # 父提交 -root() # 根提交 -bookmarks() # 所有 bookmark - -# 运算符 -:: # 祖先(包含自己) -.. # 不包含祖先 -~ # 差集 -| # 并集 -& # 交集 - -# 示例 -jj log -r ::@ # 当前 commit 的祖先链 -jj log -r 'all()' # 所有可见 commit -jj log -r main.. # main 分支后的 commit +# Common symbols +@ # Current working-copy commit +@- # Parent commit +root() # Root commit +bookmarks() # All bookmarks + +# Operators +:: # Ancestors (inclusive) +.. # Excluding ancestors +~ # Difference +| # Union +& # Intersection + +# Examples +jj log -r ::@ # Ancestor chain of current commit +jj log -r 'all()' # All visible commits +jj log -r main.. # Commits after main branch ``` -## 获取帮助 +## Getting Help ```bash jj help jj help ``` -更多内容:见 `references/` 目录 +More content: see `references/` directory diff --git a/skills/jujutsu/references/advanced.md b/skills/jujutsu/references/advanced.md index 7f2c537..079830b 100644 --- a/skills/jujutsu/references/advanced.md +++ b/skills/jujutsu/references/advanced.md @@ -1,259 +1,259 @@ -# 高级主题 +# Advanced Topics -> 基于官方文档的补充内容 +> Supplementary content based on official docs -## Colocated Workspaces(共存工作区) +## Colocated Workspaces -jj 和 git 可以共存于同一目录,方便迁移和混用工具。 +jj and git can coexist in the same directory, facilitating migration and tool interoperability. -### 创建 +### Creation ```bash -# 新建共存工作区(默认行为) +# Create colocated workspace (default) jj git init -# 或 +# or jj git clone -# 禁用共存 +# Disable colocation jj git init --no-colocate jj git clone --no-colocate ``` -### 混用 jj 和 git +### Mixing jj and git ```bash -# 在共存工作区中可以: +# In colocated workspace you can: jj st -git status # 也可以用,但可能显示"detached HEAD" +git status # Can also use, but may show "detached HEAD" -# jj 命令会自动 import/export 到 git -# 但建议主要用 jj,git 只做只读操作 +# jj commands auto import/export to git +# But recommend mainly using jj, git for read-only only ``` -### 切换共存状态 +### Switching Colocation State ```bash -# 查看当前状态 +# Check current status jj git colocation status -# 启用共存 +# Enable colocation jj git colocation enable -# 禁用共存 +# Disable colocation jj git colocation disable ``` -### 注意事项 +### Notes -- jj 命令会频繁自动 import/export,可能导致分支冲突 -- 大型仓库中 jj 会变慢(每次命令都执行 git import) -- 有冲突文件时 Git 工具可能出问题 +- jj commands frequently auto import/export, may cause branch conflicts +- In large repos jj can be slower (executes git import on every command) +- Git tools may have issues with conflicted files -## Multiple Remotes(多远程) +## Multiple Remotes -### 典型工作流 +### Typical Workflows -#### Fork 工作流(贡献上游) +#### Fork Workflow (Contributing Upstream) ```bash -# 1. 配置同时从多个 remote 拉取 -jj config set --repo git.fetch '["upstream", "origin"]' +# 1. Configure fetch from multiple remotes +jj config set --user git.fetch '["upstream", "origin"]' -# 2. 推送只用 origin -jj config set --repo git.push origin +# 2. Push only to origin +jj config set --user git.push origin -# 3. 跟踪远程 bookmark -jj bookmark track main # 跟踪 origin/main -jj bookmark track main --remote=upstream # 也跟踪 upstream +# 3. Track remote bookmarks +jj bookmark track main # Track origin/main +jj bookmark track main --remote=upstream # Also track upstream -# 4. 设置 trunk(作为 immutable 基础) -jj config set --repo 'revset-aliases."trunk()"' main@upstream +# 4. Set trunk (as immutable base) +jj config set --user 'revset-aliases."trunk()"' main@upstream ``` -#### 集成工作流(独立仓库) +#### Integration Workflow (Independent Repo) ```bash -# 1. 只从 origin 拉取和推送 -jj config set --repo git.fetch '["origin"]' +# 1. Only fetch and push from/to origin +jj config set --user git.fetch '["origin"]' -# 2. 只跟踪 origin +# 2. Only track origin jj bookmark track main --remote=origin jj bookmark untrack main --remote=upstream -# 3. 设置 trunk 为 origin -jj config set --repo 'revset-aliases."trunk()"' main@origin +# 3. Set trunk to origin +jj config set --user 'revset-aliases."trunk()"' main@origin ``` -### Remote Bookmarks 引用 +### Remote Bookmark References ```bash -# 引用远程 bookmark -main@origin # origin 上的 main -main@upstream # upstream 上的 main +# Reference remote bookmarks +main@origin # main on origin +main@upstream # main on upstream -# 在新远程上创建 +# Create on new remote jj new main@upstream ``` -## Divergent Changes(分叉变化) +## Divergent Changes -当同一 change ID 有多个可见 commit 时发生。 +When a change ID has multiple visible commits. -### 原因 +### Causes -1. 本地和远程同时修改了同一个 change -2. 从不同 workspace 操作同一 change -3. 并发操作导致 +1. Local and remote both modified same change +2. Operating on same change from different workspaces +3. Concurrent operations -### 识别 +### Identification ```bash jj log -# 显示: +# Shows: # mzvwutvl/0 ... (divergent) # mzvwutvl/1 ... (divergent) ``` -### 解决策略 +### Resolution Strategies -#### 1. 放弃一个 +#### 1. Abandon One ```bash -# 放弃不需要的版本 +# Abandon unwanted version jj abandon ``` -#### 2. 生成新 change ID +#### 2. Generate New Change ID ```bash -# 为一个 commit 生成新的 change ID +# Generate new change ID for a commit jj metaedit --update-change-id ``` -#### 3. 合并内容 +#### 3. Squash Together ```bash -# 把一个 squash 到另一个 +# Squash one into another jj squash --from --into ``` -#### 4. 忽略 +#### 4. Ignore -如果不影响工作,可以暂时不管。 +If not affecting work, can leave as-is. -## Operation Log(操作日志) +## Operation Log -jj 记录每次修改仓库的操作,比 Git 的 reflog 更强大。 +jj records every operation that modifies the repo, more powerful than Git's reflog. -### 查看 +### Viewing ```bash -# 操作列表 +# Operation list jj op log -# 带 diff 的操作历史 +# Operations with diffs jj op log -p ``` -### 撤销 +### Undoing ```bash -# 撤销上一次操作 +# Undo last operation jj undo -# 撤销到特定操作 +# Undo to specific operation jj undo --at-operation ``` -### 恢复到之前状态 +### Restoring to Previous State ```bash -# 恢复整个仓库到某操作时的状态 +# Restore entire repo to state at operation jj op restore --at-operation ``` -### 时光倒流 +### Time Travel ```bash -# 在某个操作的状态下运行命令(不修改) +# Run command at operation state (non-destructive) jj --at-operation log ``` -## Conflict 深入 +## Deep Dive on Conflicts -### 冲突类型 +### Conflict Types -1. **文件冲突**:同一文件同一位置被不同修改 -2. **Bookmark 冲突**:本地和远程 bookmark 移动冲突 -3. **Change 分叉**:同一 change ID 多个可见 commit +1. **File conflicts**: Same file/location modified differently +2. **Bookmark conflicts**: Local and remote bookmark move conflicts +3. **Change divergence**: Same change ID multiple visible commits -### 冲突解决 +### Conflict Resolution ```bash -# 1. 创建新 commit 在冲突 commit 上 +# 1. Create new commit on conflicted commit jj new -# 2. 编辑文件解决冲突 -# 编辑冲突标记... +# 2. Edit files to resolve conflicts +# Edit conflict markers... -# 3. 标记解决 +# 3. Mark resolved jj resolve -# 4. 如果有多个冲突文件,全部解决后 +# 4. If multiple conflicted files, after all resolved jj squash ``` -### 冲突标记风格 +### Conflict Marker Styles -可配置(默认 "diff"): +Configurable (default "diff"): ```bash -# diff 风格(默认) +# diff style (default) jj config set --user ui.conflict-marker-style diff -# snapshot 风格 +# snapshot style jj config set --user ui.conflict-marker-style snapshot -# git 风格 +# git style jj config set --user ui.conflict-marker-style git ``` -## Filesets(文件集) +## Filesets -类似 revset 但用于文件选择。 +Similar to revsets but for file selection. -### 语法 +### Syntax ```bash -# 文件路径 +# File path jj diff file.txt -# glob 模式 +# glob pattern jj diff 'glob:*.rs' -# cwd 前缀 +# cwd prefix jj diff 'cwd:src/' -# root 前缀 +# root prefix jj diff 'root:src/' -# 组合 +# Combination jj diff 'src ~ glob:**/test*.rs' jj diff 'glob:*.rs | glob:*.md' ``` -### 使用场景 +### Use Cases ```bash -# 拆分时只选部分文件 +# Split only selected files jj split 'glob:*.rs' -# 查看特定目录差异 +# View specific directory diff jj diff 'root:src/' ``` -## 配置示例 +## Configuration Examples -### 用户配置 +### User Configuration ```toml [user] @@ -268,7 +268,7 @@ default-command = ["log", "--reversed"] color-words.max-inline-alternation = 3 ``` -### 自动签名 +### Auto-signing ```toml [signing] diff --git a/skills/jujutsu/references/commands.md b/skills/jujutsu/references/commands.md index 4207ad8..04e213c 100644 --- a/skills/jujutsu/references/commands.md +++ b/skills/jujutsu/references/commands.md @@ -1,109 +1,109 @@ -# 命令对照表(带解释) - -> 基于官方文档:https://www.jj-vcs.dev/latest/git-command-table/ - -## 基础操作 - -| Git | Jujutsu | 说明 | -|-----|---------|------| -| `git status` | `jj st` | 查看当前工作状态 | -| `git diff` | `jj diff` | 查看未提交的修改 | -| `git diff HEAD` | `jj diff` | 同上,jj 默认比较 HEAD | -| `git diff ..` | `jj diff -r A..B` | 比较两个提交 | -| `git add` | ❌ 不需要 | jj 自动追踪所有修改 | -| `git commit` | `jj commit -m "msg"` | 提交当前所有变更 | -| `git commit -a` | `jj commit` | 同上,jj 不需要 -a | -| `git commit --amend` | `jj squash` | 把当前变更合并到父提交 | -| `git restore ` | `jj restore ` | 撤销文件修改 | -| `git checkout -- ` | `jj restore ` | 同上 | - -## 历史查看 - -| Git | Jujutsu | 说明 | -|-----|---------|------| -| `git log` | `jj log` | 查看历史 | -| `git log --oneline` | `jj log -r ::@` | 简洁格式 | -| `git log --graph` | `jj log --graph` | 图形化 | -| `git log --all` | `jj log -r 'all()'` | 查看所有 | -| `git show ` | `jj show ` | 查看提交详情 | -| `git blame ` | `jj file annotate ` | 文件注解 | - -## ⚠️ 分支操作(关键区别!) - -| Git | Jujutsu | 说明 | -|-----|---------|------| -| `git checkout ` | `jj edit ` | **切换到某 commit 编辑** | -| `git checkout -b ` | `jj new -b ` | 创建并设置 bookmark | -| `git switch ` | `jj new ` | 创建新 change | -| `git branch` | `jj bookmark list` | 列出 | -| `git branch ` | `jj bookmark create ` | 创建 | -| `git branch -d ` | `jj bookmark delete ` | 删除 | -| `git branch -f ` | `jj bookmark move --to ` | 移动 | - -**关键点**: -- jj 没有 `jj co` 或 `jj checkout` 命令! -- 用 `jj edit ` 切换到某 commit 进行编辑(类似 checkout) -- 用 `jj new` 创建新 change(不是切换!) - -## 变基与合并 - -| Git | Jujutsu | 说明 | -|-----|---------|------| -| `git merge ` | `jj new @ A` | 合并(创建新 merge commit) | -| `git rebase A B` | `jj rebase -s A -o B` | A 及其后代移到 B 上 | -| `git rebase --onto B A^ ` | `jj rebase -s A -o B` | 同上 | - -**关键区别**: -- `-b` = 移动整个分支(包含祖先,不含 destination 的祖先) -- `-s` = 移动指定 commit 及其所有后代 -- `-r` = 只移动指定的 commit(不含后代) - -## 远程操作 - -| Git | Jujutsu | 说明 | -|-----|---------|------| -| `git fetch` | `jj git fetch` | 拉取 | +# Command Reference (with Explanations) + +> Based on official docs: https://www.jj-vcs.dev/latest/git-command-table/ + +## Basic Operations + +| Git | Jujutsu | Notes | +|-----|---------|-------| +| `git status` | `jj st` | View current state | +| `git diff` | `jj diff` | View uncommitted changes | +| `git diff HEAD` | `jj diff` | Same, jj compares to HEAD by default | +| `git diff ..` | `jj diff -r A..B` | Compare two commits | +| `git add` | ❌ Not needed | jj auto-tracks all changes | +| `git commit` | `jj commit -m "msg"` | Commit all current changes | +| `git commit -a` | `jj commit` | Same, jj doesn't need -a | +| `git commit --amend` | `jj squash` | Squash changes into parent | +| `git restore ` | `jj restore ` | Discard file changes | +| `git checkout -- ` | `jj restore ` | Same | + +## History Viewing + +| Git | Jujutsu | Notes | +|-----|---------|-------| +| `git log` | `jj log` | View history | +| `git log --oneline` | `jj log -r ::@` | Compact format | +| `git log --graph` | `jj log --graph` | Graph view | +| `git log --all` | `jj log -r 'all()'` | View all | +| `git show ` | `jj show ` | View commit details | +| `git blame ` | `jj file annotate ` | File annotation | + +## ⚠️ Branch Operations (Key Differences!) + +| Git | Jujutsu | Notes | +|-----|---------|-------| +| `git checkout ` | `jj edit ` | **Switch to edit commit** | +| `git checkout -b ` | `jj new -b ` | Create and set bookmark | +| `git switch ` | `jj new ` | Create new change | +| `git branch` | `jj bookmark list` | List | +| `git branch ` | `jj bookmark create ` | Create | +| `git branch -d ` | `jj bookmark delete ` | Delete | +| `git branch -f ` | `jj bookmark move --to ` | Move | + +**Key Points**: +- jj has no `jj co` or `jj checkout` commands! +- Use `jj edit ` to switch to a commit for editing +- Use `jj new` to create new changes (not switching!) + +## Rebase and Merge + +| Git | Jujutsu | Notes | +|-----|---------|-------| +| `git merge ` | `jj new @ A` | Merge (create new merge commit) | +| `git rebase A B` | `jj rebase -s A -o B` | A and descendants onto B | +| `git rebase --onto B A^ ` | `jj rebase -s A -o B` | Same | + +**Key Differences**: +- `-b` = Move entire branch (includes ancestors, excluding destination's ancestors) +- `-s` = Move specified commit and all descendants +- `-r` = Move only the specified commit (no descendants) + +## Remote Operations + +| Git | Jujutsu | Notes | +|-----|---------|-------| +| `git fetch` | `jj git fetch` | Fetch | | `git pull` | `jj git fetch` (+ `jj new`) | | -| `git push` | `jj git push` | 推送 | +| `git push` | `jj git push` | Push | | `git push ` | `jj git push --bookmark ` | | | `git remote add` | `jj git remote add` | | -| `git branch -u /` | `jj bookmark track --remote=` | 跟踪远程 | - -## 暂存与撤销 - -| Git | Jujutsu | 说明 | -|-----|---------|------| -| `git stash` | `jj new @-` | 暂存到兄弟 commit | -| `git stash pop` | `jj edit ` | 恢复 | -| `git reset --hard` | `jj abandon` | 放弃当前 change | -| `git reset --soft HEAD~` | `jj squash --from @-` | 保留修改 | -| `git cherry-pick ` | `jj duplicate -o @` | 复制提交 | - -## 撤销操作 - -| Git | Jujutsu | 说明 | -|-----|---------|------| -| `git reflog` | `jj op log` | 查看操作日志 | -| `git reset --hard ` | `jj undo` | 撤销上一次操作 | - -**jj 的 `jj undo` 更强大** — 可以撤销几乎任何操作! - -## 文件操作 - -| Git | Jujutsu | 说明 | -|-----|---------|------| -| `git ls-files` | `jj file list` | 列出文件 | -| `git rm ` | `jj file delete ` | 删除 | -| `git rm --cached ` | `jj file untrack ` | 取消跟踪(需匹配 ignore pattern) | -| `git rev-parse --show-toplevel` | `jj workspace root` | 仓库根目录 | - -## 高级操作 - -| Git | Jujutsu | 说明 | -|-----|---------|------| -| `git add -p` | `jj split` | 交互式拆分 | -| `git rebase -i` | `jj rebase -r` | 交互式变基 | -| | `jj absorb` | 自动吸收修改到之前的 commit | -| | `jj diffedit` | 交互式编辑某 commit 的 diff | -| | `jj describe` | 修改 commit 信息 | -| | `jj evolog` | 查看 change 的演化历史 | +| `git branch -u /` | `jj bookmark track --remote=` | Track remote | + +## Stashing and Undo + +| Git | Jujutsu | Notes | +|-----|---------|-------| +| `git stash` | `jj new @-` | Stash to sibling commit | +| `git stash pop` | `jj edit ` | Restore | +| `git reset --hard` | `jj abandon` | Abandon current change | +| `git reset --soft HEAD~` | `jj squash --from @-` | Keep changes | +| `git cherry-pick ` | `jj duplicate -o @` | Copy commit | + +## Undo Operations + +| Git | Jujutsu | Notes | +|-----|---------|-------| +| `git reflog` | `jj op log` | View operation log | +| `git reset --hard ` | `jj undo` | Undo last operation | + +**jj's `jj undo` is more powerful** — can undo almost any operation! + +## File Operations + +| Git | Jujutsu | Notes | +|-----|---------|-------| +| `git ls-files` | `jj file list` | List files | +| `git rm ` | `jj file delete ` | Delete | +| `git rm --cached ` | `jj file untrack ` | Untrack (must match ignore pattern) | +| `git rev-parse --show-toplevel` | `jj workspace root` | Repo root | + +## Advanced Operations + +| Git | Jujutsu | Notes | +|-----|---------|-------| +| `git add -p` | `jj split` | Interactive split | +| `git rebase -i` | `jj rebase -r` | Interactive rebase | +| | `jj absorb` | Auto-absorb changes into earlier commits | +| | `jj diffedit` | Interactive edit diff of a commit | +| | `jj describe` | Edit commit message | +| | `jj evolog` | View evolution history of a change | diff --git a/skills/jujutsu/references/pitfalls.md b/skills/jujutsu/references/pitfalls.md index 34bd2e9..5c1feb0 100644 --- a/skills/jujutsu/references/pitfalls.md +++ b/skills/jujutsu/references/pitfalls.md @@ -1,209 +1,209 @@ -# 常见错误与陷阱 +# Common Mistakes and Pitfalls -> 基于官方文档,Agent 容易犯的错误。 +> Based on official docs, mistakes agents commonly make. -## 🔴 严重错误 +## 🔴 Critical Mistakes -### 用 `git add` +### Using `git add` -**错误**:想暂存文件时用 `git add` +**Mistake**: Using `git add` to stage files -**问题**:jj 没有暂存区概念,`git add` 不会生效 +**Problem**: jj has no staging area, `git add` has no effect -**正确做法**: +**Correct**: ```bash -# jj 自动追踪所有修改,直接提交即可 +# jj auto-tracks all changes, just commit directly jj commit -m "message" -# 如果只想提交部分文件,用 jj split +# If you only want to commit some files, use jj split jj split file1 file2 ``` -### 用 `jj co` 或 `jj checkout` 切换 +### Using `jj co` or `jj checkout` to Switch -**错误**:用 `jj co ` 或 `jj checkout` +**Mistake**: Using `jj co ` or `jj checkout` -**问题**:jj 根本没有这两个命令! +**Problem**: jj doesn't have these commands at all! -**正确做法**: +**Correct**: ```bash -# 创建新 change 在 bookmark 上(相当于 checkout -b) +# Create new change on bookmark (like checkout -b) jj new main -# 创建新 change 并设置 bookmark +# Create new change and set bookmark jj new main -b myfeature -# 编辑现有 commit +# Edit existing commit jj edit ``` -### 用 `git stash` 暂存 +### Using `git stash` -**错误**:用 `git stash` +**Mistake**: Using `git stash` -**问题**:jj 没有 stash,用 `jj new @-` 创建兄弟 commit +**Problem**: jj has no stash, use `jj new @-` to create sibling commit -**正确做法**: +**Correct**: ```bash -# 临时保存当前工作(创建兄弟 commit) +# Temporarily save current work (create sibling commit) jj new @- -# 恢复:用 jj edit 回到原 commit -jj edit <原commit> +# Restore: jj edit to go back to original commit +jj edit ``` -### 用 `git merge` +### Using `git merge` -**错误**:用 `jj merge` +**Mistake**: Using `jj merge` -**问题**:jj 没有 merge 命令 +**Problem**: jj has no merge command -**正确做法**: +**Correct**: ```bash -# 合并 A 到当前 commit +# Merge A into current commit jj new @ A ``` -## 🟠 易错操作 +## 🟠 Common Mistakes -### 混淆 `-b` 和 `-s` 在 rebase +### Confusing `-b` and `-s` in Rebase -**误解**:`-b` 移动单个 commit +**Misconception**: `-b` moves a single commit -**正确**: -- `-b `:移动整个分支(包含祖先,不含 destination 的祖先) -- `-s `:移动 commit 及其所有后代 -- `-r `:只移动指定的 commit(不含后代) +**Correct**: +- `-b `: Move entire branch (includes ancestors, excluding destination's ancestors) +- `-s `: Move commit and all descendants +- `-r `: Move only the specified commit (no descendants) ```bash -# 移动 A 及其后代 +# Move A and descendants jj rebase -s A -o B -# 移动整个分支 +# Move entire branch jj rebase -b bookmark -o main -# 只移动单个 commit +# Move only single commit jj rebase -r A -o B ``` -### `jj new` 不带参数 +### `jj new` Without Arguments -**误解**:`jj new` 等于 `git checkout -b` +**Misconception**: `jj new` equals `git checkout -b` -**正确**:`jj new` 基于当前 `@` 创建新 change,不带 bookmark 名 +**Correct**: `jj new` creates a new change based on current `@`, no bookmark name ```bash -# 创建新 change(无 bookmark) +# Create new change (no bookmark) jj new -# 创建并设置 bookmark +# Create and set bookmark jj new -b -# 基于某提交创建 +# Create based on some commit jj new ``` -### 冲突后不知如何继续 +### Not Knowing How to Continue After Conflicts -**误解**:遇到冲突必须立即解决 +**Misconception**: Must resolve conflicts immediately -**正确**:jj 允许先继续工作,稍后再解决 +**Correct**: jj allows continuing work first, resolving later ```bash -# 冲突后,jj 会创建 conflicted change -# 可以继续创建新 commit +# After conflict, jj creates conflicted change +# Can continue creating new commits jj new -# 之后回到冲突 commit 解决 +# Then go back to resolve jj new -# 解决文件中的冲突 +# Resolve conflicts in files jj resolve jj squash ``` -### 用 `jj file untrack` 但不设置 ignore +### Using `jj file untrack` Without Setting Ignore -**错误**:直接 `jj file untrack` +**Mistake**: Running `jj file untrack` directly -**问题**:文件必须匹配 ignore pattern 才能 untrack +**Problem**: File must match ignore pattern to untrack -**正确做法**: +**Correct**: ```bash -# 1. 先添加到 .gitignore +# 1. Add to .gitignore first echo "file.txt" >> .gitignore -# 2. 再 untrack +# 2. Then untrack jj file untrack file.txt ``` -### 混淆 bookmarks 和 changes +### Confusing Bookmarks and Changes -**误解**:bookmark 就是 branch +**Misconception**: Bookmark equals branch -**正确**: -- **Bookmark**:类似 Git branch,是指向提交的指针 -- **Change**:jj 核心概念,是可编辑的提交 -- **Working-copy commit**:当前工作目录的 commit(@ 符号) -- **无"当前 bookmark"** — jj 没有活跃分支的概念 +**Correct**: +- **Bookmark**: Similar to Git branch, pointer to a commit +- **Change**: jj's core concept, editable commit +- **Working-copy commit**: The commit in current working directory (@ symbol) +- **No "current bookmark"** — jj has no active branch concept -### 忽略 divergent changes +### Ignoring Divergent Changes -**误解**:只要用 change ID 就不会有歧义 +**Misconception**: Using change ID is always unambiguous -**正确**:如果 change ID 分叉了,需要用 commit ID 或带偏移的 change ID +**Correct**: If change ID has diverged, need to use commit ID or change ID with offset ```bash -# 分叉的 change ID -jj log # 显示为 xyz/0, xyz/1 +# Diverged change ID +jj log # Shows as xyz/0, xyz/1 -# 用 commit ID 指定 +# Use commit ID jj edit -# 或用带偏移的 change ID +# Or use change ID with offset jj edit xyz/0 ``` -## 🟡 小问题 +## 🟡 Minor Issues -### 忘记 `-m` 参数 +### Forgetting `-m` Flag -**问题**:`jj commit` 不带 `-m` 会打开编辑器 +**Problem**: `jj commit` without `-m` opens editor -**建议**:习惯用 `jj commit -m "message"` +**Suggestion**: Get in habit of using `jj commit -m "message"` -### 在 Git 项目中直接用 `git init` +### Using `git init` in Git Projects -**问题**:应该用 `jj git init` +**Problem**: Should use `jj git init` -**正确**: +**Correct**: ```bash jj git init -# 或 +# or jj git clone ``` -### 混淆 tracked vs untracked bookmarks +### Confusing Tracked vs Untracked Bookmarks -**误解**:fetch 后自动跟踪 +**Misconception**: Auto-tracks after fetch -**正确**: +**Correct**: ```bash -# 默认只跟踪 origin 的 main -# 其他需要手动 track +# Only tracks origin/main by default +# Others need manual track jj bookmark track --remote= -# 查看tracked +# View tracked jj bookmark list --tracked ``` -## 检查清单 - -操作前快速检查: -- [ ] 不要用 `git add` -- [ ] 不要用 `jj co` 或 `jj checkout` -- [ ] 用 `jj commit` 而不是 `git commit` -- [ ] 用 `jj bookmark` 而不是 `git branch` -- [ ] 用 `jj new @ A` 而不是 `git merge` -- [ ] 用 `jj rebase -b` 或 `-s` 变基 -- [ ] 用 `jj new @-` 暂存而不是 `git stash` -- [ ] 分叉的 change ID 需要用 commit ID 明确指定 +## Checklist + +Before operating, quick check: +- [ ] Don't use `git add` +- [ ] Don't use `jj co` or `jj checkout` +- [ ] Use `jj commit` not `git commit` +- [ ] Use `jj bookmark` not `git branch` +- [ ] Use `jj new @ A` not `git merge` +- [ ] Use `jj rebase -b`, `-s`, or `-r` for rebase +- [ ] Use `jj new @-` for stash, not `git stash` +- [ ] Diverged change IDs need explicit commit ID From 16eb1edff5b0e0980ccd3fc0cb11dde33c98af26 Mon Sep 17 00:00:00 2001 From: Yelo Date: Fri, 6 Mar 2026 02:28:16 +0800 Subject: [PATCH 6/6] docs(jujutsu): streamline skill documentation and add English revsets - Simplify skill description and remove redundant "When to Use" section - Streamline command examples with cleaner formatting - Remove Git-to-jj command mapping table (now in references/) - Convert revsets reference from Chinese to English - Add new revset functions (empty, mutable) to reference - Add reference files section pointing to separate docs - Remove switching colocation state section from advanced.md --- skills/jujutsu/SKILL.md | 162 ++++++++---------------- skills/jujutsu/references/advanced.md | 13 -- skills/jujutsu/references/revsets.md | 174 +++++++++++++------------- 3 files changed, 137 insertions(+), 212 deletions(-) diff --git a/skills/jujutsu/SKILL.md b/skills/jujutsu/SKILL.md index 00737c5..e5f0411 100644 --- a/skills/jujutsu/SKILL.md +++ b/skills/jujutsu/SKILL.md @@ -1,24 +1,15 @@ --- name: jujutsu -description: Use Jujutsu (jj) for version control in jj-enabled projects. Applies when the project uses jj (has .jj/ directory, README specifies jj, or user requests jj). +description: Use Jujutsu (jj) for version control in jj-enabled projects. Covers command workflows, bookmark management, rebasing, conflict resolution, revsets, and common pitfalls. Triggers when: project has a `.jj/` directory, README requires jj, or user explicitly requests jj commands. Do NOT use for regular git-only projects. --- # Jujutsu Usage Guide -Jujutsu (jj) is a next-generation distributed version control system written in Rust, compatible with fundamentally different usage with Git repositories but patterns. - -## When to Use - -**Only use this skill for projects that explicitly use jj.** How to identify: -- Has a `.jj/` directory -- Project README explicitly requires jj -- User explicitly specifies jj - -For regular Git projects, use standard Git tools. +Jujutsu (jj) is a next-generation VCS compatible with Git repositories but with fundamentally different usage patterns. ## Mental Model (Fundamental Differences from Git) -### ❌ Don't Think in Git Terms +### Don't Think in Git Terms | Git Thinking | Problem | |--------------|---------| @@ -28,7 +19,7 @@ For regular Git projects, use standard Git tools. | `git stash` | Use `jj new @-` instead | | Conflicts must be resolved immediately | jj conflicts can be deferred | -### ✅ Correct Mental Model +### Correct Mental Model 1. **Auto-tracking** — jj tracks all changes automatically, no `git add` needed 2. **Mutable commits** — commits are editable "changes", can be modified anytime @@ -74,27 +65,27 @@ jj log --graph # Graph view # Working with changes (no add needed) jj diff # View current changes -jj describe # Edit commit message -jj commit -m "message" # Commit (auto-includes all changes) -jj squash # Squash into parent (like git commit --amend) -jj restore # Discard file changes +jj describe # Edit commit message +jj commit -m "message" # Commit (auto-includes all changes) +jj squash # Squash into parent (like git commit --amend) +jj restore # Discard file changes # ⚠️ No checkout! # Switch to edit a commit: jj edit # Create new change: jj new # Creation and switching -jj new # Create new empty change (child of current @) -jj new # Create new change based on revision -jj new -b # Create new change and set bookmark -jj edit # Switch to a commit for editing (like checkout) +jj new # Create new empty change (child of current @) +jj new # Create new change based on revision +jj new -b # Create new change and set bookmark +jj edit # Switch to a commit for editing (like checkout) # Bookmarks -jj bookmark list # List bookmarks -jj bookmark create -r # Create bookmark -jj bookmark delete # Delete bookmark -jj bookmark move --to # Move bookmark -jj bookmark track --remote= # Track remote bookmark +jj bookmark list # List bookmarks +jj bookmark create -r # Create bookmark +jj bookmark delete # Delete bookmark +jj bookmark move --to # Move bookmark +jj bookmark track --remote= # Track remote bookmark # Rebase jj rebase -b -o # Move entire branch @@ -102,31 +93,26 @@ jj rebase -s -o # Move commit and descendants jj rebase -r -o # Move only specified commit # Remote operations -jj git fetch # Fetch -jj git push # Push -jj git push --bookmark # Push specific bookmark +jj git fetch # Fetch +jj git push # Push +jj git push --bookmark # Push specific bookmark # Undo -jj undo # Undo last operation -jj op log # View operation log +jj undo # Undo last operation +jj op log # View operation log # Multiple remotes jj config set --user git.fetch '["upstream", "origin"]' -jj bookmark track main --remote=origin # Track origin/main +jj bookmark track main --remote=origin ``` ## Common Workflows ### Daily Commit ```bash -# 1. View changes jj st jj diff - -# 2. Commit (no add!) jj commit -m "feat: add new feature" - -# 3. View history jj log ``` @@ -144,116 +130,61 @@ jj squash --into ### Editing Existing Commit (like git checkout) ```bash -# Switch to a commit for editing +# Switch to a commit for editing — all subsequent changes amend this commit jj edit - -# All subsequent changes will amend this commit ``` ### Creating New Branch ```bash -# Create new change and set bookmark jj new main -b topic ``` ### Rebase ```bash -# Move entire branch (with all descendants) -jj rebase -b topic -o main - -# Move single commit and descendants -jj rebase -s -o - -# Move only single commit (no descendants) -jj rebase -r -o +jj rebase -b topic -o main # Move entire branch (with all descendants) +jj rebase -s -o # Move single commit and descendants +jj rebase -r -o # Move only single commit (no descendants) ``` ### Handling Conflicts ```bash -# 1. Conflicts don't block; creates conflicted change -# 2. Create new commit to resolve -jj new - -# 3. Resolve conflict markers in files -# Edit files... - -# 4. Mark as resolved -jj resolve - -# 5. Squash into original -jj squash +# Conflicts don't block; jj creates a conflicted change +jj new # Create new commit to resolve +# Edit conflict markers in files... +jj resolve # Mark resolved +jj squash # Squash into original ``` ### Temporarily Stashing Work ```bash -# Like git stash: create sibling commit -jj new @- - -# Restore: jj edit to go back +jj new @- # Create sibling commit (like git stash) +jj edit # Restore ``` ### Divergent Changes - -When a change ID has multiple visible commits: ```bash -# View -jj log # Shows divergent label - -# Resolution strategies -jj abandon # Abandon one -jj metaedit --update-change-id # Generate new change ID -jj squash --from --into # Merge both +jj log # Shows divergent label +jj abandon # Abandon one version +jj metaedit --update-change-id # Generate new change ID +jj squash --from --into # Merge both versions ``` -## Key Command Mapping - -| Git | Jujutsu | Notes | -|-----|---------|-------| -| `git status` | `jj st` | | -| `git diff` | `jj diff` | | -| `git add` | ❌ Not needed | jj auto-tracks | -| `git commit` | `jj commit -m "msg"` | | -| `git commit --amend` | `jj squash` | | -| `git checkout ` | `jj edit ` | **Switch to edit commit** | -| `git checkout -b ` | `jj new -b ` | Create and set bookmark | -| `git branch` | `jj bookmark list` | | -| `git switch ` | `jj new ` | **Create new change** | -| `git merge A` | `jj new @ A` | Create merge commit | -| `git rebase A B` | `jj rebase -s A -o B` | A and descendants onto B | -| `git stash` | `jj new @-` | | -| `git reset --hard` | `jj abandon` | | -| `git reflog` | `jj op log` | | - -**Note**: -- `jj new` is **NOT** `git checkout` — it creates a new change -- `jj edit` is the command for "switching to a commit" - ## Important Notes 1. **Don't use `git add`** — jj auto-tracks 2. **No checkout** — use `jj edit` to switch, `jj new` to create 3. **`jj commit` auto-includes all changes** — no `-a` needed 4. **Conflicts don't block** — can continue working, resolve later -5. **`jj new` creates a change** — editable empty commit +5. **`jj new` creates a change** — editable empty commit, NOT a checkout 6. **Bookmarks have tracked concept** — like Git's upstream ## Revset Quick Reference ```bash -# Common symbols -@ # Current working-copy commit -@- # Parent commit -root() # Root commit -bookmarks() # All bookmarks - -# Operators -:: # Ancestors (inclusive) -.. # Excluding ancestors -~ # Difference -| # Union -& # Intersection - -# Examples +@ # Current working-copy commit +@- # Parent commit +root() # Root commit + jj log -r ::@ # Ancestor chain of current commit jj log -r 'all()' # All visible commits jj log -r main.. # Commits after main branch @@ -266,4 +197,9 @@ jj help jj help ``` -More content: see `references/` directory +## Reference Files + +- **`references/commands.md`** — Full Git-to-jj command mapping table; read when looking up a specific command equivalent +- **`references/revsets.md`** — Complete revset query syntax and functions; read when writing `-r` expressions +- **`references/pitfalls.md`** — Common mistakes and pre-operation checklist; read when uncertain about correct approach +- **`references/advanced.md`** — Colocated workspaces, multiple remotes, divergent changes, filesets, operation log; read for advanced scenarios diff --git a/skills/jujutsu/references/advanced.md b/skills/jujutsu/references/advanced.md index 079830b..78289ee 100644 --- a/skills/jujutsu/references/advanced.md +++ b/skills/jujutsu/references/advanced.md @@ -30,19 +30,6 @@ git status # Can also use, but may show "detached HEAD" # But recommend mainly using jj, git for read-only only ``` -### Switching Colocation State - -```bash -# Check current status -jj git colocation status - -# Enable colocation -jj git colocation enable - -# Disable colocation -jj git colocation disable -``` - ### Notes - jj commands frequently auto import/export, may cause branch conflicts diff --git a/skills/jujutsu/references/revsets.md b/skills/jujutsu/references/revsets.md index 105ff02..1de8d9b 100644 --- a/skills/jujutsu/references/revsets.md +++ b/skills/jujutsu/references/revsets.md @@ -1,133 +1,135 @@ -# Revset 查询语法 +# Revset Query Syntax -> 基于官方文档:https://www.jj-vcs.dev/latest/revsets/ +> Based on official docs: https://www.jj-vcs.dev/latest/revsets/ -Revset 是 jj 强大的查询语法,能精确定位提交。 +Revsets are jj's powerful query syntax for precisely locating commits. -## 基本语法 +## Basic Syntax ```bash jj log -r ``` -## 常用符号 - -| 符号 | 含义 | -|------|------| -| `@` | 当前 working-copy commit | -| `@-` | 当前 commit 的父提交 | -| `@--` | 祖父提交 | -| `main` | bookmark 名为 main 的提交 | -| `HEAD` | HEAD 指向的提交 | -| `root()` | 仓库根提交(虚拟 commit,hash 全为 0) | - -## 运算符 - -| 运算符 | 含义 | 示例 | -|--------|------|------| -| `::` | 祖先范围(包含自己) | `main::` = main 的所有后代 | -| `..` | 不包含祖先 | `main..main~5` | -| `|` | 并集 | `main \| feature` | -| `&` | 交集 | `main & @` | -| `~` | 差集 | `@ ~ main` | -| `-` | 父母(单数) | `@-` = 父提交 | -| `+` | 子孙(单数) | | - -## 范围运算符 - -| 运算符 | 含义 | -|--------|------| -| `x::y` | x 到 y 之间的后代(包含 x 和 y) | -| `x..y` | x 到 y 之间的祖先(不包含 x 的祖先) | -| `::x` | x 的所有祖先 | -| `x::` | x 的所有后代 | - -**注意**:`..` 在左边时不分配(不同于 `|`): -- `(A | B)..` = `A.. & B..`(交集) -- `A.. | B..` = 并集 - -## 函数 - -| 函数 | 用法 | 说明 | -|------|------|------| -| `all()` | `all()` | 所有可见 commit | -| `none()` | `none()` | 空集 | -| `bookmarks()` | `bookmarks()` | 所有本地 bookmark | -| `bookmarks(pattern)` | `bookmarks("main")` | 匹配 pattern 的 bookmark | -| `remote_bookmarks()` | `remote_bookmarks()` | 所有远程 bookmark | -| `visible_heads()` | `visible_heads()` | 所有可见 head | -| `parents(x)` | `parents(@)` | x 的父母 | -| `children(x)` | `children(@)` | x 的子孙 | -| `ancestors(x)` | `ancestors(@)` | x 的祖先 | -| `descendants(x)` | `descendants(@)` | x 的后代 | -| `first_parent(x)` | `first_parent(@)` | 只取第一个父母 | -| `latest(x)` | `latest(@, 5)` | 最近 N 个 | -| `merges()` | `merges()` | 合并提交 | -| `file(path)` | `file("src/main.rs")` | 包含某文件的 commit | -| `author(name)` | `author("yelo")` | 作者匹配 | -| `description(text)` | `description("feat")` | 描述包含 | -| `date(expr)` | `date(2024-01-01)` | 日期 | - -## 常见用法 +## Common Symbols + +| Symbol | Meaning | +|--------|---------| +| `@` | Current working-copy commit | +| `@-` | Parent of current commit | +| `@--` | Grandparent commit | +| `main` | Commit pointed to by bookmark `main` | +| `HEAD` | Commit pointed to by HEAD | +| `root()` | Repository root commit (virtual commit, all-zero hash) | + +## Operators + +| Operator | Meaning | Example | +|----------|---------|---------| +| `::` | Ancestor range (inclusive) | `main::` = all descendants of main | +| `..` | Excluding ancestors | `main..main~5` | +| `\|` | Union | `main \| feature` | +| `&` | Intersection | `main & @` | +| `~` | Difference | `@ ~ main` | +| `-` | Parent (singular) | `@-` = parent commit | +| `+` | Child (singular) | | + +## Range Operators + +| Operator | Meaning | +|----------|---------| +| `x::y` | Descendants between x and y (inclusive) | +| `x..y` | Ancestors between x and y (excluding x's ancestors) | +| `::x` | All ancestors of x | +| `x::` | All descendants of x | + +**Note**: `..` on the left side does not distribute like `|`: +- `(A | B)..` = `A.. & B..` (intersection) +- `A.. | B..` = union + +## Functions + +| Function | Usage | Description | +|----------|-------|-------------| +| `all()` | `all()` | All visible commits | +| `none()` | `none()` | Empty set | +| `bookmarks()` | `bookmarks()` | All local bookmarks | +| `bookmarks(pattern)` | `bookmarks("main")` | Bookmarks matching pattern | +| `remote_bookmarks()` | `remote_bookmarks()` | All remote bookmarks | +| `visible_heads()` | `visible_heads()` | All visible heads | +| `parents(x)` | `parents(@)` | Parents of x | +| `children(x)` | `children(@)` | Children of x | +| `ancestors(x)` | `ancestors(@)` | Ancestors of x | +| `descendants(x)` | `descendants(@)` | Descendants of x | +| `first_parent(x)` | `first_parent(@)` | First parent only | +| `latest(x, n)` | `latest(@, 5)` | Most recent N commits | +| `merges()` | `merges()` | Merge commits | +| `file(path)` | `file("src/main.rs")` | Commits touching a file | +| `author(name)` | `author("yelo")` | Commits by author | +| `description(text)` | `description("feat")` | Commits with matching description | +| `date(expr)` | `date(2024-01-01)` | Commits on date | +| `empty()` | `empty()` | Commits with no file changes | +| `mutable()` | `mutable()` | Locally mutable commits | + +## Common Usage ```bash -# 当前分支的历史 +# History of current branch jj log -r ::@ -# 所有未推送的提交 +# All unpushed commits jj log -r '@..@|bookmarks(@)..' -# 某个 bookmark 的历史 +# History of a bookmark jj log -r main::main -# 最近 5 个提交 +# Most recent 5 commits jj log -r latest(@, 5) -# 包含某个文件的提交 +# Commits touching a file jj log -r 'file(path/to/file)' -# 在某日期之后的提交 +# Commits after a date jj log -r 'date(2024-01-01)..' -# 作者包含某字符串的提交 +# Commits by author jj log -r 'author(yelo)' -# 合并提交 +# Merge commits jj log -r 'merges()' -# 空提交(无文件变更) +# Empty commits (no file changes) jj log -r 'empty()' -# 可变 commits(本地修改过的) +# Mutable commits (locally modified) jj log -r 'mutable()' ``` -## 快捷方式 +## Shortcuts -| 快捷 | 展开 | -|-------|------| -| `@~n` | `@-n`,第 n 个祖先 | -| `@^` | `@-`,父提交 | -| `main~3` | main 的第 3 个祖先 | +| Shorthand | Expands to | +|-----------|-----------| +| `@~n` | nth ancestor of @ | +| `@^` | `@-`, parent commit | +| `main~3` | 3rd ancestor of main | -## 示例 +## Examples ```bash -# 查看当前 commit 的祖先链 +# View ancestor chain of current commit jj log -r ::@ -# 查看 feature 分支独有的提交 +# View commits unique to feature branch jj log -r 'feature - main' -# 查看最近一周的提交 +# View commits from the last week jj log -r 'date(-7d)..' -# 查看两个 bookmark 之间的差异 +# View diff between two bookmarks jj diff -r main..feature -# 查看某个人的所有提交 +# View all commits by a specific author jj log -r 'author(yelo)' -# 查看所有 bookmark 的最新位置 +# View latest position of all bookmarks jj log -r 'bookmarks()' ```