Skip to content

integration: Move regeneration out of merge driver#1252

Open
ed-irl wants to merge 5 commits into
ed-irl/integration-auto-resolvefrom
ed-irl/integration-regenerate
Open

integration: Move regeneration out of merge driver#1252
ed-irl wants to merge 5 commits into
ed-irl/integration-auto-resolvefrom
ed-irl/integration-regenerate

Conversation

@ed-irl

@ed-irl ed-irl commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

integration: Move regeneration out of merge driver

The regenerate merge driver previously ran generators (mise generate,
go test -update) from inside git's merge process. Those generators
side-effect on many files in one pass, and git aborts subsequent merge
steps with 'your local changes would be overwritten' when it sees a
worktree dirtied by an earlier driver invocation. The existing
stage_outputs workaround called git add from inside the driver to
stage the side effects, but git holds the index lock for the duration
of the merge — git add silently failed with rc=128 every time.

This commit moves regeneration out of the merge driver entirely:

  • The driver becomes take-incoming + log: cp the incoming version
    into place, append the path to the file named by
    $GS_INTEGRATION_REGEN_LOG. No side effects.

  • gs runs all tip merges with that env var pointing at a per-merge
    temp file, accumulates the deduplicated path list across the
    rebuild, and invokes .gs/integration-regenerate (a project-level
    executable at the repo root) with the list on stdin. The script
    chooses what to regenerate based on which categories of files
    appear in its input — so a rebuild with no derived conflicts
    pays one process spawn and exits.

  • Whatever the script wrote to the worktree gets folded into the
    last merge commit via git add -A && git commit --amend --no-edit
    --allow-empty.

The contract is well-orthogonalized: gs hands the script an
allow-listed list of paths (only files tagged merge=regenerate in
.gitattributes can appear there), the script returns by writing to
the worktree, gs takes care of the commit-amend wrap-up. Project
generator knowledge stays in the project's script; gs doesn't carry
a dispatch table.

integration regenerate: Regenerate CLI reference

@ed-irl

ed-irl commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator Author

@ed-irl ed-irl force-pushed the ed-irl/integration-auto-resolve branch from 2744c7a to b0ecc92 Compare June 13, 2026 13:40
@ed-irl ed-irl force-pushed the ed-irl/integration-regenerate branch from fa21086 to 95531f4 Compare June 13, 2026 13:40
@ed-irl ed-irl force-pushed the ed-irl/integration-auto-resolve branch from b0ecc92 to af57956 Compare June 15, 2026 09:53
@ed-irl ed-irl force-pushed the ed-irl/integration-regenerate branch from 95531f4 to 682c26c Compare June 15, 2026 09:53
ed-irl and others added 4 commits June 23, 2026 11:43
The regenerate merge driver previously ran generators (mise generate,
go test -update) from inside git's merge process. Those generators
side-effect on many files in one pass, and git aborts subsequent merge
steps with 'your local changes would be overwritten' when it sees a
worktree dirtied by an earlier driver invocation. The existing
stage_outputs workaround called git add from inside the driver to
stage the side effects, but git holds the index lock for the duration
of the merge — git add silently failed with rc=128 every time.

This commit moves regeneration out of the merge driver entirely:

  - The driver becomes take-incoming + log: cp the incoming version
    into place, append the path to the file named by
    $GS_INTEGRATION_REGEN_LOG. No side effects.

  - gs runs all tip merges with that env var pointing at a per-merge
    temp file, accumulates the deduplicated path list across the
    rebuild, and invokes .gs/integration-regenerate (a project-level
    executable at the repo root) with the list on stdin. The script
    chooses what to regenerate based on which categories of files
    appear in its input — so a rebuild with no derived conflicts
    pays one process spawn and exits.

  - Whatever the script wrote to the worktree gets folded into the
    last merge commit via git add -A && git commit --amend --no-edit
    --allow-empty.

The contract is well-orthogonalized: gs hands the script an
allow-listed list of paths (only files tagged merge=regenerate in
.gitattributes can appear there), the script returns by writing to
the worktree, gs takes care of the commit-amend wrap-up. Project
generator knowledge stays in the project's script; gs doesn't carry
a dispatch table.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant