Python bindings for libgit2 providing comprehensive Git repository operations and version control functionality.
—
Core Git object types including commits, trees, blobs, and tags. These represent the fundamental data structures in Git repositories and provide object-oriented access to Git's content-addressable storage system.
All Git objects inherit from the base Object class providing common properties and methods.
class Object:
@property
def oid(self) -> Oid:
"""Object identifier (SHA-1 hash)"""
@property
def type(self) -> int:
"""Object type (GIT_OBJECT_COMMIT, GIT_OBJECT_TREE, etc.)"""
@property
def size(self) -> int:
"""Object size in bytes"""
def peel(self, target_type: int) -> Object:
"""Peel object to target type"""
def __str__(self) -> str:
"""String representation of object"""
def __eq__(self, other) -> bool:
"""Compare objects by OID"""
# Object Type Constants
GIT_OBJECT_ANY: int
GIT_OBJECT_COMMIT: int
GIT_OBJECT_TREE: int
GIT_OBJECT_BLOB: int
GIT_OBJECT_TAG: int
GIT_OBJECT_INVALID: intCommit objects represent snapshots in repository history with metadata about changes.
class Commit(Object):
@property
def message(self) -> str:
"""Commit message"""
@property
def author(self) -> Signature:
"""Commit author signature"""
@property
def committer(self) -> Signature:
"""Commit committer signature"""
@property
def commit_time(self) -> int:
"""Commit timestamp"""
@property
def commit_time_offset(self) -> int:
"""Commit timezone offset"""
@property
def author_time(self) -> int:
"""Author timestamp"""
@property
def author_time_offset(self) -> int:
"""Author timezone offset"""
@property
def tree(self) -> Tree:
"""Root tree object"""
@property
def tree_id(self) -> Oid:
"""Root tree OID"""
@property
def parents(self) -> list[Commit]:
"""Parent commit objects"""
@property
def parent_ids(self) -> list[Oid]:
"""Parent commit OIDs"""
@property
def raw_message(self) -> bytes:
"""Raw commit message bytes"""
def message_trailers(self) -> dict[str, str]:
"""Parse commit message trailers"""Tree objects represent directory structures in Git, containing references to blobs and other trees.
class Tree(Object):
def __len__(self) -> int:
"""Number of entries in tree"""
def __getitem__(self, key: str | int) -> Object:
"""Get tree entry by name or index"""
def __contains__(self, name: str) -> bool:
"""Check if entry exists in tree"""
def __iter__(self):
"""Iterate over tree entries"""
@property
def id(self) -> Oid:
"""Tree object ID"""
def diff_to_tree(self, tree: 'Tree' = None, **kwargs) -> Diff:
"""Compare with another tree"""
def diff_to_workdir(self, **kwargs) -> Diff:
"""Compare with working directory"""
def diff_to_index(self, **kwargs) -> Diff:
"""Compare with index"""
class TreeEntry:
@property
def name(self) -> str:
"""Entry name"""
@property
def oid(self) -> Oid:
"""Entry object ID"""
@property
def filemode(self) -> int:
"""Entry file mode"""
@property
def type(self) -> int:
"""Entry object type"""TreeBuilder enables programmatic construction of tree objects.
class TreeBuilder:
def __init__(self, repo: Repository, tree: Tree = None):
"""Create tree builder, optionally from existing tree"""
def insert(self, name: str, oid: Oid, filemode: int):
"""Insert entry into tree"""
def remove(self, name: str):
"""Remove entry from tree"""
def __len__(self) -> int:
"""Number of entries"""
def __getitem__(self, name: str) -> Object:
"""Get entry by name"""
def __contains__(self, name: str) -> bool:
"""Check if entry exists"""
def write(self) -> Oid:
"""Write tree to object database"""
def clear(self):
"""Remove all entries"""
# File Mode Constants
GIT_FILEMODE_UNREADABLE: int
GIT_FILEMODE_TREE: int
GIT_FILEMODE_BLOB: int
GIT_FILEMODE_BLOB_EXECUTABLE: int
GIT_FILEMODE_LINK: int
GIT_FILEMODE_COMMIT: intBlob objects store file content data in Git's object database.
class Blob(Object):
@property
def data(self) -> bytes:
"""Blob content as bytes"""
@property
def size(self) -> int:
"""Blob size in bytes"""
@property
def is_binary(self) -> bool:
"""True if blob contains binary data"""
def diff(self, blob: 'Blob' = None, **kwargs) -> Patch:
"""Compare with another blob"""
class BlobIO:
"""Stream interface for large blob content"""
def __init__(self, blob: Blob):
"""Create stream from blob"""
def read(self, size: int = -1) -> bytes:
"""Read blob data"""
def readline(self, size: int = -1) -> bytes:
"""Read single line"""
def readlines(self, hint: int = -1) -> list[bytes]:
"""Read all lines"""
def __iter__(self):
"""Iterate over lines"""Tag objects create named references to other Git objects with optional metadata.
class Tag(Object):
@property
def name(self) -> str:
"""Tag name"""
@property
def target(self) -> Object:
"""Tagged object"""
@property
def target_id(self) -> Oid:
"""Tagged object ID"""
@property
def tagger(self) -> Signature:
"""Tag creator signature"""
@property
def message(self) -> str:
"""Tag message"""
@property
def raw_message(self) -> bytes:
"""Raw tag message bytes"""
def peel(self, target_type: int = None) -> Object:
"""Peel tag to target object type"""Oid class represents Git object identifiers (SHA-1 hashes).
class Oid:
def __init__(self, raw: bytes | str):
"""Create OID from raw bytes or hex string"""
@property
def raw(self) -> bytes:
"""Raw bytes representation"""
@property
def hex(self) -> str:
"""Hexadecimal string representation"""
def __str__(self) -> str:
"""Hex string representation"""
def __eq__(self, other) -> bool:
"""Compare OIDs"""
def __hash__(self) -> int:
"""Hash for use in collections"""
# OID Constants
GIT_OID_RAWSZ: int # Raw OID size (20 bytes)
GIT_OID_HEXSZ: int # Hex OID size (40 chars)
GIT_OID_MINPREFIXLEN: int # Minimum prefix length
GIT_OID_HEX_ZERO: str # Zero OID hex stringSignature class represents author and committer information in commits and tags.
class Signature:
def __init__(
self,
name: str,
email: str,
time: int = None,
offset: int = None,
encoding: str = 'utf-8'
):
"""
Create signature.
Parameters:
- name: Person's name
- email: Email address
- time: Unix timestamp (default: current time)
- offset: Timezone offset in minutes
- encoding: Text encoding
"""
@property
def name(self) -> str:
"""Person's name"""
@property
def email(self) -> str:
"""Email address"""
@property
def time(self) -> int:
"""Unix timestamp"""
@property
def offset(self) -> int:
"""Timezone offset in minutes"""
@property
def encoding(self) -> str:
"""Text encoding"""
def __str__(self) -> str:
"""String representation"""
def __eq__(self, other) -> bool:
"""Compare signatures"""import pygit2
repo = pygit2.Repository('/path/to/repo')
# Get latest commit
commit = repo[repo.head.target]
print(f"Commit: {commit.oid}")
print(f"Author: {commit.author.name} <{commit.author.email}>")
print(f"Message: {commit.message}")
print(f"Tree: {commit.tree_id}")
# Walk commit history
for commit in repo.walk(repo.head.target):
print(f"{commit.oid}: {commit.message.split('\n')[0]}")
if len(commit.parents) > 1:
print(" (merge commit)")# Explore tree structure
tree = repo[commit.tree]
for entry in tree:
obj = repo[entry.oid]
if entry.type == pygit2.GIT_OBJECT_TREE:
print(f"Directory: {entry.name}/")
elif entry.type == pygit2.GIT_OBJECT_BLOB:
blob = obj
print(f"File: {entry.name} ({blob.size} bytes)")
if not blob.is_binary:
content = blob.data.decode('utf-8')
print(f" Preview: {content[:50]}...")
# Create new tree
builder = pygit2.TreeBuilder(repo)
blob_oid = repo.create_blob(b"Hello, World!")
builder.insert("hello.txt", blob_oid, pygit2.GIT_FILEMODE_BLOB)
tree_oid = builder.write()# Create signature
signature = pygit2.Signature(
'John Doe',
'john@example.com'
)
# Create blob from data
blob_oid = repo.create_blob(b"File content")
# Create tree with blob
builder = pygit2.TreeBuilder(repo)
builder.insert("file.txt", blob_oid, pygit2.GIT_FILEMODE_BLOB)
tree_oid = builder.write()
# Create commit
commit_oid = repo.create_commit(
'refs/heads/main',
signature, # author
signature, # committer
'Add new file',
tree_oid,
[] # parents
)
# Create tag
tag_oid = repo.create_tag(
'v1.0.0',
commit_oid,
signature,
'Version 1.0.0 release'
)# Stream large blob content
blob = repo[blob_oid]
if blob.size > 1024 * 1024: # > 1MB
stream = pygit2.BlobIO(blob)
while True:
chunk = stream.read(8192)
if not chunk:
break
# Process chunk
process_data(chunk)Install with Tessl CLI
npx tessl i tessl/pypi-pygit2