mcpField
S
stack-rebase

stack-rebase

github.com/athola开发34376 次安装1 天前更新
代码仓库

关于 stack-rebase

stack-rebase 是用于已发布 Git 分支栈的技能,帮助开发者在基准分支或栈内提交变化后级联变基。它还指导冲突处理、分支推送及相关 PR 基准更新。

主要功能

  1. 01识别变基触发原因
  2. 02使用 --update-refs 级联变基
  3. 03处理或中止冲突变基
  4. 04使用 --force-with-lease 推送分支
  5. 05更新并核验 PR 基准

适用场景

  1. 01栈中首个 PR 合并到 master 后调整后续分支
  2. 02master 前进后让分支栈纳入新提交
  3. 03中间切片修改后更新其后续分支

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/athola/claude-night-market --skill stack-rebase

安装后在 Claude Code 中输入/stack-rebase确认已加载。

详细介绍

Stack Rebase

在基础 PR 合并或上游基础分支发生变化后,级联 rebase 整个 PR 堆栈。

适用场景

在以下任一情况下运行 stack-rebase:

  • 堆栈中的第一个 PR 已合并到 master;第二个 PR 现在需要直接以 master 为目标分支
  • master 已前进,堆栈分支需要纳入新提交
  • 堆栈中间的 PR 已修订,后续分支需要获取这些更改

不适用场景

  • 堆栈从未发布过(使用 sanctum:stack-push)
  • 堆栈尚不存在(使用 sanctum:stack-create)

前置条件

  • 所有切片分支都在本地存在(git branch --list)
  • 远程状态为最新(git fetch origin)
  • 工作区干净(git status)
  • Git 2.38+,以支持 --update-refs

必需的进度跟踪

开始前创建以下进度项:

  1. stack-rebase:fetch-complete
  2. stack-rebase:trigger-identified
  3. stack-rebase:rebase-complete
  4. stack-rebase:conflicts-resolved
  5. stack-rebase:force-pushed
  6. stack-rebase:prs-updated

步骤 1:获取远程状态(fetch-complete)

git fetch origin

如果已合并的 PR 分支仍存在于远程,请注意 GitHub 会在合并后保留该分支。 已合并的分支本身不再是有效的堆栈基础。

步骤 2:确定触发原因(trigger-identified)

确定发生了什么变化:

情况 A,基础 PR 已合并到 master: 原本作为“根”的切片现在已进入 master。 所有剩余切片都需要 rebase 到 master 上。

# Confirm the merged branch is now in master
git branch -r --merged origin/master | grep "${MERGED_BRANCH}"

情况 B,master 已前进: 切片落后于 master,但堆栈拓扑结构未变。 将根切片 rebase 到 master 上;--update-refs 会连带更新所有后续分支。

情况 C,堆栈中间的分支已修订: 某个切片已修改。 所有后续切片都需要 rebase 到该切片上。

步骤 3:运行级联 rebase(rebase-complete)

情况 A 和 B:将根切片 rebase 到 master 上
STACK=stack/my-feature
BASE=master

# Check out the root slice
ROOT_SLICE=$(git branch --list "${STACK}/*" \
  | sed 's/^[* ]*//' | sort | head -1)

git checkout "${ROOT_SLICE}"

# Rebase with --update-refs rewrites all stack branches
git rebase --update-refs origin/${BASE}

--update-refs 会扫描 reflog,并更新所有指向正在 rebase 的提交的本地分支引用。 堆栈中的所有切片分支都会在一次操作中重写。

情况 C:从堆栈中间的切片开始 rebase
# Check out the first slice BELOW the amended one
CHILD_SLICE=stack/my-feature/add-api  # example

git checkout "${CHILD_SLICE}"
git rebase --update-refs stack/my-feature/add-schema
jj 加速方式(如果可用)
# jj rebases all descendants automatically on any change
# To rebase the whole stack onto master:
jj rebase -d master \
  -r "ancestors(${STACK}/add-ui) & !ancestors(master)"

步骤 4:解决冲突(conflicts-resolved)

如果 rebase 因冲突而暂停:

# See which file conflicts
git status

# After resolving each file:
git add <resolved-file>
git rebase --continue

重复上述操作,直到 rebase 完成。 如果冲突过于复杂,请中止并进行调查:

git rebase --abort

然后检查冲突提交之间的差异,再重试。

步骤 5:强制推送更新后的分支(force-pushed)

成功 rebase 后,推送所有切片分支。 使用 --force-with-lease,以防护上次获取后远程发生的更改:

for branch in $(git branch --list "${STACK}/*" \
    | sed 's/^[* ]*//' | sort); do
  git push --force-with-lease origin "${branch}"
  echo "force-pushed: ${branch}"
done

切勿使用 --force(它会取消远程更改防护)。

jj 加速方式(如果可用)
jj git push --all --allow-new

步骤 6:更新 PR 基础分支(prs-updated)

仅适用于情况 A:根切片合并后,如果你将剩余切片 rebase 到 master 上,堆栈中的下一个 PR 现在会指向错误的基础分支。 使用 GitHub CLI 更新其基础分支:

NEXT_PR=456   # PR number of the new stack root

gh pr edit "${NEXT_PR}" --base master

对于堆栈中更靠后的 PR,其基础分支仍是前一个切片分支;--update-refs 已重写该分支,因此无需修改基础分支。

验证整个堆栈是否一致:

for branch in $(git branch --list "${STACK}/*" \
    | sed 's/^[* ]*//' | sort); do
  pr_num=$(gh pr list --head "${branch}" \
    --json number,baseRefName \
    --jq '.[0] | "#\(.number) base=\(.baseRefName)"')
  echo "${branch}: ${pr_num}"
done

防止冲突的技巧

  • 保持切片较小:每个 PR 越小,rebase 时发生冲突的范围就越小
  • 经常 rebase:每天 rebase 到刚合并的 master 上,比解决一周积累的偏差更省事
  • 避免修改已进入评审的提交;优先使用 fixup 提交,并在合并时压缩提交

备注

  • git rebase --update-refs 需要 Git 2.38+;运行前使用 git version 确认
  • 如果无法使用 --update-refs,请按从根到顶端的顺序,手动检出并 rebase 每个切片分支
  • 强制推送后,GitHub 会自动将 PR 评审标记为过期;请提醒评审者重新批准
  • stack-push 技能说明了如何在 rebase 更改 PR SHA 后重新发布堆栈摘要评论

退出标准

  • 在 rebase 开始前创建全部 6 个进度项(从 stack-rebase:fetch-complete 到 stack-rebase:prs-updated),并按顺序标记为已完成
  • 在确定并归类 rebase 触发条件为 Case A、B 或 C 之前, git fetch origin 已完成
  • 对于 Case A 和 B,git rebase --update-refs 完成且未中止;如果发生冲突, 继续操作前先逐一解决冲突
  • 使用 --force-with-lease 强制推送所有切片分支;绝不使用普通的 --force
  • 仅对于 Case A:使用 gh pr edit <next-pr> --base master 更新 新堆栈根分支的目标基准,并通过 gh pr list 的输出验证完整堆栈拓扑

评论

支持 Markdown