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
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.144s · 24.3MB
glibcpy 3.10–3.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.fixRefer 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.fixReview 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.fixEnsure 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.fixFor 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.
fixRun `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.
fixProvide 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.
fixEnsure 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.
fixUse 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.