关于 git-rebase-sync
用于将当前功能分支通过 rebase 同步到最新基础分支的工作流 Skill。它要求重写历史前先确认,并在冲突意图不明确时询问用户。
主要功能
- 01rebase 前创建备份标签
- 02重写历史前要求确认
- 03检测并更新堆叠分支
- 04通过询问处理模糊冲突
- 05rebase 后检查与安全推送
适用场景
- 01从最新基础分支更新功能分支
- 02处理意图不明确的冲突
- 03重设含依赖本地分支的分支
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ alleneubank/ claude-code --skill git-rebase-sync安装后在 Claude Code 中输入/git-rebase-sync确认已加载。
详细介绍
git-rebase-sync
当你需要通过 git rebase 将功能分支同步到最新的 origin/{base_branch} 时,使用此技能;如果冲突意图不明确,还应提出明确的澄清问题。
目标
- 将当前分支变基到指定的基础分支上(通常是仓库的默认分支,如
dev或main)。 - 谨慎解决冲突,不凭空猜测。
- 保留安全措施:备份引用、在执行重写历史的命令前征求确认,并安全推送。
硬性规则
- 不要创建或切换到其他功能分支。除非我明确提出,否则始终操作当前分支。
- 在执行任何重写历史的命令(
git rebase ...、git push --force*)之前,先打印将要运行的准确命令,并等待我确认。 - 开始变基前,创建一个本地备份引用(优先使用附注标签)。除非我明确要求,否则不要推送备份引用。
- 优先使用
git push --force-with-lease,绝不使用普通的--force。 - 如果无法确定正确的冲突解决方式,请停下来提出有针对性的问题。不要臆造产品行为。
工作流
1) 确认基础分支和当前分支
- 确定当前分支:
git branch --show-current
- 确定要变基到的基础分支:
- 如果未提供,则使用 GitHub 默认分支:
gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
- 如果未提供,则使用 GitHub 默认分支:
- 获取最新更新:
git fetch origin
2) 变基前安全检查
- 确认工作区干净,且没有正在进行的操作:
git status
- 如果
git status显示正在进行合并、变基或拣选提交,请停下来询问应如何处理(中止还是继续)。
3) 创建本地备份引用(不要推送)
- 在当前
HEAD创建一个附注标签:git tag -a {branch_name}-rebase-backup-$(date +%Y%m%d-%H%M%S) -m "pre-rebase backup" HEAD
- 将标签名记录为
{backup_ref},以便恢复。
4) 选择变基模式(普通模式或保留合并提交)
- 检查分支是否包含合并提交:
git rev-list --count --merges origin/{base_branch}..HEAD
- 如果存在合并提交,请询问是否保留这些提交(
--rebase-merges)或将其压平(普通变基)。
5) 检测堆叠分支(它们是否会跟随变基?)
其他本地分支可能指向待重写范围(origin/{base_branch}..HEAD)中的中间提交;分阶段的 NN-description 分支堆栈就是常见情况。普通变基会重写这些提交,并使堆叠分支孤立在旧的、变基前的提交上(以及基于这些分支创建的所有未关闭 PR)。--update-refs(步骤 6 中的默认选项)会将它们移至重写后的提交上。请列出这些分支,以便报告变基会一并处理哪些分支:
# Branches pointing into the range being rewritten — these get orphaned by a
# plain rebase and require --update-refs to follow the rewrite.
cur=$(git branch --show-current)
git for-each-ref --format='%(refname:short)' refs/heads | while read -r br; do
[ "$br" = "$cur" ] && continue
if git merge-base --is-ancestor "$br" HEAD \
&& ! git merge-base --is-ancestor "$br" origin/{base_branch}; then
echo "stacked: $br ($(git rev-parse --short "$br"))"
fi
done
- 变基前,向我报告检测到的堆叠分支。
- 在其他工作树中已检出的分支不会被
--update-refs处理(Git 不会移动已检出的分支);请标记这些分支,以便我在变基后手动核查。
6) 执行变基(需要确认)
- 默认使用
--update-refs,使任何指向待重写范围内提交的堆叠分支跟随重写,而不是变得孤立。 - 打印准备运行的准确命令,然后等待确认:
- 默认:
git rebase --update-refs origin/{base_branch}
- 保留合并提交时:
git rebase --rebase-merges --update-refs origin/{base_branch}
- 默认:
- 若要将其设为永久默认值,以后无需指定该标志:
git config --global rebase.updateRefs true。
7) 冲突处理循环
发生冲突时:
- 收集上下文:
git status- 从状态输出中识别冲突文件。
- 对每个冲突文件:
- 打开文件,理解周围的代码及其意图。
- 优先采用最小化、机械式的冲突解决方式:
- 除非功能分支有意取代上游更改,否则保留上游更改。
- 适当情况下,重新运行生成器(锁文件、代码生成),而不是手动编辑。
- 如果意图不明确,提出一个有针对性的问题,例如:
- “应该保留新的上游行为 X,还是保留功能行为 Y?”
- “此文件是生成文件,可以安全地重新生成,还是需要手动解决?”
- 应用解决方案,然后仅暂存已解决的文件:
git add <file...>
- 继续:
git rebase --continue
- 如果继续解决的风险过高或情况不明确:
- 停下来询问;也可以建议中止 rebase。
冲突期间可用的命令:
- 检查当前冲突块:
git diff - 查看正在重放的提交:
git show - 如需回退:
git rebase --abort(此操作安全,且应优先于破坏性重置)
8) Rebase 后验证
- 显示新的提交范围:
git log --oneline --decorate origin/{base_branch}..HEAD
- 确认第 5 步中的每个堆叠分支都已移至重写后的提交范围。
git rebase --update-refs会输出“Updated the following refs with --update-refs”摘要;已移动的分支引用也应作为装饰标记出现在上述日志中的新提交上。记录任何未移动的分支(例如在另一个工作树中已检出的分支),以便手动处理。 - 如果有可用的适当仓库检查(测试、类型检查、lint),请运行。
9) 推送已更新的分支(需要确认)
- 如果该分支已存在于 origin,rebase 会重写历史,因此推送时需要使用 force-with-lease。
--update-refs只会移动本地引用。普通的git push只会更新当前分支;每个同样存在于 origin 上的堆叠分支(来自第 5 步)都必须单独强制推送。- 打印确切的命令,并等待确认:
- 当前分支:
git push --force-with-lease origin HEAD:{branch_name}
- 每个存在于 origin 上的已移动堆叠分支(每个分支重复执行):
git push --force-with-lease origin {stacked_branch}
- 当前分支:
- 因在另一个工作树中已检出而跳过的分支并未移动——推送前请先核实。
恢复
- 如果出现问题,使用
{backup_ref}恢复 rebase 前的状态。 - 除非我在你展示确切命令后明确确认,否则不要运行破坏性命令(例如
git reset --hard)。
评论
支持 Markdown