### Install GitPython using setup.py Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/intro.md Alternatively, install GitPython from the distribution using the setup.py script. Ensure GitDB is installed manually. ```bash # python setup.py install ``` -------------------------------- ### Install GitPython from downloaded source Source: https://github.com/gitpython-developers/gitpython/blob/main/README.md Install GitPython by running pip from within the unpacked source code directory. ```sh pip install . ``` -------------------------------- ### Run GitPython Unit Tests Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/intro.md Verify the installation by running the unit tests for GitPython. ```bash python -m unittest ``` -------------------------------- ### Install GitPython from PyPI Source: https://github.com/gitpython-developers/gitpython/blob/main/README.md Install GitPython and its dependencies using pip from the Python Package Index. ```sh pip install GitPython ``` -------------------------------- ### Clone GitPython repository and install Source: https://github.com/gitpython-developers/gitpython/blob/main/README.md Clone the GitPython repository from GitHub, initialize tests, and perform an editable install with test dependencies. ```sh git clone https://github.com/gitpython-developers/GitPython cd GitPython ./init-tests-after-clone.sh ``` ```sh pip install -e ".[test]" ``` -------------------------------- ### Install Test Dependencies for GitPython Source: https://github.com/gitpython-developers/gitpython/blob/main/README.md Ensures that all necessary testing libraries are installed. This command is useful if you initially installed GitPython without test dependencies. ```sh pip install -e ".[test]" ``` -------------------------------- ### Install GitPython using pip Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/intro.md Use this command to install the latest version of GitPython from the Python Package Index. ```bash # pip install GitPython ``` -------------------------------- ### Editable Installation of GitPython and Dependencies Source: https://github.com/gitpython-developers/gitpython/blob/main/README.md Use this command to install GitPython and its dependencies (gitdb, smmap) in editable mode. This is rarely needed and should only be used for simultaneous development on these packages. ```sh pip install -e ".[test]" -e git/ext/gitdb -e git/ext/gitdb/gitdb/ext/smmap ``` -------------------------------- ### Example Custom SSH Executable Script Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md A sample shell script that can be used as a custom SSH executable for Git operations. Ensure the script has execute permissions. ```shell #!/bin/sh ID_RSA=/var/lib/openshift/5562b947ecdd5ce939000038/app-deployments/id_rsa exec /usr/bin/ssh -o StrictHostKeyChecking=no -i $ID_RSA "$@" Please note that the script must be executable (i.e. chmod +x script.sh). StrictHostKeyChecking=no is used to avoid prompts asking to save the hosts key to ~/.ssh/known_hosts, which happens in case you run this as daemon. ``` -------------------------------- ### Clone GitPython repository using gh CLI Source: https://github.com/gitpython-developers/gitpython/blob/main/README.md Clone your fork of the GitPython repository using the GitHub CLI and perform an editable install. ```sh gh repo clone GitPython ``` ```sh pip install -e ".[test]" ``` -------------------------------- ### Get Sub-object from Tree using Path Syntax Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Use a posix-like path syntax to retrieve named sub-objects from a tree. ```python assert tree / "smmap" == tree["smmap"] assert tree / blob.path == tree[blob.path] ``` -------------------------------- ### Get Tree from Repository by Ref-spec Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Retrieve a repository's tree object using various reference specifications, including commit hashes and tags. ```python # This example shows the various types of allowed ref-specs. assert repo.tree() == repo.head.commit.tree past = repo.commit("HEAD~5") assert repo.tree(past) == repo.tree(past.hexsha) self.assertEqual(repo.tree("v0.8.1").type, "tree") # Yes, you can provide any refspec - works everywhere. ``` -------------------------------- ### Initialize a New Git Repository Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Use `Repo.init()` to create a new Git repository in a specified directory. This is equivalent to running `git init`. ```python # $ git init from git import Repo repo = Repo.init(path_to_dir) ``` -------------------------------- ### Configure GitPython with GitCmdObjectDB Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Shows how to initialize a GitPython repository using the GitCmdObjectDB, which utilizes the git executable for faster operations. This is recommended for performance but may consume more memory. ```python repo = Repo("path/to/repo", odbt=GitCmdObjectDB) ``` -------------------------------- ### Manage Remote Repository and Tracking Branches Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Initializes a new repository, creates a remote, fetches data, sets up local tracking branches, and performs push/pull operations. Ensure the remote URL is correct. ```python empty_repo = git.Repo.init(os.path.join(rw_dir, "empty")) origin = empty_repo.create_remote("origin", repo.remotes.origin.url) assert origin.exists() assert origin == empty_repo.remotes.origin == empty_repo.remotes["origin"] origin.fetch() # Ensure we actually have data. fetch() returns useful information. # Set up a local tracking branch of a remote branch. empty_repo.create_head("master", origin.refs.master) # Create local branch "master" from remote "master". empty_repo.heads.master.set_tracking_branch(origin.refs.master) # Set local "master" to track remote "master. empty_repo.heads.master.checkout() # Check out local "master" to working tree. # Three above commands in one: empty_repo.create_head("master", origin.refs.master).set_tracking_branch(origin.refs.master).checkout() # Rename remotes. origin.rename("new_origin") # Push and pull behaves similarly to `git push|pull`. origin.pull() origin.push() # Attempt push, ignore errors. origin.push().raise_if_error() # Push and raise error if it fails. # assert not empty_repo.delete_remote(origin).exists() # Create and delete remotes. ``` -------------------------------- ### Clone and Initialize Git Repositories Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Clone an existing Git repository to a new location or initialize a new, empty repository. Both operations return a Repo object. ```python cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path")) assert cloned_repo.__class__ is Repo # Clone an existing repository. ``` ```python assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo ``` -------------------------------- ### Initialize Git Repository and Commit Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Initializes a new Git repository, adds an empty file to the index, and commits the change. This is useful for setting up a new project with GitPython. ```python import git repo_dir = os.path.join(rw_dir, "my-new-repo") file_name = os.path.join(repo_dir, "new-file") r = git.Repo.init(repo_dir) # This function just creates an empty file. open(file_name, "wb").close() r.index.add([file_name]) r.index.commit("initial commit") ``` -------------------------------- ### Get Root Tree of Latest Commit Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Obtain the root tree object for the latest commit on the master branch. ```python tree = repo.heads.master.commit.tree assert len(tree.hexsha) == 40 ``` -------------------------------- ### Initialize Git Submodules Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/intro.md After cloning the repository, initialize all submodules to obtain the required dependencies. ```bash cd git-python git submodule update --init --recursive ``` -------------------------------- ### Open an Existing Local Git Repository Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Instantiate a `Repo` object by providing the path to an existing local Git repository. This is the standard way to access a repository. ```python repo = Repo(path_to_dir) ``` -------------------------------- ### Traverse Tree Entries Recursively Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Use the traverse method to get an iterator for recursively retrieving all entries within a tree. ```python assert len(tree) < len(list(tree.traverse())) ``` -------------------------------- ### Obtain Commits by Revision Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Get specific commits using revision identifiers like branch names, tags, or relative references. ```python repo.commit("master") repo.commit("v0.8.1") repo.commit("HEAD~10") ``` -------------------------------- ### Configure GitPython with GitDB Object Database Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Demonstrates how to initialize a GitPython repository using the pure-python GitDB object database. This is the default in older versions and uses less memory for huge files but can be slower for many small objects. ```python repo = Repo("path/to/repo", odbt=GitDB) ``` -------------------------------- ### Initialize and Access a Git Repository Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Initialize a Repo object to represent a local Git repository. This can be a standard repository or a bare repository. Use Repo.init() for new repositories. ```python from git import Repo # rorepo is a Repo instance pointing to the git-python repository. # For all you know, the first argument to Repo is a path to the repository you # want to work with. repo = Repo(self.rorepo.working_tree_dir) assert not repo.bare ``` ```python bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True) assert bare_repo.bare ``` -------------------------------- ### Manage Git Submodules Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Demonstrates creating, asserting existence, and removing submodules. Ensure submodules are managed correctly within the repository. ```python for sm in cloned_repo.submodules: assert not sm.remove().exists() # after removal, the sm doesn't exist anymore sm = cloned_repo.create_submodule("mysubrepo", "path/to/subrepo", url=bare_repo.git_dir, branch="master") # .gitmodules was written and added to the index, which is now being committed. cloned_repo.index.commit("Added submodule") assert sm.exists() and sm.module_exists() # This submodule is definitely available. sm.remove(module=True, configuration=False) # Remove the working tree. assert sm.exists() and not sm.module_exists() # The submodule itself is still available. # Update all submodules, non-recursively to save time. This method is very powerful, go have a look. cloned_repo.submodule_update(recursive=False) assert sm.module_exists() # The submodule's working tree was checked out by update. ``` -------------------------------- ### Create an Untracked File Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Demonstrates how to create a new, untracked file in the repository. This file will appear in `repo.untracked_files`. ```python f = open(f"{local_dir}/untracked.txt", "w") # Creates an empty file. f.close() ``` ```python repo.untracked_files # Output: ['untracked.txt'] ``` -------------------------------- ### Manage Git Remotes and Fetch Data Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Shows how to create a remote, check its existence, fetch data from it with custom progress, and delete it. ```python self.assertEqual(len(cloned_repo.remotes), 1) # We have been cloned, so should be one remote. self.assertEqual(len(bare_repo.remotes), 0) # This one was just initialized. origin = bare_repo.create_remote("origin", url=cloned_repo.working_tree_dir) assert origin.exists() for fetch_info in origin.fetch(progress=MyProgressPrinter()): print("Updated %s to %s" % (fetch_info.ref, fetch_info.commit)) # Create a local branch at the latest fetched master. We specify the name # statically, but you have all information to do it programmatically as well. bare_master = bare_repo.create_head("master", origin.refs.master) bare_repo.head.set_reference(bare_master) assert not bare_repo.delete_remote(origin).exists() ``` -------------------------------- ### Checkout Branch and Verify Commit Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Demonstrates checking out a specific branch and verifying that the repository's active branch and commit match the expected state. ```python self.assertEqual(new_branch.checkout(), cloned_repo.active_branch) # Checking out branch adjusts the wtree. self.assertEqual(new_branch.commit, past.commit) # Now the past is checked out. ``` -------------------------------- ### Add Untracked File and Compare Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Demonstrates adding an untracked file to the staging area and then comparing the staging area to the head commit. This shows the newly added file in the diff output. ```python # Let's add untracked.txt. repo.index.add(["untracked.txt"]) diffs = repo.index.diff(repo.head.commit) for d in diffs: print(d.a_path) # Output # untracked.txt ``` -------------------------------- ### Add New File to Index and Commit Changes Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Explains how to create a new file, add it to the Git index, and commit the changes to the repository. ```python new_file_path = os.path.join(cloned_repo.working_tree_dir, "my-new-file") open(new_file_path, "wb").close() # Create new file in working tree. cloned_repo.index.add([new_file_path]) # Add it to the index. # Commit the changes to deviate masters history. cloned_repo.index.commit("Added a new file in the past - for later merge") ``` -------------------------------- ### Create and Manage Tags in GitPython Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Demonstrates how to create tag objects and tag references with messages, and how to access their associated commits. ```python past = cloned_repo.create_tag( "past", ref=new_branch, message="This is a tag-object pointing to %s" % new_branch.name, ) self.assertEqual(past.commit, new_branch.commit) # The tag points to the specified commit assert past.tag.message.startswith("This is") # and its object carries the message provided. now = cloned_repo.create_tag("now") # This is a tag-reference. It may not carry meta-data. assert now.tag is None ``` -------------------------------- ### Check Fuzzer Build Source: https://github.com/gitpython-developers/gitpython/blob/main/fuzzing/README.md Verifies the build of the fuzzers within the OSS-Fuzz environment. ```shell python infra/helper.py check_build gitpython ``` -------------------------------- ### Run Pre-commit Hooks for Linting and Formatting Source: https://github.com/gitpython-developers/gitpython/blob/main/README.md Applies linting fixes and automatic code formatting across all files using pre-commit hooks. This includes checks by Ruff and other configured tools. ```sh pre-commit run --all-files ``` -------------------------------- ### Execute Raw Git Commands Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Shows how to execute raw git commands using the `git` command object. This is useful for accessing functionality not directly wrapped by GitPython. Note that hyphens in command names are converted to underscores. ```python git_cmd = repo.git git_cmd.checkout("HEAD", b="my_new_branch") # Create a new branch. git_cmd.branch("another-new-one") git_cmd.branch("-D", "another-new-one") # Pass strings for full control over argument order. git_cmd.for_each_ref() # '-' becomes '_' when calling it. ``` -------------------------------- ### Build OSS-Fuzz Docker Image Source: https://github.com/gitpython-developers/gitpython/blob/main/fuzzing/README.md Builds the Docker image for the GitPython project within the OSS-Fuzz environment. ```shell python infra/helper.py build_image gitpython ``` -------------------------------- ### Clone OSS-Fuzz Repository Source: https://github.com/gitpython-developers/gitpython/blob/main/fuzzing/README.md Clones the OSS-Fuzz repository to set up the environment for building and running fuzz tests locally. ```shell git clone --depth 1 https://github.com/google/oss-fuzz.git oss-fuzz cd oss-fuzz ``` -------------------------------- ### Compare Git Objects Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Demonstrates comparing different Git objects, such as commits, trees, and tags. Objects can be compared for equality and inequality. ```python hc = repo.head.commit hct = hc.tree assert hc != hct assert hc != repo.tags[0] assert hc == repo.head.reference.commit ``` -------------------------------- ### Create and Delete Git Heads (Branches) Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Demonstrates creating a new branch, setting its commit pointer without altering the index or working tree, and deleting it. Deletion only works if the branch is not currently checked out. ```python new_branch = repo.create_head("new") # Create a new one. new_branch.commit = "HEAD~10" # Set branch to another commit without changing index or working trees. repo.delete_head(new_branch) # Delete an existing head - only works if it is not checked out. ``` -------------------------------- ### Run GitPython Tests with Pytest Source: https://github.com/gitpython-developers/gitpython/blob/main/README.md Execute the test suite for GitPython using the pytest framework. Ensure you have run the `./init-tests-after-clone.sh` script first. ```sh pytest ``` -------------------------------- ### Add and Remove Files from Index Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Demonstrates how to add new files and remove existing files from the Git index. The working tree remains untouched by these operations. ```python new_file_path = os.path.join(repo.working_tree_dir, "new-file-name") open(new_file_path, "w").close() index.add([new_file_path]) # Add a new file to the index. index.remove(["LICENSE"]) # Remove an existing one. assert os.path.isfile(os.path.join(repo.working_tree_dir, "LICENSE")) # Working tree is untouched. ``` -------------------------------- ### Build Local Development Docker Image Source: https://github.com/gitpython-developers/gitpython/blob/main/fuzzing/README.md Builds the Docker image for local fuzzing development. This image includes Atheris and is preconfigured for running fuzz targets. ```shell docker build -f fuzzing/local-dev-helpers/Dockerfile -t gitpython-fuzzdev . ``` -------------------------------- ### Check Repository Status and Untracked Files Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Query the dirty state of a repository and retrieve a list of untracked files. Ensure the repository is not bare before checking its dirty state. ```python assert not bare_repo.is_dirty() # Check the dirty state. ``` ```python repo.untracked_files # Retrieve a list of untracked files. # ['my_untracked_file'] ``` -------------------------------- ### Execute Fuzz Target Source: https://github.com/gitpython-developers/gitpython/blob/main/fuzzing/README.md Execute the desired fuzz target using the helper script. Arguments after '--' are passed directly to the fuzzing engine, allowing for fine-grained control over execution. ```shell python infra/helper.py run_fuzzer gitpython $FUZZ_TARGET -- -max_total_time=60 -print_final_stats=1 ``` -------------------------------- ### Traverse Git Trees and Count Files/Directories Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Illustrates how to traverse a commit's tree to count the number of files (blobs) and directories (trees) it contains. ```python # You can traverse trees as well to handle all contained files of a particular commit. file_count = 0 tree_count = 0 tree = past.commit.tree for item in tree.traverse(): file_count += item.type == "blob" tree_count += item.type == "tree" assert file_count and tree_count # We have accumulated all directories and files. self.assertEqual(len(tree.blobs) + len(tree.trees), len(tree)) # A tree is iterable on its children. ``` -------------------------------- ### Safe Branch Checkout with GitPython Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Demonstrates how to safely check out a branch using git-checkout, which prevents overwriting changes in the working copy and index. It shows how to handle cases where the working tree is dirty. ```python self.assertRaises(git.GitCommandError, repo.heads.master.checkout) repo.heads.past_branch.checkout() ``` -------------------------------- ### Switch Branches Cheaply Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Shows how to change the active branch by modifying the HEAD symbolic reference. This operation is efficient as it does not affect the index or the working tree. ```python new_branch = repo.create_head("another-branch") repo.head.reference = new_branch ``` -------------------------------- ### Build GitPython Fuzzers with AddressSanitizer Source: https://github.com/gitpython-developers/gitpython/blob/main/fuzzing/README.md Builds the fuzz targets for GitPython using the AddressSanitizer. This command can optionally take a local path to your GitPython repository clone. ```shell python infra/helper.py build_fuzzers --sanitizer address gitpython ``` -------------------------------- ### git.__version__ Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/reference.md Provides the current version of the GitPython library. ```APIDOC ## Attribute git.__version__ ### Description Retrieves the installed version of the GitPython library. ### Type string ``` -------------------------------- ### Build GitPython Fuzzers Locally Source: https://github.com/gitpython-developers/gitpython/blob/main/fuzzing/README.md Builds fuzz targets using a local GitPython repository clone, allowing development without modifying the OSS-Fuzz repository. ```shell python infra/helper.py build_fuzzers --sanitizer address gitpython ~/code/GitPython ``` -------------------------------- ### Manage Git Tags Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Demonstrates accessing, creating, and deleting tags. Tags can point to tag objects or directly to commits. Use the repository object for tag creation and deletion. ```python tags = repo.tags tagref = tags[0] tagref.tag # Tags may have tag objects carrying additional information tagref.commit # but they always point to commits. repo.delete_tag(tagref) # Delete or repo.create_tag("my_tag") # create tags using the repo for convenience. ``` -------------------------------- ### Configure Logging for Git Command Output Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Provides Python code to configure logging to display INFO-level messages, which is necessary to see the output of executed git commands when GIT_PYTHON_TRACE is set. ```python import logging logging.basicConfig(level=logging.INFO) ``` -------------------------------- ### Clone a Git Repository from a URL Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Use `Repo.clone_from()` to clone a repository from a remote URL to a local directory. This is analogous to `git clone `. ```python # $ git clone repo_url = "https://github.com/gitpython-developers/QuickStartTutorialFiles.git" repo = Repo.clone_from(repo_url, local_dir) ``` -------------------------------- ### Query Tree Entries by Name and Path Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Access tree entries by name or by their relative path. Also demonstrates intuitive iteration over tree members. ```python self.assertEqual(tree["smmap"], tree / "smmap") # Access by index and by sub-path. for entry in tree: # Intuitive iteration of tree members. print(entry) blob = tree.trees[1].blobs[0] # Let's get a blob in a sub-tree. assert blob.name assert len(blob.path) < len(blob.abspath) self.assertEqual(tree.trees[1].name + "/" + blob.name, blob.path) # This is how relative blob path generated. self.assertEqual(tree[blob.path], blob) # You can use paths like 'dir/file' in tree, ``` -------------------------------- ### Create and Delete Git Tags Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Illustrates creating a new tag with an optional message and deleting it. Note that tags are immutable and cannot be changed after creation; they must be re-created if a different commit is desired. ```python new_tag = repo.create_tag("my_new_tag", message="my message") # You cannot change the commit a tag points to. Tags need to be re-created. self.assertRaises(AttributeError, setattr, new_tag, "commit", repo.commit("HEAD~1")) repo.delete_tag(new_tag) ``` -------------------------------- ### Create Index from Tree and Merge Trees Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Loads a tree into a temporary in-memory index or merges two trees three-way. The resulting index can be persisted to a file. ```python from git import IndexFile # Load a tree into a temporary index, which exists just in memory. IndexFile.from_tree(repo, "HEAD~1") # Merge two trees three-way into memory... merge_index = IndexFile.from_tree(repo, "HEAD~10", "HEAD", repo.merge_base("HEAD~10", "HEAD")) # ...and persist it. merge_index.write(os.path.join(rw_dir, "merged_index")) ``` -------------------------------- ### Access Git Repository Configuration Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Obtain configuration readers or writers for a Git repository. Use a config_writer within a 'with' statement to ensure changes are saved and locks are released. ```python repo.config_reader() # Get a config reader for read-only access. ``` ```python with repo.config_writer(): # Get a config writer to change configuration. pass # Call release() to be sure changes are written and locks are released. ``` -------------------------------- ### Access Reflog Entries Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Shows how to access the reflog for a reference, allowing inspection of its history. Entries can be accessed by index, with `log[0]` being the oldest and `log[-1]` the most recent. ```python log = master.log() log[0] # first (i.e. oldest) reflog entry log[-1] # last (i.e. most recent) reflog entry ``` -------------------------------- ### Modifying Project Description Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/changes.md The project description can now be easily modified by assigning a new string to the `description` property of the Repo object. ```python >>> repo.description = "Foo Bar" >>> repo.description 'Foo Bar' ``` -------------------------------- ### Execute Fuzz Target Locally Source: https://github.com/gitpython-developers/gitpython/blob/main/fuzzing/README.md Runs a specific fuzz target within the local development Docker container. Use this for quick iteration and testing of fuzz targets. ```shell docker run -it -v "$PWD":/src gitpython-fuzzdev python fuzzing/fuzz-targets/fuzz_config.py -atheris_runs=10000 ``` -------------------------------- ### Update Branch Reference and Head Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Demonstrates how to update a branch's commit pointer and set the repository's HEAD reference to that branch, without altering the working tree or index. ```python # Now new_branch is ahead of master, which probably should be checked out and reset softly. # Note that all these operations didn't touch the working tree, as we managed it ourselves. # This definitely requires you to know what you are doing! :) assert os.path.basename(new_file_path) in new_branch.commit.tree # New file is now in tree. master.commit = new_branch.commit # Let master point to most recent commit. cloned_repo.head.reference = master # We adjusted just the reference, not the working tree or index. ``` -------------------------------- ### Clone GitPython Repository Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/intro.md Clone the GitPython repository from GitHub to browse or contribute to the source code. ```bash $ git clone https://github.com/gitpython-developers/GitPython git-python ``` -------------------------------- ### Access and Inspect Submodules Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Retrieves and inspects submodule information from a repository. GitPython aims to maintain repository consistency when handling submodules. ```python repo = self.rorepo sms = repo.submodules assert len(sms) == 1 sm = sms[0] self.assertEqual(sm.name, "gitdb") # GitPython has gitdb as its one and only (direct) submodule... self.assertEqual(sm.children()[0].name, "smmap") # ...which has smmap as its one and only submodule. ``` -------------------------------- ### Access Repository Paths Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Query essential paths associated with a Git repository, such as the working tree directory and the Git directory itself. Bare repositories do not have a working tree. ```python assert os.path.isdir(cloned_repo.working_tree_dir) # Directory with your work files. ``` ```python assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir) # Directory containing the git repository. ``` ```python assert bare_repo.working_tree_dir is None # Bare repositories have no working tree. ``` -------------------------------- ### Access and Manipulate Index File Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Interact with the Git index (staging area) to view its contents, which are stored as a flat list of blobs. ```python index = repo.index # The index contains all blobs in a flat list. assert len(list(index.iter_blobs())) == len([o for o in repo.head.commit.tree.traverse() if o.type == "blob"]) ``` -------------------------------- ### Perform a Three-Way Merge and Commit Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Details the process of preparing and executing a three-way merge using the index, specifying parent commits, and committing the merge result. ```python # Prepare a merge. master = cloned_repo.heads.master # Right-hand side is ahead of us, in the future. merge_base = cloned_repo.merge_base(new_branch, master) # Allows for a three-way merge. cloned_repo.index.merge_tree(master, base=merge_base) # Write the merge result into index. cloned_repo.index.commit( "Merged past and now into future ;)", parent_commits=(new_branch.commit, master.commit), ) ``` -------------------------------- ### Traverse Git Objects and Read Data Streams Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Shows how to traverse commit objects to access their tree structure and read file data directly from binary streams without a working tree. ```python assert now.commit.message != past.commit.message # You can read objects directly through binary streams, no working tree required. assert (now.commit.tree / "VERSION").data_stream.read().decode("ascii").startswith("3") ``` -------------------------------- ### Clone Repository and Access Heads Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Clones a repository and accesses its heads, specifically the 'master' branch. Heads can be accessed by name and their associated commit can be retrieved. ```python import git repo = git.Repo.clone_from(self._small_repo_url(), os.path.join(rw_dir, "repo"), branch="master") heads = repo.heads master = heads.master # Lists can be accessed by name for convenience. master.commit # the commit pointed to by head called master. master.rename("new_name") # Rename heads. master.rename("master") ``` -------------------------------- ### Access and Read a File Blob Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Access a specific file (blob) within the current commit's tree using dictionary-like syntax (`tree[print_file]`). Then, read its content using `blob.data_stream.read().decode()`. ```python print_file = "dir1/file2.txt" tree[print_file] # The head commit tree. blob = tree[print_file] print(blob.data_stream.read().decode()) ``` -------------------------------- ### Add File to Staging Area Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Modify a file and then add it to the Git staging area using `repo.index.add()`. This prepares the file for the next commit. Note that `add()` expects a list of file paths. ```python # We must make a change to a file so that we can add the update to git update_file = "dir1/file2.txt" # we'll use local_dir/dir1/file2.txt with open(f"{local_dir}/{update_file}", "a") as f: f.write("\nUpdate version 2") # $ git add add_file = [update_file] # relative path from git root repo.index.add(add_file) # notice the add function requires a list of paths ``` -------------------------------- ### Recursively Display Tree Contents Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md A recursive function to traverse a Git tree and print the paths and types of all files and subdirectories. Useful for visualizing the entire repository structure. ```python def print_files_from_git(root, level=0): for entry in root: print(f"{'| ' * level}| {entry.path}, {entry.type}") if entry.type == "tree": print_files_from_git(entry, level + 1) print_files_from_git(tree) ``` -------------------------------- ### Managing Daemon Export Property Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/changes.md The daemon export functionality is now exposed as a property of the Repo object, allowing for easier management. ```python >>> exported = repo.daemon_export >>> repo.daemon_export = True ``` -------------------------------- ### Checking Working Directory Status Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/changes.md A new read-only property `is_dirty` has been added to the Repo object to reflect the status of the working directory. ```python # No code example provided in source ``` -------------------------------- ### Display Level 1 Contents of a Tree Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Iterate through the entries (files and subdirectories) of a Git tree object and display their names and types. This provides a snapshot of the repository's structure at a given commit. ```python tree = repo.head.commit.tree files_and_dirs = [(entry, entry.name, entry.type) for entry in tree] files_and_dirs ``` -------------------------------- ### Switching to a Past Branch Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Create a new symbolic reference to a past commit and update HEAD to point to it. Resets the index and working tree to match the new HEAD. ```python # Reset our working tree 10 commits into the past. past_branch = repo.create_head("past_branch", "HEAD~10") repo.head.reference = past_branch assert not repo.head.is_detached # Reset the index and working tree to match the pointed-to commit. repo.head.reset(index=True, working_tree=True) ``` -------------------------------- ### Configure Remote Push URL Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Accesses and modifies remote configuration, specifically setting a custom push URL. Note potential timing issues with configuration writing in Python 3. ```python assert origin.url == repo.remotes.origin.url with origin.config_writer as cw: cw.set("pushurl", "other_url") # Please note that in Python 2, writing origin.config_writer.set(...) is totally # safe. In py3 __del__ calls can be delayed, thus not writing changes in time. ``` -------------------------------- ### Iterate and Page Commits Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Iterate through commits with options to limit the number of commits returned and skip a specified number of initial commits. ```python fifty_first_commits = list(repo.iter_commits("master", max_count=50)) assert len(fifty_first_commits) == 50 # This will return commits 21-30 from the commit list as traversed backwards master. ten_commits_past_twenty = list(repo.iter_commits("master", max_count=10, skip=20)) assert len(ten_commits_past_twenty) == 10 assert fifty_first_commits[20:30] == ten_commits_past_twenty ``` -------------------------------- ### Access Git References (Heads, Tags, Remotes) Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Access and compare Git references like heads (branches), tags, and remote branches. References can be accessed via attributes or dictionary-like indexing. ```python self.assertEqual( repo.head.ref, repo.heads.master, # head is a sym-ref pointing to master. "It's ok if TC not running from `master`.", ) ``` ```python self.assertEqual(repo.tags["0.3.5"], repo.tag("refs/tags/0.3.5")) # You can access tags in various ways too. ``` ```python self.assertEqual(repo.refs.master, repo.heads["master"]) # .refs provides all refs, i.e. heads... ``` ```python if "TRAVIS" not in os.environ: self.assertEqual(repo.refs["origin/master"], repo.remotes.origin.refs.master) # ... remotes ... self.assertEqual(repo.refs["0.3.5"], repo.tags["0.3.5"]) # ... and tags. ``` -------------------------------- ### Modify a Tracked File Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Shows how to modify an existing tracked file. This change will be reflected when comparing the index to the working directory. ```python # Let's modify one of our tracked files. with open(f"{local_dir}/Downloads/file3.txt", "w") as f: f.write("file3 version 2") # Overwrite file 3. ``` ```python repo.index.diff(None) # Compares staging area to working directory. # Output: [, # ] diffs = repo.index.diff(None) for d in diffs: print(d.a_path) # Output # Downloads/file3.txt ``` -------------------------------- ### Compare Staging Area to Head Commit Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Compares the staging area with the latest commit in the repository. Useful for seeing what changes are staged but not yet committed. ```python diffs = repo.index.diff(repo.head.commit) for d in diffs: print(d.a_path) # Output ``` -------------------------------- ### Create a New Git Branch Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Create a new branch in a Git repository. The new branch initially points to the same commit as the currently active branch. ```python new_branch = cloned_repo.create_head("feature") # Create a new branch ... assert cloned_repo.active_branch != new_branch # which wasn't checked out yet ... self.assertEqual(new_branch.commit, cloned_repo.active_branch.commit) # pointing to the checked-out commit. # It's easy to let a branch point to the previous commit, without affecting anything else. ``` -------------------------------- ### Access Git Object Properties Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Explains how to access common properties of Git objects, including their type, size in bytes, and SHA1 hash (both hexadecimal and binary representations). ```python self.assertEqual(hct.type, "tree") # Preset string type, being a class attribute. assert hct.size > 0 # size in bytes assert len(hct.hexsha) == 40 assert len(hct.binsha) == 20 ``` -------------------------------- ### Compare Two Commits Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Compares the differences between two specific commits in the repository history. This helps in understanding changes introduced between versions. ```python first_commit = list(repo.iter_commits(all=True))[-1] diffs = repo.head.commit.diff(first_commit) for d in diffs: print(d.a_path) # Output # dir1/file2.txt ``` -------------------------------- ### Iterating Added Diffs Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Traverse a DiffIndex to find and process only the added files. This is useful for implementing status-like functionality. ```python # Traverse added Diff objects only for diff_added in hcommit.diff("HEAD~1").iter_change_type("A"): print(diff_added) ``` -------------------------------- ### Format Commit Dates Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Convert commit dates from seconds since epoch to human-readable formats using the time module. ```python import time time.asctime(time.gmtime(headcommit.committed_date)) time.strftime("%a, %d %b %Y %H:%M", time.gmtime(headcommit.committed_date)) ``` -------------------------------- ### Access Index Object Properties Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Details properties specific to index objects (trees, blobs, submodules), such as their file system path and mode. Trees have directory modes, while blobs have file modes. ```python self.assertEqual(hct.path, "") # Root tree has no path. assert hct.trees[0].path != "" # The first contained item has one though. self.assertEqual(hct.mode, 0o40000) # Trees have the mode of a Linux directory. self.assertEqual(hct.blobs[0].mode, 0o100644) # Blobs have specific mode, comparable to a standard Linux fs. ``` -------------------------------- ### Implement Custom Remote Progress for Git Operations Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Defines a custom progress printer class inheriting from `RemoteProgress` to display real-time updates during fetch operations. ```python from git import RemoteProgress class MyProgressPrinter(RemoteProgress): def update(self, op_code, cur_count, max_count=None, message=""): print( op_code, cur_count, max_count, cur_count / (max_count or 100.0), message or "NO MESSAGE", ) ``` -------------------------------- ### Set Fuzz Target Source: https://github.com/gitpython-developers/gitpython/blob/main/fuzzing/README.md Set the FUZZ_TARGET environment variable to specify the fuzz target without its file extension. This prepares the environment for executing a specific fuzzing script. ```shell export FUZZ_TARGET=fuzz_config ``` -------------------------------- ### Access Blob Data Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/tutorial.md Shows how to read data from a blob object using a stream or write it to a specified stream. This is useful for accessing the content of files stored in Git. ```python hct.blobs[0].data_stream.read() # Stream object to read data from. hct.blobs[0].stream_data(open(os.path.join(rw_dir, "blob_data"), "wb")) # Write data to a given stream. ``` -------------------------------- ### Access Previous Version of a File Source: https://github.com/gitpython-developers/gitpython/blob/main/doc/source/quickstart.md Retrieve the tree of a previous commit by iterating through commits and selecting an older one. Then, access the file blob from that older tree to read its content. ```python commits_for_file = list(repo.iter_commits(all=True, paths=print_file)) tree = commits_for_file[-1].tree # Gets the first commit tree. blob = tree[print_file] print(blob.data_stream.read().decode()) ```