gg

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

gg

gg

Use this skill to operate git-gud (
gg
) as a CLI tool
for day-to-day stacked-diff workflows across GitHub and GitLab.
使用本技能操作git-gud(
gg
)作为CLI工具
,在GitHub和GitLab上完成日常的堆叠差异工作流。

When to use

适用场景

  • You need multiple PRs/MRs that depend on each other
  • You need to sync stack changes and keep review metadata updated (including GG-ID/GG-Parent normalization)
  • You need machine-readable command output for automation (
    --json
    )
  • 你需要多个相互依赖的PR/MR
  • 你需要同步堆叠变更并更新评审元数据(包括GG-ID/GG-Parent标准化)
  • 你需要机器可读的命令输出用于自动化(
    --json
    参数)

Prerequisites

前置条件

  • gg
    installed
  • Provider CLI installed + authenticated:
    • GitHub:
      gh auth status
    • GitLab:
      glab auth status
  • Git repo with
    gg
    initialized (
    gg setup
    )
Note: Network errors during auth check are non-fatal — gg prints a warning and continues. The operation may fail later if authentication is actually required.
  • 已安装
    gg
  • 已安装并认证对应的提供商CLI:
    • GitHub:
      gh auth status
    • GitLab:
      glab auth status
  • 已通过
    gg setup
    初始化的Git仓库
注意: 认证检查期间的网络错误不会导致程序终止——gg会打印警告并继续执行。如果后续操作确实需要认证,可能会失败。

Setup

配置

Interactive wizard (recommended)

交互式向导(推荐)

bash
gg setup        # Quick mode: essential settings (provider, base, username)
gg setup --all  # Full mode: all settings organized by category
Quick mode prompts for: provider, base branch, username.
Full mode organizes all settings into groups: General, Sync, Land, Lint, Worktrees, and GitLab (if applicable). Includes sync_draft, sync_update_descriptions, and sync_update_title options.
bash
gg setup        # 快速模式:仅配置必要项(提供商、基础分支、用户名)
gg setup --all  # 完整模式:按类别配置所有设置
快速模式会提示你输入:提供商、基础分支、用户名。
完整模式将所有设置分为以下组别:通用、同步、合并、检查、工作树,以及GitLab专属设置(若适用)。包含sync_draft、sync_update_descriptions和sync_update_title等选项。

Global config

全局配置

Store shared defaults in
~/.config/gg/config.json
that apply to all repos. Local config (
gg setup
) takes precedence.
将共享默认配置存储在
~/.config/gg/config.json
中,适用于所有仓库。本地配置(通过
gg setup
设置)优先级更高。

Manual setup (
.git/gg/config.json
)

