教程 / 原生 Mac IDE / 完成开发分支
📝 文字 ● 中级 更新于 2026-05-19

完成开发分支 — 合并、PR 或丢弃

"所有测试通过"并不等于完成。只有当差异正是你所期望的、main 分支没有在你之下漂移、且集成路径符合项目约定时,分支才能干净落地。LingCode 执行收尾清单 — 并在正确答案是"丢掉它"时告诉你。

为什么"测试绿了就推"会让分支出问题

0

最简单的收尾流程是:本地测试通过,推送,开 PR,完事。但从测试绿到干净合并,有四件事经常出错:

  • main 已经前进了。你的分支落后了 N 个提交,而其中某个提交与你的修改产生了本地测试无法暴露的冲突。
  • 差异比意图更大。游离的打印语句、注释掉的代码、一个不相关的清理混入了重构。PR 描述与补丁不符。
  • 合并策略与仓库不匹配。只接受 squash 的仓库收到了 12 个提交的功能分支,或者只接受 rebase 的仓库收到了 merge commit。团队在合并时才发现问题。
  • 这段工作根本不该发布。有时正确的答案是"这个方案行不通,保留测试,删掉分支"。一旦 PR 打开、有人评论了,这个决定就更难做了。

本教程中的技能为 LingCode 提供了明确的收尾协议:审查差异、与 main 同步、选择集成路径,以及在工作不值得发布时干净放弃。

你需要什么

1
  • LingCode下载安装包
  • 一个测试通过、待集成的功能分支。
  • 了解仓库的合并约定 — squash、rebase 还是 merge commit。如果你不确定,LingCode 会从 git log main 推断。

对照意图审查差异

2

在做任何其他事情之前,让 LingCode 将分支中的实际内容与分支本应完成的任务进行比对:

Compare the branch diff against the original task. Run:
- git diff main...HEAD
- git log main..HEAD --oneline

For each change, classify:
- IN-SCOPE: matches the stated task.
- DRIVE-BY: small unrelated fix or cleanup.
- ACCIDENTAL: stray prints, commented-out code, dead imports,
  unrelated formatting churn.

Flag anything ACCIDENTAL for removal. Flag DRIVE-BY for a
decision — keep, split into a separate branch, or revert.

意外改动是最容易避免的审查意见。顺手修复的内容则需要判断 — 小的可以随行,真正的重构应该单独开 PR,让下一个看 git log 的人明白为什么。

与 main 同步并重新运行测试

3

本地绿不等于集成后绿。让 LingCode 按仓库惯例将 main 并入分支,然后重新跑完整测试套件:

