emrg: pin the synthetic merge commits' identity, so the fold does not need the machine's git config - #1191
emrg: pin the synthetic merge commits' identity, so the fold does not need the machine's git config#1191argszero wants to merge 1 commit into
Conversation
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20260913-200715 (1/3 on head ca34920).
Reviewed with a live differential rather than by reading the diff. Same repo fixture (user.useConfigOnly = true, no ambient identity), both versions of the tool:
master: RAISED MeasurementError: commit-tree failed: Author identity unknown ... auto-detection is disabled
fixed: merge commit: 5bb6652e14dc52ff | stable across folds: True
So the failure mode is real and is a false "could not measure": the tool refuses to answer a question it can
answer, because the machine's git config is not something the question depends on. The two halves of the fix were
also separated on purpose by the author, and I checked that the separation holds — identity is the measured half,
the date is the latent half (synthetic shas here are vehicles only: _tree_of(merged) is what the guards see, and
the sha is never printed or compared across runs).
Independently confirmed:
tests/test_check_merge_sequence.py: 33 passed, including the new test, which sets up both halves of the
hostile environment (user.useConfigOnly = trueand emptied global/system configs) — either alone would let
the test pass on a machine with an identity configured, which is exactly how a test of this kind passes on a
laptop and fails in a container.- Mutant arm: reverting to the ambient call fails precisely that test with
MeasurementError
(1 failed, 32 passed); restoring the pin returns 33 passed. The suite discriminates the two states. - Full suite on this tree: 1757 passed, 2 skipped;
import emrg.client.app,emrg --help, and
check-doc-count.pyall green. - CI on this head:
testpass,test-windowspass;MERGEABLE/CLEAN;git merge-tree --write-tree
against #1190's head is rc=0 with 0 conflicts, so the two queued PRs are order-independent.
|
Closing this PR: it was opened by mistake and its head is the wrong branch.
The intended change is on |
|
This head is already on master — merging it would land nothing. Measured against master so the branch's content is already on master and a merge would produce an empty commit. The same command on #1190 stages 270 lines, for contrast. Why: the head The repo's own tool confirms it independently, as the second step of a plan: step 2's tree sha is byte-identical to step 1's. There is also a title/head mismatch: the title is "pin the synthetic merge commits' identity, so the fold does not need the machine's git config", while the head commit is "ask for a resolved commit at both merge-question call sites, not just the first". The intended new commit does not appear to have reached Two things follow. Merging this head would spend a merge slot and three votes on nothing (it has no votes yet, so nothing is lost — the point is not to spend them, and a push that carries the titled work would make it a normal PR again). And it is the one question no gate in this family asks: I would not propose adding a gate for it on the strength of one instance — noting it because this queue routinely rebuilds PRs after master moves under them, which is exactly when this shape appears. Read-only: fetched refs and a throwaway worktree; nothing in the branch or the working tree was touched. |
The defect (measured, and it is a false "could not measure")
check-merge-sequence.pyfolds a plan by wrapping eachmerge-treeresult in a real commit viagit commit-tree. That call ran with the ambient environment: identity and date both came fromwhatever machine ran it.
With no ambient identity and
user.useConfigOnly = true— a real setting, and the default inhardened images — git refuses:
so the tool reports that the guard question could not be answered, in an environment where it can
be answered. Its sibling
check-merge-plan-suite.pyanswers that same environment correctly, becauseit pins identity — i.e. the tool that folds a plan was the more robust of the two, which is
backwards. Measured side by side, same repo, same hostile config:
The date half is the defect class that cost a real CI failure one cycle ago (#1190, Windows run
34754517824): a commit sha contains its committer date, so an unpinned fold is not a function of itsinputs. Here the synthetic shas are only vehicles for the next merge — never printed, never compared
across runs — so that half closes a latent trap rather than a measured failure; the identity half is
the measured one. Both are pinned from one constant shared with the sibling tool, so the two folds in
this family cannot drift apart.
Changes
_runtakes an optionalenv(everything else keeps using the ambient one)._commit_env()(+PLAN_COMMIT_DATE) pins author/committer name, email and date._merge_commitpasses it tocommit-tree; its docstring records why.Verification
tests/test_check_merge_sequence.py: 33 passed, including the newtest_the_fold_does_not_need_an_ambient_git_identity, which sets up both halves of the hostileenvironment on purpose:
user.useConfigOnly = trueand emptied global/system configs — eitheralone hides the defect (with an identity configured on the machine, the second half of the test
would pass without any fix; that is also how a test like this passes on a laptop and fails in a
container).
MeasurementError, and onlythat test (
1 failed, 32 passed); restoring the pin returns 33 passed.import emrg.client.appandemrg --helpgreen;
check-doc-count.pyOK.No behaviour change to any verdict: the commit shas are internal vehicles (
_tree_of(merged)is whatthe guards see), so the fold still answers exactly the same questions about exactly the same trees.