手动配置(
.git/gg/config.json

json
{
  "defaults": {
    "provider": "github",
    "base": "main",
    "branch_username": "your-github-user",
    "lint": ["cargo fmt --all --check", "cargo clippy -- -D warnings"],
    "auto_add_gg_ids": true,
    "sync_auto_rebase": false,
    "sync_behind_threshold": 1,
    "sync_auto_lint": false,
    "sync_draft": false,
    "sync_update_descriptions": true,
    "sync_update_title": false,
    "land_auto_clean": false,
    "land_wait_timeout_minutes": 30,
    "unstaged_action": "ask"
  }
}
json
{
  "defaults": {
    "provider": "gitlab",
    "base": "main",
    "branch_username": "your-gitlab-user",
    "lint": ["cargo fmt --all --check", "cargo clippy -- -D warnings"],
    "gitlab": {
      "auto_merge_on_land": false
    }
  }
}
auto_add_gg_ids
is deprecated and kept only for compatibility with existing configs; runtime behavior always treats it as enabled.
json
{
  "defaults": {
    "provider": "github",
    "base": "main",
    "branch_username": "your-github-user",
    "lint": ["cargo fmt --all --check", "cargo clippy -- -D warnings"],
    "auto_add_gg_ids": true,
    "sync_auto_rebase": false,
    "sync_behind_threshold": 1,
    "sync_auto_lint": false,
    "sync_draft": false,
    "sync_update_descriptions": true,
    "sync_update_title": false,
    "land_auto_clean": false,
    "land_wait_timeout_minutes": 30,
    "unstaged_action": "ask"
  }
}
json
{
  "defaults": {
    "provider": "gitlab",
    "base": "main",
    "branch_username": "your-gitlab-user",
    "lint": ["cargo fmt --all --check", "cargo clippy -- -D warnings"],
    "gitlab": {
      "auto_merge_on_land": false
    }
  }
}
auto_add_gg_ids
已被弃用,仅为兼容现有配置而保留;运行时始终将其视为启用状态。

Core workflow

核心工作流

  1. Create/switch stack (prefer worktree):
bash
gg co -w feature-auth
When shell integration is installed (
eval "$(gg init zsh)"
,
eval "$(gg init bash)"
, or
gg init fish | source
),
gg co -w
changes into the stack worktree after checkout succeeds. Without it, read the printed worktree path and
cd
there before editing.
When splitting an existing stack into lower and upper stacks, prefer a managed worktree for the new upper stack:
bash
gg unstack --target 3 --name feature-auth-followup --wt
  1. Commit logical changes:
bash
git add <files>
git commit -m "feat: add input validation"
  1. Check stack state:
bash
gg ls --json        # single-stack details + summary metrics
gg log --json       # smartlog-style view of the current stack
gg inbox --json     # cross-stack triage buckets for action needed
  1. Publish/update PR/MR chain:
bash
gg sync --json
If a mapped PR/MR still points at an old source branch after a stack split,
gg sync
recreates that PR/MR with the current entry branch, remaps config to the new number, comments on the old one, and closes it. JSON action is
"recreated"
.
If
gg sync --json
returns a warning that the stack branch does not use the configured prefix, surface it to the user. The command may continue, but stack discovery/listing and saved PR/MR mappings can be inaccurate until the branch is renamed to match
defaults.branch_username
.
  1. When approved + green CI, land only after user confirmation:
bash
gg land -a -c --json
  1. 创建/切换堆叠(优先使用工作树):
bash
gg co -w feature-auth
当安装了Shell集成(
eval "$(gg init zsh)"
,
eval "$(gg init bash)"
, 或
gg init fish | source
)后,
gg co -w
会在检出成功后切换到堆叠工作树。未安装时,请查看打印的工作树路径,在编辑前通过
cd
命令进入该路径。
当将现有堆叠拆分为下层和上层堆叠时,优先为新的上层堆叠使用托管工作树:
bash
gg unstack --target 3 --name feature-auth-followup --wt
  1. 提交逻辑变更:
bash
git add <files>
git commit -m "feat: add input validation"
  1. 检查堆叠状态:
bash
gg ls --json        # 单堆叠详情 + 汇总指标
gg log --json       # 当前堆叠的智能日志视图
gg inbox --json     # 跨堆叠分类待处理事项
  1. 发布/更新PR/MR链:
bash
gg sync --json
如果在堆叠拆分后,映射的PR/MR仍然指向旧的源分支,
gg sync
会使用当前条目分支重新创建该PR/MR,将配置重新映射到新编号,在旧PR/MR上添加评论并关闭它。JSON输出中的操作类型为
"recreated"
如果
gg sync --json
返回警告,提示堆叠分支未使用配置的前缀,请告知用户。命令可能会继续执行,但直到分支重命名为匹配
defaults.branch_username
的格式后,堆叠发现/列表以及已保存的PR/MR映射才会准确。
  1. 当PR/MR获批且CI通过后,仅在用户确认后合并
bash
gg land -a -c --json

Agent operating rules (mandatory)

Agent操作规则(强制)

  1. Never run
    gg land
    without explicit user confirmation.
  2. Always use
    --json
    for
    gg ls
    ,
    gg sync
    ,
    gg land
    ,
    gg clean -a
    , and
    gg lint
    .
  3. Prefer worktrees for isolation (
    gg co -w <stack>
    ). If shell integration is unavailable, manually
    cd
    to the printed worktree path before editing.
  4. Verify
    approved: true
    and
    ci_status
    success before landing. If the user requests
    --admin
    , skip the approval check (GitHub only — GitLab ignores the flag).
  5. If sync warns stack is behind base, run
    gg rebase
    first.
  6. Prefer
    gg absorb -s
    for multi-commit edits.
  7. Never use
    git add -A
    blindly.
    Review
    git status
    first and only stage intended files. Use
    git add <specific-files>
    to avoid leaking secrets, env files, or unrelated changes.
  8. Respect the immutability guard. Rewrite-style commands (
    gg sc
    ,
    gg absorb
    ,
    gg reorder
    /
    gg arrange
    ,
    gg split
    ,
    gg unstack
    ,
    gg drop
    ,
    gg rebase
    ,
    gg restack
    ) refuse to rewrite merged PRs/MRs or commits already on the base branch, except that
    gg rebase
    silently skips base-ancestor commits that naturally drop out when rebasing onto the refreshed base. If a command exits with
    ImmutableTargets
    , surface the listed commits and reasons to the user and get explicit confirmation before retrying with
    -f
    /
    --force
    (alias
    --ignore-immutable
    ). If the error comes from
    gg sync
    's auto-rebase, the override is
    gg rebase --force
    /
    gg rebase --ignore-immutable
    , not
    gg sync --force
    .
  1. 未经用户明确确认,绝不要运行
    gg land
    命令。
  2. 对于
    gg ls
    gg sync
    gg land
    gg clean -a
    gg lint
    命令,始终使用
    --json
    参数。
  3. 优先使用工作树来实现隔离(
    gg co -w <stack>
    )。如果Shell集成不可用,请在编辑前手动
    cd
    到打印的工作树路径。
  4. 合并前需验证
    approved: true
    ci_status
    为成功状态。如果用户要求使用
    --admin
    参数,则跳过审批检查(仅GitHub支持——GitLab会忽略该标志)。
  5. 如果同步时警告堆叠落后于基础分支,请先运行
    gg rebase
  6. 多提交编辑优先使用
    gg absorb -s
  7. 绝不要盲目使用
    git add -A
    先查看
    git status
    ,仅暂存目标文件。使用
    git add <specific-files>
    避免泄露密钥、环境文件或无关变更。
  8. 遵循不可变保护机制。 重写类命令(
    gg sc
    gg absorb
    gg reorder
    /
    gg arrange
    gg split
    gg unstack
    gg drop
    gg rebase
    gg restack
    )会拒绝重写已合并的PR/MR或已在基础分支上的提交,除了
    gg rebase
    会自动跳过在重新基于更新后的基础分支时自然会被丢弃的基础祖先提交。如果命令因
    ImmutableTargets
    错误退出,请向用户列出相关提交及原因,并在使用
    -f
    /
    --force
    (别名
    --ignore-immutable
    )重试前获得明确确认。如果错误来自
    gg sync
    的自动重基,则需要通过
    gg rebase --force
    /
    gg rebase --ignore-immutable
    覆盖,而非
    gg sync --force

Common operations

常见操作

  • Navigate:
    gg mv
    ,
    gg first
    ,
    gg last
    ,
    gg prev
    ,
    gg next
  • Amend current commit:
    gg sc
    /
    gg sc -a
  • Auto-distribute staged hunks:
    gg absorb -s
  • Split a commit into two:
    gg split
    — opens a two-panel TUI for hunk selection (files on the left, colored diff on the right), followed by inline commit message inputs for both the new and remainder commits. Use
    --no-tui
    to fall back to sequential
    git add -p
    style prompts. The
    -m
    flag bypasses the TUI message input for the new commit. The
    --no-edit
    flag skips the remainder message input. Pass
    FILES...
    to auto-select all hunks from those files (e.g.,
    gg split -c 3 file1.rs file2.rs
    ).
  • Split a stack into two stacks:
    gg unstack
    — opens a picker by default. The selected entry and descendants become a new independent stack; lower entries remain in the original stack. Use
    --target <position|gg-id|sha> --no-tui
    for scripts, and
    --name <stack>
    to choose the new stack name.
  • Drop commits from stack:
    gg drop <position|sha|gg-id>... -y
    (alias:
    gg abandon
    ). Use
    -y
    /
    --yes
    to skip confirmation; add
    -f
    /
    --force
    only to bypass the immutability guard for merged/base-ancestor commits.
  • Reorder/drop stack (TUI):
    gg reorder
    (or
    gg arrange
    ) — opens interactive TUI for visual reordering and dropping commits. Press
    d
    to mark a commit for dropping. Use
    --no-tui
    to fall back to text editor (delete lines to drop).
  • Reorder stack (direct):
    gg reorder -o "3,1,2"
  • Sync subset:
    gg sync -u <position|gg-id|sha> --json
  • Lint stack:
    gg lint --json
  • Run a command across the stack:
    gg run -- <cmd...>
    (see below)
  • Triage multiple stacks at once:
    gg inbox --json
  • Repair ancestry drift:
    gg restack
    /
    gg restack --dry-run --json
    (see below)
  • Clean merged stacks:
    gg clean -a --json
  • Undo last local mutation:
    gg undo
    (see below)
  • 导航:
    gg mv
    ,
    gg first
    ,
    gg last
    ,
    gg prev
    ,
    gg next
  • 修改当前提交:
    gg sc
    /
    gg sc -a
  • 自动分配暂存块:
    gg absorb -s
  • 将一个拆分为两个提交:
    gg split
    —— 打开双面板TUI用于选择代码块(左侧为文件,右侧为带颜色的差异),随后为新提交和剩余提交输入内联提交信息。使用
    --no-tui
    参数回退到顺序式
    git add -p
    风格的提示。
    -m
    参数跳过新提交的TUI信息输入。
    --no-edit
    参数跳过剩余提交的信息输入。传入
    FILES...
    可自动选择这些文件的所有代码块(例如:
    gg split -c 3 file1.rs file2.rs
    )。
  • 将一个堆叠拆分为两个堆叠:
    gg unstack
    —— 默认打开选择器。选中的条目及其子条目将成为新的独立堆叠;下层条目保留在原堆叠中。对于脚本,使用
    --target <position|gg-id|sha> --no-tui
    参数,使用
    --name <stack>
    参数指定新堆叠的名称。
  • 从堆叠中删除提交:
    gg drop <position|sha|gg-id>... -y
    (别名:
    gg abandon
    )。使用
    -y
    /
    --yes
    参数跳过确认;仅当需要绕过已合并/基础祖先提交的不可变保护时,添加
    -f
    /
    --force
    参数。
  • 重新排序/删除堆叠(TUI):
    gg reorder
    (或
    gg arrange
    )—— 打开交互式TUI用于可视化重新排序和删除提交。按
    d
    键标记要删除的提交。使用
    --no-tui
    参数回退到文本编辑器(删除行即可删除提交)。
  • 直接重新排序堆叠:
    gg reorder -o "3,1,2"
  • 同步子集:
    gg sync -u <position|gg-id|sha> --json
  • 检查堆叠:
    gg lint --json
  • 在整个堆叠中运行命令:
    gg run -- <cmd...>
    (详见下文)
  • 同时分类多个堆叠:
    gg inbox --json
  • 修复祖先漂移:
    gg restack
    /
    gg restack --dry-run --json
    (详见下文)
  • 清理已合并的堆叠:
    gg clean -a --json
  • 撤销上次本地变更:
    gg undo
    (详见下文)

Undoing local mutations (
gg undo
)

撤销本地变更(
gg undo

gg undo
reverses the ref/
HEAD
effects of the most recent mutating
gg
command by replaying a snapshot from the per-repo operation log at
<commondir>/gg/operations/*.json
. It never touches the working tree, index, or untracked files — only refs move.
bash
gg undo              # reverse the most recent local operation
gg undo --list       # see recent operations (newest-first)
gg undo <op_id>      # target a specific record from --list
gg undo; gg undo     # redo: a second undo reverses the first
gg undo --json       # machine-readable output
Every mutating command (
sc
,
drop
,
split
,
unstack
,
rebase
,
reorder
,
absorb
,
reconcile
,
restack
,
checkout
, nav,
clean
,
sync
,
land
, and
run --amend
) snapshots the refs it will touch before mutating and records the operation on success. The log keeps the last 100 records; interrupted/pending records are never pruned.
Refusal modes (exit 1, no refs touched, JSON includes
refusal.reason
):
  • remote
    — target operation pushed/merged/closed/created a PR/MR. gg prints a provider-specific revert hint (
    gh pr close <n>
    ,
    glab mr close <n>
    ,
    git push --delete …
    ). Agents must surface the hint to the user rather than attempt silent remote rollback.
  • interrupted
    — operation crashed or was Ctrl-C'd mid-flight.
  • stale
    — refs moved since the target operation finalised. The error names the ref, expected OID, and actual OID.
  • unsupported_schema
    — record was written by a newer
    gg
    binary.
gg undo
does not restore working-tree content (use
git reflog
or
git stash
), does not touch remotes, and does not support an
--all
/
--range
mode.
gg undo
通过重放仓库操作日志(位于
<commondir>/gg/operations/*.json
)中的快照,撤销最近一次变更类
gg
命令对引用/
HEAD
的影响。它绝不会修改工作树、索引或未跟踪文件——仅会移动引用。
bash
gg undo              # 撤销最近一次本地操作
gg undo --list       # 查看最近操作(按时间倒序)
gg undo <op_id>      # 针对--list中的特定记录进行撤销
gg undo; gg undo     # 重做:再次撤销会恢复之前的操作
gg undo --json       # 机器可读输出
所有变更类命令(
sc
drop
split
unstack
rebase
reorder
absorb
reconcile
restack
checkout
、导航命令、
clean
sync
land
以及
run --amend
)都会在变更前快照其将修改的引用,并在成功执行后记录该操作。日志保留最近100条记录;中断/未完成的记录绝不会被删除。
拒绝模式(退出码1,不修改任何引用,JSON输出包含
refusal.reason
):
  • remote
    —— 目标操作推送/合并/关闭/创建了PR/MR。gg会打印提供商特定的撤销提示(如
    gh pr close <n>
    glab mr close <n>
    git push --delete …
    )。Agent必须将该提示告知用户,而非尝试静默回滚远程操作。
  • interrupted
    —— 操作在执行过程中崩溃或被Ctrl-C中断。
  • stale
    —— 自目标操作完成后,引用已被修改。错误信息会列出引用名称、预期OID和实际OID。
  • unsupported_schema
    —— 记录由更新版本的
    gg
    二进制文件写入。
gg undo
不会恢复工作树内容(请使用
git reflog
git stash
),不会修改远程仓库,不支持
--all
/
--range
模式。

Repairing stack ancestry (
gg restack
)

修复堆叠祖先关系(
gg restack

gg restack
detects and repairs ancestry drift — when a commit's
GG-Parent
trailer no longer matches its expected parent in the stack order. This happens after manual
git rebase
,
git commit --amend
, cherry-picks, or upstream rebases that rewrite commit SHAs without updating GG metadata.
bash
gg restack --dry-run        # show plan without changes
gg restack --dry-run --json # machine-readable plan
gg restack                  # execute full ancestry repair
gg restack --from 3         # repair only from position 3 upward
gg restack --json           # execute with JSON output
Each step in the plan is one of:
  • ok — parent already correct, no action needed
  • reattach — parent differs, needs rebasing
  • skip — below
    --from
    threshold, not checked
After a successful restack, run
gg sync
to push the repaired commits.
gg restack
会检测并修复祖先漂移——即提交的
GG-Parent
尾部信息与堆叠顺序中的预期父提交不匹配的情况。这种情况会在手动执行
git rebase
git commit --amend
、cherry-pick或上游重基(未更新GG元数据)后发生。
bash
gg restack --dry-run        # 显示修复计划但不执行变更
gg restack --dry-run --json # 机器可读的修复计划
gg restack                  # 执行完整的祖先修复
gg restack --from 3         # 仅从第3个位置开始向上修复
gg restack --json           # 执行并输出JSON格式结果
计划中的每个步骤为以下类型之一:
  • ok —— 父提交已正确,无需操作
  • reattach —— 父提交不匹配,需要重基
  • skip —— 低于
    --from
    阈值,不检查
成功修复后,运行
gg sync
推送修复后的提交。

Running commands across the stack (
gg run
)

在整个堆叠中运行命令(
gg run

gg run
walks every commit in the current stack (oldest → newest) and executes a command at each one. Use it for things that don't fit the
lint
config — ad-hoc verifications, formatters, single-shot scripts, etc.
  • Read-only (default):
    gg run -- cargo test -p mycrate
    Each commit is checked out, the command runs, and the tree must stay clean. Any modification fails that commit (same contract as
    gg lint
    without
    --amend
    ).
  • Amend mode:
    gg run --amend -- cargo fmt
    Changes the command makes are folded into each commit via
    git commit --amend
    , then the rest of the stack is rebased on top. This is the same engine
    gg lint
    uses.
  • Discard mode:
    gg run --discard -- ./mutating-check.sh
    Runs the command and throws away any changes (working tree + index + untracked). Useful when you only care about the exit code of a command that happens to mutate state.
  • Stop on first failure (default) vs keep going: Add
    --keep-going
    /
    -k
    to continue through failing commits instead of aborting at the first one.
  • Limit how far you go:
    --until <position|gg-id|sha>
    stops after the named commit. Everything above it is left untouched.
  • Parallelize read-only runs:
    -j N
    /
    --jobs N
    spawns isolated worktrees per commit. Valid only with the default (read-only) mode. The dirty-tree check in each worker matches the sequential path (untracked files are ignored, tracked modifications fail).
  • JSON output:
    gg run --json -- <cmd...>
    emits a single
    RunResponse
    document on stdout (see
    reference.md
    ). Failures set
    run.all_passed = false
    ; the process still exits non-zero, but only the run payload is printed — no trailing
    {"error":...}
    object.
Argument boundaries are preserved:
gg run -- git commit -m "multi word"
passes exactly those argv elements to
git
without shell splitting, so quoted args with spaces, globs, or shell metacharacters go through intact. Use
--
before the command (as shown) so clap treats subsequent tokens as the command, not as
gg run
flags.
For repeatable linter runs with commands configured in
.git/gg/config.json
, prefer
gg lint
— it's
gg run --amend
with the command list coming from config.
gg run
会遍历当前堆叠中的每个提交(从最旧到最新),并在每个提交上执行指定命令。适用于不适合配置在
lint
中的场景——临时验证、格式化工具、一次性脚本等。
  • 只读模式(默认)
    gg run -- cargo test -p mycrate
    每个提交都会被检出,执行命令,且工作树必须保持干净。任何修改都会导致该提交执行失败(与未使用
    --amend
    参数的
    gg lint
    规则相同)。
  • 修改模式
    gg run --amend -- cargo fmt
    命令产生的变更会通过
    git commit --amend
    合并到每个提交中,然后将堆叠的其余部分重新基于该提交。这与
    gg lint
    使用的引擎相同。
  • 丢弃模式
    gg run --discard -- ./mutating-check.sh
    执行命令并丢弃所有变更(工作树 + 索引 + 未跟踪文件)。适用于仅关心命令退出码,而命令本身会修改状态的场景。
  • 首次失败即停止(默认)vs 继续执行: 添加
    --keep-going
    /
    -k
    参数可继续执行后续提交,而非在首次失败时终止。
  • 限制执行范围
    --until <position|gg-id|sha>
    参数会在指定提交后停止执行。该提交之上的所有内容保持不变。
  • 并行化只读执行
    -j N
    /
    --jobs N
    参数会为每个提交创建独立的工作树。仅适用于默认(只读)模式。每个工作树中的脏树检查与顺序执行一致(忽略未跟踪文件,跟踪文件的修改会导致失败)。
  • JSON输出
    gg run --json -- <cmd...>
    会在标准输出中输出单个
    RunResponse
    文档(详见
    reference.md
    )。执行失败时会设置
    run.all_passed = false
    ;进程仍会返回非零退出码,但仅会打印执行负载——不会附加
    {"error":...}
    对象。
参数边界会被保留:
gg run -- git commit -m "multi word"
会将这些参数完整传递给
git
,不会进行Shell拆分,因此包含空格、通配符或Shell元字符的带引号参数会完整传递。请在命令前使用
--
(如示例所示),以便clap将后续标记视为命令而非
gg run
的参数。
对于可重复的检查器运行,且命令配置在
.git/gg/config.json
中,优先使用
gg lint
——它相当于从配置中读取命令列表的
gg run --amend

Immutable commits

不可变提交

gg refuses by default to rewrite commits that look "already published":
  • the tracked PR/MR is merged, or
  • the commit is already reachable from
    origin/<base>
    (or the local base, as a fallback).
The guard protects
gg sc
,
gg absorb
,
gg reorder
/
gg arrange
,
gg split
,
gg unstack
,
gg drop
,
gg rebase
, and
gg restack
.
gg rebase
is a special case: merged commits (both base-ancestor commits and squash-merged PRs) are silently skipped because
git rebase
would drop them naturally via patch-id matching instead of rewriting them. For the remaining commands the command exits with an
ImmutableTargets
error listing every affected position, short SHA, title, and reason (e.g.
merged as !123
,
already in origin/main
).
To bypass it intentionally, pass
-f
/
--force
(long alias
--ignore-immutable
). Always surface the listed commits and reasons to the user first; the override still emits a warning and proceeds.
If
gg sync
surfaces the guard during auto-rebase, run
gg rebase --force
or
gg rebase --ignore-immutable
after user confirmation, then retry
gg sync
.
gg sync --force
only affects push behavior.
gg land
's post-merge cleanup bypasses the guard by design, and
gg absorb --dry-run
skips it (no rewrite happens). See
reference.md
→ "Immutable commits" for details.
默认情况下,gg会拒绝重写看起来“已发布”的提交:
  • 对应的PR/MR已合并,或
  • 提交已可从
    origin/<base>
    (或本地基础分支,作为备选)访问。
该保护机制适用于
gg sc
gg absorb
gg reorder
/
gg arrange
gg split
gg unstack
gg drop
gg rebase
gg restack
命令。
gg rebase
是特殊情况:已合并的提交(包括基础祖先提交和 squash合并的PR)会被自动跳过,因为
git rebase
会通过patch-id匹配自然丢弃它们,而非重写。对于其他命令,命令会因
ImmutableTargets
错误退出,并列出所有受影响的位置、短SHA、标题和原因(例如
merged as !123
already in origin/main
)。
若要有意绕过该机制,请传递
-f
/
--force
(长别名
--ignore-immutable
)参数。请始终先向用户列出相关提交及原因;即使使用覆盖参数,命令仍会发出警告并继续执行。
如果
gg sync
在自动重基时触发该保护机制,请在用户确认后运行
gg rebase --force
gg rebase --ignore-immutable
,然后重试
gg sync
gg sync --force
仅影响推送行为。
gg land
的合并后清理操作会默认绕过该保护机制,
gg absorb --dry-run
会跳过该机制(不会执行重写)。详情请见
reference.md
→ "Immutable commits"。

PR/MR body ownership

PR/MR正文所有权

gg sync
uses managed markers to separate generated content from user edits:
(user content — preserved across syncs)

<!-- gg:managed:start -->
(generated by gg — regenerated on every sync)
<!-- gg:managed:end -->

(user content — preserved across syncs)
  • New PRs/MRs: Body is wrapped in managed markers automatically.
  • Re-sync with markers: Only the managed block is replaced; user content above/below is preserved.
  • Legacy PRs (no markers): Body is left untouched with a warning — no risk of clobbering manual edits.
  • Content inside the managed block is regenerated on each sync. Place persistent checklists and notes outside the markers.
gg sync
使用托管标记区分生成内容与用户编辑内容:
(用户内容 —— 同步时会保留)

<!-- gg:managed:start -->
(由gg生成 —— 每次同步都会重新生成)
<!-- gg:managed:end -->

(用户内容 —— 同步时会保留)
  • 新PR/MR:正文会自动被托管标记包裹。
  • 带标记的重新同步:仅托管块会被替换;标记上下的用户内容会保留。
  • 旧PR(无标记):正文保持不变并发出警告——不会覆盖手动编辑内容。
  • 托管块内的内容:每次同步都会重新生成。请将持久化的检查清单和注释放在标记之外。

Stack-navigation comments

堆叠导航评论

If the repo's
.git/gg/config.json
has
defaults.stack_nav_comments: true
,
gg sync
posts and maintains a managed comment on each open PR/MR in the stack. The comment lists every entry (
#N
on GitHub,
!N
on GitLab) with a 👉 marker on the current one. The comment is identified by a hidden
<!-- gg:stack-nav -->
marker and managed entirely by git-gud — don't edit these comments manually, and don't be surprised when
gg sync
adds, updates, or removes them automatically.
Disable the feature by setting
defaults.stack_nav_comments: false
(the default). The next
gg sync
then cleans up any existing managed comments. Reconcile is skipped under
--until
to avoid partial-stack inconsistencies.
如果仓库的
.git/gg/config.json
中设置了
defaults.stack_nav_comments: true
gg sync
会在堆叠中的每个开放PR/MR上发布并维护一条托管评论。该评论会列出每个条目(GitHub为
#N
,GitLab为
!N
),并在当前条目旁标注👉标记。该评论通过隐藏的
<!-- gg:stack-nav -->
标记识别,完全由git-gud管理——请勿手动编辑这些评论,也无需惊讶
gg sync
会自动添加、更新或删除它们。
通过设置
defaults.stack_nav_comments: false
(默认值)可禁用该功能。下次
gg sync
会清理所有现有的托管评论。使用
--until
参数时会跳过协调,以避免部分堆叠不一致。

GitLab-specific

GitLab专属特性

  • gg land --auto-merge
    is GitLab-only and requests queueing/auto-merge.
  • With merge trains enabled, landing may enqueue MRs instead of immediate merge.
  • After queueing, GitLab may temporarily omit the MR from the merge-train listing. Treat the
    gg land --wait
    "not reported yet; still polling" status as non-terminal unless the command reports closed, skipped, failed CI, timeout, or repeated API errors.
  • Track train state in
    gg ls --json
    with:
    • in_merge_train
    • merge_train_position
  • Land action values on GitLab may include
    queued
    /
    already_queued
    (in addition to
    merged
    ).
  • When
    --wait
    detects CI failure, the error message includes the names and stages of failed pipeline jobs (fetched from the MR's head pipeline).
  • After landing an MR, downstream MRs are automatically retargeted away from the merged branch — no manual retargeting in GitLab UI is needed.
    gg sync
    also handles this if an MR was merged directly in the UI.
  • Use
    glab
    for auxiliary GitLab checks/actions.
  • JSON fields always use
    pr_*
    naming, even for GitLab MRs (
    pr_number
    ,
    pr_state
    ).
  • gg land --auto-merge
    是GitLab专属功能,用于请求排队/自动合并。
  • 启用合并队列后,合并操作可能会将MR加入队列而非立即合并。
  • 加入队列后,GitLab可能会暂时在合并队列列表中省略该MR。除非命令报告已关闭、已跳过、CI失败、超时或重复API错误,否则请将
    gg land --wait
    的“尚未报告;仍在轮询”状态视为非终止状态。
  • 通过
    gg ls --json
    跟踪队列状态,相关字段:
    • in_merge_train
    • merge_train_position
  • GitLab上的合并操作值可能包括
    queued
    /
    already_queued
    (除
    merged
    外)。
  • --wait
    检测到CI失败时,错误信息会包含失败流水线作业的名称和阶段(从MR的头流水线获取)。
  • 合并MR后,下游MR会自动重新定向,不再指向已合并的分支——无需在GitLab UI中手动重新定向。如果MR是直接在UI中合并的,
    gg sync
    也会处理该情况。
  • 使用
    glab
    进行辅助GitLab检查/操作。
  • JSON字段始终使用
    pr_*
    命名,即使是GitLab MR(如
    pr_number
    pr_state
    )。

Provider-neutral notes

提供商中立说明

  • pr_state
    values:
    open
    ,
    merged
    ,
    closed
    ,
    draft
    (same for both GitHub and GitLab).
  • pr_url
    format varies by provider (
    /pull/N
    for GitHub,
    /-/merge_requests/N
    for GitLab).
  • pr_state
    取值:
    open
    merged
    closed
    draft
    (GitHub和GitLab一致)。
  • pr_url
    格式因提供商而异(GitHub为
    /pull/N
    ,GitLab为
    /-/merge_requests/N
    )。

See also

另请参阅

  • Full command + schema reference:
    reference.md
  • End-to-end walkthrough:
    examples/basic-flow.md
  • Multi-commit editing:
    examples/multi-commit.md
  • Merge trains (GitLab):
    examples/merge-train.md
  • MCP server tools & schemas:
    reference.md
    → MCP Server section
  • 完整命令 + 架构参考:
    reference.md
  • 端到端演练:
    examples/basic-flow.md
  • 多提交编辑:
    examples/multi-commit.md
  • 合并队列(GitLab):
    examples/merge-train.md
  • MCP服务器工具与架构:
    reference.md
    → MCP Server章节

MCP Server Usage for Agents

Agent使用MCP服务器

The
gg-mcp
binary exposes git-gud as an MCP server (stdio transport). Set
GG_REPO_PATH
to the target repo.
gg-mcp
二进制文件将git-gud暴露为MCP服务器(stdio传输)。设置
GG_REPO_PATH
为目标仓库路径。

Read-only tools (safe, no side effects)

只读工具(安全,无副作用)

  • stack_list
    /
    stack_log
    /
    stack_list_all
    /
    stack_status
    — inspect stacks (
    stack_log
    gives a smartlog-style view of the current stack;
    stack_list_all
    is cross-stack)
  • pr_info
    — check PR state, CI, approval
  • config_show
    — read repo configuration
  • stack_undo_list
    — list recent operations from the per-repo operation log
  • stack_list
    /
    stack_log
    /
    stack_list_all
    /
    stack_status
    —— 检查堆叠(
    stack_log
    提供当前堆叠的智能日志视图;
    stack_list_all
    为跨堆叠视图)
  • pr_info
    —— 检查PR状态、CI、审批情况
  • config_show
    —— 读取仓库配置
  • stack_undo_list
    —— 从仓库操作日志中列出最近操作

Write tools (mutating, use with care)

写入工具(会修改数据,谨慎使用)

  • stack_checkout
    — create or switch stacks
  • stack_sync
    — push and create/update PRs (use
    draft: true
    for safety)
  • stack_land
    — merge approved PRs (always confirm with user first)
  • stack_clean
    — remove merged stacks
  • stack_rebase
    — rebase onto latest base
  • stack_squash
    /
    stack_absorb
    — amend commits
  • stack_reconcile
    — fix out-of-sync remote branches (pass
    yes: true
    to skip the metadata normalization confirmation prompt in non-interactive/MCP contexts; this does not bypass safety checks or immutability protections)
  • stack_drop
    — remove commits from the stack (always passes
    --yes
    ; set
    force: true
    only to bypass the immutability guard for merged/base commits; agent confirms with user before any drop)
  • stack_split
    — split a commit using interactive hunk selection (TUI opens by default; pass FILES... to auto-select all hunks for those files)
  • stack_reorder
    — reorder commits with explicit order string (no TUI)
  • stack_restack
    — repair stack ancestry drift (
    dry_run
    ,
    from
    params)
  • stack_undo
    — reverse the ref/HEAD effects of the most recent mutating
    gg
    command (refuses on remote-touching ops, returns provider-specific revert hints; agents must surface those hints rather than attempt silent remote rollback)
  • stack_checkout
    —— 创建或切换堆叠
  • stack_sync
    —— 推送并创建/更新PR(为安全起见,使用
    draft: true
  • stack_land
    —— 合并已获批的PR(必须先获得用户确认
  • stack_clean
    —— 删除已合并的堆叠
  • stack_rebase
    —— 重新基于最新的基础分支
  • stack_squash
    /
    stack_absorb
    —— 修改提交
  • stack_reconcile
    —— 修复不同步的远程分支(在非交互式/MCP环境中,传递
    yes: true
    可跳过元数据标准化确认提示;这不会绕过安全检查或不可变保护)
  • stack_drop
    —— 从堆叠中删除提交(始终传递
    --yes
    ;仅当需要绕过已合并/基础提交的不可变保护时,设置
    force: true
    ;Agent在执行任何删除操作前需获得用户确认)
  • stack_split
    —— 通过交互式代码块选择拆分提交(默认打开TUI;传入FILES...可自动选择这些文件的所有代码块)
  • stack_reorder
    —— 使用明确的顺序字符串重新排序提交(无TUI)
  • stack_restack
    —— 修复堆叠祖先漂移(支持
    dry_run
    from
    参数)
  • stack_undo
    —— 撤销最近一次变更类
    gg
    命令对引用/HEAD的影响(会拒绝修改远程的操作,返回提供商特定的撤销提示;Agent必须将这些提示告知用户,而非尝试静默回滚远程操作)

Navigation tools

导航工具

  • stack_move
    — jump to a commit by position, GG-ID, or SHA
  • stack_navigate
    — move first/last/prev/next in the stack
  • stack_move
    —— 通过位置、GG-ID或SHA跳转到指定提交
  • stack_navigate
    —— 在堆叠中跳转到第一个/最后一个/上一个/下一个提交

Agent guidelines for MCP

Agent使用MCP的指南

  • Prefer read-only tools to understand state before writing.
  • Use
    stack_sync
    with
    draft: true
    for new PRs unless the user asks for non-draft. Note:
    draft: true
    only affects newly created PRs, not existing ones.
  • Never call
    stack_land
    without explicit user approval.
  • Parse JSON output from
    stack_sync
    ,
    stack_land
    ,
    stack_clean
    , and
    stack_lint
    .
  • If
    stack_status
    shows
    behind_base > 0
    , run
    stack_rebase
    before syncing.
  • Rewrite tools (
    stack_squash
    ,
    stack_absorb
    ,
    stack_reorder
    ,
    stack_split
    ,
    stack_drop
    ,
    stack_rebase
    , plus CLI
    gg unstack
    ) will fail with
    ImmutableTargets
    when a target commit is merged or already on the base branch. Each tool accepts a
    force: bool
    parameter that maps to
    --force
    /
    --ignore-immutable
    . Only set
    force: true
    after surfacing the affected commits to the user and getting explicit approval.
    stack_drop
    always passes
    --yes
    (MCP is non-interactive), but its
    force: bool
    param is separate from the confirmation-skip — leave it
    false
    unless the user has approved rewriting merged/base commits.
  • 优先使用只读工具了解状态,再执行写入操作。
  • 除非用户要求非草稿,否则使用
    stack_sync
    时设置
    draft: true
    创建新PR。注意:
    draft: true
    仅影响新创建的PR,不影响现有PR。
  • 绝不要在未获得用户明确批准的情况下调用
    stack_land
  • 解析
    stack_sync
    stack_land
    stack_clean
    stack_lint
    的JSON输出。
  • 如果
    stack_status
    显示
    behind_base > 0
    ,请在同步前运行
    stack_rebase
  • 重写工具(
    stack_squash
    stack_absorb
    stack_reorder
    stack_split
    stack_drop
    stack_rebase
    ,以及CLI命令
    gg unstack
    )在目标提交已合并或已在基础分支上时,会因
    ImmutableTargets
    错误失败。每个工具都接受
    force: bool
    参数,对应
    --force
    /
    --ignore-immutable
    。仅在向用户列出受影响的提交并获得明确批准后,才设置
    force: true
    stack_drop
    始终传递
    --yes
    (MCP为非交互式),但其
    force: bool
    参数与跳过确认是分开的——除非用户已批准重写已合并/基础提交,否则请保持
    false