Repository navigation
fix(copier-update): take the new template version for a conflicted file the project never edited (AI-CLI-sds5) - #420
Merged
sergeiwallace merged 3 commits intoOct 22, 2026
Conversation
…le the project never edited (AI-CLI-sds5) Copier renders the old copy of a template with the new template's _exclude rules. When a new rule excludes a file behind a question the old template never declared, the old copy lacks that file, Copier reads the update as a file addition, and it conflicts with the identical file already in the project. A scheduled run then reports a conflict for a file nobody edited. After a conflicted update, render the previous and the current template versions with the project's recorded answers. A conflicted file whose committed bytes equal the previous render was never edited, so it takes the new render. A file that differs by even one byte stays a conflict. The backup anchor is taken before any file is written, each resolved path is printed, and the resolved path is left as an ordinary unstaged change so the parity check sees it. If either render fails, or the anchor cannot be taken, nothing is written. Test-edit-reason: the recovery tests' Copier double answered every invocation as an update; it now answers only "update" and fails a render, which is the condition those tests assume (conflicts stay). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y23LPSiKBWEaNYrtaqUn7W Provenance-schema: aih-commit/v2 Provenance-tool: aih-commit/0.1.0 Authoring-session: ai-cli-mac-1 Authoring-machine: machine-a55de1a7d9c6e9a8 Authoring-class: ai Authoring-family: claude Authoring-model: Sonnet Authoring-effort: medium Authoring-profile: interactive Authoring-run-id: claude-run:4f57d1268b6334762f885771212fc582 Delegated-to: none
…LF renders match (AI-CLI-sds5) The previous commit compared a conflicted file's committed bytes with the previous template render. On Windows Copier writes the render with CRLF line endings while Git stores the committed file with LF, so an unedited file never matched and stayed a conflict (three tests failed on the Windows runner). Compare the way Git stores the content: the committed blob id against the id Git computes for the rendered copy at the same path, which applies the same line-ending conversion. A new test renders a CRLF template into a project that normalises line endings and reproduces the failure on any platform. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y23LPSiKBWEaNYrtaqUn7W Provenance-schema: aih-commit/v2 Provenance-tool: aih-commit/0.1.0 Authoring-session: ai-cli-mac-1 Authoring-machine: machine-a55de1a7d9c6e9a8 Authoring-class: ai Authoring-family: claude Authoring-model: Sonnet Authoring-effort: medium Authoring-profile: interactive Authoring-run-id: claude-run:4f57d1268b6334762f885771212fc582 Delegated-to: none
…i-sds5-unchanged-conflicts
sergeiwallace
deleted the
wt/ai-cli-mac-1/ai-cli-sds5-unchanged-conflicts
branch
October 22, 2026 10:10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A scheduled
ai copier-updateconflicted on files that no project had edited. This takes the new template version for exactly those files and leaves every real conflict alone.Why
Copier renders the old copy of a template using the new template's
_excluderules. When a new rule excludes a file behind a question the old template never declared, the old copy lacks that file. Copier then reads the update as a file addition and conflicts with the identical file already in the project. A project recorded before the question was added conflicts on every run until someone merges the file by hand. A control project recorded after the boundary updates cleanly.How
After a conflicted update, render the previous and current template versions with the project's recorded answers. A conflicted file whose committed bytes equal the previous render was never edited, so it takes the new render. A file that differs by one byte stays a conflict.
Tests
New tests use real Copier and a real two-commit template that crosses the boundary: unedited file takes the new version, a backup anchor survives, a one-byte edit stays a conflict, a mixed case reports only the real conflict, a template shaped like a test-plugin exclusion, and the main tree is untouched. The recovery tests' Copier double now answers only
update(reason in the commit).Full suite: 5576 passed, 23 skipped before the double fix; the affected files re-run green (112 passed).
🤖 Generated with Claude Code
https://claude.ai/code/session_01Y23LPSiKBWEaNYrtaqUn7W