vcspull sync¶
The vcspull sync command clones and updates repositories defined in your
vcspull configuration. It’s the primary command for keeping your local workspace
synchronized with remote repositories.
Command¶
Synchronize VCS repositories.
Usage¶
usage: vcspull sync [-h] [-f FILE] [-w DIR] [--dry-run] [--json] [--ndjson] [--color {auto,always,never}] [--exit-on-error] [--show-unchanged] [--summary-only] [--long] [--relative-paths] [--fetch] [--offline] [-v] [--all] [--include-worktrees] [--timeout SECONDS] [--panel-lines N] [--log-file PATH] [--no-log-file] [pattern ...]
Examples¶
$ vcspull sync --all
$ vcspull sync "django-*"
$ vcspull sync --dry-run --all
$ vcspull sync -f ./myrepos.yaml --all
$ vcspull sync -w ~/code myproject
Positional Arguments¶
- repo_patterns pattern¶
patterns / terms of repos, accepts globs / fnmatch(3)
Options¶
- -f, --file FILE¶
path to config file (default: ~/.vcspull.yaml or ./.vcspull.yaml)
- -w, --workspace, --workspace-root DIR¶
filter by workspace root directory
- --dry-run, -n¶
preview what would be synced without making changes
- --json¶
output as JSON
- --ndjson¶
output as NDJSON (one JSON per line)
- --color¶
when to use colors (default: auto)
- --exit-on-error, -x¶
exit immediately encountering error (when syncing multiple repos)
- --show-unchanged¶
include repositories that are already up to date
- --summary-only¶
print only the plan summary line
- --long¶
show extended details for each repository
- --relative-paths¶
display repository paths relative to the workspace root
- --fetch¶
refresh remote tracking information before planning
- --offline¶
skip network access while planning (overrides --fetch)
- -v, --verbose¶
increase verbosity. -v opens libvcs INFO ('Updating to ...'); -vv opens libvcs DEBUG (full per-repo trace) plus extra dry-run plan detail. Default keeps libvcs at WARNING+.
- --all, -a¶
sync all configured repositories
- --include-worktrees¶
also sync configured worktrees for each repository
- --timeout SECONDS¶
per-repository wall-clock deadline in seconds (default: 10; env: VCSPULL_SYNC_TIMEOUT_SECONDS). Repos that exceed the deadline are skipped and the rest of the batch continues.
- --panel-lines N¶
live-trail panel height for streaming subprocess output above the spinner (default: 3; 0 hides; -1 unbounded; env: VCSPULL_PROGRESS_LINES). The panel collapses when each repo finishes, leaving only the permanent ✓ Synced line.
- --log-file PATH¶
write a debug log to PATH (default: $TMPDIR/vcspull/debug-<ts>-<pid>.log; $TMPDIR/vcspull-test/... under pytest). The path is only printed to the terminal when a sync fails or times out, matching npm/pnpm/yarn.
- --no-log-file¶
disable the debug log file entirely
Filtering repos¶
Running vcspull sync with no patterns syncs nothing and prints the generated
help text. You always say which repositories to touch, with patterns or
--all.
Sync all repos¶
Sync everything with the * pattern:
$ vcspull sync '*'
Depending on how your shell expands the wild card / asterisk, you may not
need to quote *.
Filtering¶
Filter repos starting with “django-“:
$ vcspull sync 'django-*'
Multiple terms¶
Name several repositories exactly:
$ vcspull sync 'django-anymail' 'django-guardian'
Configuration file selection¶
Specify a custom config file with -f/--file:
$ vcspull sync --file ~/projects/.vcspull.yaml '*'
By default, vcspull searches for config files in:
Current directory (
.vcspull.yaml)Home directory (
~/.vcspull.yaml)XDG config directory (
~/.config/vcspull/)
Workspace filtering¶
Filter repositories by workspace root with -w/--workspace or --workspace-root:
$ vcspull sync --workspace ~/code/ '*'
This syncs only repositories in the specified workspace root, useful for:
Selective workspace updates
Multi-workspace setups
Targeted sync operations
The -w, --workspace, and --workspace-root spellings work identically:
$ vcspull sync --workspace-root ~/code/ '*'
Error handling¶
Repos not found in config¶
If a repo term has no match in your configurations, vcspull shows a warning:
$ vcspull sync non_existent_repo
No repo found in config(s) for "non_existent_repo"
$ vcspull sync non_existent_repo existing_repo
No repo found in config(s) for "non_existent_repo"
$ vcspull sync non_existent_repo existing_repo another_repo_not_in_config
No repo found in config(s) for "non_existent_repo"
No repo found in config(s) for "another_repo_not_in_config"
Sync terms act as a filter rather than a lookup, so the message is a
warning — it does not stop the run, even with --exit-on-error.
Continuing past errors¶
When syncing multiple repositories, vcspull continues to the next repository if one fails.
Pass --exit-on-error / -x to stop the whole run at the first failing
repository instead:
$ vcspull sync --exit-on-error grako django
Print traceback for errored repos:
$ vcspull --log-level DEBUG sync --exit-on-error grako django
Dry run mode¶
Preview what would be synchronized without making changes:
$ vcspull sync --dry-run '*'
Plan: 2 to clone (+), 0 to update (~), 2 unchanged (✓), 0 blocked (⚠), 0 errors (✗)
~/code/
+ django-extensions ~/code/django-extensions missing
~/study/ai/
+ tiktoken ~/study/ai/tiktoken missing
Tip: run without --dry-run to apply. Use --show-unchanged to include ✓ rows.
Use --dry-run or -n to:
Verify your configuration before syncing
Check which repositories would be updated
Test pattern filters
Preview operations in CI/CD
JSON output¶
Export sync operations as JSON for automation:
$ vcspull sync --dry-run --json 'flask' 'tiktoken'
Output:
[
{
"format_version": "1",
"type": "operation",
"name": "tiktoken",
"path": "~/study/ai/tiktoken",
"workspace_root": "~/study/ai/",
"action": "clone",
"detail": "missing",
"url": "git+https://github.com/openai/tiktoken.git"
},
{
"format_version": "1",
"type": "summary",
"clone": 1,
"update": 0,
"unchanged": 1,
"blocked": 0,
"errors": 0,
"total": 2,
"duration_ms": 8
}
]
Each event emitted during the run includes:
format_version: Schema version of the event stream (currently"1")type:"operation"for repository events,"summary"for the final summaryname,path,workspace_root,url: Repository metadata from your configaction:"clone","update","unchanged","blocked", or"error"detail: Short explanation of the action, when availablebranch,ahead,behind,dirty: Working-tree state for existing checkouts
Use --json without --dry-run to capture actual sync executions—successful
and failed repositories are emitted with their final state.
NDJSON output¶
Stream sync events line-by-line with --ndjson:
$ vcspull sync --dry-run --ndjson 'flask' 'tiktoken'
{"format_version": "1", "type": "operation", "name": "tiktoken", "path": "~/study/ai/tiktoken", "workspace_root": "~/study/ai/", "action": "clone", "detail": "missing", "url": "git+https://github.com/openai/tiktoken.git"}
{"format_version": "1", "type": "summary", "clone": 1, "update": 0, "unchanged": 1, "blocked": 0, "errors": 0, "total": 2, "duration_ms": 7}
Each line is a JSON object representing a sync event, ideal for:
Real-time processing
Progress monitoring
Log aggregation
Color output¶
Control colored output with --color:
--color auto(default): Use colors if outputting to a terminal--color always: Always use colors--color never: Never use colors
The NO_COLOR environment variable is also
respected.