Registry / devops / dulwich

dulwich

JSON →
library1.2.13pypypi✓ verified 26d ago

Dulwich is a pure-Python implementation of Git, providing an interface to both local and remote Git repositories without relying on the `git` executable or native code like `pygit2`. It offers both lower-level "plumbing" and higher-level "porcelain" APIs for interacting with Git objects and operations. The current version is 1.1.0, and it generally releases new versions every few weeks to months.

pip install dulwich
INSTALL
IMPORT
SIG · DULWICH
D
dulwich
devopspythonv1.2.13
Install
4.0s avg
Import
139ms
Disk
24MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.2.13 · 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.910 runs
installs and imports cleanly · install 0.0s · import 0.144s · 24.3MB
glibc
py 3.103.910 runs
installs and imports cleanly · install 4.0s · import 0.133s · 27MB
24MB installed
● package 24MB
Code
Verified usage

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

Repo
from dulwich.repo import Repo
porcelain
from dulwich import porcelain
For higher-level Git operations like clone, commit, log, etc.

This quickstart demonstrates how to initialize a new Git repository, add a file, commit the changes using Dulwich's high-level 'porcelain' API, and then retrieve the latest commit message using its lower-level 'plumbing' API. It uses a temporary directory for a clean example.

import os from dulwich.repo import Repo from dulwich import porcelain from tempfile import TemporaryDirectory # Create a temporary directory for the repository with TemporaryDirectory() as temp_dir: repo_path = os.path.join(temp_dir, 'my_repo') # Initialize a new repository repo = porcelain.init(repo_path) print(f"Initialized repository at: {repo_path}") # Create a file file_path = os.path.join(repo_path, 'README.md') with open(file_path, 'w') as f: f.write('# My Dulwich Repo\n') print(f"Created file: {file_path}") # Add the file to the index and commit porcelain.add(repo_path, ['README.md']) porcelain.commit(repo_path, message=b'Initial commit: Add README') print("Committed initial README.md") # Log the commit for entry in porcelain.log(repo_path, max_entries=1): print(f"Latest commit: {entry.commit.message.decode().strip()}") # Example of low-level (plumbing) API to get commit message low_level_repo = Repo(repo_path) head_id = low_level_repo.head() latest_commit = low_level_repo[head_id] print(f"Low-level API: Latest commit message: {latest_commit.message.decode().strip()}")
dulwich --version
Debug
Known issues
breakingDulwich 1.0.0 removed several deprecated functions. Code relying on these removed functions will break.
fix
Refer to the Dulwich documentation for the 1.0.0 release notes and replace usage of deprecated functions with their modern equivalents.
affects: >=1.0.0
breakingVersion 0.25.0 introduced significant changes to public APIs, particularly the `dulwich.porcelain` module which was reorganized into submodules (e.g., `dulwich.porcelain.tags`, `dulwich.porcelain.notes`). While the main `dulwich.porcelain` module re-exports functions for backward compatibility, direct imports from old submodule paths or reliance on the previous internal structure may break in future releases, especially after 1.0.0.
fix
Review calls to `dulwich.porcelain` functions. Ensure compatibility with the current API by referring to the official documentation. If directly importing from `dulwich.porcelain.*` submodules, verify the paths are still valid or use the top-level `dulwich.porcelain` module for re-exported functions.
affects: >=0.25.0, <1.0.0 (API changes occurred), >=1.0.0 (removed deprecated functions)
gotchaDulwich requires Python 3.10 or newer for recent versions. Running with older Python 3 versions (e.g., 3.9 or earlier) will lead to compatibility issues or errors.
fix
Ensure your Python environment is running Python 3.10 or a newer compatible version. Check `python --version`.
affects: >=1.0.0 (and potentially earlier recent releases)
gotchaWhile Dulwich is a pure-Python Git implementation, its performance for low-level operations can be significantly improved by installing with optional Rust bindings (formerly C extensions). Without these, operations might be noticeably slower.
fix
For optimal performance, install Dulwich without the `--no-binary` option, allowing the optional Rust extensions to be built (requires a Rust toolchain). If using `--no-binary dulwich`, ensure `--config-settings "--build-option=--pure"` is *not* used unless slower performance is acceptable.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'dulwich'
The 'dulwich' library is not installed in the Python environment where the code is being executed.
fix
Run `pip install dulwich` in your terminal or ensure it's included in your project's `requirements.txt` and installed within your virtual environment.
dulwich.client.HTTPUnauthorized: No valid credentials provided.
Authentication failed when attempting to access a remote Git repository over HTTP/HTTPS, likely due to incorrect or missing username, password, or access token.
fix
Provide valid credentials, either by embedding them in the URL (e.g., `https://username:password@example.com/repo.git`) or by passing `username` and `password` (or `auth_info` for more complex authentication) directly to `dulwich.porcelain.clone` or `dulwich.porcelain.push`.
KeyError: b'HEAD'
This error typically occurs when `dulwich` attempts to read the 'HEAD' reference in a Git repository, but the repository is empty, corrupted, or not properly initialized, thus 'HEAD' does not exist or points to an invalid object.
fix
Ensure the repository has been initialized with `dulwich.porcelain.init()` and has at least one commit. If it's an existing repository, check its integrity and ensure the `.git/HEAD` file and other references are valid.
TypeError: __init__() got an unexpected keyword argument 'username'.
You are passing 'username' and 'password' as direct keyword arguments to a lower-level `dulwich.client` constructor (e.g., `HttpGitClient.__init__`) which does not accept them directly, especially in older versions or when bypassing the recommended `dulwich.porcelain` functions.
fix
Use the higher-level `dulwich.porcelain.clone` or `dulwich.porcelain.push` functions, which are designed to handle `username` and `password` keyword arguments correctly for remote operations, or embed the credentials directly in the remote URL string.
Upgrade
Version history
1.2.13latest on PyPI · released Aug 24, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
11 hits · last 30 days
node
10
Resources