Skip to content

Commit c4bd8f8

Browse files
authored
feat(sync) Recover from hangs and surface progress (#544)
`vcspull sync` no longer freezes a batch when one repository hangs on credentials or stalls on a slow fetch, and the user can see what's running while it does. Adds a per-repo timeout, a live status indicator, a streaming output panel, an npm/pnpm-style debug log, SIGINT-clean Ctrl-C handling, and quieter libvcs output by default. - **Per-repo timeout** with a 10s wall-clock default (`--timeout SECONDS`, `VCSPULL_SYNC_TIMEOUT_SECONDS`). Timed-out repos surface in the summary with a copy-pasteable rerun command. - **Live status indicator** — spinner in a terminal, periodic "still syncing" heartbeat in pipes. Disabled under `--json`, `--ndjson`, `--color=never`. - **Streaming output trail** — git's `From <url>` / `* [new branch]` output appears in a 3-line panel above the spinner and collapses to the permanent `✓ Synced` line on completion. Tunable with `--panel-lines N` / `VCSPULL_PROGRESS_LINES`. - **Per-invocation debug log** under `$TMPDIR/vcspull/`, surfaced only on failure or timeout (`--log-file PATH`, `--no-log-file`). - **Ctrl-C aborts shell chains** — `vcspull sync ~/a; vcspull sync ~/b` now stops on the first interrupt, matching `git clone; git fetch`. - **Quieter default output** — libvcs's per-repo log crumbs no longer print at the default verbosity. `-v` opens INFO; `-vv` opens DEBUG. The debug log file always captures DEBUG. Breaking changes: - Minimum libvcs bumped from 0.39.0 to 0.40.0 (for upstream per-repo timeout and fast `set_remotes` fixes this branch relies on). Fixes #543
2 parents 419b94d + 2c22011 commit c4bd8f8

15 files changed

Lines changed: 3461 additions & 67 deletions

CHANGES

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,55 @@ $ 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+
### 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
86+
87+
- Sync no longer hangs on credential prompts or slow fetches (#544)
88+
4089
### Documentation
4190

4291
- Visual improvements to API docs from [gp-sphinx](https://gp-sphinx.git-pull.com)-based Sphinx packages (#542)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ keywords = [
5353
]
5454
homepage = "https://vcspull.git-pull.com"
5555
dependencies = [
56-
"libvcs~=0.39.0",
56+
"libvcs>=0.40.0,<0.41.0",
5757
"colorama>=0.3.9",
5858
"PyYAML>=6.0"
5959
]

src/vcspull/cli/__init__.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,14 @@ def cli(_args: list[str] | None = None) -> None:
440440
) = subparsers
441441
args = parser.parse_args(_args)
442442

443-
setup_logger(log=log, level=args.log_level.upper())
443+
# ``args.verbosity`` is only set by the sync subcommand; default 0
444+
# everywhere else. The sync ``-v`` ladder (0 → libvcs WARNING; 1 → INFO;
445+
# 2+ → DEBUG) is documented in :func:`vcspull.log.setup_logger`.
446+
setup_logger(
447+
log=log,
448+
level=args.log_level.upper(),
449+
verbosity=getattr(args, "verbosity", 0),
450+
)
444451

445452
if args.subparser_name is None:
446453
parser.print_help()
@@ -466,6 +473,10 @@ def cli(_args: list[str] | None = None) -> None:
466473
sync_all=getattr(args, "sync_all", False),
467474
parser=sync_parser,
468475
include_worktrees=getattr(args, "include_worktrees", False),
476+
timeout=getattr(args, "timeout", None),
477+
log_file=getattr(args, "log_file", None),
478+
no_log_file=getattr(args, "no_log_file", False),
479+
panel_lines=getattr(args, "panel_lines", None),
469480
)
470481
elif args.subparser_name == "list":
471482
list_repos(

0 commit comments

Comments
 (0)