1. git fetch origin
2. If the repo rebases: git rebase origin/main
   If the repo merges:  git merge origin/main
   (Infer from `git log --merges main | head` — if main has merge
    commits, this repo merges; if it's a flat line, it rebases.)
3. Resolve conflicts. For each conflict, explain in 1-2 lines what
   the conflict is and how you resolved it.
4. Re-run the full test suite — not just the affected file.
如果冲突涉及逻辑而非仅导入或格式,请停下来询问。逻辑冲突是无声 bug 的温床。人眼检查解决后的代码块,比一次重跑后变绿更有价值。

推送前验证收尾清单

4

这是让"我完成了"的声明变得可验证的环节。让 LingCode 执行固定清单,并对每一项报告 PASS/FAIL:

Run the closing checklist. For each item, report PASS / FAIL /
N/A with one-line evidence:

- Tests pass: full suite, post-rebase.
- Linter clean: project's linter, not just LingCode's opinion.
- Type-check clean: tsc / mypy / xcodebuild / etc.
- No console.log / dbg! / print() debug noise.
- No commented-out code.
- No TODO that should have been done in this branch.
- Diff matches the intent — re-run the IN-SCOPE / ACCIDENTAL
  classification on the post-rebase diff.
- Commit messages are imperative ("Add X", "Fix Y"), no WIP,
  no fixup commits.
- If the repo squashes: the PR title will be the merge commit
  message — does it say what changed?

Stop on first FAIL. Don't proceed to merge with anything red.

"遇到第一个 FAIL 就停下"是铁律。忍不住带着警告合并的冲动,正是问题分支落地的方式。

选择集成路径

5

从一个完成的分支出发,有三条合理的路径。请有意识地选择:

  • 开 PR。团队仓库的默认选择。即使是单人项目,PR 视图也是最后一次自审的好界面。使用 gh pr create
  • 直接推送到 main。单人项目、小改动、你已经自审过了。适合拼写修正、文档微调和紧急热修复 — 不适合功能开发。
  • 仅清理 — 不合并。工作为某个决策提供了信息,但代码本身不需要发布。把测试或笔记合入 main,删掉分支。

让 LingCode 根据仓库历史推荐一条路径:

Recommend the integration path. Consider:
- Does main accept direct pushes from this user / role?
- Does the repo require PRs (branch protection)?
- Is this a single-author repo or a team?
- Is the change risky (logic) or trivial (typo)?

Then propose one path with a one-line justification.

创建与差异相符的 PR 描述

6

如果选择 PR 路径,描述应该反映补丁实际做了什么 — 而不是你在分支开始时的计划。让 LingCode 从最终差异起草,而不是从原始任务描述:

Draft the PR body from the post-rebase diff, not from the
original task description. Structure:

## Summary
1-3 bullets of what changed in the codebase, in plain language.

## Why
The user-visible reason or the problem this fixes. One paragraph.

## Test plan
Bulleted checklist of how to verify. Include the exact commands
you ran locally.

## Risk
What could go wrong, if anything? Migration steps? Config flags?
"N/A" if genuinely none.

Title: imperative, under 70 characters, no trailing punctuation.

"Why" 一节是大家最容易跳过、而审阅者最需要的部分。为什么现在做,为什么用这种方案,为什么不用显而易见的替代方案。

"丢弃"路径

7

有时正确的答案就是丢掉这个分支。该技能让 LingCode 识别这些信号,并主动提出,而不是硬推:

Recommend SCRAP if any of these hold:
- The branch tried an approach the codebase clearly resists
  (the diff fights existing abstractions in >3 files).
- A simpler approach became obvious mid-way and the branch
  is now legacy thinking.
- The feature was speculatively built and product changed
  direction.
- Tests pass but the code is structurally bad and rewriting
  is cheaper than refactoring.

If recommending SCRAP, identify what's worth salvaging:
- Any tests written? They probably encode useful behavior.
- Any docstrings or comments capturing decisions?
- Any small utility extractions?

Land the salvage as a tiny PR. Then delete the branch.

带着干净的 salvage PR 丢弃一个分支不是失败 — 这是在不继承其错误的情况下,保留分支所学成果的最低成本方式。

不要悄悄丢弃。如果这个分支来自一个工单,在工单上留下评论:"尝试了这个方案,因为 X 放弃,这是 salvage PR。"未来的你会去找它的。

合并后删除分支

8

分支删除之前,收尾清单都不算完成。让 LingCode 来清理:

After merge:
- git checkout main
- git pull origin main
- git branch -d <branch-name>       # local
- git push origin --delete <branch>  # remote, if not auto-deleted

If `git branch -d` refuses because the branch isn't merged
(common with squash-merge), verify the squashed commit is in
main, then use `-D`. Don't `-D` without verification.

过时的分支,是六个月后"那个实验去哪儿了"这类排查的起点。

在 LingCode 中使用此功能

9

收尾协议被打包成一个技能 — 将它放入你的技能文件夹,在测试通过后让 LingCode "完成这个分支":

---
name: finishing-a-development-branch
description: Use when implementation is complete, all tests pass, and you need to decide how to integrate the work. Triggers: 'tests pass, what now', 'wrap up this branch', 'merge vs PR', 'finish up', 'close this out', 'I'm done coding', 'ship it'. Actions: diff audit (IN-SCOPE/DRIVE-BY/ACCIDENTAL), sync with main, run closing checklist, choose integration path (PR / direct push / scrap), post-merge branch cleanup. Output: clean commit history + clear next step (PR opened, merge done, or branch deleted).
---

Walk a finished feature branch to a clean integration. Green
tests are not done; the branch still needs to land.

1. Audit the diff against intent. Classify each change as
   IN-SCOPE / DRIVE-BY / ACCIDENTAL. Strip ACCIDENTAL.

2. Sync with main. Rebase or merge based on the repo's
   convention (infer from git log). Resolve conflicts and
   re-run the full test suite.

3. Run the closing checklist: tests, lint, type-check, no
   debug noise, no commented-out code, commit messages clean,
   diff matches intent. Stop on first FAIL.

4. Pick an integration path: PR, direct push, or SCRAP. Justify
   in one line based on repo history and risk.

5. If PR: draft the body from the post-rebase diff (not the
   original task). Summary + Why + Test plan + Risk.
   Imperative title under 70 chars.

6. If SCRAP: identify salvage (tests, decisions, utilities),
   land them as a tiny PR, then delete the branch.

7. Post-merge cleanup: pull main, delete local + remote
   branches. Verify squash-merge before -D.

Bail at any step rather than ship a broken branch.

保存为 ~/.lingcode/skills/finishing-a-development-branch/SKILL.md — 查看安装技能了解确切位置及技能的发现机制。

获取 LingCode →

下一步