GitHub

libvcs logo

The Swiss Army Knife for Version Control Systems in Python.

PyPI version Python versions Tests status Coverage License

libvcs provides a unified, typed, and pythonic interface for managing Git, Mercurial, and Subversion repositories. Whether you're building a deployment tool, a developer utility, or just need to clone a repo in a script, libvcs handles the heavy lifting.

It powers vcspull and simplifies VCS interactions down to a few lines of code.


Features at a Glance

  • ๐Ÿ”„ Repository Synchronization: Clone, update, and manage local repository copies with a high-level API.
  • ๐Ÿ›  Command Abstraction: Speak fluent git, hg, and svn through fully-typed Python objects.
  • ๐Ÿ”— URL Parsing: Robustly validate, parse, and manipulate VCS URLs (including SCP-style).
  • ๐Ÿงช Pytest Fixtures: Batteries-included fixtures for spinning up temporary repositories in your test suite.

Installation

$ pip install libvcs

With uv:

$ uv add libvcs

Try it interactively:

$ uvx --with libvcs ipython

Tip: libvcs is pre-1.0. Pin a version range in projects to avoid surprises:

# pyproject.toml
dependencies = ["libvcs>=0.37,<0.38"]

Usage

1. Synchronize Repositories

Clone and update repositories with a consistent API, regardless of the VCS.

Learn more about Synchronization

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

Traverse repository entities intuitively with ORM-like filtering, then run targeted commands against them.

Learn more about Command Abstraction

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

Stop writing regex for Git URLs. Let libvcs handle the edge cases.

Learn more about URL Parsing

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

Writing a tool that interacts with VCS? Use our fixtures to keep your tests clean and isolated.

Learn more about Pytest Fixtures

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

Support

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

Read the original on github.com โ†—