Metadata-Version: 2.5
Name: libvcs
Version: 0.46.0
Summary: Lite, typed, python utilities for Git, SVN, Mercurial, etc.
Project-URL: Bug Tracker, https://github.com/vcs-python/libvcs/issues
Project-URL: Documentation, https://libvcs.git-pull.com
Project-URL: Repository, https://github.com/vcs-python/libvcs
Project-URL: Changes, https://github.com/vcs-python/libvcs/blob/master/CHANGES
Author-email: Tony Narlock <tony@git-pull.com>
License: MIT
License-File: LICENSE
Keywords: abstraction,checkout,clone,git,hg,lib,library,libvcs,mercurial,scm,subversion,svn,vcs,version control,version-control,wrapper
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Framework :: Pytest
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Version Control
Classifier: Topic :: Software Development :: Version Control :: Git
Classifier: Topic :: Software Development :: Version Control :: Mercurial
Classifier: Topic :: System :: Shells
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Python: <4.0,>=3.10
Requires-Dist: typing-extensions; python_version == '3.10'
Description-Content-Type: text/markdown

<div align="center">
  <a href="https://libvcs.git-pull.com/"><img src="https://raw.githubusercontent.com/vcs-python/libvcs/master/docs/_static/img/libvcs.svg" alt="libvcs logo" height="120"></a>
  <h1>libvcs</h1>
  <p><strong>A typed Python interface for Git, Mercurial, and Subversion repositories.</strong></p>
  <p>
    <a href="https://pypi.org/project/libvcs/"><img src="https://img.shields.io/pypi/v/libvcs.svg" alt="PyPI version"></a>
    <a href="https://pypi.org/project/libvcs/"><img src="https://img.shields.io/pypi/pyversions/libvcs.svg" alt="Python versions"></a>
    <a href="https://github.com/vcs-python/libvcs/actions"><img src="https://github.com/vcs-python/libvcs/actions/workflows/tests.yml/badge.svg" alt="Tests status"></a>
    <a href="https://codecov.io/gh/vcs-python/libvcs"><img src="https://codecov.io/gh/vcs-python/libvcs/branch/master/graph/badge.svg" alt="Coverage"></a>
    <a href="https://github.com/vcs-python/libvcs/blob/master/LICENSE"><img src="https://img.shields.io/github/license/vcs-python/libvcs.svg" alt="License"></a>
  </p>
</div>

**libvcs** parses and validates Git, Mercurial, and Subversion URLs, wraps
each VCS's command-line tool in a [typed](https://docs.python.org/3/library/typing.html)
Python object, and synchronizes a local checkout against a remote —
cloning it if it does not exist, fetching and updating it if it does. It
also ships a pytest plugin for creating disposable repositories in your own
test suite.

