Repository navigation
Check the patch series without git, at git apply's strictness - #982
Conversation
`check` could only run where git exists, so on the machine the Bots work on the two shapes that broke the series — #934's extra blank context line and #966's hunk header running to 662 in a 661-line file — waited for CI's `package` job, a review cycle later. `scripts/ds-bot-patches.mjs` now carries its own applier, used by `build()` and `diffReproduces()` only when git is absent: a hunk body must carry the counts its header declares, every hunk must match at the old-side line its header names (no search for nearby context), no hunk may run past the end of the file, and `\ No newline at end of file` is honoured on both sides. Tracked files come from a walk with the root .gitignore rules, and the pin prints `skipped pin (no git)` instead of passing silently. A machine with git keeps the git path: CI is the reference, and a test builds the series both ways and compares the trees byte for byte. `generate` still needs git, because it asks git for the diff. Fixes #978
|
Verdict: PASS at 3866461 No What it does. With git absent, This machine has no Ran (this review, on 3866461): Two non-blocking notes, neither worth a new tip:
|
Written-by: Dev4
Owner: Dev4
Reviewer: Reviewer
Fixes #978
Tip SHA: 3866461
Base: 90ff273
Reproduce
On a machine without
git(this one),node scripts/ds-bot-patches.mjs checkdies inspawnSync git ENOENTbefore it looks at a patch:tracked(),build(),checkPin()anddiffReproduces()all go throughgit. So the two shapes that cost a review cycle each were only caught by CI'spackagejob —#934(a patch with an extra blank line as trailing context) and#966(a hunk header running to 662 in a 661-line file, which the hand-rolled "search for the context" applier happily placed 4 lines earlier).What changed
scripts/ds-bot-patches.mjs:applyPatchText(), a git-free applier used bybuild()anddiffReproduces()only whengitis absent. It holds git apply's rules: a hunk body carries exactly the counts its header declares; every hunk matches at the old-side line the header names (no search nearby); no hunk runs past the end of the file on either side;\ No newline at end of fileis honoured on both sides and a missing final newline survives;-p1strip, whole-file create/delete andnew file modebehave as withgit apply.tracked()falls back to a walk with the root.gitignorerules (a symlink to an ignored directory counts as that directory, as it does to git).checkPin()printsskipped pin (no git): the tree hash cannot be computed hereand continues;generaterefuses without git in one line, because it asks git for the diff..github/scripts/ds-bot-patches.test.mjs: five git-free cases — the#966shape, the#934shape, a hunk whose context only matches elsewhere (must fail at the declared line, not move),\ No newlineon both sides plus a false marker, and-p1/create/delete/mode. Plus one case, registered only where git exists, that builds the whole series with both appliers and compares every file byte for byte and its mode. The four existing format cases ask git for a diff, so they are now registered underif (gitAvailable): CI still runs them, and a git-free machine no longer dies on them before reaching the new cases.patches/ds-bot/README.mdanddocs/subsystems/ds-bot-core.md: the rules the validator now enforces, and what a git-free run does and does not claim.No
core/file changes, sopatches/ds-bot/*cannot move; the series is the one main has.What I ran
node scripts/ds-bot-patches.mjs check(no git here) →skipped pin (no git): the tree hash cannot be computed here,ok 10 patches apply cleanly in order,ok core/ equals ds-bot/ + patches/ds-bot/.node scripts/ds-bot-patches.mjs apply(no git here) →core/rebuilt from the series, every one of its 360 files identical to the committed bytes.node --test .github/scripts/ds-bot-patches.test.mjs→ 5/5 here; the git-only cases are registered and run on CI'spackagejob (test.yml:113).0003last hunk@@ -658,4 +658,14 @@→-659,4:src/client/sidebar.js hunk 15 (@@ -659,4 +659,14 @@): runs past the end of the file (661 lines).src/client/sidebar.js hunk 15 (@@ -658,4 +658,14 @@): the body has 5 old and 15 new line(s), the header declares 4 and 14.oklines again.#966shape); deleting the count rule → exactly one red (the#934shape); restored → 5/5.node .github/scripts/changelog.mjs check→ 62 fragments well formed;oxlinton both JS files → 0 warnings, 0 errors.Red without the source change
Pristine
90ff273don this machine:node scripts/ds-bot-patches.mjs check→Error: spawnSync git ENOENT, before it reads a patch. With the change the same command reads the series and prints the twooklines. The new cases cannot even import on pristine sources (noapplyPatchTextexport).Not run
npm run verify: itsarch-docsandgeneratesteps needgit, which this machine does not have (github.com:443does not resolve either). CI'stestandpackagejobs judge those. The owned pagedocs/subsystems/ds-bot-core.mdis updated in this PR, so noDocs-not-needed:trailer is needed.Risk
The one way to make this worse is the git-free applier accepting what git refuses (or the reverse), so a broken series looks fine locally and red on CI — the agreement case exists for exactly that and runs where git exists. The other is the git-free
tracked()walk: it lists what is on disk minus.gitignore, where CI'sgit ls-filesreads the index. A stray untracked, non-ignored file undercore/is then reported as "produced by the patches but not committed": loud, and never a false pass.generatedeliberately has no git-free path — writing diffs is git's job and the issue asks for the validator; that is the one command this does not bring to a git-free machine.