CLI tool
gitpython-developers/GitPython avatar
gitpython-developers/GitPython

GitPython: the Python wrapper over the git executable, now in maintenance mode

GitPython is a python library used to interact with Git repositories.

5,184 stars1,006 forksPythonBSD-3-Clause

At a glance

What is it?
A pure Python library that talks to the git command line rather than reimplementing it, wrapping objects, refs and repositories in Python classes. The maintainer has declared it feature complete, and the recent releases are almost entirely security fixes.
Who is it for?
GitPython is still the quickest route from a Python script to git behaviour that is awkward in pure Python, and the object model is pleasant to work with, but it is now a project you adopt with maintenance mode in mind. Everything it does routes through the `git` executable, so a `PATH` that cannot find git is the first thing to configure, and the resource leak it documents makes it a poor fit for a long-lived daemon.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Installing from PyPI, and the git binary you already need

Installation is one line from PyPI, and the README recommends doing it inside a virtual environment:

sh
pip install GitPython

The requirement that catches people out is not the package, it is the `git` executable. GitPython needs the git command installed on the system and available in `PATH` for most operations. If it is not there, the environment variable `GIT_PYTHON_GIT_EXECUTABLE` is how you tell the library where to find it, which matters on Windows and in containers where git lives somewhere other than the usual path.

The stated requirements are Git 1.7.x or newer and Python 3.8 or newer. The declared dependencies are equally short, and the file says so in full:

text
gitdb>=4.0.1,<5
typing-extensions>=3.10.0.2;python_version<"3.10"

Two dependencies tells you the architecture. `gitdb` gives fast object database access without shelling out for every read, and the typing extension is a conditional marker for Python versions that lack it. Everything else is the git binary.

The project metadata is unusually thorough for a library in maintenance mode. The classifiers claim Production/Stable status, Operating System independence across Console, POSIX, Windows and macOS, and Typed, and the declared Python support runs from 3.8 through 3.15. The version and the dependency list are both read from files at build time rather than hardcoded, which is why `VERSION`, `requirements.txt` and a `Makefile` with `release`, `force_release` and `clean` targets all exist at the repository root.

Why it shells out instead of reimplementing git

GitPython's stated position is that it provides abstractions of git objects for easy access to repository data, and that this is often backed by calling the git command line program. That word, often, is the honest part. The library is not a pure Python implementation of git, it is a typed object model over a subprocess.

The consequence is that you get git's actual behaviour, including its quirks, its configuration handling and its version differences, and you get it without reimplementing the parts of git that took two decades to get right. The topics on the repository make the scope explicit with `git-plumbing` and `git-porcelain`, the two layers of git's own command vocabulary.

The maintainer has been unusually candid about the design. The README opens by saying the project began in 2009, that the author did not know what he was doing at the time, and that this shows in many places. The comparison drawn is to Python itself, which is good enough at the same time as being flawed in ways that cannot be repaired. The stated hope is that one day the library will not be needed anymore, and the pointer offered for anyone who wants to build git differently is Gitoxide, an implementation of git in Rust, with the explicit caveat that it is not currently available for use from Python and that Rust is required.

That framing is worth holding on to. The library is a maintained adapter, not a foundation, and the author says so on the first page.

#### Development status

The README is explicit that the project is in maintenance mode, which means there will be no feature development unless it is contributed, no bug fixes unless they are relevant to the safety of users or contributed, and issues can wait up to a month for a response. The repository is open to contributions of all kinds as well as to new maintainers.

The resource leak that rules out daemons

The limitations section is short and both items matter. The first is a warning that GitPython is not suited to long-running processes such as daemons, because it tends to leak system resources. The stated reason is historical and specific: the library was written at a time when destructors, as implemented in the `__del__` method, still ran deterministically, and that assumption no longer holds under modern Python.

The README offers two workarounds rather than pretending the problem is not there. You can search the codebase for `__del__` implementations and call them yourself where it suits you, or you can factor GitPython out into a separate process which can be dropped periodically. The second is the more honest answer for a service that must stay up.

The second limitation is Windows support, which the README defers entirely to issue 525. That is an unusually thin answer for a project whose classifiers list Microsoft Windows as a supported operating system, and it is worth resolving in your own environment rather than assuming.

For an interactive script, a build step or a CI job, neither limitation bites. For a long-running service that shells out to git repeatedly, the leak is a design constraint you have to design around, not a bug you can wait for a release to fix.

The recent releases are almost all security work

Three releases in the list, 3.1.60, 3.1.61 and 3.1.62, and the change list is much more security-flavoured than a typical patch series. Version 3.1.60 preserves Git config escape semantics, hardens diff path and actor identity parsing, and requires explicit opt-in for filesystem diffs. Requiring opt-in for filesystem diffs is a change with a visible side effect, since code that relied on the old behaviour will now fail loudly rather than silently.

Version 3.1.61 has a note that is worth reading twice: it fixes an accidental removal of an exploitable regex in `Actor` by bringing it back, and deprecating it. So a regex that had a security problem was restored and simultaneously marked for removal, which is an unusual and candid way to describe a regression. The same release fixes repository discovery precedence and waits for git daemon to listen before connecting.

Version 3.1.62 rejects unsafe submodule checkout paths, keeps bare repository worktrees non-bare, and joins backslash line continuations when reading config values. That last one is a real-world Windows annoyance, and it also means configuration parsing respects git's own continuation semantics instead of treating a backslash as a literal character.

Read together, these releases describe a project that is holding a stable API steady while closing paths where untrusted input could reach the filesystem or the config parser. For an adopter, the practical conclusion is that pinning a recent version matters more here than it would for a library whose patches are only about features, and that a version from before 3.1.60 predates several of these hardening changes.

Working on the code rather than installing it

The contributor path is more involved than the install path, and the README is clear that one step must not be skipped. Cloning for development is documented as:

sh
git clone https://github.com/gitpython-developers/GitPython
cd GitPython
./init-tests-after-clone.sh

The README flags this twice, once in the clone instructions and again in the testing section, stating that without running `./init-tests-after-clone.sh` right after cloning you will encounter test failures. On Windows the script runs in a Git Bash shell. There is also a documented `gh repo clone GitPython` path if you have the CLI and a fork by that name.

The three commands you will actually run are short:

sh
pytest
pre-commit run --all-files
mypy

Linting runs through pre-commit and includes Ruff, plus other checks, and type checking is mypy. Test dependencies come from an editable install with extras, `pip install -e ".[test]"`, which the README says is taken care of if you installed that way.

One structural detail is worth knowing before you touch the tree. GitPython, gitdb and smmap all live in this one repository as independently packaged projects, and the README documents installing all three editable at once with `pip install -e smmap -e gitdb -e ".[test]"`. It marks that approach as not preferred and rarely needed, recommending instead that gitdb and smmap be retrieved from PyPI in their latest stable versions. The tree reflects that split, with `git/`, `gitdb/` and `smmap/` as sibling directories.

Editorial conclusion

GitPython is still the quickest route from a Python script to git behaviour that is awkward in pure Python, and the object model is pleasant to work with, but it is now a project you adopt with maintenance mode in mind. Everything it does routes through the `git` executable, so a `PATH` that cannot find git is the first thing to configure, and the resource leak it documents makes it a poor fit for a long-lived daemon. Pin a version, run it in a process you can restart, and if you are starting something new in 2026, the maintainer's own Gitoxide recommendation in the README is worth reading before you settle.

Frequently asked questions

How do I install GitPython?

From PyPI, inside a virtual environment: `pip install GitPython`. From a source checkout, run `pip install .` in the unpacked directory, or `pip install -e ".[test]"` for an editable install that includes the test dependencies. GitPython also needs the git executable on your PATH, or the GIT_PYTHON_GIT_EXECUTABLE environment variable pointing at it.

How can I run a Git command using Python?

GitPython is the library built for that. It provides abstractions over git objects, repositories and refs, and it is often backed by calling the git command line program rather than reimplementing git. Its only non-git dependency is gitdb, which handles faster object database access.

Is GitPython still being developed?

The README states the project is in maintenance mode: no feature development unless contributed, no bug fixes unless they matter for user safety or are contributed, and issue responses that can take a month. The repository is still receiving releases, with 3.1.62 published on 2026-09-07, and it is open to new maintainers.

Can I use GitPython in a long-running daemon?

The README says not to, because it tends to leak system resources, having been written when __del__ destructors still ran deterministically. It suggests either calling the __del__ implementations yourself where appropriate, or running GitPython in a separate process that can be dropped periodically.

Official sources

  1. gitpython-developers/GitPython on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gitpython-developers-gitpython.svg)](https://hysenlabs.com/projects/gitpython-developers-gitpython)