SuperAPI AI 工具集

upstream-patches

编程与开发

查看项目

更新于 10-15 14:22

技能介绍

用途

upstream-patches 用于管理 Terraform provider 子模块的补丁。其中 upstream/ 是一个指向上游 Terraform provider 的 git 子模块,patches/ 目录包含应用在其上的补丁文件。通过 ./scripts/upstream.sh 脚本可以管理补丁状态,适用于 upgrade-provider 流程或手动补丁维护工作。

默认行为

如果修复的是由现有补丁引入的回归问题,应修改拥有该补丁的提交(amend),而不是新建补丁。除非用户明确要求,否则不要创建新补丁。

命令参考

  • ./scripts/upstream.sh init:初始化 upstream 并将补丁应用到工作目录。
  • ./scripts/upstream.sh init -f:破坏性地丢弃 checkout/rebase 状态并重新初始化 upstream。
  • ./scripts/upstream.sh checkout:创建分支,将补丁作为提交以便编辑。
  • ./scripts/upstream.sh rebase -i:交互式编辑补丁提交。
  • ./scripts/upstream.sh rebase -o <commit>:将补丁变基到新的上游提交。
  • ./scripts/upstream.sh check_in:将提交写回补丁并退出 checkout 模式。

护栏

  • 未经 checkout/check_in,切勿直接提交到 upstream/。
  • 在 checkout 之外直接编辑 upstream/ 下的内容在 upgrade-provider 期间是临时的,工具会重置子模块状态。
  • 除非有意进行原始补丁手术,否则不要手动编辑 patches/*.patch。
  • 对于智能体,优先使用非交互式重写流程,而非交互式 rebase。

先找到拥有补丁

在编辑补丁内容之前,先确定拥有该补丁的 patch/commit。

./scripts/upstream.sh checkout

# 按触及的文件路径或唯一 hunk 文本查找候选补丁文件
rg -n "path/to/file|unique_symbol" patches/*.patch

# 可选:检查候选补丁的头部/hunk
sed -n '1,120p' patches/00NN-Example.patch

# 将补丁文件映射到 upstream checkout 分支中的提交
patch=patches/00NN-Example.patch
subject=$(sed -n 's/^Subject: \[PATCH\] //p' "$patch" | head -n1)
cd upstream
git log --oneline pulumi/patch-checkout --grep "$subject"

# 如需要,按触及路径消歧
git log --oneline pulumi/patch-checkout -- path/to/file
cd ..

如果 rg 不可用,使用 grep -En 进行补丁搜索。将 target_sha 设为拥有该补丁的提交,并编辑该提交,而不是 HEAD。

修改现有补丁(首选,非交互式)

./scripts/upstream.sh checkout
cd upstream

target_sha=<owning-commit-sha>
base_sha=$(git rev-parse "${target_sha}^")
tmp_branch="rewrite-${target_sha:0:8}"

# 从目标提交的父提交重建历史
git checkout -b "$tmp_branch" "$base_sha"
git cherry-pick "$target_sha"

# 应用修复并修改目标提交
# ...编辑文件...
git add <files>
git commit --amend --no-edit

# 重放剩余提交
git cherry-pick "${target_sha}..pulumi/patch-checkout"

# 如果 cherry-pick 出现冲突:
#   解决文件
#   git add <resolved files>
#   git cherry-pick --continue

# 将 checkout 分支移动到重写后的历史
git branch -f pulumi/patch-checkout HEAD
git checkout pulumi/patch-checkout
git branch -D "$tmp_branch"
cd ..

交互式回退方案:

./scripts/upstream.sh checkout
./scripts/upstream.sh rebase -i
# 将目标提交标记为 edit,修改后继续

删除整个补丁

当补丁应被完全删除时使用。

rm patches/00NN-Description.patch
./scripts/upstream.sh checkout
./scripts/upstream.sh check_in

删除补丁的一部分

当只应从现有补丁中删除选定的 hunk/文件时使用。

找到拥有该补丁的 patch/commit(target_sha),使用上述修改工作流。仅从目标提交中还原不需要的更改,然后修改。

修改步骤中的示例:

cd upstream
# 从被修改提交的父提交恢复特定的仅文档文件
git checkout HEAD^ -- path/to/docs-only-file path/to/another-doc-file
git add path/to/docs-only-file path/to/another-doc-file
git commit --amend --no-edit
cd ..

创建新补丁(仅在要求时)

./scripts/upstream.sh checkout
cd upstream
# ...进行更改...
git add <files>
git commit -m "Describe new patch"
cd ..
./scripts/upstream.sh check_in

将补丁变基到新的上游版本

./scripts/upstream.sh checkout

# 变基到新的上游提交
./scripts/upstream.sh rebase -o <new_commit_sha>
# 解决出现的任何冲突

# 写回更新后的补丁文件
./scripts/upstream.sh check_in

验证清单

check_in 之前:

  • 确认预期的补丁数量变化(默认 0;完全删除补丁时为 -1)。
  • 确认目标补丁应保留(默认是)还是被删除(显式删除场景)。
  • 确认你正在编辑拥有该补丁的提交,而不是意外添加新提交。

check_in 之后:

  • 验证补丁数量符合预期。
  • 在预期保留时,验证目标补丁编号/用途仍然存在。
  • 验证没有引入意外的新的 00NN-*.patch。

中断的 Checkout 或 Rebase

默认保留工作成果。检查 git -C upstream status,完成正在进行的 git am/rebase,验证每个补丁都已应用,并在重新运行自动化之前运行 ./scripts/upstream.sh check_in。中断的 checkout 会为每个补丁单独调用 git am,因此后续补丁文件可能尚未被处理。

仅当有意丢弃所有中断的工作时,才使用 ./scripts/upstream.sh init -f。它可能移除冲突解决、补丁提交、操作元数据和未跟踪文件;它不是卡住的 checkout 的常规恢复手段。