Python bindings for libgit2 providing comprehensive Git repository operations and version control functionality.
—
Git configuration management for repository, global, and system settings. Provides type-safe access to Git configuration values with support for multiple configuration levels and data types.
The Config class provides access to Git configuration at various levels with type-safe value retrieval.
class Config:
# Value Access
def __getitem__(self, key: str):
"""Get configuration value"""
def __setitem__(self, key: str, value):
"""Set configuration value"""
def __delitem__(self, key: str):
"""Delete configuration key"""
def __contains__(self, key: str) -> bool:
"""Check if key exists"""
def __iter__(self):
"""Iterate over configuration entries"""
def get(self, key: str, default=None):
"""Get value with default fallback"""
# Typed Value Access
def get_bool(self, key: str) -> bool:
"""Get boolean value"""
def get_int(self, key: str) -> int:
"""Get integer value"""
def get_string(self, key: str) -> str:
"""Get string value"""
def get_multivar(self, key: str) -> list[str]:
"""Get multiple values for key"""
def set_multivar(self, key: str, pattern: str, value: str):
"""Set multiple values matching pattern"""
def delete_multivar(self, key: str, pattern: str):
"""Delete multiple values matching pattern"""
# Configuration Management
def add_file(self, path: str, level: int, force: bool = False):
"""Add configuration file"""
def snapshot(self) -> 'Config':
"""Create immutable snapshot"""
def parse_bool(self, value: str) -> bool:
"""Parse string as boolean"""
def parse_int32(self, value: str) -> int:
"""Parse string as 32-bit integer"""
def parse_int64(self, value: str) -> int:
"""Parse string as 64-bit integer"""
# Repository config access
class Repository:
@property
def config(self) -> Config:
"""Repository configuration (all levels)"""
@property
def config_snapshot(self) -> Config:
"""Immutable configuration snapshot"""
# Global config access
def config_global() -> Config:
"""Get global configuration"""
def config_system() -> Config:
"""Get system configuration"""ConfigEntry provides detailed information about individual configuration values.
class ConfigEntry:
@property
def name(self) -> str:
"""Configuration key name"""
@property
def value(self) -> str:
"""Configuration value as string"""
@property
def level(self) -> int:
"""Configuration level"""
@property
def include_depth(self) -> int:
"""Include file depth"""
@property
def free(self):
"""Free entry resources"""Iterate over configuration entries with filtering capabilities.
class ConfigIterator:
def __init__(self, config: Config, pattern: str = None):
"""Create iterator for config entries"""
def __iter__(self):
"""Iterate over matching entries"""
def __next__(self) -> ConfigEntry:
"""Get next entry"""
class ConfigMultivarIterator:
def __init__(self, config: Config, name: str, pattern: str = None):
"""Create iterator for multivar entries"""
def __iter__(self):
"""Iterate over multivar values"""
def __next__(self) -> ConfigEntry:
"""Get next multivar entry"""Constants defining the hierarchy of configuration files.
# Configuration Level Constants
GIT_CONFIG_LEVEL_SYSTEM: int # System-wide config (/etc/gitconfig)
GIT_CONFIG_LEVEL_XDG: int # User XDG config (~/.config/git/config)
GIT_CONFIG_LEVEL_GLOBAL: int # User global config (~/.gitconfig)
GIT_CONFIG_LEVEL_LOCAL: int # Repository config (.git/config)
GIT_CONFIG_LEVEL_WORKTREE: int # Worktree config (.git/config.worktree)
GIT_CONFIG_LEVEL_APP: int # Application-specific config
GIT_CONFIG_LEVEL_PROGRAMDATA: int # Windows program data config
GIT_CONFIG_HIGHEST_LEVEL: int # Highest priority levelAccess and modify Git configuration at specific levels.
def config_find_global() -> str:
"""Find path to global config file"""
def config_find_system() -> str:
"""Find path to system config file"""
def config_find_xdg() -> str:
"""Find path to XDG config file"""
def config_find_programdata() -> str:
"""Find path to program data config file"""import pygit2
repo = pygit2.Repository('/path/to/repo')
config = repo.config
# Get configuration values
user_name = config['user.name']
user_email = config['user.email']
print(f"User: {user_name} <{user_email}>")
# Set configuration values
config['user.name'] = 'John Doe'
config['user.email'] = 'john@example.com'
# Check if key exists
if 'core.autocrlf' in config:
autocrlf = config['core.autocrlf']
print(f"Auto CRLF: {autocrlf}")
# Get with default
editor = config.get('core.editor', 'nano')
print(f"Editor: {editor}")# Boolean values
bare = config.get_bool('core.bare')
ignore_case = config.get_bool('core.ignorecase')
# Integer values
abbrev = config.get_int('core.abbrev')
filemode = config.get_int('core.filemode')
# Handle missing keys with defaults
try:
push_default = config.get_string('push.default')
except KeyError:
push_default = 'simple'
print(f"Push default: {push_default}")# Get all values for a key (like multiple remotes)
try:
remote_urls = config.get_multivar('remote.origin.url')
for url in remote_urls:
print(f"Origin URL: {url}")
except KeyError:
print("No origin remote configured")
# Set multiple values
config.set_multivar('remote.backup.url', '.*', 'https://backup1.com/repo.git')
config.set_multivar('remote.backup.url', '.*', 'https://backup2.com/repo.git')
# Delete specific multivar
config.delete_multivar('remote.backup.url', 'backup2')# Access different configuration levels
global_config = pygit2.config_global()
global_config['user.name'] = 'Global User'
system_config = pygit2.config_system()
# system_config is usually read-only
# Repository-specific config
repo.config['user.name'] = 'Repo Specific User'
# The effective value considers all levels
effective_name = repo.config['user.name'] # Will be 'Repo Specific User'# Iterate over all configuration entries
print("All configuration:")
for entry in config:
print(f"{entry.name} = {entry.value} (level: {entry.level})")
# Iterate over specific pattern
print("\nUser configuration:")
for entry in pygit2.ConfigIterator(config, 'user.*'):
print(f"{entry.name} = {entry.value}")
# Iterate over multivar entries
for entry in pygit2.ConfigMultivarIterator(config, 'remote.origin.url'):
print(f"Origin URL: {entry.value}")# Create immutable snapshot
snapshot = config.snapshot()
# Snapshot values don't change even if config is modified
original_name = snapshot['user.name']
config['user.name'] = 'Changed Name'
snapshot_name = snapshot['user.name'] # Still original value
print(f"Original: {original_name}")
print(f"Current: {config['user.name']}")
print(f"Snapshot: {snapshot_name}")# Set up user identity
config['user.name'] = 'Jane Developer'
config['user.email'] = 'jane@company.com'
config['user.signingkey'] = 'GPG_KEY_ID'
# Configure editor and diff tool
config['core.editor'] = 'code --wait'
config['merge.tool'] = 'vscode'
config['mergetool.vscode.cmd'] = 'code --wait $MERGED'
# Set up aliases
config['alias.st'] = 'status'
config['alias.co'] = 'checkout'
config['alias.br'] = 'branch'
config['alias.lg'] = 'log --oneline --graph --all'
# Configure line endings
config['core.autocrlf'] = 'input' # Linux/Mac
# config['core.autocrlf'] = 'true' # Windows
# Configure push behavior
config['push.default'] = 'simple'
config['push.followTags'] = 'true'
# Configure pull behavior
config['pull.rebase'] = 'false'
# Configure colors
config['color.ui'] = 'auto'
config['color.status'] = 'auto'
config['color.diff'] = 'auto'
config['color.branch'] = 'auto'# Set up repository-specific hooks path
config['core.hooksPath'] = '.githooks'
# Configure repository-specific gitignore
config['core.excludesfile'] = '.gitignore_global'
# Set up work tree specific settings
config['core.worktree'] = '../working-directory'
# Configure sparse checkout
config['core.sparseCheckout'] = 'true'
# Set up Git LFS
config['filter.lfs.clean'] = 'git-lfs clean -- %f'
config['filter.lfs.smudge'] = 'git-lfs smudge -- %f'
config['filter.lfs.process'] = 'git-lfs filter-process'
config['filter.lfs.required'] = 'true'# Working with included config files
config.add_file('/path/to/custom.config', pygit2.GIT_CONFIG_LEVEL_LOCAL)
# Parse configuration values
bool_val = config.parse_bool('true') # True
int_val = config.parse_int32('42') # 42
int_val = config.parse_int64('1000000') # 1000000
# Find config file paths
try:
global_path = pygit2.config_find_global()
print(f"Global config: {global_path}")
system_path = pygit2.config_find_system()
print(f"System config: {system_path}")
xdg_path = pygit2.config_find_xdg()
print(f"XDG config: {xdg_path}")
except OSError as e:
print(f"Config file not found: {e}")
# Delete configuration keys
del config['old.setting']
# Check configuration level priority
for entry in config:
level_names = {
pygit2.GIT_CONFIG_LEVEL_SYSTEM: 'system',
pygit2.GIT_CONFIG_LEVEL_GLOBAL: 'global',
pygit2.GIT_CONFIG_LEVEL_LOCAL: 'local',
pygit2.GIT_CONFIG_LEVEL_WORKTREE: 'worktree'
}
level_name = level_names.get(entry.level, f'level-{entry.level}')
print(f"{entry.name} = {entry.value} ({level_name})")Install with Tessl CLI
npx tessl i tessl/pypi-pygit2