chadtmiller.com/knotless
git that lives in your Atmosphere account
A pull's branch updates from its base, keeping lines both sides added
MergedThis adds knotless update-branch and the MCP update_branch tool. They merge an open pull's base into its branch with no checkout and push the result unforced. A conflict where both sides only added lines at the same place is resolved with the base's lines first. Any other conflict is refused, with its paths named.
I found nothing that must change.
- Conservative resolution:
resolveaccepts a conflict only when the common-ancestor section is empty.- Files holding a 32-character marker line are refused by
marked. - Binary files, deleted sides, differing modes, add/add with no ancestor, and a
merge-fileresult with no conflicts all fall to the author.
- Permissions and race safety: only the owner and collaborators may run it, only on an open pull whose branch is in the same repository, and the unforced push fails if the branch moved since it was read.
- Docs and changeset: the
AGENTS.mdrequirements are met. There is a changeset, and thecli.md,mcp.mdandcollaboration.mdpages are updated. - Tests: unit, CLI (
forge.rs) and MCP tests cover the main paths and the refusals. - CI:
checkhas passed.testande2ewere still running or queued when I looked, so I can't confirm the coverage gate or the tests pass.
The only change since my last review is in the tests. Two test inputs now end their last line with a newline, and the mode-change test checks out with -f. There is no production code change, and nothing I found earlier needs revisiting. My earlier approval stands. The check and test runs on this head were still running or queued when I looked, so I can't confirm they pass.
The only change since my last review is in the forge.rs test. It now reads the merge commit's subject and parents with separate git log calls, instead of one string split on |. That's a more robust assertion. There is no production code change, so my earlier approval stands. I didn't check CI on this head.
The only change since my last review is in cli.rs. The "both sides only added lines" message is now built with format! and then written, instead of being written as a multi-line writeln!. The output text is the same. The commit says this is so coverage counts the line. My earlier approval stands. The check run on this head was still running and test was queued when I looked, so I can't confirm either passes.
8 passed, 2 skipped
What changes
knotless update-branch <url> <pull>and the MCPupdate_branchtool bring an open pull's branch up to date with the branch it merges into, as GitHub's Update branch button does. A merge commit of the base's tip into the branch is built in the target's mirror, with no checkout, and pushed to the branch, not forced. The owner and collaborators may, for a pull whose branch is in the repository itself.Lines both sides only added are merged. Where every conflict in a file is lines both sides added at the same place, with nothing of the common ancestor's between them, the base's lines are kept first and the pull's after, and the merge commit names the file. Any other conflict is refused, naming its paths: both sides changing a line, a file deleted on one side, a binary file, or modes that differ. git's own conflicts are read through
git merge-file --diff3with 32-character markers, and a file holding such a line is left to the author.Why
This is the first part of the keeper asked for in Queued pulls stall until their own author notices and moves them. Of the 268 queue ejections from 10-22 to 11-02, 62 were conflicts, and 58% of those pulls were ejected again after being queued once more. The files they conflicted in most were
docs/design/serve.mdanddocs/reference/api.md, where pulls add sections side by side. git calls two additions at one place a conflict, but neither side's lines are in doubt, so this resolves them with no model, and the keeper can call it for ejected pulls next. A plain union merge was ruled out: it would also "resolve" changed lines by keeping both.How it was checked
Unit tests merge in a scratch repository: a clean merge, two sections added at one place (base's first), and the kinds left to the author (changed lines, delete against change, binary, a file holding a marker's line, modes that differ), named together while a resolvable file beside them is not.
forge.rsdrives the CLI over the reference PDS: a branch holding its base already, additions merged with two parents and the base's lines first, a stranger refused, and changed lines refused with nothing pushed.mcp.rscovers the tool, and refuses a fork's branch and a merged pull. Builds and tests are left to CI. Another build was running on this machine.Shortcomings
Two additions at one place merge as text, so order or meaning may still be wrong, such as two rows in a sorted table. The pull's checks run on the new head and the batch checks it again. A fork's branch is not updated. Nothing calls this on its own yet: the keeper that does comes next.