Skip to content

sync hangs indefinitely on credential prompts and slow fetches #543

@tony

Description

@tony

Summary

vcspull sync --workspace <path> --all can hang indefinitely when syncing large batches of repositories. The sync loop is sequential with no subprocess timeouts and no protection against git blocking on stdin for credential prompts.

Reproduction

$ vcspull sync --workspace ~/study/rust/ --all

With a workspace containing ~60+ repos, sync completes the first several repos then hangs indefinitely on a repo that either:

  • Needs SSH credentials (git waits on stdin)
  • Has a very large .git directory (e.g. rust-lang/rust at 15GB)
  • Has a malformed URL causing protocol negotiation to stall

Root cause

  1. No subprocess timeoutsubprocess.run() in _maybe_fetch() (cli/sync.py) has no timeout parameter. libvcs update_repo() calls also lack timeouts.
  2. No GIT_TERMINAL_PROMPT=0 — git can prompt for credentials on stdin, blocking the entire process with no visible indication.
  3. Sequential sync loop — repos are synced one-by-one; one hanging repo blocks all subsequent repos.

Proposed fix

1. Set GIT_TERMINAL_PROMPT=0 during batch sync

os.environ.setdefault("GIT_TERMINAL_PROMPT", "0")

At the start of sync(), prevent git from blocking on credential prompts. Uses setdefault so users can override with GIT_TERMINAL_PROMPT=1 if desired. This is the highest-impact fix — git fails fast instead of hanging.

2. Add timeout to _maybe_fetch

result = subprocess.run(
    ["git", "fetch", "--prune"],
    cwd=repo_path,
    capture_output=True,
    text=True,
    check=False,
    timeout=120,
    env=_get_no_prompt_env(),
)

Catch subprocess.TimeoutExpired and return a meaningful error instead of blocking forever.

3. Future: --timeout CLI flag

Allow users to configure the per-repo timeout for sync operations. Would need to be threaded through to libvcs calls.

Files affected

  • src/vcspull/cli/sync.py_maybe_fetch(), sync(), update_repo()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions