### Full Build, Install, and Test Source: https://github.com/libgit2/pygit2/blob/master/AGENTS.md Builds a wheel package, installs it, and then runs the tests. This simulates a user installation process. ```bash sh build.sh wheel ``` -------------------------------- ### Install pygit2 and verify Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Installs pygit2 using pip and verifies the installation by importing it in a Python script. ```sh pip install pygit2 # ... python -c 'import pygit2' ``` -------------------------------- ### Install libgit2 from source (System-wide) Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Installs the latest version of libgit2 system-wide to the /usr/local directory. Requires a C compiler and Python development headers. ```sh wget https://github.com/libgit2/libgit2/archive/refs/tags/v1.9.4.tar.gz -O libgit2-1.9.4.tar.gz tar -xzf libgit2-1.9.4.tar.gz cd libgit2-1.9.4/ cmake . make sudo make install ``` -------------------------------- ### Install pygit2 using pip Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Installs or upgrades pip and then installs the pygit2 library. This method attempts to use pre-compiled binary wheels for faster installation. ```sh pip install -U pip pip install pygit2 ``` -------------------------------- ### Install libgit2 and pygit2 on OS X using Homebrew Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md This command sequence installs libgit2 using Homebrew and then installs pygit2 using pip3 on OS X. ```sh brew update brew install libgit2 pip3 install pygit2 ``` -------------------------------- ### Build libgit2 from source on Windows Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md This PowerShell script demonstrates how to clone, build, and install libgit2 from source on Windows, setting environment variables for the build process. ```pwsh git clone --depth=1 -b v1.9.4 https://github.com/libgit2/libgit2.git $env:CMAKE_INSTALL_PREFIX = "C:/Dev/libgit2" $env:CMAKE_GENERATOR = "Visual Studio 17 2022" # or "Visual Studio 18 2026" $env:CMAKE_GENERATOR_PLATFORM = "x64" # or "Win32" or "ARM64" cmake -B libgit2/build -S libgit2 cmake --build libgit2/build --config release --target install # let pip know where to find libgit2 when building pygit2 $env:LIBGIT2 = "$env:CMAKE_INSTALL_PREFIX" ``` -------------------------------- ### Install libgit2 in a virtual environment Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Installs libgit2 within a virtual environment, specifying the installation prefix to the virtual environment's root. ```sh wget https://github.com/libgit2/libgit2/archive/refs/tags/v1.9.4.tar.gz -O libgit2-1.9.4.tar.gz tar xzf libgit2-1.9.4.tar.gz cd libgit2-1.9.4/ cmake . -DCMAKE_INSTALL_PREFIX=$LIBGIT2 cmake --build . --target install ``` -------------------------------- ### Install Sphinx Theme for Docs Source: https://github.com/libgit2/pygit2/blob/master/docs/development.md Install the sphinx-rtd-theme package using pip. This is a prerequisite for building the documentation. ```sh pip install sphinx-rtd-theme ``` -------------------------------- ### Install pygit2 using pip on Windows Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Use this command to install the pygit2 wheel package on Windows. ```console pip install pygit2 ``` -------------------------------- ### Quick Development Build Source: https://github.com/libgit2/pygit2/blob/master/AGENTS.md Builds the C extension inplace and runs tests. Requires libgit2 development headers and library to be installed or pointed to via LIBGIT2 environment variable. ```bash python setup.py build_ext --inplace pytest ``` -------------------------------- ### Get libgit2 Version String Source: https://github.com/libgit2/pygit2/blob/master/docs/general.md Obtain the full version number of the linked libgit2 library as a string. Example: '1.9.4'. ```python >>> print(pygit2.LIBGIT2_VERSION) '1.9.4' ``` -------------------------------- ### Pytest Configuration Example Source: https://github.com/libgit2/pygit2/blob/master/AGENTS.md Shows the pytest configuration settings used for running tests, including capture mode, verbosity, and test path. ```ini [pytest] addopts = --capture=no -ra --verbose testpaths = test/ ``` -------------------------------- ### Install pygit2 in a virtual environment with rpath Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Installs pygit2 within a virtual environment, setting the LDFLAGS to include the rpath for the libgit2 library, and verifies the installation. ```sh export LDFLAGS="-Wl,-rpath,'$LIBGIT2/lib',--enable-new-dtags $LDFLAGS" # on OSX: export LDFLAGS="-Wl,-rpath,'$LIBGIT2/lib' $LDFLAGS" pip install pygit2 python -c 'import pygit2' ``` -------------------------------- ### Install Requirements for Valgrind Testing Source: https://github.com/libgit2/pygit2/blob/master/docs/development.md Install pygit2 and pytest using the debug-enabled Python interpreter. This prepares the environment for Valgrind execution. ```sh $PYTHONBIN/python3 setup.py install pip install pytest ``` -------------------------------- ### Python Documentation String Format Source: https://github.com/libgit2/pygit2/blob/master/docs/development.md Illustrates the expected format for documentation strings in pygit2, including general description, parameters, and examples. ```python def f(a, b): """ The general description goes here. Returns: bla bla. Parameters: a : Bla bla. b : Bla bla. Examples:: >>> f(...) """ ``` -------------------------------- ### Accessing and Listing References Source: https://github.com/libgit2/pygit2/blob/master/docs/references.md Demonstrates how to get a list of all references and access a specific reference by its name. ```APIDOC ## Accessing and Listing References ### Description Get a list of all references or access a specific reference by its name. ### Usage ```python # Get all references all_refs = list(repo.references) # Access a specific reference by name master_ref = repo.references["refs/heads/master"] # Get a reference, returning None if not found head = repo.references.get('refs/heads/master') # Access HEAD reference head = repo.head ``` ``` -------------------------------- ### Valgrind Memory Leak Summary Example Source: https://github.com/libgit2/pygit2/wiki/Guidelines This is an example of a successful Valgrind memory leak check summary. 'Definitely lost' and 'indirectly lost' should ideally be 0 bytes. ```text ==23689== LEAK SUMMARY: ==23689== definitely lost: 0 bytes in 0 blocks ==23689== indirectly lost: 0 bytes in 0 blocks ==23689== possibly lost: 498,605 bytes in 3,381 blocks ==23689== still reachable: 1,329,196 bytes in 10,504 blocks ==23689== suppressed: 0 bytes in 0 blocks ``` -------------------------------- ### Python Docstring Style Source: https://github.com/libgit2/pygit2/blob/master/CONTRIBUTING.md Example of the required docstring format for Python functions. ```python def f(a, b): """ The general description goes here. Returns: bla bla. Parameters: a : Bla bla. b : Bla bla. """ ``` -------------------------------- ### Get libgit2 Version Tuple Source: https://github.com/libgit2/pygit2/blob/master/docs/general.md Retrieve the version numbers of the linked libgit2 library as a tuple. Example: for version '1.9.4', this returns (1, 9, 4). ```python >>> print(pygit2.LIBGIT2_VER) (1, 9, 4) ``` -------------------------------- ### Iterate and access Tree entries Source: https://github.com/libgit2/pygit2/blob/master/docs/objects.md Provides an example of iterating through a tree object to access its entries, and how to retrieve a specific entry by name. ```Python tree = commit.tree print(len(tree)) # Number of entries for obj in tree: # Iteration print(obj.id, obj.type_str, obj.name) obj = tree / 'pygit2.c' # Get an object by name print(obj) ``` -------------------------------- ### Pygit2 Clone with Custom SSH Credentials Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-clone-ssh.md Shows how to clone a repository using pygit2 with custom SSH credentials. This example defines a `RemoteCallbacks` class to handle username and SSH key authentication. ```python class MyRemoteCallbacks(pygit2.RemoteCallbacks): def credentials(self, url, username_from_url, allowed_types): if allowed_types & pygit2.enums.CredentialType.USERNAME: return pygit2.Username("git") elif allowed_types & pygit2.enums.CredentialType.SSH_KEY: return pygit2.Keypair("git", "id_rsa.pub", "id_rsa", "") else: return None print("Cloning pygit2 over ssh") pygit2.clone_repository("ssh://github.com/libgit2/pygit2", "pygit2.git", callbacks=MyRemoteCallbacks()) ``` -------------------------------- ### Access Reference Log Entries Source: https://github.com/libgit2/pygit2/blob/master/docs/references.md Shows how to retrieve a specific reference and iterate through its log entries, printing the message for each entry. It highlights the difference between `get` (returns None if not found) and dictionary access (raises KeyError if not found). ```python >>> head = repo.references.get('refs/heads/master') # Returns None if not found >>> # Almost equivalent to >>> head = repo.references['refs/heads/master'] # Raises KeyError if not found >>> for entry in head.log(): ... print(entry.message) ``` -------------------------------- ### Set LD_LIBRARY_PATH for non-standard libgit2 location Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Demonstrates setting the LD_LIBRARY_PATH environment variable to point to the libgit2 library directory when it's installed in a non-standard location. ```sh export LD_LIBRARY_PATH=$LIBGIT2/lib python -c 'import pygit2' ``` -------------------------------- ### Get Commit Author Signature Source: https://github.com/libgit2/pygit2/blob/master/docs/objects.md Demonstrates how to access the author information of a commit, which is represented as a pygit2.Signature object. ```Python print(commit.author) ``` -------------------------------- ### Get All Patches for a Diff Source: https://github.com/libgit2/pygit2/blob/master/docs/diff.md Iterate through a diff object to retrieve all individual patches. This is useful for detailed analysis of changes. ```python # Get all patches for a diff >>> diff = repo.diff('HEAD^', 'HEAD~3') >>> patches = [p for p in diff] ``` -------------------------------- ### Get Diff Statistics Source: https://github.com/libgit2/pygit2/blob/master/docs/diff.md Access the statistics of a diff, which typically include the number of files changed and lines added/deleted. This provides a high-level overview of the changes. ```python # Get the stats for a diff >>> diff = repo.diff('HEAD^', 'HEAD~3') >>> diff.stats ``` -------------------------------- ### Traverse Commit History using pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-log.md Iterate through the commit history starting from the HEAD commit and print each commit message. This demonstrates traversing the commit graph. ```python >>> last = repo[repo.head.target] >>> for commit in repo.walk(last.id, pygit2.enums.SortMode.TIME): >>> print(commit.message) # or some other operation ``` -------------------------------- ### Build Documentation Source: https://github.com/libgit2/pygit2/blob/master/CONTRIBUTING.md Generate HTML documentation locally. Requires sphinx-rtd-theme. ```bash make -C docs html ``` -------------------------------- ### Get libgit2 Revision Version Source: https://github.com/libgit2/pygit2/blob/master/docs/general.md Access the revision number of the linked libgit2 library. Example: for version '1.9.4', this returns 4. ```python >>> print(pygit2.LIBGIT2_VER_REVISION) 4 ``` -------------------------------- ### Get libgit2 Minor Version Source: https://github.com/libgit2/pygit2/blob/master/docs/general.md Access the minor version number of the linked libgit2 library. Example: for version '1.9.4', this returns 9. ```python >>> print(pygit2.LIBGIT2_VER_MINOR) 9 ``` -------------------------------- ### Get libgit2 Major Version Source: https://github.com/libgit2/pygit2/blob/master/docs/general.md Access the major version number of the linked libgit2 library. Example: for version '1.9.4', this returns 1. ```python >>> print(pygit2.LIBGIT2_VER_MAJOR) 1 ``` -------------------------------- ### Create Standard Repository (CLI) Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-init.md Use this command to initialize a new standard Git repository with a working directory. ```bash git init path/to/git ``` -------------------------------- ### Create Bare Repository (CLI) Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-init.md Use this command to initialize a new bare Git repository. Bare repositories do not have a working directory and are typically used for central repositories. ```bash git init --bare path/to/git ``` -------------------------------- ### Create Bare Repository (pygit2) Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-init.md Initialize a bare repository using pygit2. Set the second argument to True to create a bare repository. ```python pygit2.init_repository('path/to/git', True) ``` -------------------------------- ### Set up virtual environment for pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Creates and activates a virtual environment, setting the LIBGIT2 environment variable to the virtual environment's root. ```sh virtualenv venv source venv/bin/activate export LIBGIT2=$VIRTUAL_ENV ``` -------------------------------- ### Clone Repository as Mirror (Git) Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-clone-mirror.md Use the `--mirror` flag with `git clone` to create a mirror of the repository. This copies all refs and sets up the repository for mirroring. ```bash $ git clone --mirror https://github.com/libgit2/pygit2 ``` -------------------------------- ### Create Standard Repository (pygit2) Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-init.md Initialize a standard Git repository using pygit2. Set the second argument to False to create a standard repository. ```python pygit2.init_repository('path/to/git', False) ``` -------------------------------- ### Initial Commit with Git CLI Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-commit.md Use this command to add all changes and create the initial commit. ```bash $ git add . $ git commit -m "Initial commit" ``` -------------------------------- ### Clone and Build pygit2 for Testing Source: https://github.com/libgit2/pygit2/blob/master/docs/development.md Clone the repository, build the extension in-place, and run pytest to execute unit tests. ```sh git clone git://github.com/libgit2/pygit2.git cd pygit2 python setup.py build_ext --inplace pytest test ``` -------------------------------- ### Full Build with Bundled Dependencies Source: https://github.com/libgit2/pygit2/blob/master/AGENTS.md Builds the pygit2 extension inplace, bundling libgit2, libssh2, and OpenSSL. This is a convenience target. ```bash make ``` -------------------------------- ### Creating a Reference Source: https://github.com/libgit2/pygit2/blob/master/docs/references.md Shows how to create a new reference in the repository. ```APIDOC ## Creating a Reference ### Description Creates a new reference with a given name and target. ### Usage ```python # Create a new tag reference ref = repo.references.create('refs/tags/version1', LAST_COMMIT) ``` ``` -------------------------------- ### List and Manage Repository References Source: https://github.com/libgit2/pygit2/blob/master/docs/references.md Demonstrates common operations on repository references, such as listing all references, accessing a specific reference by name, peeling a reference to its commit, creating a new tag reference, deleting a reference, and compressing loose references. ```python >>> all_refs = list(repo.references) >>> master_ref = repo.references["refs/heads/master"] >>> commit = master_ref.peel() # or repo[master_ref.target] # Create a reference >>> ref = repo.references.create('refs/tags/version1', LAST_COMMIT) # Delete a reference >>> repo.references.delete('refs/tags/version1') # Pack loose references >>> repo.references.compress() ``` -------------------------------- ### Show All Git Tags Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-tag.md Use the 'git tag' command to list all available tags in the repository. ```bash git tag ``` -------------------------------- ### Build pygit2 In-place Source: https://github.com/libgit2/pygit2/blob/master/docs/development.md Build the pygit2 C extension in-place using the make command. This is required before building the documentation. ```sh make ``` -------------------------------- ### Initial Commit with pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-commit.md Create an initial commit by adding all changes and writing the index to create a tree, then creating the commit. ```python >>> index = repo.index >>> index.add_all() >>> index.write() >>> ref = "HEAD" >>> author = Signature('Alice Author', 'alice@authors.tld') >>> committer = Signature('Cecil Committer', 'cecil@committers.tld') >>> message = "Initial commit" >>> tree = index.write_tree() >>> parents = [] >>> repo.create_commit(ref, author, committer, message, tree, parents) ``` -------------------------------- ### Build pygit2 Documentation Source: https://github.com/libgit2/pygit2/blob/master/docs/development.md Generate the HTML documentation for pygit2 by running the make command with the 'docs html' target. ```sh make -C docs html ``` -------------------------------- ### Troubleshooting ImportError Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Demonstrates the common ImportError when the dynamic linker cannot find the libgit2 library and the fix using ldconfig. ```text python -c 'import pygit2' Traceback (most recent call last): File "", line 1, in File "pygit2/__init__.py", line 29, in from ._pygit2 import * ImportError: libgit2.so.0: cannot open shared object file: No such file or directory ``` -------------------------------- ### Full Build and Test Execution Source: https://github.com/libgit2/pygit2/blob/master/AGENTS.md Builds the pygit2 project and then runs the tests. The build.sh script automatically adds coverage flags when tests are run. ```bash sh build.sh test ``` -------------------------------- ### Basic Git Clone via SSH Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-clone-ssh.md Demonstrates a standard Git clone operation using an SSH URL. This is a common way to clone repositories when SSH access is configured. ```bash $ git clone git@example.com ``` -------------------------------- ### Initialize and Add Entry to an Independent Index in pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/index_file.md Demonstrates creating an index object independently of a repository and adding a custom entry to it. This is useful for scenarios where you need to build an index from scratch. ```python >>> index = pygit2.Index() >>> entry = pygit2.IndexEntry('README.md', blob_id, blob_filemode) >>> index.add(entry) ``` -------------------------------- ### Diff Empty Tree to Tree Source: https://github.com/libgit2/pygit2/blob/master/docs/diff.md Compare an empty tree with an existing tree to see what changes would be needed to create that tree from scratch. The `swap` argument can reverse the comparison. ```python # Diffing the empty tree >>> tree = revparse_single('HEAD').tree >>> tree.diff_to_tree() # Diff empty tree to a tree >>> tree = revparse_single('HEAD').tree >>> tree.diff_to_tree(swap=True) ``` -------------------------------- ### Show All Files in Commit Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-show.md Iterate through and print the names of all files present in a commit's tree. ```python for e in commit.tree: print(e.name) ``` -------------------------------- ### Manual Full Build with Specific Versions Source: https://github.com/libgit2/pygit2/blob/master/AGENTS.md Manually builds pygit2 by downloading and compiling specific versions of libssh2 and libgit2. Use this for precise control over dependency versions. ```bash LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.4 sh build.sh ``` -------------------------------- ### Create a new Commit Source: https://github.com/libgit2/pygit2/blob/master/docs/objects.md Shows the process of creating a new commit in the repository, including specifying author, committer, tree, message, and parent commits. ```Python from pygit2 import Signature author = Signature('Alice Author', 'alice@authors.tld') committer = Signature('Cecil Committer', 'cecil@committers.tld') tree = repo.TreeBuilder().write() repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'one line commit message\n\ndetailed commit message', tree, # binary string representing the tree object ID [] # list of binary strings representing parents of the new commit ) ``` -------------------------------- ### Run Stubtest Source: https://github.com/libgit2/pygit2/blob/master/AGENTS.md Runs stubtest against the mypy stub file (_pygit2.pyi) for pygit2 using the build.sh script. ```bash sh build.sh stubtest ``` -------------------------------- ### Run Linters and Type Checkers Source: https://github.com/libgit2/pygit2/blob/master/CONTRIBUTING.md Apply code formatting, check for style issues, and validate type stubs. ```bash ruff format --diff ``` ```bash ruff check ``` ```bash sh build.sh mypy # or: mypy ``` ```bash sh build.sh stubtest # validate .pyi stubs ``` -------------------------------- ### Signed Commit with Git CLI Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-commit.md Use this command to add all changes and create a commit with a GPG signature. ```bash $ git add . $ git commit -S -m "Signed commit" ``` -------------------------------- ### Stage a file with pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-add-reset.md Use this to add a new or modified file to the Git index, similar to `git add`. ```bash $ git add foo.txt ``` ```python >>> index = repo.index >>> index.add(path) >>> index.write() ``` -------------------------------- ### Verify rpath setting in pygit2 extension module Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Uses readelf to inspect the dynamic section of the pygit2 extension module, showing the hard-coded RUNPATH. ```sh readelf --dynamic lib/python2.7/site-packages/pygit2-0.27.0-py2.7-linux-x86_64.egg/pygit2/_pygit2.so | grep PATH ``` -------------------------------- ### Sign Commit String and Add to Repository with pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-commit.md Sign the prepared commit string using a GPG tool and then create the commit object in the repository using the signed commit data. Finally, update the HEAD to point to the new commit. ```python >>> gpg = YourGPGToolHere() >>> signed_commit = gpg.sign( >>> commit_string, >>> passphrase='secret', >>> detach=True, >>> ) ``` ```python >>> commit = repo.create_commit_with_signature( >>> commit_string, signed_commit.data.decode('utf-8') >>> ) >>> repo.head.set_target(commit) ``` -------------------------------- ### Pygit2 Clone with Username in URL and SSH Key Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-clone-ssh.md Illustrates cloning a repository with pygit2 where the username is included in the SSH URL and SSH key authentication is used. This is an alternative method for specifying credentials. ```python print("Cloning pygit2 over ssh with the username in the URL") keypair = pygit2.Keypair("git", "id_rsa.pub", "id_rsa", "") callbacks = pygit2.RemoteCallbacks(credentials=keypair) pygit2.clone_repository("ssh://git@github.com/libgit2/pygit2", "pygit2.git", callbacks=callbacks) ``` -------------------------------- ### Perform Atomic Reference Updates with Transactions Source: https://github.com/libgit2/pygit2/blob/master/docs/references.md Demonstrates how to use reference transactions for atomically updating multiple references. This ensures that either all changes are applied successfully, or none are. ```python # Update multiple refs atomically with repo.transaction() as txn: txn.lock_ref('refs/heads/master') txn.lock_ref('refs/heads/develop') txn.set_target('refs/heads/master', new_oid, message='Release') txn.set_target('refs/heads/develop', dev_oid, message='Continue dev') ``` -------------------------------- ### Clone Repository as Mirror (pygit2) Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-clone-mirror.md Use `pygit2.clone_repository` with a custom remote configuration to achieve mirroring. This involves setting a refspec to copy all refs and enabling the mirror option for the remote. ```python def init_remote(repo, name, url): # Create the remote with a mirroring url remote = repo.remotes.create(name, url, "+refs/*:refs/*") # And set the configuration option to true for the push command mirror_var = f"remote.{name.decode()}.mirror" repo.config[mirror_var] = True # Return the remote, which pygit2 will use to perform the clone return remote print("Cloning pygit2 as mirror") pygit2.clone_repository("https://github.com/libgit2/pygit2", "pygit2.git", bare=True, remote=init_remote) ``` -------------------------------- ### Create Commit String for Signing with pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-commit.md Prepare a commit string that can be signed by an external GPG tool. This involves adding all changes, writing the index, and creating the commit string without directly creating a commit object in the repository. ```python >>> index = repo.index >>> index.add_all() >>> index.write() >>> author = Signature('Alice Author', 'alice@authors.tld') >>> committer = Signature('Cecil Committer', 'cecil@committers.tld') >>> message = "Signed commit" >>> tree = index.write_tree() >>> parents = [] >>> commit_string = repo.create_commit_string( >>> author, committer, message, tree, parents >>> ) ``` -------------------------------- ### Compressing References Source: https://github.com/libgit2/pygit2/blob/master/docs/references.md Explains how to pack loose references into a more efficient format. ```APIDOC ## Compressing References ### Description Packs loose references into a more efficient format. ### Usage ```python # Pack loose references repo.references.compress() ``` ``` -------------------------------- ### Show a Commit by SHA Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-show.md Retrieve a commit object from a repository using its SHA hash. This is the first step to accessing commit details. ```bash git show d370f56 ``` ```python repo = pygit2.Repository('/path/to/repository') commit = repo.revparse_single('d370f56') ``` -------------------------------- ### Clone Repository with Progress Monitor Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-clone-progress.md Use this snippet to clone a repository and monitor the transfer progress by implementing a custom RemoteCallbacks class. ```bash $ git clone https://github.com/libgit2/pygit2 ``` ```python class MyRemoteCallbacks(pygit2.RemoteCallbacks): def transfer_progress(self, stats): print(f'{stats.indexed_objects}/{stats.total_objects}') print("Cloning pygit2") pygit2.clone_repository("https://github.com/libgit2/pygit2", "pygit2.git", callbacks=MyRemoteCallbacks()) ``` -------------------------------- ### Attempting to instantiate a Git Object directly Source: https://github.com/libgit2/pygit2/blob/master/docs/objects.md Shows that derived Git object types (like Blob) cannot be instantiated directly using their class constructors. ```Python from pygit2 import Blob blob = Blob("data") # This will raise a TypeError: cannot create '_pygit2.Blob' instances ``` -------------------------------- ### Configure Python for Valgrind Debugging Source: https://github.com/libgit2/pygit2/blob/master/docs/development.md Configure and build a Python interpreter with specific flags for debugging with Valgrind. Ensure debug symbols are enabled. ```sh ./configure --prefix=~/Python-3.9.18 --without-pymalloc --with-pydebug --with-valgrind make make install export PYTHONBIN=~/Python-3.9.18/bin ``` -------------------------------- ### Create and Add Custom Index Entry in pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/index_file.md Explains how to create a custom IndexEntry object with a path, blob ID, and file mode, and then add it to the repository's index. This allows for manual manipulation of index contents. ```python >>> entry = pygit2.IndexEntry('README.md', blob_id, blob_filemode) >>> repo.index.add(entry) ``` -------------------------------- ### List All Branches Source: https://github.com/libgit2/pygit2/blob/master/docs/branches.md Lists all branches (local and remote) in the repository. Use `.local` or `.remote` for filtered lists. ```python >>> # Listing all branches >>> branches_list = list(repo.branches) >>> # Local only >>> local_branches = list(repo.branches.local) >>> # Remote only >>> remote_branches = list(repo.branches.remote) ``` -------------------------------- ### Read and Access Index Entries in pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/index_file.md Demonstrates how to read the index file into memory and access specific entries by path to retrieve their object IDs. This is useful for inspecting the current state of the index. ```python >>> index = repo.index >>> index.read() >>> id = index['path/to/file'].id # from path to object id >>> blob = repo[id] # from object id to object ``` -------------------------------- ### Iterate Over Index Entries in pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/index_file.md Shows how to iterate through all entries present in the Git index. This is helpful for processing or displaying the contents of the index. ```python >>> for entry in index: ... print(entry.path, entry.id) ``` -------------------------------- ### Reference Log Source: https://github.com/libgit2/pygit2/blob/master/docs/references.md Shows how to iterate through the log entries for a specific reference. ```APIDOC ## Reference Log ### Description Iterate through the log entries associated with a reference. ### Usage ```python # Get a reference head = repo.references['refs/heads/master'] # Iterate through log entries for entry in head.log(): print(entry.message) ``` ``` -------------------------------- ### Build pygit2 with Debug Symbols for Valgrind Source: https://github.com/libgit2/pygit2/blob/master/docs/development.md Rebuild the pygit2 extension in-place, including debug symbols, for use with Valgrind. Ensure the correct Python binary is used. ```sh rm build -rf && $PYTHONBIN/python3 setup.py build_ext --inplace -g ``` -------------------------------- ### Format git show-like Commit Message Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-show.md Construct a formatted commit message string similar to the output of `git show`, including author, date, and message. ```python from datetime import datetime, timezone, timedelta tzinfo = timezone( timedelta(minutes=commit.author.offset) ) dt = datetime.fromtimestamp(float(commit.author.time), tzinfo) timestr = dt.strftime('%c %z') msg = '\n'.join([f'commit {commit.tree_id}', f'Author: {commit.author.name} <{commit.author.email}>', f'Date: {timestr}', '', commit.message]) ``` -------------------------------- ### Atomic Swap of Two Branches Source: https://github.com/libgit2/pygit2/blob/master/docs/transactions.md Demonstrates atomically swapping the targets of two branches using a transaction. Ensure both references are locked before modifying them. ```python # Swap two branches atomically with repo.transaction() as txn: txn.lock_ref('refs/heads/branch-a') txn.lock_ref('refs/heads/branch-b') # Get current targets ref_a = repo.lookup_reference('refs/heads/branch-a') ref_b = repo.lookup_reference('refs/heads/branch-b') # Swap them txn.set_target('refs/heads/branch-a', ref_b.target, message='Swap') txn.set_target('refs/heads/branch-b', ref_a.target, message='Swap') ``` -------------------------------- ### List Tags with pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-tag.md Filter repository references to display only those matching the 'refs/tags/' pattern, effectively listing all tags. ```python import re regex = re.compile('^refs/tags/') [r for r in repo.references if regex.match(r)] ``` -------------------------------- ### Basic Reference Update Transaction Source: https://github.com/libgit2/pygit2/blob/master/docs/transactions.md Use the `Repository.transaction()` context manager for basic atomic updates. Changes are committed automatically on successful exit or rolled back if an exception occurs. ```python with repo.transaction() as txn: txn.lock_ref('refs/heads/master') txn.set_target('refs/heads/master', new_oid, message='Update master') ``` -------------------------------- ### Manual Reference Transaction Commit Source: https://github.com/libgit2/pygit2/blob/master/docs/transactions.md Shows how to manually manage a reference transaction using `ReferenceTransaction`. Remember to `commit()` changes and `del` the transaction object to free resources. ```python from pygit2 import ReferenceTransaction txn = ReferenceTransaction(repo) try: txn.lock_ref('refs/heads/master') txn.set_target('refs/heads/master', new_oid, message='Update') txn.commit() finally: del txn # Ensure transaction is freed ``` -------------------------------- ### Access HEAD Reference Source: https://github.com/libgit2/pygit2/blob/master/docs/references.md Provides two equivalent ways to access and resolve the HEAD reference in a repository. The first uses the references dictionary and resolves it, while the second uses a direct property access. ```python >>> head = repo.references['HEAD'].resolve() >>> head = repo.head ``` -------------------------------- ### Create Oid Object from Raw Byte String Source: https://github.com/libgit2/pygit2/blob/master/docs/oid.md Instantiate an Oid object using its raw 20-byte string representation. This requires converting the hex string to bytes using `binascii.unhexlify`. ```python from binascii import unhexlify from pygit2 import Oid raw = unhexlify("cff3ceaefc955f0dbe1957017db181bc49913781") oid2 = Oid(raw=raw) ``` -------------------------------- ### Show Commit Diff Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-show.md Generate and display the difference between a commit and its parent. ```python diff = repo.diff(commit.parents[0], commit) ``` -------------------------------- ### Modify and Write Index in pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/index_file.md Illustrates how to add, remove, or recursively remove files and directories from the index, followed by writing the changes back to the index file. Remember to call write() to persist changes. ```python >>> index.add('path/to/file') # git add >>> index.remove('path/to/file') # git rm >>> index.remove_directory('path/to/directory/') # git rm -r >>> index.write() # don't forget to save the changes ``` -------------------------------- ### Cherry-pick with Working Copy using pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-cherry-pick.md Use `Repository.cherrypick()` for a straightforward cherry-pick operation when a working copy and index are present. This method requires cleaning up the repository state afterward. ```bash cd /path/to/repo git checkout basket git cherry-pick 9e044d03c ``` ```python repo = pygit2.Repository('/path/to/repo') repo.checkout('basket') cherry_id = pygit2.Oid('9e044d03c') repo.cherrypick(cherry_id) if repo.index.conflicts is None: tree_id = repo.index.write_tree() cherry = repo.get(cherry_id) committer = pygit2.Signature('Archimedes', 'archy@jpl-classics.org') repo.create_commit(basket.name, cherry.author, committer, cherry.message, tree_id, [basket.target]) del basket # outdated, prevent from accidentally using it repo.state_cleanup() ``` -------------------------------- ### Thread-Local Transactions Source: https://github.com/libgit2/pygit2/blob/master/docs/transactions.md Demonstrates safe concurrent use of reference transactions from different threads. Each thread manages its own transaction, preventing conflicts unless the same references are locked. ```python # This is safe - each thread has its own transaction def thread1(): with repo.transaction() as txn: txn.lock_ref('refs/heads/branch1') txn.set_target('refs/heads/branch1', oid1) def thread2(): with repo.transaction() as txn: txn.lock_ref('refs/heads/branch2') txn.set_target('refs/heads/branch2', oid2) # Both threads can run concurrently without conflicts ``` -------------------------------- ### Create and Delete Local Branch Source: https://github.com/libgit2/pygit2/blob/master/docs/branches.md Creates a new local branch from a specified commit and then deletes it. Ensure the branch name is unique before creation. ```python >>> # Create a local branch, branching from master >>> new_branch = repo.branches.local.create('new-branch', repo[master_branch.target]) >>> # And delete it >>> repo.branches.delete('new-branch') ``` -------------------------------- ### Run Valgrind for Memory Leak Detection Source: https://github.com/libgit2/pygit2/blob/master/docs/development.md Execute pytest under Valgrind to perform a full memory leak check. Redirect output to a file for analysis. ```sh valgrind -v --leak-check=full --suppressions=misc/valgrind-python.supp $PYTHONBIN/pytest &> valgrind.txt ``` -------------------------------- ### Transaction Rollback on Exception Source: https://github.com/libgit2/pygit2/blob/master/docs/transactions.md Illustrates automatic rollback of reference updates if an exception is raised within the transaction context. The repository remains in its original state. ```python try: with repo.transaction() as txn: txn.lock_ref('refs/heads/master') txn.set_target('refs/heads/master', new_oid) # If this raises an exception, the ref update is rolled back validate_commit(new_oid) except ValidationError: # Master still points to its original target pass ``` -------------------------------- ### Run Memory Leak Check with Valgrind Source: https://github.com/libgit2/pygit2/wiki/Guidelines Use this command to perform a memory leak check with Valgrind. Ensure you have the necessary suppression file for accurate results. Check the summary for 'definitely lost' bytes. ```bash valgrind --leak-check=full --tool=memcheck --suppressions=misc/valgrind-python.supp python2 setup.py test ``` -------------------------------- ### Show Commit Trailers using pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-log.md Extract and display specific trailer information (e.g., 'Bug') from the latest commit. This is useful for parsing structured metadata within commit messages. ```python >>> last = repo[repo.head.target] >>> for commit in repo.walk(last.id, pygit2.enums.SortMode.TIME): >>> print(commit.message_trailers.get('Bug')) ``` -------------------------------- ### Deleting a Reference Source: https://github.com/libgit2/pygit2/blob/master/docs/references.md Demonstrates how to delete an existing reference. ```APIDOC ## Deleting a Reference ### Description Deletes a reference by its name. ### Usage ```python # Delete a tag reference repo.references.delete('refs/tags/version1') ``` ``` -------------------------------- ### Run pygit2 Tests Source: https://github.com/libgit2/pygit2/blob/master/CONTRIBUTING.md Execute the test suite using pytest to ensure code changes are valid. ```bash pytest ``` -------------------------------- ### Subsequent Commit with pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-commit.md Create a subsequent commit by referencing the current HEAD and its target as parents. Ensure all changes are added and written to the index before creating the commit. ```python >>> ref = repo.head.name >>> parents = [repo.head.target] ``` ```python >>> index = repo.index >>> index.add_all() >>> index.write() >>> author = Signature('Alice Author', 'alice@authors.tld') >>> committer = Signature('Cecil Committer', 'cecil@committers.tld') >>> message = "Initial commit" >>> tree = index.write_tree() >>> repo.create_commit(ref, author, committer, message, tree, parents) ``` -------------------------------- ### Show Commit SHA Hash Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-show.md Retrieve and display the full SHA hash of a commit object. ```python hash = str(commit.id) ``` -------------------------------- ### Run Mypy Type Checking Source: https://github.com/libgit2/pygit2/blob/master/AGENTS.md Executes mypy type checking on the pygit2 codebase using the build.sh script. ```bash sh build.sh mypy ``` -------------------------------- ### Oid Type Constructor Source: https://github.com/libgit2/pygit2/blob/master/docs/oid.md The Oid constructor can be used to create an Oid object from either a raw byte string or a hexadecimal string representation of the OID. It does not accept both arguments simultaneously. ```APIDOC ## Oid Type Constructor ### Description The `Oid` constructor expects either a raw or a hex oid, but not both. ### Method `pygit2.Oid(raw = None, hex = None)` ### Parameters #### Request Body - **raw** (bytes) - Optional - A raw byte string of 20 bytes representing the OID. - **hex** (str) - Optional - A hexadecimal string of 40 characters representing the OID. ### Request Example #### From Hex String ```default >>> from pygit2 import Oid >>> hex = "cff3ceaefc955f0dbe1957017db181bc49913781" >>> oid1 = Oid(hex=hex) ``` #### From Raw Bytes ```default >>> from binascii import unhexlify >>> from pygit2 import Oid >>> raw = unhexlify("cff3ceaefc955f0dbe1957017db181bc49913781") >>> oid2 = Oid(raw=raw) ``` ### Response An `Oid` object is returned upon successful instantiation. ``` -------------------------------- ### Fixing ImportError with ldconfig Source: https://github.com/libgit2/pygit2/blob/master/docs/install.md Applies the ldconfig command to update the dynamic linker cache, resolving the ImportError for libgit2. ```sh sudo ldconfig python -c 'import pygit2' ``` -------------------------------- ### Check if an object is a pygit2 Object Source: https://github.com/libgit2/pygit2/blob/master/docs/objects.md Demonstrates how to check if a retrieved object is an instance of the base pygit2 Object type. ```Python from pygit2 import Object commit = repository.revparse_single('HEAD') print(isinstance(commit, Object)) ``` -------------------------------- ### Create Oid Object from Hexadecimal String Source: https://github.com/libgit2/pygit2/blob/master/docs/oid.md Instantiate an Oid object using its hexadecimal string representation. This is a common way to interact with OIDs when they are provided as strings. ```python from pygit2 import Oid hex = "cff3ceaefc955f0dbe1957017db181bc49913781" oid1 = Oid(hex=hex) ``` -------------------------------- ### Create Diffs Between Commits Source: https://github.com/libgit2/pygit2/blob/master/docs/diff.md Generate diffs between two commits or between a commit and its ancestors. Equivalent methods are shown. ```python # Changes between commits >>> t0 = revparse_single('HEAD') >>> t1 = revparse_single('HEAD^') >>> repo.diff(t0, t1) >>> t0.diff(t1) # equivalent >>> repo.diff('HEAD', 'HEAD^') # equivalent ``` -------------------------------- ### Oid Constants Source: https://github.com/libgit2/pygit2/blob/master/docs/oid.md pygit2 provides several constants related to Object IDs for convenience. ```APIDOC ## Oid Constants ### Description These constants provide standard sizes and values related to Git Object IDs. ### Constants - **GIT_OID_RAWSZ**: The size of a raw OID in bytes (20). - **GIT_OID_HEXSZ**: The size of a hexadecimal OID string (40). - **GIT_OID_HEX_ZERO**: A string representing a null OID (40 zeros). - **GIT_OID_MINPREFIXLEN**: The minimum length for a unique OID prefix. ``` -------------------------------- ### Reference Transactions Source: https://github.com/libgit2/pygit2/blob/master/docs/references.md Details how to perform atomic updates on multiple references using transactions. ```APIDOC ## Reference Transactions ### Description Provides a mechanism for performing atomic updates on multiple references simultaneously. ### Usage ```python # Update multiple references atomically with repo.transaction() as txn: txn.lock_ref('refs/heads/master') txn.lock_ref('refs/heads/develop') txn.set_target('refs/heads/master', new_oid, message='Release') txn.set_target('refs/heads/develop', dev_oid, message='Continue dev') ``` ``` -------------------------------- ### Create a Commit After Merge Source: https://github.com/libgit2/pygit2/blob/master/docs/merge.md After resolving merge conflicts, create a new commit using `repo.create_commit()`. This requires the repository signature, a tree object, a commit message, the tree, and a list of parent commit Oids. ```python >>> user = repo.default_signature >>> tree = repo.index.write_tree() >>> message = "Merging branches" >>> new_commit = repo.create_commit('HEAD', user, user, message, tree, [repo.head.target, other_branch_tip]) ``` -------------------------------- ### pygit2 File Status Flags Source: https://github.com/libgit2/pygit2/blob/master/docs/index_file.md Lists the available status flags for a file in pygit2, indicating its state in the index relative to HEAD and in the working directory relative to the index. These flags are used to determine file modifications, additions, deletions, and conflicts. ```default enums.FileStatus.CURRENT enums.FileStatus.INDEX_NEW enums.FileStatus.INDEX_MODIFIED enums.FileStatus.INDEX_DELETED enums.FileStatus.INDEX_RENAMED enums.FileStatus.INDEX_TYPECHANGE enums.FileStatus.WT_NEW enums.FileStatus.WT_MODIFIED enums.FileStatus.WT_DELETED enums.FileStatus.WT_TYPECHANGE enums.FileStatus.WT_RENAMED enums.FileStatus.WT_UNREADABLE enums.FileStatus.IGNORED enums.FileStatus.CONFLICTED ``` -------------------------------- ### Access Specific Branches Source: https://github.com/libgit2/pygit2/blob/master/docs/branches.md Access a specific branch by its name. Raises a KeyError if the branch does not exist, or use `.get()` to return None instead. ```python >>> # Get a branch >>> master_branch = repo.branches['master'] >>> other_branch = repo.branches['does-not-exist'] # Will raise a KeyError >>> other_branch = repo.branches.get('does-not-exist') # Returns None >>> remote_branch = repo.branches.remote['upstream/feature'] ``` -------------------------------- ### Unstage a file with pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-add-reset.md Use this to remove a file from the Git index, effectively unstaging it, similar to `git reset HEAD `. ```bash $ git reset HEAD src/tree.c ``` ```python >>> index = repo.index # Remove path from the index >>> path = 'src/tree.c' >>> index.remove(path) # Restore object from db >>> obj = repo.revparse_single('HEAD').tree[path] # Get object from db >>> index.add(pygit2.IndexEntry(path, obj.id, obj.filemode)) # Add to index # Write index >>> index.write() ``` -------------------------------- ### Show Commit Log Message Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-show.md Access and display the log message associated with a commit object. ```python message = commit.message ``` -------------------------------- ### Cherry-pick without Working Copy using pygit2 Source: https://github.com/libgit2/pygit2/blob/master/docs/recipes/git-cherry-pick.md Perform a cherry-pick manually using `merge_trees()` for more control, suitable for bare repositories. This method involves explicitly merging trees and creating a new commit. ```python repo = pygit2.Repository('/path/to/repo') cherry = repo.revparse_single('9e044d03c') basket = repo.branches.get('basket') base_tree = cherry.parents[0].tree index = repo.merge_trees(base_tree, basket, cherry) tree_id = index.write_tree(repo) author = cherry.author committer = pygit2.Signature('Archimedes', 'archy@jpl-classics.org') repo.create_commit(basket.name, author, committer, cherry.message, tree_id, [basket.target]) del None # outdated, prevent from accidentally using it ```