Propagate only what changed, and replace a directory with a symlink - #62
Propagate only what changed, and replace a directory with a symlink#62woksin wants to merge 1 commit into
Conversation
Propagation has failed on every run since 2026-07-03, for two unrelated reasons that hit different repositories - which is why the failing subset kept changing size and looked flaky. A path the source ships as a symlink cannot simply gain a blob where the target still holds a directory: the tree API answers GitRPC::BadObjectState. Six targets have .github/instructions as a real directory. Converting one has to be expressed as a delete plus an add, so the tree now carries the delete first. The other five hit the secondary rate limit. The up-to-date check stopped at the first file that differed and then a blob was created for every propagated file - 63 symlinks plus the rest, to every one of ~26 targets, on every run. The check now keeps what it learned and only the files that actually differ are uploaded, which is usually one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JfEAq3cyHk3mrWpo8QA9db
|
Reviewer notes. How the two causes were separated. The failing set is 11 repositories. Comparing all 63 source symlink paths against each target's trees splits them cleanly:
Arc, Studio and Lens have no conflict and are not failing. Arc was failing in earlier runs and dropped out once its Note Volume, concretely. Before: every propagated file uploaded to every target on every run. After: only the files whose blob sha or mode differs. On a typical run that is one file rather than 63-plus, per repository, which is what puts the rate limit out of reach rather than merely further away. What I verified, and how. The step-3/step-4 logic was extracted and run against a simulated tree where one file matches, one differs, and one path is a directory in the target. It selected exactly the two differing files, flagged only the directory, and emitted What I could not verify. I have not run this against the real API. Two things to watch on the first run:
If (1) turns out not to work, the fallback is two tree calls — delete, then add on the resulting tree — which costs one extra request per affected repository and only on the conversion run. |
Fixed