Registry / devops / pygit2

pygit2

JSON →
library1.20.0pypypi✓ verified 26d ago

pygit2 is a set of Python bindings for libgit2, a portable, pure C implementation of the Git core methods. It provides a low-level, plumbing-focused API for interacting with Git repositories. The library is actively maintained, with version 1.19.2 being the latest as of March 2026, and typically sees multiple minor releases per year, often in sync with libgit2 updates and bug fixes. It supports Python versions 3.11 through 3.14, and PyPy3 7.3+.

pip install pygit2
INSTALL
IMPORT
SIG · PYGIT2
P
pygit2
devopspythonv1.20.0
Install
2.2s avg
Import
145ms
Disk
33MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.18.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.150s · 34.3MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 2.2s · import 0.140s · 35MB
33MB installed
● package 33MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Repository
from pygit2 import Repository
init_repository
from pygit2 import init_repository
Signature
from pygit2 import Signature
GitError
from pygit2 import GitError
from pygit2._pygit2 import GitError
While `GitError` can be imported from `_pygit2`, the public API exposes it directly under `pygit2`.
enums
from pygit2 import enums

This quickstart demonstrates how to initialize a new Git repository, create a file, add it to the index, and make the first commit using pygit2. It also includes cleanup of the temporary repository directory.

import pygit2 import os import shutil import tempfile from pygit2 import enums def create_and_commit_repo(): # Create a temporary directory for the repository repo_path = tempfile.mkdtemp() print(f"Creating repository at: {repo_path}") try: # Initialize a new bare repository # For a non-bare repo with a working directory, use `bare=False` repo = pygit2.init_repository(repo_path, bare=False) # Configure author and committer details author = pygit2.Signature("Test User", "test@example.com") committer = pygit2.Signature("Test User", "test@example.com") # Create a file in the working directory file_path = os.path.join(repo_path, "README.md") with open(file_path, "w") as f: f.write("# My New Repository\n\nThis is a test repository.") # Add the file to the index repo.index.add("README.md") repo.index.write() # Create a tree from the index tree = repo.index.write_tree() # Create the initial commit # For an initial commit, the parents list is empty, and HEAD is used commit_id = repo.create_commit( 'HEAD', # Reference to update author, # Author signature committer, # Committer signature 'Initial commit', # Commit message tree, # Tree object for the commit [] # Parent commits (empty for initial commit) ) print(f"Initial commit created with ID: {commit_id}") # Checkout the branch to populate the working directory repo.checkout('refs/heads/main') # Or 'refs/heads/master' depending on default branch print(f"Repository content in working directory: {os.listdir(repo_path)}") finally: # Clean up the temporary directory shutil.rmtree(repo_path) print(f"Cleaned up repository at: {repo_path}") if __name__ == "__main__": create_and_commit_repo()
Debug
Known issues
breaking`Odb.read(...)` now returns `enums.ObjectType` (an enum) instead of an integer for the object type. If your code expects an `int` for the object type when reading from the ODB, it will break.
fix
Update your code to expect and handle `pygit2.enums.ObjectType` when retrieving object types from `Odb.read(...)` or `Odb.read_header(...)`. For example, use `obj_type.value` if an integer is strictly required, but it's recommended to use the enum directly.
affects: 1.19.2+
breakingThe `IndexEntry.hex` property has been removed. Accessing it will raise an AttributeError.
fix
Replace `entry.hex` with `str(entry.id)` to get the hexadecimal representation of an index entry's OID.
affects: 1.18.0+
breakingSeveral repository methods related to remotes and submodules have been removed or deprecated in favor of accessing them through the `Repository.remotes` and `Repository.submodules` objects. E.g., `Repository.create_remote` was removed.
fix
Use `repo.remotes.create(...)` instead of `repo.create_remote(...)`. Similarly, replace `Repository.add_submodule(...)` with `Repository.submodules.add(...)`, `Repository.lookup_submodule(...)` with `Repository.submodules[...]`, and `Repository.update_submodule(...)` with `Repository.submodules.update(...)`.
affects: 1.14.0+
gotchaBuilding pygit2 from source requires the `libgit2` development files to be installed on your system. If these are not found, installation will fail with `fatal error: git2.h: No such file or directory`. Binary wheels are available for many platforms, but not all (e.g., macOS often requires manual `libgit2` installation via Homebrew).
fix
Ensure `libgit2` development packages are installed before `pip install pygit2`. On macOS, use `brew install libgit2`. On Debian/Ubuntu, use `apt-get install libgit2-dev`. On Fedora/RHEL, use `dnf install libgit2-devel`.
affects: All versions (when building from source)
gotchaOlder versions of `pygit2` (e.g., v1.4.0, often found in older Linux distributions) might use `libgit2` builds that do not support modern SSH key types (e.g., RSA SHA-1 keys are deprecated by GitHub). This can lead to `GitError: ERROR: You're using an RSA key with SHA-1, which is no longer allowed` when pushing/pulling via SSH.
fix
Upgrade `pygit2` and its underlying `libgit2` to a recent version (1.9.x or newer) that supports modern SSH protocols and key types. Ensure your SSH agent is running and contains compatible keys (e.g., Ed25519 or RSA SHA-2).
affects: < 1.9.x
gotchaWhen making an *initial* commit in a newly created repository, the first argument to `Repository.create_commit()` should typically be `'HEAD'` (or a specific branch name like `'refs/heads/main'`) instead of an uninitialized reference like `'refs/heads/master'` if the branch does not yet exist. Using an incorrect or non-existent ref might lead to errors or unexpected behavior if the head hasn't been established.
fix
For initial commits, use `repo.create_commit('HEAD', author, committer, message, tree, [])` and then `repo.checkout('refs/heads/main')` (or desired branch) to set the head and populate the working directory.
affects: All versions
gotchaThe `pygit2` library versions often track the `libgit2` C library versions. Installing a `pygit2` version that is incompatible with your system's `libgit2` version (especially when building from source) can lead to compilation errors or runtime issues. For example, `pygit2 1.19.x` is designed for `libgit2 1.9.x`.
fix
Always check the `pygit2` documentation or PyPI page for the recommended `libgit2` version matching your `pygit2` installation. If installing from source, ensure your system's `libgit2` version aligns with the `pygit2` version you are trying to install.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'pygit2'
The 'pygit2' library is not installed in the Python environment where the code is being executed.
fix
Install the library using pip: `pip install pygit2`
fatal error: git2.h: No such file or directory
During installation, pip failed to find a pre-compiled binary wheel for pygit2 and attempted to build it from source, but the required libgit2 development headers are missing on the system.
fix
Install the libgit2 development package specific to your operating system, then retry the pygit2 installation. For Debian/Ubuntu: `sudo apt-get install libgit2-dev`. For Fedora/RHEL: `sudo dnf install libgit2-devel`. For macOS (with Homebrew): `brew install libgit2`. After installing the dependencies, run `pip install pygit2` again.
KeyError: 'object not found - no match for id (some_object_id)'
This error occurs when attempting to retrieve a Git object (such as a commit, blob, or tree) using an Object ID (OID) that does not exist in the repository's object database.
fix
Verify that the OID is correct and corresponds to an existing object within the repository. Use `repo.get(oid)` which returns `None` for non-existent objects, rather than `repo[oid]` which raises a KeyError. Ensure the repository is fully cloned (not shallow) if you expect all history to be present.
Upgrade
Version history
1.20.0latest on PyPI · released Aug 8, 2026
Audit
Dependencies
libgit2requiredpygit2 is a binding to the libgit2 C library. While binary wheels often bundle libgit2, building from source requires a system-wide installation of libgit2 development files.
cffirequiredUsed for Python Foreign Function Interface to interact with libgit2.
Agent activity
9 hits · last 30 days
node
8
Resources
pygit2 — pip install pygit2 · libregistry