@@ -37,107 +37,54 @@ $ uvx --from 'vcspull' --prerelease allow vcspull
3737_ Notes on upcoming releases will be added here_
3838<!-- END PLACEHOLDER - ADD NEW CHANGELOG ENTRIES BELOW THIS LINE -->
3939
40- ### New features
40+ ### Breaking changes
41+
42+ - Bump minimum libvcs from 0.39.0 to 0.40.0 (#544 )
43+
44+ ### What's new
45+
46+ #### ` vcspull sync ` : per-repo timeout
47+
48+ A stuck repository no longer freezes the whole batch. Each repo runs
49+ under a 10-second wall-clock deadline; override with `--timeout
50+ SECONDS` or ` VCSPULL_SYNC_TIMEOUT_SECONDS`. The summary lists any
51+ timed-out repos with a copy-pasteable rerun command. (#544 )
52+
53+ #### ` vcspull sync ` : live status indicator
54+
55+ The active repo is now visible while sync runs. In a terminal you get
56+ a spinner with the repo name and elapsed time; in pipes you get a
57+ start line plus a periodic "still syncing" heartbeat. Disabled under
58+ ` --json ` , ` --ndjson ` , and ` --color=never ` . (#544 )
59+
60+ #### ` vcspull sync ` : streaming output trail
61+
62+ Git's streaming output now appears in a 3-line trail above the
63+ spinner and collapses to the permanent ` ✓ Synced ` line when the repo
64+ finishes. Tunable with ` --panel-lines ` (` 0 ` hides, ` -1 ` unbounded) or
65+ ` VCSPULL_PROGRESS_LINES ` . (#544 )
66+
67+ #### ` vcspull sync ` : per-invocation debug log
68+
69+ Every run drops a debug log under ` $TMPDIR/vcspull/ ` (npm/pnpm style),
70+ surfaced to the terminal only when something failed or timed out.
71+ Override with ` --log-file PATH ` ; disable with ` --no-log-file ` . (#544 )
72+
73+ #### ` vcspull sync ` : Ctrl-C aborts shell chains
74+
75+ ` vcspull sync ` now exits via signal on Ctrl-C, so chained invocations
76+ like ` vcspull sync ~/a; vcspull sync ~/b ` stop on the first interrupt
77+ instead of running the whole list. Matches ` git clone; git fetch ` . (#544 )
78+
79+ #### ` vcspull ` : quieter default output
80+
81+ libvcs's per-repo log crumbs no longer print at the default verbosity.
82+ Pass ` -v ` for INFO-level libvcs activity (` Updating to 'main'. ` ); pass
83+ ` -vv ` for DEBUG. The debug log file always captures DEBUG regardless. (#544 )
84+
85+ ### Bug fixes
4186
42- #### ` vcspull sync ` : collapsing 3-line live-trail above the spinner
43-
44- Streaming subprocess output (git's ` From <url> ` , ` * [new branch] ` ,
45- ` Already on 'main' ` , ` Successfully rebased ` , etc.) now flows into a
46- fixed-height live-trail region above the per-repo spinner. The trail
47- shows the most recent 3 lines, rolls under as new ones arrive, and
48- ** collapses** when the repo finishes -- leaving only the permanent
49- ` ✓ Synced <name> → <path> ` line. Modeled on tmuxp's ` before_script `
50- panel.
51-
52- Tweak with ` --panel-lines N ` (` 0 ` hides; ` -1 ` unbounded; default 3) or
53- the ` VCSPULL_PROGRESS_LINES ` environment variable. The panel is only
54- active when the indicator itself is (TTY + human + colour mode); pipes,
55- ` --json ` , ` --ndjson ` , and ` --color=never ` keep their existing line-
56- oriented output.
57-
58- #### ` vcspull ` : libvcs is quiet by default; ` -v ` / ` -vv ` opens it back up
59-
60- The chatty ` |git| (repo) head_sha: ... ` / ` git_remote_name: ... ` /
61- ` tag_sha: ... ` crumb lines no longer appear at the default verbosity.
62- Pass ` -v ` to see libvcs ` INFO ` (` Updating to 'main'. ` ,
63- ` Already up-to-date. ` ); pass ` -vv ` to see ` DEBUG ` (the full crumb
64- trail). The npm/pnpm-style debug log file always captures ` DEBUG `
65- regardless of verbosity.
66-
67- During ` vcspull sync ` itself the libvcs terminal stream is also
68- silenced for ` WARNING ` / ` ERROR ` records at default verbosity --
69- libvcs's ` |git| (rye) Failed to determine current branch ` warning
70- was duplicating the same content vcspull's own `✗ Failed syncing
71- rye: Command failed with code 128: git symbolic-ref HEAD --short`
72- line already carried, breaking the
73- ` ✓ Synced X / ✗ Failed X / - Timed out X ` rhythm. The debug log
74- file still captures every libvcs entry, so a post-mortem after a
75- failure has the full trace.
76-
77- Root cause for the regression that prompted this: ` setup_file_logger `
78- raised both the ` vcspull ` and ` libvcs ` loggers to ` DEBUG ` so the
79- ` FileHandler ` could capture full traces, but the terminal ` StreamHandler `
80- had no per-handler level filter -- so the bump opened the floodgate to
81- the terminal too. ` setup_logger ` now pins explicit per-handler levels
82- on every ` StreamHandler ` so file-logger and terminal-logger filters
83- are independent.
84-
85- #### ` vcspull sync ` : Ctrl-C aborts the whole shell chain, not one command
86-
87- ` vcspull sync ` now terminates with ` WIFSIGNALED(SIGINT) ` on Ctrl-C instead
88- of exiting cleanly with status ` 130 ` . Bash/zsh sequential lists
89- (` cmd1; cmd2; cmd3 ` ) abort on the first signal-terminated child, so
90- chained invocations like
91- `vcspull sync --workspace ~ /study/rust/ --all; vcspull sync --workspace
92- ~ /study/otel/ --all` now stop on a single Ctrl-C — matching how ` git
93- clone; git fetch` compose. Behaviour is implemented via the canonical
94- git pattern (` sigchain.h:20-34 ` ): flush output, close the debug log
95- handle, install ` SIG_DFL ` , self-deliver SIGINT. Windows falls back to
96- the conventional ` SystemExit(130) ` because it has no ` WIFSIGNALED `
97- analogue.
98-
99- #### ` vcspull sync ` : per-repository watchdog and copyable rerun recipe
100-
101- A single stuck repository no longer freezes the whole batch. Every repository
102- sync now runs under a wall-clock watchdog. The default deadline is 10 seconds
103- -- a healthy fetch/pull against a warm remote finishes well under that, so
104- anything slower is surfaced rather than waited on. Override with `--timeout
105- N` or the ` VCSPULL_SYNC_TIMEOUT_SECONDS` environment variable.
106-
107- When one or more repositories time out, the summary is followed by a
108- copy-pasteable rerun recipe that retries just those repositories with a
109- larger timeout, plus a ` -vv ` variant for diagnosis and a manual
110- ` git fetch --dry-run ` probe per repo. Timed-out repositories are counted in
111- the summary as "N timed out" alongside synced / failed.
112-
113- #### ` vcspull sync ` : live status indicator (spinner + heartbeat)
114-
115- Every ` vcspull sync ` run now shows which repository is currently running
116- and how long it has been. In a terminal the output is a single-line braille
117- spinner that refreshes in place; when output is piped (CI, ` tee ` , log
118- capture), the indicator degrades to a ` · syncing <name> ` line on start plus
119- a periodic ` … still syncing <name> (45s elapsed) ` heartbeat. The indicator
120- is disabled under machine-readable output (` --json ` / ` --ndjson ` ) or when
121- colours are turned off.
122-
123- #### ` vcspull sync ` : per-invocation debug log (npm/pnpm style)
124-
125- Every ` vcspull sync ` invocation now writes a debug log to
126- ` $TMPDIR/vcspull/debug-<timestamp>-<pid>.log ` (or
127- ` $TMPDIR/vcspull-test/debug-<timestamp>-<pid>.log ` when running under
128- pytest, an automatic safety net so the production log dir stays
129- uncontaminated by test runs). Clean runs stay quiet -- the log path is
130- only surfaced to the terminal when at least one repository failed or
131- timed out. Override the destination with ` --log-file PATH ` , or disable
132- entirely with ` --no-log-file ` . The log captures the full libvcs per-repo
133- activity (progress callback output, exit codes, errors) so a hang can be
134- post-mortemed even after the CLI has moved on.
135-
136- ### Dependencies
137-
138- - Bump ` libvcs ` to ` >=0.40.0,<0.41.0 ` for timeout + fast ` set_remotes ` fixes
139- that let ` vcspull sync ` recover from a single stuck repository without
140- hanging the whole batch.
87+ - Sync no longer hangs on credential prompts or slow fetches (#544 )
14188
14289### Documentation
14390
0 commit comments