It powers [vcspull](https://github.com/vcs-python/vcspull), which uses it to
sync many repositories from a single config file.

---

## Features at a Glance

- **Repository synchronization**: One `obtain()` / `update_repo()` call
  clones a repository if it is missing and fetches it if it already exists,
  the same way for git, hg, and svn.
- **Command abstraction**: Call `git`, `hg`, and `svn` through typed Python
  objects instead of shelling out and parsing text yourself.
- **URL parsing**: Parse, validate, and transform VCS URLs, including
  SCP-style `git@host:path` remotes.
- **Pytest fixtures**: Create disposable local git, hg, and svn repositories
  for your own tests, with per-test isolation.

## Installation

```console
$ pip install libvcs
```

With [uv](https://docs.astral.sh/uv/):

```console
$ uv add libvcs
```

Try it interactively:

```console
$ uvx --with libvcs ipython
```

libvcs is pre-1.0: a minor version bump (0.45 to 0.46) may change the public
API. Pin a version range in projects to avoid surprises:

```toml
# pyproject.toml
dependencies = ["libvcs>=0.45,<0.46"]
```

## Usage

### 1. Synchronize Repositories

`GitSync`, `HgSync`, and `SvnSync` give the same two calls regardless of the
underlying VCS: `obtain()` clones if the path does not exist yet, and
`update_repo()` does that or fetches and updates an existing checkout — call
it either way and let libvcs decide.

[**Learn more about Synchronization**](https://libvcs.git-pull.com/sync/)

```python
import pathlib
from libvcs.sync.git import GitSync

# Define your repository
repo = GitSync(
    url="https://github.com/vcs-python/libvcs",
    path=pathlib.Path.cwd() / "libvcs",
    remotes={"gitlab": "https://gitlab.com/vcs-python/libvcs"},
)

# Clone (if not exists) or fetch & update (if exists)
result = repo.update_repo()

if result.ok:
    print(f"Current revision: {repo.get_revision()}")
else:
    for error in result.errors:
        print(f"Sync failed at {error.step}: {error.message}")
```

### 2. Command Abstraction

`Git`, `Hg`, and `Svn` wrap the binary directly — each call maps to one
subprocess invocation of the real VCS tool, so there is no divergent
reimplementation to trust. Branches, remotes, and tags are also reachable
through `QueryList`, which filters like a Django ORM queryset.

[**Learn more about Command Abstraction**](https://libvcs.git-pull.com/cmd/)

```python
import pathlib
from libvcs.cmd.git import Git

# Initialize the wrapper
git = Git(path=pathlib.Path.cwd() / "libvcs")

# Run commands directly
git.clone(url="https://github.com/vcs-python/libvcs.git")
git.checkout(ref="master")

# Traverse branches with ORM-like filtering
git.branches.create("feature/new-gui")
print(git.branches.ls())  # Returns QueryList for filtering

# Target specific entities with contextual commands
git.remotes.set_url(name="origin", url="git@github.com:vcs-python/libvcs.git")
git.tags.create(name="v1.0.0", message="Release version 1.0.0")
```

### 3. URL Parsing

`GitURL`, `HgURL`, and `SvnURL` parse and validate VCS URLs — including
SCP-style git remotes — without hand-written regular expressions, and let
you rewrite a parsed URL's parts back into a valid URL string.

[**Learn more about URL Parsing**](https://libvcs.git-pull.com/url/)

```python
from libvcs.url.git import GitURL

# Validate URLs
GitURL.is_valid(url="https://github.com/vcs-python/libvcs.git")  # True

# Parse complex URLs
url = GitURL(url="git@github.com:vcs-python/libvcs.git")

print(url.user)  # 'git'
print(url.hostname)  # 'github.com'
print(url.path)  # 'vcs-python/libvcs'

# Transform URLs
url.hostname = "gitlab.com"
print(url.to_url())  # 'git@gitlab.com:vcs-python/libvcs.git'
```

### 4. Testing with Pytest

The bundled pytest plugin builds a real, temporary VCS repository per test
and tears it down after — no network access, no shared state between tests.
A VCS's fixtures are only available when its binary is installed.

[**Learn more about Pytest Fixtures**](https://libvcs.git-pull.com/api/pytest-plugin/)

```python
import pathlib
from libvcs.pytest_plugin import CreateRepoFn
from libvcs.sync.git import GitSync


def test_my_git_tool(create_git_remote_repo: CreateRepoFn, tmp_path: pathlib.Path):
    # Spin up a real, temporary Git server
    git_server = create_git_remote_repo()

    # Clone it to a temporary directory
    checkout_path = tmp_path / "checkout"
    repo = GitSync(path=checkout_path, url=f"file://{git_server}")
    repo.obtain()

    assert checkout_path.exists()
    assert (checkout_path / ".git").is_dir()
```

## Project Information

- **Python Support**: 3.10+
- **VCS Support**: Git (including AWS CodeCommit), Mercurial (hg), Subversion (svn)
- **License**: MIT

## Links & Resources

- **Documentation**: [libvcs.git-pull.com](https://libvcs.git-pull.com)
- **Source Code**: [github.com/vcs-python/libvcs](https://github.com/vcs-python/libvcs)
- **Issue Tracker**: [GitHub Issues](https://github.com/vcs-python/libvcs/issues)
- **Changelog**: [History](https://libvcs.git-pull.com/history.html)
- **PyPI**: [pypi.org/project/libvcs](https://pypi.org/project/libvcs/)

## Support

Your donations fund development of new features, testing, and support.

- [Donation Options](https://tony.sh/support.html)
