fix(auto-sync): reliable cross-platform post-commit auto-update#211
Merged
Conversation
The post-commit hook was racing with itself: concurrent `repowise update` invocations from rapid commits all started from the same stale base, took 12+ minutes each, never converged, and discarded all output to /dev/null. The augment staleness warning then fired noisily for every tool call while the zombie updates ran in the background. Changes: - Single-flight enforcement: `repowise update` (single-repo and workspace paths) checks `.repowise/.update.lock` before starting. If another update is running, the new invocation writes `.update.pending` with the current HEAD and exits; the running update rolls forward to it. - Hook pre-writes `.update.queued` synchronously before backgrounding, so the augment hook sees an in-flight marker during the 1-5s start-up window before the real lock file lands on disk. - Augment hook emits "Wiki update in background — started Ns ago, target X" instead of "Wiki is stale" when a lock or queued marker is present. Falls through to the stale warning only when no update is in flight (or the marker is older than its staleness window). - Hook captures stdout/stderr to `.repowise/.update.log` (rotated to 64KB tail when it exceeds 256KB) instead of /dev/null, so silent failures are diagnosable. - Hook installer upgrades the marker block in place when the body differs from the current `_HOOK_SCRIPT`, preserving any surrounding hook content. Previously it bailed with "already installed" and left users stuck on the buggy hook after a repowise upgrade. - Fix `re.sub` backslash-escape bug: passing the hook script as a string repl silently turned literal `\n` (inside the printf format) into real newlines, breaking shell quoting. Use a callable repl to bypass. Cross-platform: git always runs hooks under POSIX sh (/bin/sh on Linux/macOS, git-bash on Windows), so the same script body works on all three platforms — no platform detection needed.
swati510
approved these changes
May 18, 2026
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.
Summary
The post-commit hook installed by
repowise hook installwas racing with itself: concurrentrepowise updateinvocations from rapid commits all started from the same stale base, took 12+ minutes each, never converged, and discarded all output to/dev/null. The augment staleness warning then fired noisily for every tool call while zombie updates piled up in the background.This PR makes auto-sync reliable on Windows, macOS, and Linux.
Changes
repowise update(single-repo) and the workspace update path check.repowise/.update.lockbefore starting. If another update is running, the new invocation writes.update.pendingwith the current HEAD and exits cleanly; the running update rolls forward to that HEAD when it finishes..update.queuedsynchronously, then backgrounds the heavy work. The augment hook treats the queued marker the same as a held lock, closing the 1–5s race window during Python start-up.Wiki update in background — started Ns ago, target Xinstead ofWiki is stale. Falls through to the stale warning only when no update is in flight (or the marker is past its staleness window: 30 min for the lock, 5 min for the queued marker)..repowise/.update.log(rotated to a 64 KB tail when it exceeds 256 KB) instead of/dev/null._HOOK_SCRIPT,installreplaces the block in place (preserving surrounding hook content) and returnsupgraded. Previously it bailed withalready installed, leaving users stuck on the buggy hook after arepowiseupgrade.re.subbackslash-escape fix. Passing the hook script as a stringreplsilently turned literal\n(inside aprintfformat) into real newlines, breaking shell quoting. The replacement now uses a callablereplto bypass escape processing.Cross-platform notes
Git always runs hooks under POSIX
sh(/bin/shon Linux/macOS,git-bashon Windows), so the same script body is correct on all three platforms — no platform detection needed. The hook stays POSIX-clean (no[[ ]], no<( ), no arrays), verified by a sanity test.Test plan
tests/unit/cli/test_helpers.py— queued/pending marker round-trips, log rotationtests/unit/cli/test_hooks_legacy_migration.py— legacy strip, in-place upgrade, surrounding-hook preservation, POSIX-clean sanity checktests/unit/cli/test_augment_staleness.py— in-flight notice for lock and queued marker, fall-through to stale warning when markers are old, per-HEAD dedupe still works