Repository navigation
feat(sync): stop before the merge when upstream changed its sync config, add migrate --run - #39
Merged
Merged
Conversation
… state
The app has the old `{ "applied": [...] }` record and a full copy of `cella/migrations/`.
Within the sync range upstream changes and deletes existing note files and adds a note,
and an unrelated file conflicts. The first run stops at the conflict with the folder gone
from the working tree and the index and the record converted to `{ "pending": [...] }`.
The finishing rerun commits, and the folder stays gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ig, add migrate --run Sync - A new merge checks upstream's sync config first. When upstream changed `overrides.pinned`, `overrides.ignored` or `settings.packageJsonSync` since the last sync point in ways the app's config does not follow, the run prints the report and stops before anything is merged: the merge would run on the app's old lists, so a path upstream newly ignores or pins would arrive as an ordinary synced file. `--keep-config` merges with the config as it stands (also on `forks`). `analyze` keeps reporting without stopping, and the rerun that commits a staged merge is not gated. - `settings.packageJsonSync` is part of that comparison: keys upstream added that the app lacks and keys upstream dropped that the app still lists appear in the same report (`analyze --json` too). - A run that stops before the merge drops its temporary `cella/sync/*` branch and returns to the branch it started from: the sync config gate, the CLI version gate, a `--ref` that does not resolve, an unreachable upstream. Before, the empty branch stayed checked out. - An upstream release or branch behind the last sync point ends the run as a no-op with a message instead of an error. A pinned `--ref` behind it is still refused. - The protected-but-behind lists of `analyze` and `sync` end with one `git diff <last-sync>..<upstream> -- <entry>` line per pinned or ignored entry. - `ignored entry not found` only warns when the path is in neither the app nor upstream, read at the upstream branch as last fetched. Nothing changes while that ref does not resolve. Migrate - `pnpm cella migrate --run <id> [-- <args>]` extracts a note, runs its codemod with tsx from the app root and gives the files the codemod changed that were byte-identical to the last synced upstream commit their upstream content back. Without arguments the codemod gets `inventory` and the note's roots. `--script <file>` names the script when the folder holds several. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
The CLI side of raak's and projectcampus's feedback on their syncs to cella 0.16.0. The template side is cellajs/cella#1312.
Sync config is checked before the merge
cella/cella.config.tsnever syncs, and the merge runs on the app's lists as they stand. Both apps received paths upstream had newly ignored (upstream renamed an ignored folder, the apps' lists still named the old one), and the report that names such entries came after the merge.--keep-configmerges with the config as it stands (also onforks).analyzestill only reports, and the rerun that commits a staged merge is not checked.settings.packageJsonSyncis part of the comparison. Replayed on projectcampus's config from before its sync, the report now holds all six entries it had to find by hand,exportsincluded.This changes what an unattended
cella syncdoes: it exits 1 where it used to merge.A stop before the merge leaves nothing behind
--refthat does not resolve, an unreachable upstream) removes the temporarycella/sync/*branch and returns to the starting branch. Before, the empty branch stayed checked out.--refbehind it is still refused.analyzestill reports it as an error.Reports
analyzeandsyncend with onegit diff <last-sync>..<upstream> -- <entry>line per pinned or ignored entry. An e2e test runs the printed command and checks it shows upstream's change without the app's.ignored entry not foundonly warns when the path is in neither the app nor upstream (read at the upstream branch as last fetched). An app ignores some paths to keep them from arriving, and every run warned about those.migrate --run <id> [-- <args>]A codemod's roots cover template-owned files, and one rewrote a file upstream had changed after writing the codemod.
--runextracts the note, runs its codemod with tsx from the app root, and gives every file the codemod changed that was byte-identical to the last synced upstream commit its upstream content back. Without arguments the codemod getsinventoryand the note's roots, the report-only run: all eight codemods in cella take that subcommand first.--script <file>names the script when a folder holds several.The legacy notes folder
projectcampus reported that a conflicted first run kept the old
{ "applied": [...] }record and itscella/migrations/copy. Its lockfile shows that merge ran on CLI 0.2.3, which predates this code. The new e2e test covers that path on the current code: conflicted run from the legacy state, upstream changing and deleting existing note files in range. It passes onmainunchanged, so no fix was needed.Verification
pnpm lint,pnpm ts: clean.pnpm test: 26 files, 271 tests pass (24 files, 236 tests before).pnpm test:release: 1 passes.--runexample from the README was run in a sandbox app with a copy of the real tailwind note: it rewrote the app's file and restored the template's.forks --keep-confighas a parse test only.After the release
cella can then require this version in its root
package.json(the version check makes apps install it before their next sync) and point itsmigrateskill at--run.🤖 Generated with Claude Code