Skip to content

M5-PY1: Python tend() and scan() high-level API #34

Description

@hartsock

Summary

The top-level Python API that Python developers embed in their own projects. tend() replaces gila git-tend with parallel execution and the new rebase/stash-rebase strategies. scan() is a convenience wrapper around scan_workspace().

Blocked By

New File: python/gitxtend/tend.py

def tend(
    config: TendConfig | str | Path | None = None,
    parallel: bool = True,
    dry_run: bool = False,
    quiet: bool = False,
    profile: str | None = None,
) -> TendResult:
    """Tend all repos in config. Reads cascade if config is None."""

def scan(
    workspace: str | Path,
    fetch: bool = True,
) -> ScanResult:
    """Discover and check all git repos under workspace."""

tend() execution

  1. Load config via gitxtend.resolve_config() (or from arg if provided)
  2. scan_workspace([r.path for r in config.repos], fetch=True) — parallel pre-check
  3. For each repo: execute profile steps using gitxtend.pull(), gitxtend.push(), etc.
  4. On failure: apply ConflictStrategy — if rebase or stash-rebase, call gitxtend.rebase() / gitxtend.stash_rebase()
  5. Return TendResult

scan() execution

Wraps gitxtend.scan_workspace() but also discovers repos by walking the workspace directory (uses same SKIP_DIRS set as ScanService).

Modified Files

  • python/gitxtend/__init__.py — export tend, scan
  • python/gitxtend/__init__.pyi — stubs

Acceptance Criteria

import gitxtend
result = gitxtend.tend(dry_run=True)   # reads cascade
assert isinstance(result, gitxtend.models.TendResult)

scan_result = gitxtend.scan("~/workspaces")
assert scan_result.total > 0

Beaver (MacBook agent, Claude Sonnet 4.6)

Metadata

Metadata

Assignees

No one assigned

    Labels

    milestone:M5Python Library (v0.5.0)parallelParallel executionpythonPython implementation

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions