File: README.md
[Gitoxide](https://github.com/Byron/gitoxide): A peek into the futureβ¦
I started working on GitPython in 2009, back in the days when Python was 'my thing' and I had great plans with it.
Of course, back in the days, I didn't really know what I was doing and this shows in many places. Somewhat similar to
Python this happens to be 'good enough', but at the same time is deeply flawed and broken beyond repair.
By now, GitPython is widely used and I am sure there is a good reason for that, it's something to be proud of and happy about.
The community is maintaining the software and is keeping it relevant for which I am absolutely grateful. For the time to come I am happy to continue maintaining GitPython, remaining hopeful that one day it won't be needed anymore.
More than 15 years after my first meeting with 'git' I am still in excited about it, and am happy to finally have the tools and
probably the skills to scratch that itch of mine: implement git in a way that makes tool creation a piece of cake for most.
If you like the idea and want to learn more, please head over to gitoxide, an
implementation of 'git' in Rust.
(Please note that gitoxide is not currently available for use in Python, and that Rust is required.)
GitPython
GitPython is a python library used to interact with git repositories, high-level like git-porcelain,
or low-level like git-plumbing.
It provides abstractions of git objects for easy access of repository data often backed by calling the git
command-line program.
DEVELOPMENT STATUS
This project is in maintenance mode, which means that
- β¦there will be no feature development, unless these are contributed
- β¦there will be no bug fixes, unless they are relevant to the safety of users, or contributed
- β¦issues will be responded to with waiting times of up to a month
The project is open to contributions of all kinds, as well as new maintainers.
REQUIREMENTS
GitPython needs the git executable to be installed on the system and available in yourPATH for most operations. If it is not in your PATH, you can help GitPython find it
by setting the GIT_PYTHON_GIT_EXECUTABLE= environment variable.
- Git (1.7.x or newer)
- Python >= 3.7
The list of dependencies are listed in ./requirements.txt and ./test-requirements.txt.
The installer takes care of installing them for you.
INSTALL
GitPython and its required package dependencies can be installed in any of the following ways, all of which should typically be done in a virtual environment.
From PyPI
To obtain and install a copy from PyPI, run:
pip install GitPython(A distribution package can also be downloaded for manual installation at the PyPI page.)
From downloaded source code
If you have downloaded the source code, run this from inside the unpacked GitPython directory:
pip install .By cloning the source code repository
To clone the the GitHub repository from source to work on the code, you can do it like so:
git clone https://github.com/gitpython-developers/GitPython
cd GitPython
./init-tests-after-clone.shOn Windows, ./init-tests-after-clone.sh can be run in a Git Bash shell.
If you are cloning your own fork, then replace the above git clone command with one that gives the URL of your fork. Or use this gh command (assuming you have gh and your fork is called GitPython):
gh repo clone GitPythonHaving cloned the repo, create and activate your virtual environment.
Then make an editable install:
pip install -e ".[test]"In the less common case that you do not want to install test dependencies, pip install -e . can be used instead.
With editable *dependencies* (not preferred, and rarely needed)
GitPython, gitdb, and smmap live in this repository as independently packaged projects. To work on all three at once, install each one editably in the same virtual environment:
pip install -e smmap -e gitdb -e ".[test]"You can use pip list to check which packages are installed editably and which are installed normally.
To reiterate, this approach should only rarely be used. For most development it is preferable to allow the gitdb and smmap dependencices to be retrieved automatically from PyPI in their latest stable packaged versions.
Limitations
Leakage of System Resources
GitPython is not suited for long-running processes (like daemons) as it tends to
leak system resources. It was written in a time where destructors (as implemented
in the __del__ method) still ran deterministically.
In case you still want to use it in such a context, you will want to search the
codebase for __del__ implementations and call these yourself when you see fit.
Another way assure proper cleanup of resources is to factor out GitPython into a
separate process which can be dropped periodically.
Windows support
See Issue #525.
RUNNING TESTS
Important: Right after cloning this repository, please be sure to have executed
the ./init-tests-after-clone.sh script in the repository root. Otherwise
you will encounter test failures.
Install test dependencies
Ensure testing libraries are installed. This is taken care of already if you installed with:
pip install -e ".[test]"If you had installed with a command like pip install -e . instead, you can still run
the above command to add the testing dependencies.
Test commands
To test, run:
pytestTo lint, and apply some linting fixes as well as automatic code formatting, run:
pre-commit run --all-filesThis includes the linting and autoformatting done by Ruff, as well as some other checks.
To typecheck, run:
mypyCI (and tox)
Style and formatting checks, and running tests on all the different supported Python versions, will be performed:
- Upon submitting a pull request.
- On each push, if you have a fork with GitHub Actions enabled.
- Locally, if you run
tox(this skips any Python versions you don't have installed).
Configuration files
Specific tools are all configured in the ./pyproject.toml file:
pytest(test runner)coverage.py(code coverage)ruff(linter and formatter)mypy(type checker)
Orchestration tools:
- Configuration for
pre-commitis in the./.pre-commit-config.yamlfile. - Configuration for
toxis in./tox.ini. - Configuration for GitHub Actions (CI) is in files inside
./.github/workflows/.
Contributions
Please have a look at the contributions file.
INFRASTRUCTURE
- User Documentation
- Questions and Answers
- Please post on Stack Overflow and use the
gitpythontag - Issue Tracker
- Post reproducible bugs and feature requests as a new issue.
Please be sure to provide the following information if posting bugs:- GitPython version (e.g.
import git; git.__version__) - Python version (e.g.
python --version) - The encountered stack-trace, if applicable
- Enough information to allow reproducing the issue
- GitPython version (e.g.
- Post reproducible bugs and feature requests as a new issue.
How to make a new release
- Update/verify the version in the
VERSIONfile. - Update/verify that the
doc/source/changes.rstchangelog file was updated. It should include a link to the forthcoming release page:https://github.com/gitpython-developers/GitPython/releases/tag/<version> - Commit everything.
- Run
git tag -s <version>to tag the version in Git. - Optionally create and activate a virtual environment. (Then the next step can install
buildandtwine.) - Run
make release. - Go to GitHub Releases and publish a new one with the recently pushed tag. Generate the changelog.
Projects using GitPython
- PyDriller
- Kivy Designer
- Prowl
- Python Taint
- Buster
- git-ftp
- Git-Pandas
- PyGitUp
- PyJFuzz
- Loki
- Omniwallet
- GitViper
- Git Gud
LICENSE
3-Clause BSD License, also known as the New BSD License. See the LICENSE file.
One file exclusively used for fuzz testing is subject to a separate license, detailed here.
This file is not included in the wheel or sdist packages published by the maintainers of GitPython.
File: doc/source/changes.rst
========= Changelog
3.1.60
Security fixes for
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-g5vv-9gxw-82hx
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-whh4-5q6c-9v3x
If you can, also try and provide feedback on the upcoming v4 branch
https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.60
3.1.59
Security fixes for
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-5xxx-qhh7-9287
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-3wxw-xv34-2frg
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-8mcc-hrx5-hvxc
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-284h-m62q-gf8w
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-7833-fr7j-v32q
If you can, also try and provide feedback on the upcoming v4 branch
https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.59
3.1.58
Security fixes for
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-hh9p-6wh2-4mfc
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-9rj7-rf2p-w77r
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-4gmw-gg2m-w46p
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-wvpp-8hx9-p66j
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-jm78-9fvv-mhgr
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-hmq2-w58f-27jc
If you can, also try and provide feedback on the upcoming v4 branch
https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.58
3.1.57
A security fix for
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-3f7w-8rr8-f37f
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-539m-9xh6-q6rr
If you can, also try and provide feedback on the upcoming v4 branch
https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.57
3.1.56
A security fix for
If you can, also try and provide feedback on the upcoming v4 branch
https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.56
3.1.55
A security fix for
If you can, also try and provide feedback on the upcoming v4 branch
https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.55
3.1.54
A security fix for
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-r9mr-m37c-5fr3
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-6p8h-3wgx-97gf
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-fjr4-x663-mwxc
If you can, also try and provide feedback on the upcoming v4 branch
https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54
3.1.53
A security fix for
https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-3rp5-jjmw-4wv2
If you can, also try and provide feedback on the upcoming v4 branch
https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.53
3.1.52
A security fix for
https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rwj8-pgh3-r573.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.52
3.1.51
This is primarily a security release. It prevents additional argument-injection
paths that could allow execution of arbitrary commands or writing to arbitrary
files through unsafe Git options (GHSA-956x-8gvw-wg5v), and closes bypasses of
the existing protections using abbreviated long options or joined short options
(GHSA-2f96-g7mh-g2hx).
The release also improves support for relative worktree paths and diffs against
the empty tree, preserves stderr from failed diff processes, supports relative
configuration include paths, and includes assorted documentation, typing, test,
and CI improvements.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.51
3.1.50
Save setting of configuration values, this time sections as well, as follow-up to 3.1.49.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.50
3.1.49
Save setting of configuration values,
which could be used to inject other more configuration.
Also more conforming rev-parse implementation.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.49
3.1.48
Safe reference creation in the face of untrusted input.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.48
3.1.47
Address various security issues related to bypassing injection-protection
of unsafe Git flags.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.47
3.1.46
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.46
3.1.45
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.45
3.1.44
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.44
3.1.43
A major visible change will be the added deprecation- or user-warnings,
and greatly improved typing.
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.43
3.1.42
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.42
3.1.41
This release is relevant for security as it fixes a possible arbitrary
code execution on Windows.
See this PR for details: https://github.com/gitpython-developers/GitPython/pull/1792
An advisory is available soon at: https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-2mqj-m65w-jghx
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.41
3.1.40
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.40
3.1.38
See the following for all changes.
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.38
3.1.37
This release contains another security fix that further improves validation of symbolic references
and thus properly fixes this CVE: https://github.com/advisories/GHSA-cwvm-v4w8-q58c .
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/67?closed=1
3.1.36
Note that this release should be a no-op, it's mainly for testing the changed release-process.
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/66?closed=1
3.1.35
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/65?closed=1
3.1.34
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/64?closed=1
3.1.33
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/63?closed=1
3.1.32
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/62?closed=1
3.1.31
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/61?closed=1
3.1.30
- Make injections of command-invocations harder or impossible for clone and others.
See https://github.com/gitpython-developers/GitPython/pull/1518 for details.
Note that this might constitute a breaking change for some users, and if so please
let us know and we add an opt-out to this. - Prohibit insecure options and protocols by default, which is potentially a breaking change,
but a necessary fix for https://github.com/gitpython-developers/GitPython/issues/1515.
Please take a look at the PR for more information and how to bypass these protections
in case they cause breakage: https://github.com/gitpython-developers/GitPython/pull/1521.
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/60?closed=1
3.1.29
- Make the git.version re-appear.
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/59?closed=1
3.1.28
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/58?closed=1
3.1.27
- Reduced startup time due to optimized imports.
- Fix a vulenerability that could cause great slowdowns when encountering long remote path names
when pulling/fetching.
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/57?closed=1
3.1.26
- Fixes a leaked file descriptor when reading the index, which would cause make writing a previously
read index on windows impossible.
See https://github.com/gitpython-developers/GitPython/issues/1395 for details.
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/56?closed=1
3.1.25
See the following for all changes.
https://github.com/gitpython-developers/gitpython/milestone/55?closed=1
3.1.24
- Newly added timeout flag is not be enabled by default, and was renamed to kill_after_timeout
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/54?closed=1
https://github.com/gitpython-developers/gitpython/milestone/53?closed=1
3.1.23 (YANKED)
This is the second typed release with a lot of improvements under the hood.
General:
Remove python 3.6 support
Remove distutils ahead of deprecation in standard library.
Update sphinx to 4.1.12 and use autodoc-typehints.
Include README as long_description on PyPI
Test against earliest and latest minor version available on Github Actions (e.g. 3.9.0 and 3.9.7)
Typing:
Add types to ALL functions.
Ensure py.typed is collected.
Increase mypy strictness with disallow_untyped_defs, warn_redundant_casts, warn_unreachable.
Use typing.NamedTuple and typing.OrderedDict now 3.6 dropped.
Make Protocol classes ABCs at runtime due to new behaviour/bug in 3.9.7 & 3.10.0-rc1
Remove use of typing.TypeGuard until later release, to allow dependent libs time to update.
Tracking issue: https://github.com/gitpython-developers/GitPython/issues/1095
Runtime improvements:
Add clone_multi_options support to submodule.add()
Delay calling get_user_id() unless essential, to support sand-boxed environments.
Add timeout to handle_process_output(), in case thread.join() hangs.
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/53?closed=1
3.1.20 (YANKED)
- This is the second typed release with a lot of improvements under the hood.
- Tracking issue: https://github.com/gitpython-developers/GitPython/issues/1095
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/52?closed=1
3.1.19 (YANKED)
- This is the second typed release with a lot of improvements under the hood.
- Tracking issue: https://github.com/gitpython-developers/GitPython/issues/1095
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/51?closed=1
3.1.18
- drop support for python 3.5 to reduce maintenance burden on typing. Lower patch levels of python 3.5 would break, too.
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/50?closed=1
3.1.17
- Fix issues from 3.1.16 (see https://github.com/gitpython-developers/GitPython/issues/1238)
- Fix issues from 3.1.15 (see https://github.com/gitpython-developers/GitPython/issues/1223)
- Add more static typing information
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/49?closed=1
3.1.16 (YANKED)
- Fix issues from 3.1.15 (see https://github.com/gitpython-developers/GitPython/issues/1223)
- Add more static typing information
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/48?closed=1
3.1.15 (YANKED)
- add deprecation warning for python 3.5
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/47?closed=1
3.1.14
- git.Commit objects now have a
replacemethod that will return a
copy of the commit with modified attributes. - Add python 3.9 support
- Drop python 3.4 support
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/46?closed=1
3.1.13
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/45?closed=1
3.1.12
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/44?closed=1
3.1.11
Fixes regression of 3.1.10.
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/43?closed=1
3.1.10
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/42?closed=1
3.1.9
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/41?closed=1
3.1.8
- support for 'includeIf' in git configuration files
- tests are now excluded from the package, making it conisderably smaller
See the following for more details:
https://github.com/gitpython-developers/gitpython/milestone/40?closed=1
3.1.7
- Fix tutorial examples, which disappeared in 3.1.6 due to a missed path change.
3.1.6
- Greatly reduced package size, see https://github.com/gitpython-developers/GitPython/pull/1031
3.1.5
- rollback: package size was reduced significantly not placing tests into the package anymore.
See https://github.com/gitpython-developers/GitPython/issues/1030
3.1.4
- all exceptions now keep track of their cause
- package size was reduced significantly not placing tests into the package anymore.
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/39?closed=1
3.1.3
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/38?closed=1
3.1.2
- Re-release of 3.1.1, with known signature
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/37?closed=1
3.1.1
- support for PyOxidizer, which previously failed due to usage of
__file__.
See the following for details:
https://github.com/gitpython-developers/gitpython/milestone/36?closed=1
3.1.0
- Switched back to using gitdb package as requirement
(gitdb#59 <https://github.com/gitpython-developers/gitdb/issues/59>_)
3.0.9
- Restricted GitDB (gitdb2) version requirement to < 4
- Removed old nose library from test requirements
Bugfixes
- Changed to use UTF-8 instead of default encoding when getting information about a symbolic reference
(#774 <https://github.com/gitpython-developers/GitPython/issues/774>_) - Fixed decoding of tag object message so as to replace invalid bytes
(#943 <https://github.com/gitpython-developers/GitPython/issues/943>_)
3.0.8
- Added support for Python 3.8
- Bumped GitDB (gitdb2) version requirement to > 3
Bugfixes
- Fixed Repo.repr when subclassed
(#968 <https://github.com/gitpython-developers/GitPython/pull/968>_) - Removed compatibility shims for Python < 3.4 and old mock library
- Replaced usage of deprecated unittest aliases and Logger.warn
- Removed old, no longer used assert methods
- Replaced usage of nose assert methods with unittest
3.0.7
Properly signed re-release of v3.0.6 with new signature
(See #980 <https://github.com/gitpython-developers/GitPython/issues/980>_)
3.0.6
| Note: There was an issue that caused this version to be released to PyPI without a signature
| See the changelog for v3.0.7 and #980 <https://github.com/gitpython-developers/GitPython/issues/980>_
Bugfixes
- Fixed warning for usage of environment variables for paths containing
$or%
(#832 <https://github.com/gitpython-developers/GitPython/issues/832>,#961 <https://github.com/gitpython-developers/GitPython/pull/961>) - Added support for parsing Git internal date format (@
)
(#965 <https://github.com/gitpython-developers/GitPython/pull/965>_) - Removed Python 2 and < 3.3 compatibility shims
(#979 <https://github.com/gitpython-developers/GitPython/pull/979>_) - Fixed GitDB (gitdb2) requirement version specifier formatting in requirements.txt
(#979 <https://github.com/gitpython-developers/GitPython/pull/979>_)
3.0.5 - Bugfixes
see the following for details:
https://github.com/gitpython-developers/gitpython/milestone/32?closed=1
3.0.4 - Bugfixes
see the following for details:
https://github.com/gitpython-developers/gitpython/milestone/31?closed=1
3.0.3 - Bugfixes
see the following for (most) details:
https://github.com/gitpython-developers/gitpython/milestone/30?closed=1
3.0.2 - Bugfixes
- fixes an issue with installation
3.0.1 - Bugfixes and performance improvements
- Fix a
performance regression <https://github.com/gitpython-developers/GitPython/issues/906>__ which could make certain workloads 50% slower - Add
currently_rebasing_onmethod onRepo, seethe PR <https://github.com/gitpython-developers/GitPython/pull/903/files#diff-c276fc3c4df38382ec884e59657b869dR1065>__ - Fix incorrect
requirements.txtwhich could lead to broken installations, see thisissue <https://github.com/gitpython-developers/GitPython/issues/908>__ for details.
3.0.0 - Remove Python 2 support
Motivation for this is a patch which improves unicode handling when dealing with filesystem paths.
Python 2 compatibility was introduced to deal with differences, and I thought it would be a good idea
to 'just' drop support right now, mere 5 months away from the official maintenance stop of python 2.7.
The underlying motivation clearly is my anger when thinking python and unicode, which was a hassle from the
start, at least in a codebase as old as GitPython, which totally doesn't handle encodings correctly in many cases.
Having migrated to using Rust exclusively for tooling, I still see that correct handling of encodings isn't entirely
trivial, but at least Rust makes clear what has to be done at compile time, allowing to write software that is pretty
much guaranteed to work once it compiles.
Again, my apologies if removing Python 2 support caused inconveniences, please see release 2.1.13 which returns it.
see the following for (most) details:
https://github.com/gitpython-developers/gitpython/milestone/27?closed=1
or run have a look at the difference between tags v2.1.12 and v3.0.0:
https://github.com/gitpython-developers/GitPython/compare/2.1.12...3.0.0.
2.1.15
- Fixed GitDB (gitdb2) requirement version specifier formatting in requirements.txt
(Backported from#979 <https://github.com/gitpython-developers/GitPython/pull/979>_) - Restricted GitDB (gitdb2) version requirement to < 3
(#897 <https://github.com/gitpython-developers/GitPython/issues/897>_)
2.1.14
- Fixed handling of 0 when transforming kwargs into Git command arguments
(Backported from#899 <https://github.com/gitpython-developers/GitPython/pull/899>_)
2.1.13 - Bring back Python 2.7 support
My apologies for any inconvenience this may have caused. Following semver, backward incompatible changes
will be introduced in a minor version.
2.1.12 - Bugfixes and Features
- Multi-value support and interface improvements for Git configuration. Thanks to A. Jesse Jiryu Davis.
or run have a look at the difference between tags v2.1.11 and v2.1.12:
https://github.com/gitpython-developers/GitPython/compare/2.1.11...2.1.12
2.1.11 - Bugfixes
see the following for (most) details:
https://github.com/gitpython-developers/gitpython/milestone/26?closed=1
or run have a look at the difference between tags v2.1.10 and v2.1.11:
https://github.com/gitpython-developers/GitPython/compare/2.1.10...2.1.11
2.1.10 - Bugfixes
see the following for (most) details:
https://github.com/gitpython-developers/gitpython/milestone/25?closed=1
or run have a look at the difference between tags v2.1.9 and v2.1.10:
https://github.com/gitpython-developers/GitPython/compare/2.1.9...2.1.10
2.1.9 - Dropping support for Python 2.6
see the following for (most) details:
https://github.com/gitpython-developers/gitpython/milestone/24?closed=1
or run have a look at the difference between tags v2.1.8 and v2.1.9:
https://github.com/gitpython-developers/GitPython/compare/2.1.8...2.1.9
2.1.8 - bugfixes
see the following for (most) details:
https://github.com/gitpython-developers/gitpython/milestone/23?closed=1
or run have a look at the difference between tags v2.1.7 and v2.1.8:
https://github.com/gitpython-developers/GitPython/compare/2.1.7...2.1.8
2.1.6 - bugfixes
- support for worktrees
2.1.3 - Bugfixes
All issues and PRs can be viewed in all detail when following this URL:
https://github.com/gitpython-developers/GitPython/milestone/21?closed=1
2.1.1 - Bugfixes
All issues and PRs can be viewed in all detail when following this URL:
https://github.com/gitpython-developers/GitPython/issues?q=is%3Aclosed+milestone%3A%22v2.1.1+-+Bugfixes%22
2.1.0 - Much better windows support!
Special thanks to @ankostis, who made this release possible (nearly) single-handedly.
GitPython is run by its users, and their PRs make all the difference, they keep
GitPython relevant. Thank you all so much for contributing !
Notable fixes
- The
GIT_DIRenvironment variable does not override thepathargument when
initializing aRepoobject anymore. However, if saidpathunset,GIT_DIR
will be used to fill the void.
All issues and PRs can be viewed in all detail when following this URL:
https://github.com/gitpython-developers/GitPython/issues?q=is%3Aclosed+milestone%3A%22v2.1.0+-+proper+windows+support%22
2.0.9 - Bugfixes
tag.commitwill now resolve commits deeply.Repoobjects can now be pickled, which helps with multi-processing.Head.checkout()now deals with detached heads, which is when it will return
theHEADreference instead.DiffIndex.iter_change_type(...)produces better results when diffing
2.0.8 - Features and Bugfixes
DiffIndex.iter_change_type(...)produces better results when diffing
an index against the working tree.Repo().is_dirty(...)now supports thepathparameter, to specify a single
path by which to filter the output. Similar togit status- Symbolic refs created by this library will now be written with a newline
character, which was previously missing. blame()now properly preserves multi-line commit messages.- No longer corrupt ref-logs by writing multi-line comments into them.
2.0.7 - New Features
IndexFile.commit(...,skip_hooks=False)added. This parameter emulates the
behaviour of--no-verifyon the command-line.
2.0.6 - Fixes and Features
- Fix: remote output parser now correctly matches refs with non-ASCII
chars in them - API: Diffs now have
a_rawpath,b_rawpath,raw_rename_from,raw_rename_toproperties, which are the raw-bytes equivalents of their
unicode path counterparts. - Fix: TypeError about passing keyword argument to string decode() on
Python 2.6. - Feature:
setUrl API on Remotes <https://github.com/gitpython-developers/GitPython/pull/446#issuecomment-224670539>__
2.0.5 - Fixes
- Fix: parser of fetch info lines choked on some legitimate lines
2.0.4 - Fixes
- Fix: parser of commit object data is now robust against cases where
commit object contains invalid bytes. The invalid characters are now
replaced rather than choked on. - Fix: non-ASCII paths are now properly decoded and returned in
.diff()output - Fix:
RemoteProgresswill now strip the ', ' prefix or suffix from messages. - API: Remote.fetch|push|pull methods now allow the
progressargument to
be a callable. This saves you from creating a custom type with usually just one
implemented method.
2.0.3 - Fixes
- Fix: bug in
git-blame --incrementaloutput parser that broken when
commit messages contained\rcharacters - Fix: progress handler exceptions are not caught anymore, which would usually just hide bugs
previously. - Fix: The
Git.executemethod will now redirectstdouttodevnullifwith_stdoutis false,
which is the intended behaviour based on the parameter's documentation.
2.0.2 - Fixes
- Fix: source package does not include *.pyc files
- Fix: source package does include doc sources
2.0.1 - Fixes
- Fix: remote output parser now correctly matches refs with "@" in them
2.0.0 - Features
Please note that due to breaking changes, we have to increase the major version.
- IMPORTANT: This release drops support for python 2.6, which is
officially deprecated by the python maintainers. - CRITICAL:
Diffobjects created with patch output will now not carry
the --- and +++ header lines anymore. All diffs now start with the
@@ header line directly. Users that rely on the old behaviour can now
(reliably) read this information from the a_path and b_path properties
without having to parse these lines manually. Commitnow has extra propertiesauthored_datetimeandcommitter_datetime(to get Python datetime instances rather than
timestamps)Commit.diff()now supports diffing the root commit viaCommit.diff(NULL_TREE).Repo.blame()now respectsincremental=True, supporting incremental
blames. Incremental blames are slightly faster since they don't include
the file's contents in them.- Fix:
Diffobjects created with patch output will now have theira_pathandb_pathproperties parsed out correctly. Previously, some
values may have been populated incorrectly when a file was added or
deleted. - Fix: diff parsing issues with paths that contain "unsafe" chars, like
spaces, tabs, backslashes, etc.
1.0.2 - Fixes
- IMPORTANT: Changed default object database of
Repoobjects toGitCmdObjectDB. The pure-python implementation
used previously usually fails to release its resources (i.e. file handles), which can lead to problems when working
with large repositories. - CRITICAL: fixed incorrect
Commitobject serialization when authored or commit date had timezones which were not
divisiblej by 3600 seconds. This would happen if the timezone was something like+0530for instance. - A list of all additional fixes can be found
on GitHub <https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v1.0.2+-+Fixes%22+is%3Aclosed>__ - CRITICAL:
Tree.cachewas removed without replacement. It is technically impossible to change individual trees and expect their serialization results to be consistent with what git expects. Instead, use theIndexFilefacilities to adjust the content of the staging area, and write it out to the respective tree objects usingIndexFile.write_tree()instead.
1.0.1 - Fixes
- A list of all issues can be found
on GitHub <https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v1.0.1+-+Fixes%22+is%3Aclosed>__
1.0.0 - Notes
This version is equivalent to v0.3.7, but finally acknowledges that GitPython is stable and production ready.
It follows the semantic version scheme <http://semver.org>_, and thus will not break its existing API unless it goes 2.0.
0.3.7 - Fixes
IndexFile.add()will now write the index without any extension data by default. However, you may override this behaviour with the newwrite_extension_datakeyword argument.- Renamed
ignore_tree_extension_datakeyword argument inIndexFile.write(...)toignore_extension_data
- Renamed
If the git command executed during
Remote.push(...)|fetch(...)returns with an non-zero exit code and GitPython didn't
obtain any head-information, the correspondingGitCommandErrorwill be raised. This may break previous code which expected
these operations to never raise. However, that behaviour is undesirable as it would effectively hide the fact that there
was an error. Seethis issue <https://github.com/gitpython-developers/GitPython/issues/271>__ for more information.If the git executable can't be found in the PATH or at the path provided by
GIT_PYTHON_GIT_EXECUTABLE, this is made
obvious by throwingGitCommandNotFound, both on unix and on windows.- Those who support GUI on windows will now have to set
git.Git.USE_SHELL = Trueto get the previous behaviour.
- Those who support GUI on windows will now have to set
A list of all issues can be found
on GitHub <https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.7+-+Fixes%22+is%3Aclosed>__
0.3.6 - Features
DOCS
- special members like
__init__are now listed in the API documentation - tutorial section was revised entirely, more advanced examples were added.
- special members like
POSSIBLY BREAKING CHANGES
- As
rev_parsewill now throwBadNameas well asBadObject, client code will have to catch both exception types. - Repo.working_tree_dir now returns None if it is bare. Previously it raised AssertionError.
- IndexFile.add() previously raised AssertionError when paths where used with bare repository, now it raises InvalidGitRepositoryError
- As
Added
Repo.merge_base()implementation. See therespective issue on GitHub <https://github.com/gitpython-developers/GitPython/issues/169>__[include]sections in git configuration files are now respectedAdded
GitConfigParser.rename_section()Added
Submodule.rename()A list of all issues can be found
on GitHub <https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.6+-+Features%22+>__
0.3.5 - Bugfixes
- push/pull/fetch operations will not block anymore
- diff() can now properly detect renames, both in patch and raw format. Previously it only worked when create_patch was True.
- repo.odb.update_cache() is now called automatically after fetch and pull operations. In case you did that in your own code, you might want to remove your line to prevent a double-update that causes unnecessary IO.
Repo(path)will not automatically search upstream anymore and find any git directory on its way up. If you need that behaviour, you can turn it back on using the newsearch_parent_directories=Trueflag when constructing aRepoobject.- IndexFile.commit() now runs the
pre-commitandpost-commithooks. Verified to be working on posix systems only. - A list of all fixed issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.5+-+bugfixes%22+
0.3.4 - Python 3 Support
- Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes.
- Id attribute of Commit objects is now
hexsha, instead ofbinsha. The latter makes no sense in python 3 and I see no application of it anyway besides its artificial usage in test cases. - IMPORTANT: If you were using the config_writer(), you implicitly relied on del to work as expected to flush changes. To be sure changes are flushed under PY3, you will have to call the new
release()method to trigger a flush. For some reason, del is not called necessarily anymore when a symbol goes out of scope. - The
Treenow has a.join('name')method which is equivalent totree / 'name'
0.3.3
When fetching, pulling or pushing, and an error occurs, it will not be reported on stdout anymore. However, if there is a fatal error, it will still result in a GitCommandError to be thrown. This goes hand in hand with improved fetch result parsing.
Code Cleanup (in preparation for python 3 support)
- Applied autopep8 and cleaned up code
- Using python logging module instead of print statements to signal certain kinds of errors
0.3.2.1
Fix for #207 <https://github.com/gitpython-developers/GitPython/issues/207>_
0.3.2
- Release of most recent version as non-RC build, just to allow pip to install the latest version right away.
- Have a look at the milestones (https://github.com/gitpython-developers/GitPython/milestones) to see what's next.
0.3.2 RC1
git command wrapper
Added
version_infoproperty which returns a tuple of integers representing the installed git version.Added GIT_PYTHON_GIT_EXECUTABLE environment variable, which can be used to set the desired git executable to be used. despite of what would be found in the path.
Blob Type
Added mode constants to ease the manual creation of blobs
IterableList
Added contains and delitem methods
More Changes
Configuration file parsing is more robust. It should now be able to handle everything that the git command can parse as well.
The progress parsing was updated to support git 1.7.0.3 and newer. Previously progress was not enabled for the git command or only worked with ssh in case of older git versions.
Parsing of tags was improved. Previously some parts of the name could not be parsed properly.
The rev-parse pure python implementation now handles branches correctly if they look like hexadecimal sha's.
GIT_PYTHON_TRACE is now set on class level of the Git type, previously it was a module level global variable.
GIT_PYTHON_GIT_EXECUTABLE is a class level variable as well.
0.3.1 Beta 2
Added reflog support ( reading and writing )
New types:
RefLogandRefLogEntryReflog is maintained automatically when creating references and deleting them
Non-intrusive changes to
SymbolicReference, these don't require your code to change. They allow to append messages to the reflog.abspathproperty added, similar toabspathof Object instanceslog()method addedlog_append(...)method addedset_reference(...)method added (reflog support)set_commit(...)method added (reflog support)set_object(...)method added (reflog support)
Intrusive Changes to
Headtypecreate(...)method now supports the reflog, but will not raiseGitCommandErroranymore as it is a pure python implementation now. Instead, it raisesOSError.Intrusive Changes to
Repotypecreate_head(...)method does not support kwargs anymore, instead it supports a logmsg parameterRepo.rev_parse now supports the [ref]@{n} syntax, where n is the number of steps to look into the reference's past
BugFixes
- Removed incorrect ORIG_HEAD handling
Flattened directory structure to make development more convenient.
.. note:: This alters the way projects using git-python as a submodule have to adjust their sys.path to be able to import git-python successfully.
Misc smaller changes and bugfixes
0.3.1 Beta 1
Full Submodule-Support
Added unicode support for author names. Commit.author.name is now unicode instead of string.
Head Type changes
config_reader() & config_writer() methods added for access to head specific options.
tracking_branch() & set_tracking_branch() methods added for easy configuration of tracking branches.
0.3.0 Beta 2
- Added python 2.4 support
0.3.0 Beta 1
Renamed Modules
For consistency with naming conventions used in sub-modules like gitdb, the following modules have been renamed
- git.utils -> git.util
- git.errors -> git.exc
- git.objects.utils -> git.objects.util
General
- Object instances, and everything derived from it, now use binary sha's internally. The 'sha' member was removed, in favor of the 'binsha' member. An 'hexsha' property is available for convenient conversions. They may only be initialized using their binary shas, reference names or revision specs are not allowed anymore.
- IndexEntry instances contained in IndexFile.entries now use binary sha's. Use the .hexsha property to obtain the hexadecimal version. The .sha property was removed to make the use of the respective sha more explicit.
- If objects are instantiated explicitly, a binary sha is required to identify the object, where previously any rev-spec could be used. The ref-spec compatible version still exists as Object.new or Repo.commit|Repo.tree respectively.
- The .data attribute was removed from the Object type, to obtain plain data, use the data_stream property instead.
- ConcurrentWriteOperation was removed, and replaced by LockedFD
- IndexFile.get_entries_key was renamed to entry_key
- IndexFile.write_tree: removed missing_ok keyword, its always True now. Instead of raising GitCommandError it raises UnmergedEntriesError. This is required as the pure-python implementation doesn't support the missing_ok keyword yet.
- diff.Diff.null_hex_sha renamed to NULL_HEX_SHA, to be conforming with the naming in the Object base class
0.2 Beta 2
- Commit objects now carry the 'encoding' information of their message. It wasn't parsed previously, and defaults to UTF-8
- Commit.create_from_tree now uses a pure-python implementation, mimicking git-commit-tree
0.2
General
- file mode in Tree, Blob and Diff objects now is an int compatible to definitions
in the stat module, allowing you to query whether individual user, group and other
read, write and execute bits are set. - Adjusted class hierarchy to generally allow comparison and hash for Objects and Refs
- Improved Tag object which now is a Ref that may contain a tag object with additional
Information - id_abbrev method has been removed as it could not assure the returned short SHA's
where unique - removed basename method from Objects with path's as it replicated features of os.path
- from_string and list_from_string methods are now private and were renamed to
_from_string and _list_from_string respectively. As part of the private API, they
may change without prior notice. - Renamed all find_all methods to list_items - this method is part of the Iterable interface
that also provides a more efficients and more responsive iter_items method - All dates, like authored_date and committer_date, are stored as seconds since epoch
to consume less memory - they can be converted using time.gmtime in a more suitable
presentation format if needed. - Named method parameters changed on a wide scale to unify their use. Now git specific
terms are used everywhere, such as "Reference" ( ref ) and "Revision" ( rev ).
Previously multiple terms where used making it harder to know which type was allowed
or not. - Unified diff interface to allow easy diffing between trees, trees and index, trees
and working tree, index and working tree, trees and index. This closely follows
the git-diff capabilities. - Git.execute does not take the with_raw_output option anymore. It was not used
by anyone within the project and False by default.
Item Iteration
- Previously one would return and process multiple items as list only which can
hurt performance and memory consumption and reduce response times.
iter_items method provide an iterator that will return items on demand as parsed
from a stream. This way any amount of objects can be handled. - list_items method returns IterableList allowing to access list members by name
objects Package
- blob, tree, tag and commit module have been moved to new objects package. This should
not affect you though unless you explicitly imported individual objects. If you just
used the git package, names did not change.
Blob
- former 'name' member renamed to path as it suits the actual data better
GitCommand
- git.subcommand call scheme now prunes out None from the argument list, allowing
to be called more comfortably as None can never be a valid to the git command
if converted to a string. - Renamed 'git_dir' attribute to 'working_dir' which is exactly how it is used
Commit
- 'count' method is not an instance method to increase its ease of use
- 'name_rev' property returns a nice name for the commit's sha
Config
- The git configuration can now be read and manipulated directly from within python
using the GitConfigParser - Repo.config_reader() returns a read-only parser
- Repo.config_writer() returns a read-write parser
Diff
- Members a a_commit and b_commit renamed to a_blob and b_blob - they are populated
with Blob objects if possible - Members a_path and b_path removed as this information is kept in the blobs
- Diffs are now returned as DiffIndex allowing to more quickly find the kind of
diffs you are interested in
Diffing
- Commit and Tree objects now support diffing natively with a common interface to
compare against other Commits or Trees, against the working tree or against the index.
Index
- A new Index class allows to read and write index files directly, and to perform
simple two and three way merges based on an arbitrary index.
References
- References are object that point to a Commit
- SymbolicReference are a pointer to a Reference Object, which itself points to a specific
Commit - They will dynamically retrieve their object at the time of query to assure the information
is actual. Recently objects would be cached, hence ref object not be safely kept
persistent.
Repo
Moved blame method from Blob to repo as it appeared to belong there much more.
active_branch method now returns a Head object instead of a string with the name
of the active branch.tree method now requires a Ref instance as input and defaults to the active_branch
instead of masteris_dirty now takes additional arguments allowing fine-grained control about what is
considered dirtyRemoved the following methods:
- 'log' method as it as effectively the same as the 'commits' method
- 'commits_since' as it is just a flag given to rev-list in Commit.iter_items
- 'commit_count' as it was just a redirection to the respective commit method
- 'commits_between', replaced by a note on the iter_commits method as it can achieve the same thing
- 'commit_delta_from' as it was a very special case by comparing two different repjrelated repositories, i.e. clones, git-rev-list would be sufficient to find commits that would need to be transferred for example.
- 'create' method which equals the 'init' method's functionality
- 'diff' - it returned a mere string which still had to be parsed
- 'commit_diff' - moved to Commit, Tree and Diff types respectively
Renamed the following methods:
- commits to iter_commits to improve the performance, adjusted signature
- init_bare to init, implying less about the options to be used
- fork_bare to clone, as it was to represent general clone functionality, but implied
a bare clone to be more versatile - archive_tar_gz and archive_tar and replaced by archive method with different signature
'commits' method has no max-count of returned commits anymore, it now behaves like git-rev-list
The following methods and properties were added
- 'untracked_files' property, returning all currently untracked files
- 'head', creates a head object
- 'tag', creates a tag object
- 'iter_trees' method
- 'config_reader' method
- 'config_writer' method
- 'bare' property, previously it was a simple attribute that could be written
Renamed the following attributes
- 'path' is now 'git_dir'
- 'wd' is now 'working_dir'
Added attribute
- 'working_tree_dir' which may be None in case of bare repositories
Remote
- Added Remote object allowing easy access to remotes
- Repo.remotes lists all remotes
- Repo.remote returns a remote of the specified name if it exists
Test Framework
- Added support for common TestCase base class that provides additional functionality
to receive repositories tests can also write to. This way, more aspects can be
tested under real-world ( un-mocked ) conditions.
Tree
- former 'name' member renamed to path as it suits the actual data better
- added traverse method allowing to recursively traverse tree items
- deleted blob method
- added blobs and trees properties allowing to query the respective items in the
tree - now mimics behaviour of a read-only list instead of a dict to maintain order.
- content_from_string method is now private and not part of the public API anymore
0.1.6
General
Added in Sphinx documentation.
Removed ambiguity between paths and treeishs. When calling commands that
accept treeish and path arguments and there is a path with the same name as
a treeish git cowardly refuses to pick one and asks for the command to use
the unambiguous syntax where '--' separates the treeish from the paths.Repo.commits,Repo.commits_between,Repo.commits_since,Repo.commit_count,Repo.commit,Commit.countandCommit.find_allall now optionally take a path argument which
constrains the lookup by path. This changes the order of the positional
arguments inRepo.commitsandRepo.commits_since.
Commit
Commit.messagenow contains the full commit message (rather than just
the first line) and a new propertyCommit.summarycontains the first
line of the commit message.Fixed a failure when trying to lookup the stats of a parentless commit from
a bare repo.
Diff
The diff parser is now far faster and also addresses a bug where
sometimes b_mode was not set.Added support for parsing rename info to the diff parser. Addition of new
propertiesDiff.renamed,Diff.rename_from, andDiff.rename_to.
Head
- Corrected problem where branches was only returning the last path component
instead of the entire path component following refs/heads/.
Repo
Modified the gzip archive creation to use the python gzip module.
Corrected
commits_betweenalways returning None instead of the reversed
list.
0.1.5
General
upgraded to Mock 0.4 dependency.
Replace GitPython with git in repr() outputs.
Fixed packaging issue caused by ez_setup.py.
Blob
- No longer strip newlines from Blob data.
Commit
- Corrected problem with git-rev-list --bisect-all. See
http://groups.google.com/group/git-python/browse_thread/thread/aed1d5c4b31d5027
Repo
Corrected problems with creating bare repositories.
Repo.tree no longer accepts a path argument. Use:
dict(k, o for k, o in tree.items() if k in paths)
Made daemon export a property of Repo. Now you can do this:
exported = repo.daemon_export
repo.daemon_export = TrueAllows modifying the project description. Do this:
repo.description = "Foo Bar"
repo.description
'Foo Bar'Added a read-only property Repo.is_dirty which reflects the status of the
working directory.Added a read-only Repo.active_branch property which returns the name of the
currently active branch.
Tree
Switched to using a dictionary for Tree contents since you will usually want
to access them by name and order is unimportant.Implemented a dictionary protocol for Tree objects. The following:
child = tree.contents['grit']
becomes:
child = tree['grit']
Made Tree.content_from_string a static method.
0.1.4.1
- removed
method_missingstuff and replaced with a__getattr__
override inGit.
0.1.4
- renamed
git_pythontogit. Be sure to delete all pyc files before
testing.
Commit
- Fixed problem with commit stats not working under all conditions.
Git
Renamed module to cmd.
Removed shell escaping completely.
Added support for
stderr,stdin, andwith_status.git_diris now optional in the constructor forgit.Git. Git now
falls back toos.getcwd()when git_dir is not specified.add a
with_exceptionskeyword argument to git commands.GitCommandErroris raised when the exit status is non-zero.add support for a
GIT_PYTHON_TRACEenvironment variable.GIT_PYTHON_TRACEallows us to debug GitPython's usage of git through
the use of an environment variable.
Tree
- Fixed up problem where
namedoesn't exist on root of tree.
Repo
- Corrected problem with creating bare repo. Added
Repo.createalias.
0.1.2
Tree
- Corrected problem with
Tree.__div__not working with zero length files.
Removed__len__override and replaced with size instead. Also made size
cache properly. This is a breaking change.
0.1.1
Fixed up some urls because I'm a moron
0.1.0
initial release
File: doc/source/index.rst
.. GitPython documentation master file, created by sphinx-quickstart on Sat Jan 24 11:51:01 2009.
You can adapt this file completely to your liking, but it should at least
contain the root toctree directive.
GitPython Documentation
.. toctree::
:maxdepth: 2
intro
quickstart
tutorial
reference
roadmap
changes
Indices and tables
- :ref:
genindex - :ref:
modindex - :ref:
search
File: doc/source/intro.rst
.. _intro_toplevel:
================== Overview / Install
GitPython is a python library used to interact with git repositories, high-level like git-porcelain, or low-level like git-plumbing.
It provides abstractions of git objects for easy access of repository data, and additionally allows you to access the git repository more directly using either a pure python implementation, or the faster, but more resource intensive git command implementation.
The object database implementation is optimized for handling large quantities of objects and large datasets, which is achieved by using low-level structures and data streaming.
Requirements
Python_ >= 3.7Git_ 1.7.0 or newer
It should also work with older versions, but it may be that some operations
involving remotes will not work as expected.GitDB_ - a pure python git database implementationtyping_extensions_ >= 3.7.3.4 (if python < 3.10)
.. _Python: https://www.python.org
.. _Git: https://git-scm.com/
.. _GitDB: https://pypi.python.org/pypi/gitdb
.. _typing_extensions: https://pypi.org/project/typing-extensions/
Installing GitPython
Installing GitPython is easily done usingpip_. Assuming it is
installed, just run the following from the command-line:
.. sourcecode:: none
# pip install GitPythonThis command will download the latest version of GitPython from thePython Package Index <http://pypi.python.org/pypi/GitPython>_ and install it
to your system. More information about pip and pypi can be found
here:
install pip <https://pip.pypa.io/en/latest/installing.html>_pypi <https://pypi.python.org/pypi/GitPython>_
.. _pip: https://pip.pypa.io/en/latest/installing.html
Alternatively, you can install from the distribution using the setup.py
script:
.. sourcecode:: none
# python setup.py install.. note:: In this case, you have to manually install GitDB_ as well. It would be recommended to use the :ref:git source repository in that case.
Limitations
Leakage of System Resources
GitPython is not suited for long-running processes (like daemons) as it tends to
leak system resources. It was written in a time where destructors (as implemented
in the __del__ method) still ran deterministically.
In case you still want to use it in such a context, you will want to search the
codebase for __del__ implementations and call these yourself when you see fit.
Another way assure proper cleanup of resources is to factor out GitPython into a
separate process which can be dropped periodically.
Getting Started
- :ref:
tutorial-label- This tutorial provides a walk-through of some of
the basic functionality and concepts used in GitPython. It, however, is not
exhaustive so you are encouraged to spend some time in the
:ref:api_reference_toplevel.
API Reference
An organized section of the GitPython API is at :ref:api_reference_toplevel.
.. _source-code-label:
Source Code
GitPython's git repo is available on GitHub, which can be browsed at:
and cloned using::
$ git clone https://github.com/gitpython-developers/GitPython git-pythonFinally verify the installation by running unit tests::
$ python -m unittestQuestions and Answers
Please use stackoverflow for questions, and don't forget to tag it with gitpython to assure the right people see the question in a timely manner.
http://stackoverflow.com/questions/tagged/gitpython
Issue Tracker
The issue tracker is hosted by GitHub:
https://github.com/gitpython-developers/GitPython/issues
License Information
GitPython is licensed under the New BSD License. See the LICENSE file for
more information.
File: doc/source/quickstart.rst
.. _quickdoc_toplevel:
.. highlight:: python
.. _quickdoc-label:
============================== GitPython Quick Start Tutorial
Welcome to the GitPython Quickstart Guide! Designed for developers seeking a practical and interactive learning experience, this concise resource offers step-by-step code snippets to swiftly initialize/clone repositories, perform essential Git operations, and explore GitPython's capabilities. Get ready to dive in, experiment, and unleash the power of GitPython in your projects!
git.Repo
There are a few ways to create a :class:git.Repo <git.repo.base.Repo> object
Initialize a new git Repo
#########################
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [1-test_init_repo_object]
:end-before: # ![1-test_init_repo_object]Existing local git Repo
#######################
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [2-test_init_repo_object]
:end-before: # ![2-test_init_repo_object]Clone from URL
##############
For the rest of this tutorial we will use a clone from https://github.com/gitpython-developers/QuickStartTutorialFiles.git
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [1-test_cloned_repo_object]
:end-before: # ![1-test_cloned_repo_object]Trees & Blobs
Latest Commit Tree
##################
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [12-test_cloned_repo_object]
:end-before: # ![12-test_cloned_repo_object]Any Commit Tree
###############
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [13-test_cloned_repo_object]
:end-before: # ![13-test_cloned_repo_object]Display level 1 Contents
########################
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [14-test_cloned_repo_object]
:end-before: # ![14-test_cloned_repo_object]Recurse through the Tree
########################
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [15-test_cloned_repo_object]
:end-before: # ![15-test_cloned_repo_object]
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [16-test_cloned_repo_object]
:end-before: # ![16-test_cloned_repo_object]Usage
Add file to staging area
########################
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [2-test_cloned_repo_object]
:end-before: # ![2-test_cloned_repo_object]
Now lets add the updated file to git
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [3-test_cloned_repo_object]
:end-before: # ![3-test_cloned_repo_object]
Notice the add method requires a list as a parameter
Warning: If you experience any trouble with this, try to invoke :class:`git <git.cmd.Git>` instead via repo.git.add(path)Commit
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [4-test_cloned_repo_object]
:end-before: # ![4-test_cloned_repo_object]List of commits associated with a file
#######################################
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [5-test_cloned_repo_object]
:end-before: # ![5-test_cloned_repo_object]
Notice this returns a generator object
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [6-test_cloned_repo_object]
:end-before: # ![6-test_cloned_repo_object]
returns list of :class:`Commit <git.objects.commit.Commit>` objectsPrinting text files
####################
Lets print the latest version of <local_dir>/dir1/file2.txt
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [17-test_cloned_repo_object]
:end-before: # ![17-test_cloned_repo_object]
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [18-test_cloned_repo_object]
:end-before: # ![18-test_cloned_repo_object]
Previous version of `<local_dir>/dir1/file2.txt`
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [18.1-test_cloned_repo_object]
:end-before: # ![18.1-test_cloned_repo_object]Status
* Untracked files
Lets create a new file
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [7-test_cloned_repo_object]
:end-before: # ![7-test_cloned_repo_object]
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [8-test_cloned_repo_object]
:end-before: # ![8-test_cloned_repo_object]
* Modified files
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [9-test_cloned_repo_object]
:end-before: # ![9-test_cloned_repo_object]
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [10-test_cloned_repo_object]
:end-before: # ![10-test_cloned_repo_object]
returns a list of :class:`Diff <git.diff.Diff>` objects
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [11-test_cloned_repo_object]
:end-before: # ![11-test_cloned_repo_object]Diffs
Compare staging area to head commit
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [11.1-test_cloned_repo_object]
:end-before: # ![11.1-test_cloned_repo_object]
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [11.2-test_cloned_repo_object]
:end-before: # ![11.2-test_cloned_repo_object]Compare commit to commit
.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [11.3-test_cloned_repo_object]
:end-before: # ![11.3-test_cloned_repo_object]More Resources
Remember, this is just the beginning! There's a lot more you can achieve with GitPython in your development workflow.
To explore further possibilities and discover advanced features, check out the full :ref:GitPython tutorial <tutorial_toplevel>
and the :ref:API Reference <api_reference_toplevel>. Happy coding!
File: doc/source/reference.rst
.. _api_reference_toplevel:
API Reference
Top-Level
.. py:data:: git.version
Current GitPython version.
.. automodule:: git
:members: refresh
Objects.Base
.. automodule:: git.objects.base
:members:
:undoc-members:
:special-members:
Objects.Blob
.. automodule:: git.objects.blob
:members:
:undoc-members:
:special-members:
Objects.Commit
.. automodule:: git.objects.commit
:members:
:undoc-members:
:special-members:
Objects.Tag
.. automodule:: git.objects.tag
:members:
:undoc-members:
:special-members:
Objects.Tree
.. automodule:: git.objects.tree
:members:
:undoc-members:
:special-members:
Objects.Functions
.. automodule:: git.objects.fun
:members:
:undoc-members:
:special-members:
Objects.Submodule.base
.. automodule:: git.objects.submodule.base
:members:
:undoc-members:
:special-members:
Objects.Submodule.root
.. automodule:: git.objects.submodule.root
:members:
:undoc-members:
:special-members:
Objects.Submodule.util
.. automodule:: git.objects.submodule.util
:members:
:undoc-members:
:special-members:
Objects.Util
.. automodule:: git.objects.util
:members:
:undoc-members:
:private-members: _get_intermediate_items, _list_traverse, _traverse
:special-members:
Index.Base
.. automodule:: git.index.base
:members:
:undoc-members:
:special-members:
Index.Functions
.. automodule:: git.index.fun
:members:
:undoc-members:
:special-members:
Index.Types
.. automodule:: git.index.typ
:members:
:undoc-members:
:special-members:
Index.Util
.. automodule:: git.index.util
:members:
:undoc-members:
:special-members:
GitCmd
.. automodule:: git.cmd
:members:
:undoc-members:
:special-members:
Config
.. automodule:: git.config
:members:
:undoc-members:
:special-members:
Diff
.. automodule:: git.diff
:members:
:undoc-members:
:special-members:
Exceptions
.. automodule:: git.exc
:members:
:undoc-members:
:special-members:
Refs.symbolic
.. automodule:: git.refs.symbolic
:members:
:undoc-members:
:special-members:
Refs.reference
.. automodule:: git.refs.reference
:members:
:undoc-members:
:special-members:
Refs.head
.. automodule:: git.refs.head
:members:
:undoc-members:
:special-members:
Refs.tag
.. automodule:: git.refs.tag
:members:
:undoc-members:
:special-members:
Refs.remote
.. automodule:: git.refs.remote
:members:
:undoc-members:
:special-members:
Refs.log
.. automodule:: git.refs.log
:members:
:undoc-members:
:special-members:
Remote
.. automodule:: git.remote
:members:
:undoc-members:
:special-members:
Repo.Base
.. automodule:: git.repo.base
:members:
:undoc-members:
:special-members:
Repo.Functions
.. automodule:: git.repo.fun
:members:
:undoc-members:
:special-members:
Compat
.. automodule:: git.compat
:members:
:undoc-members:
:special-members:
DB
.. automodule:: git.db
:members:
:undoc-members:
:special-members:
Types
.. automodule:: git.types
:members:
:undoc-members:
:special-members:
Util
.. automodule:: git.util
:members:
:undoc-members:
:special-members:
File: doc/source/roadmap.rst
#######
Roadmap
#######
The full list of milestones including associated tasks can be found on GitHub:
https://github.com/gitpython-developers/GitPython/issues
Select the respective milestone to filter the list of issues accordingly.
File: doc/source/tutorial.rst
.. _tutorial_toplevel:
.. highlight:: python
.. _tutorial-label:
================== GitPython Tutorial
GitPython provides object model access to your git repository. This tutorial is composed of multiple sections, most of which explain a real-life use case.
All code presented here originated from test_docs.py <https://github.com/gitpython-developers/GitPython/blob/main/test/test_docs.py>_ to assure correctness. Knowing this should also allow you to more easily run the code for your own testing purposes. All you need is a developer installation of git-python.
Meet the Repo type
The first step is to create a :class:git.Repo <git.repo.base.Repo> object to represent your repository.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [1-test_init_repo_object]
:end-before: # ![1-test_init_repo_object]
In the above example, the directory self.rorepo.working_tree_dir equals /Users/mtrier/Development/git-python and is my working repository which contains the .git directory. You can also initialize GitPython with a bare repository.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [2-test_init_repo_object]
:end-before: # ![2-test_init_repo_object]
A repo object provides high-level access to your data, it allows you to create and delete heads, tags and remotes and access the configuration of the repository.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [3-test_init_repo_object]
:end-before: # ![3-test_init_repo_object]
Query the active branch, query untracked files or whether the repository data has been modified.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [4-test_init_repo_object]
:end-before: # ![4-test_init_repo_object]
Clone from existing repositories or initialize new empty ones.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [5-test_init_repo_object]
:end-before: # ![5-test_init_repo_object]
Archive the repository contents to a tar file.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [6-test_init_repo_object]
:end-before: # ![6-test_init_repo_object]
Advanced Repo Usage
And of course, there is much more you can do with this type, most of the following will be explained in greater detail in specific tutorials. Don't worry if you don't understand some of these examples right away, as they may require a thorough understanding of git's inner workings.
Query relevant repository paths ...
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [7-test_init_repo_object]
:end-before: # ![7-test_init_repo_object]
:class:Heads <git.refs.head.Head> Heads are branches in git-speak. :class:References <git.refs.reference.Reference> are pointers to a specific commit or to other references. Heads and :class:Tags <git.refs.tag.TagReference> are a kind of references. GitPython allows you to query them rather intuitively.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [8-test_init_repo_object]
:end-before: # ![8-test_init_repo_object]
You can also create new heads ...
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [9-test_init_repo_object]
:end-before: # ![9-test_init_repo_object]
... and tags ...
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [10-test_init_repo_object]
:end-before: # ![10-test_init_repo_object]
You can traverse down to :class:git objects <git.objects.base.Object> through references and other objects. Some objects like :class:commits <git.objects.commit.Commit> have additional meta-data to query.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [11-test_init_repo_object]
:end-before: # ![11-test_init_repo_object]
:class:Remotes <git.remote.Remote> allow to handle fetch, pull and push operations, while providing optional real-time progress information to :class:progress delegates <git.util.RemoteProgress>.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [12-test_init_repo_object]
:end-before: # ![12-test_init_repo_object]
The :class:index <git.index.base.IndexFile> is also called stage in git-speak. It is used to prepare new commits, and can be used to keep results of merge operations. Our index implementation allows to stream date into the index, which is useful for bare repositories that do not have a working tree.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [13-test_init_repo_object]
:end-before: # ![13-test_init_repo_object]
:class:Submodules <git.objects.submodule.Submodule> represent all aspects of git submodules, which allows you query all of their related information, and manipulate in various ways.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [14-test_init_repo_object]
:end-before: # ![14-test_init_repo_object]
Examining References
:class:References <git.refs.reference.Reference> are the tips of your commit graph from which you can easily examine the history of your project.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [1-test_references_and_objects]
:end-before: # ![1-test_references_and_objects]
:class:Tags <git.refs.tag.TagReference> are (usually immutable) references to a commit and/or a tag object.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [2-test_references_and_objects]
:end-before: # ![2-test_references_and_objects]
A :class:symbolic reference <git.refs.symbolic.SymbolicReference> is a special case of a reference as it points to another reference instead of a commit.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [3-test_references_and_objects]
:end-before: # ![3-test_references_and_objects]
Access the :class:reflog <git.refs.log.RefLog> easily.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [4-test_references_and_objects]
:end-before: # ![4-test_references_and_objects]
Modifying References
You can easily create and delete :class:reference types <git.refs.reference.Reference> or modify where they point to.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [5-test_references_and_objects]
:end-before: # ![5-test_references_and_objects]
Create or delete :class:tags <git.refs.tag.TagReference> the same way except you may not change them afterwards.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [6-test_references_and_objects]
:end-before: # ![6-test_references_and_objects]
Change the :class:symbolic reference <git.refs.symbolic.SymbolicReference> to switch branches cheaply (without adjusting the index or the working tree).
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [7-test_references_and_objects]
:end-before: # ![7-test_references_and_objects]
Understanding Objects
An Object is anything storable in git's object database. Objects contain information about their type, their uncompressed size as well as the actual data. Each object is uniquely identified by a binary SHA1 hash, being 20 bytes in size, or 40 bytes in hexadecimal notation.
Git only knows 4 distinct object types being :class:Blobs <git.objects.blob.Blob>, :class:Trees <git.objects.tree.Tree>, :class:Commits <git.objects.commit.Commit> and :class:Tags <git.objects.tag.TagObject>.
In GitPython, all objects can be accessed through their common base, can be compared and hashed. They are usually not instantiated directly, but through references or specialized repository functions.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [8-test_references_and_objects]
:end-before: # ![8-test_references_and_objects]
Common fields are ...
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [9-test_references_and_objects]
:end-before: # ![9-test_references_and_objects]
:class:Index objects <git.objects.base.IndexObject> are objects that can be put into git's index. These objects are trees, blobs and submodules which additionally know about their path in the file system as well as their mode.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [10-test_references_and_objects]
:end-before: # ![10-test_references_and_objects]
Access :class:blob <git.objects.blob.Blob> data (or any object data) using streams.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [11-test_references_and_objects]
:end-before: # ![11-test_references_and_objects]
The Commit object
:class:Commit <git.objects.commit.Commit> objects contain information about a specific commit. Obtain commits using references as done in Examining References_ or as follows.
Obtain commits at the specified revision
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [12-test_references_and_objects]
:end-before: # ![12-test_references_and_objects]
Iterate 50 commits, and if you need paging, you can specify a number of commits to skip.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [13-test_references_and_objects]
:end-before: # ![13-test_references_and_objects]
A commit object carries all sorts of meta-data
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [14-test_references_and_objects]
:end-before: # ![14-test_references_and_objects]
Note: date time is represented in a seconds since epoch format. Conversion to human readable form can be accomplished with the various time module <http://docs.python.org/library/time.html>_ methods.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [15-test_references_and_objects]
:end-before: # ![15-test_references_and_objects]
You can traverse a commit's ancestry by chaining calls to parents
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [16-test_references_and_objects]
:end-before: # ![16-test_references_and_objects]
The above corresponds to master^^^ or master~3 in git parlance.
The Tree object
A :class:tree <git.objects.tree.Tree> records pointers to the contents of a directory. Let's say you want the root tree of the latest commit on the master branch
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [17-test_references_and_objects]
:end-before: # ![17-test_references_and_objects]
Once you have a tree, you can get its contents
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [18-test_references_and_objects]
:end-before: # ![18-test_references_and_objects]
It is useful to know that a tree behaves like a list with the ability to query entries by name
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [19-test_references_and_objects]
:end-before: # ![19-test_references_and_objects]
There is a convenience method that allows you to get a named sub-object from a tree with a syntax similar to how paths are written in a posix system
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [20-test_references_and_objects]
:end-before: # ![20-test_references_and_objects]
You can also get a commit's root tree directly from the repository
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [21-test_references_and_objects]
:end-before: # ![21-test_references_and_objects]
As trees allow direct access to their intermediate child entries only, use the traverse method to obtain an iterator to retrieve entries recursively
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [22-test_references_and_objects]
:end-before: # ![22-test_references_and_objects]
.. note:: If trees return Submodule objects, they will assume that they exist at the current head's commit. The tree it originated from may be rooted at another commit though, that it doesn't know. That is why the caller would have to set the submodule's owning or parent commit using the set_parent_commit(my_commit) method.
The Index Object
The git index is the stage containing changes to be written with the next commit or where merges finally have to take place. You may freely access and manipulate this information using the :class:IndexFile <git.index.base.IndexFile> object.
Modify the index with ease
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [23-test_references_and_objects]
:end-before: # ![23-test_references_and_objects]
Create new indices from other trees or as result of a merge. Write that result to a new index file for later inspection.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [24-test_references_and_objects]
:end-before: # ![24-test_references_and_objects]
Handling Remotes
:class:Remotes <git.remote.Remote> are used as alias for a foreign repository to ease pushing to and fetching from them
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [25-test_references_and_objects]
:end-before: # ![25-test_references_and_objects]
You can easily access configuration information for a remote by accessing options as if they were attributes. The modification of remote configuration is more explicit though.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [26-test_references_and_objects]
:end-before: # ![26-test_references_and_objects]
You can also specify per-call custom environments using a new context manager on the Git command, e.g. for using a specific SSH key. The following example works with git starting at v2.3::
ssh_cmd = 'ssh -i id_deployment_key'
with repo.git.custom_environment(GIT_SSH_COMMAND=ssh_cmd):
repo.remotes.origin.fetch()This one sets a custom script to be executed in place of ssh, and can be used in git prior to v2.3::
ssh_executable = os.path.join(rw_dir, 'my_ssh_executable.sh')
with repo.git.custom_environment(GIT_SSH=ssh_executable):
repo.remotes.origin.fetch()Here's an example executable that can be used in place of the ssh_executable above:
.. code-block:: 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.
You might also have a look at Git.update_environment(...) in case you want to setup a changed environment more permanently.
Submodule Handling
:class:Submodules <git.objects.submodule.base.Submodule> can be conveniently handled using the methods provided by GitPython, and as an added benefit, GitPython provides functionality which behave smarter and less error prone than its original c-git implementation, that is GitPython tries hard to keep your repository consistent when updating submodules recursively or adjusting the existing configuration.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [1-test_submodules]
:end-before: # ![1-test_submodules]
In addition to the query functionality, you can move the submodule's repository to a different path <move(...)>,
write its configuration <config_writer().set_value(...).release()>, update its working tree <update(...)>,
and remove or add them <remove(...), add(...)>.
If you obtained your submodule object by traversing a tree object which is not rooted at the head's commit,
you have to inform the submodule about its actual commit to retrieve the data from
by using the set_parent_commit(...) method.
The special :class:RootModule <git.objects.submodule.root.RootModule> type allows you to treat your superproject (master repository) as root of a hierarchy of submodules, which allows very convenient submodule handling. Its update(...) method is reimplemented to provide an advanced way of updating submodules as they change their values over time. The update method will track changes and make sure your working tree and submodule checkouts stay consistent, which is very useful in case submodules get deleted or added to name just two of the handled cases.
Additionally, GitPython adds functionality to track a specific branch, instead of just a commit. Supported by customized update methods, you are able to automatically update submodules to the latest revision available in the remote repository, as well as to keep track of changes and movements of these submodules. To use it, set the name of the branch you want to track to the submodule.$name.branch option of the .gitmodules file, and use GitPython update methods on the resulting repository with the to_latest_revision parameter turned on. In the latter case, the sha of your submodule will be ignored, instead a local tracking branch will be updated to the respective remote branch automatically, provided there are no local changes. The resulting behaviour is much like the one of svn::externals, which can be useful in times.
Obtaining Diff Information
Diffs can generally be obtained by subclasses of :class:Diffable <git.diff.Diffable> as they provide the diff method. This operation yields a :class:DiffIndex <git.diff.DiffIndex> allowing you to easily access diff information about paths.
Diffs can be made between the Index and Trees, Index and the working tree, trees and trees as well as trees and the working copy. If commits are involved, their tree will be used implicitly.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [27-test_references_and_objects]
:end-before: # ![27-test_references_and_objects]
The item returned is a DiffIndex which is essentially a list of Diff objects. It provides additional filtering to ease finding what you might be looking for.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [28-test_references_and_objects]
:end-before: # ![28-test_references_and_objects]
Use the diff framework if you want to implement git-status like functionality.
A diff between the index and the commit's tree your HEAD points to
use
repo.index.diff(repo.head.commit)A diff between the index and the working tree
use
repo.index.diff(None)A list of untracked files
use
repo.untracked_files
Switching Branches
To switch between branches similar to git checkout, you effectively need to point your HEAD symbolic reference to the new branch and reset your index and working copy to match. A simple manual way to do it is the following one
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [29-test_references_and_objects]
:end-before: # ![29-test_references_and_objects]
The previous approach would brutally overwrite the user's changes in the working copy and index though and is less sophisticated than a git-checkout. The latter will generally prevent you from destroying your work. Use the safer approach as follows.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [30-test_references_and_objects]
:end-before: # ![30-test_references_and_objects]
Initializing a repository
In this example, we will initialize an empty repository, add an empty file to the index, and commit the change.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: def test_add_file_and_commit
:end-before: # ![test_add_file_and_commit]
Please have a look at the individual methods as they usually support a vast amount of arguments to customize their behavior.
Using git directly
In case you are missing functionality as it has not been wrapped, you may conveniently use the :class:git <git.cmd.Git> command directly. It is owned by each repository instance.
.. literalinclude:: ../../test/test_docs.py
:language: python
:dedent: 8
:start-after: # [31-test_references_and_objects]
:end-before: # ![31-test_references_and_objects]
The return value will by default be a string of the standard output channel produced by the command.
Keyword arguments translate to short and long keyword arguments on the command-line.
The special notion git.command(flag=True) will create a flag without value like command --flag.
If None is found in the arguments, it will be dropped silently. Lists and tuples passed as arguments will be unpacked recursively to individual arguments. Objects are converted to strings using the str(...) function.
Object Databases
:class:git.Repo <git.repo.base.Repo> instances are powered by its object database instance which will be used when extracting any data, or when writing new objects.
The type of the database determines certain performance characteristics, such as the quantity of objects that can be read per second, the resource usage when reading large data files, as well as the average memory footprint of your application.
GitDB
The GitDB is a pure-python implementation of the git object database. It is the default database to use in GitPython 0.3. It uses less memory when handling huge files, but will be 2 to 5 times slower when extracting large quantities of small objects from densely packed repositories::
repo = Repo("path/to/repo", odbt=GitDB).. warning::
GitDB may fail or become extremely slow when traversing trees in
repositories with very large commits (thousands of changed files in a
single commit). If you encounter RecursionError or excessive
slowness during tree traversal, switch to GitCmdObjectDB instead.
GitCmdObjectDB
The git command database uses persistent git-cat-file instances to read repository information. These operate very fast under all conditions, but will consume additional memory for the process itself. When extracting large files, memory usage will be much higher than GitDB::
repo = Repo("path/to/repo", odbt=GitCmdObjectDB)Git Command Debugging and Customization
Using environment variables, you can further adjust the behaviour of the git command.
GIT_PYTHON_TRACE
If set to non-0, all executed git commands will be shown as they happen
If set to full, the executed git command and its entire output on stdout and stderr will be shown as they happen
NOTE: All logging is outputted using a Python logger, so make sure your program is configured to show INFO-level messages. If this is not the case, try adding the following to your program::
import logging
logging.basicConfig(level=logging.INFO)GIT_PYTHON_GIT_EXECUTABLE
If set, it should contain the full path to the git executable, e.g. c:\Program Files (x86)\Git\bin\git.exe on windows or /usr/bin/git on linux.
And even more ...
There is more functionality in there, like the ability to archive repositories, get stats and logs, blame, and probably a few other things that were not mentioned here.
Check the unit tests for an in-depth introduction on how each function is supposed to be used.
File: fuzzing/README.md
Fuzzing GitPython
This directory contains files related to GitPython's suite of fuzz tests that are executed daily on automated
infrastructure provided by OSS-Fuzz. This document aims to provide necessary information for working
with fuzzing in GitPython.
The latest details regarding OSS-Fuzz test status, including build logs and coverage reports, is available
on the Open Source Fuzzing Introspection website.
How to Contribute
There are many ways to contribute to GitPython's fuzzing efforts! Contributions are welcomed through issues,
discussions, or pull requests on this repository.
Areas that are particularly appreciated include:
- Tackling the existing backlog of open issues. While fuzzing is an effective way to identify bugs, that information
isn't useful unless they are fixed. If you are not sure where to start, the issues tab is a great place to get ideas! - Improvements to this (or other) documentation make it easier for new contributors to get involved, so even small
improvements can have a large impact over time. If you see something that could be made easier by a documentation
update of any size, please consider suggesting it!
For everything else, such as expanding test coverage, optimizing test performance, or enhancing error detection
capabilities, jump into the "Getting Started" section below.
Getting Started with Fuzzing GitPython
[!TIP]
New to fuzzing or unfamiliar with OSS-Fuzz?These resources are an excellent place to start:
- OSS-Fuzz documentation - Continuous fuzzing service for open source software.
- Google/fuzzing - Tutorials, examples, discussions, research proposals, and other resources
related to fuzzing.
- CNCF Fuzzing Handbook -
A comprehensive guide for fuzzing open source software.
- Efficient Fuzzing Guide by The Chromium Project -
Explores strategies to enhance the effectiveness of your fuzz tests, recommended for those looking to optimize their
testing efforts.
Setting Up Your Local Environment
Before contributing to fuzzing efforts, ensure Python and Docker are installed on your machine. Docker is required for
running fuzzers in containers provided by OSS-Fuzz and for safely executing test files directly. Install Docker following the official guide if you do not already have it.
Understanding Existing Fuzz Targets
Review the fuzz-targets/ directory to familiarize yourself with how existing tests are implemented. See
the Files & Directories Overview for more details on the directory structure.
Contributing to Fuzz Tests
Start by reviewing the Atheris documentation and the section
on Running Fuzzers Locally to begin writing or improving fuzz tests.
Files & Directories Overview
The fuzzing/ directory is organized into three key areas:
Fuzz Targets (`fuzz-targets/`)
Contains Python files for each fuzz test.
Things to Know:
- Each fuzz test targets a specific part of GitPython's functionality.
- Test files adhere to the naming convention:
fuzz_<API Under Test>.py, where<API Under Test>indicates the
functionality targeted by the test. - Any functionality that involves performing operations on input data is a possible candidate for fuzz testing, but
features that involve processing untrusted user input or parsing operations are typically going to be the most
interesting. - The goal of these tests is to identify previously unknown or unexpected error cases caused by a given input. For that
reason, fuzz tests should gracefully handle anticipated exception cases with atry/exceptblock to avoid false
positives that halt the fuzzing engine.
OSS-Fuzz Scripts (`oss-fuzz-scripts/`)
Includes scripts for building and integrating fuzz targets with OSS-Fuzz:
container-environment-bootstrap.sh- Sets up the execution environment. It is responsible for fetching default
dictionary entries and ensuring all required build dependencies are installed and up-to-date.build.sh- Executed within the Docker container, this script builds fuzz targets with necessary instrumentation
and prepares seed corpora and dictionaries for use.
Where to learn more:
- OSS-Fuzz documentation on the build.sh
- See GitPython's build.sh and Dockerfile in the OSS-Fuzz repository
Local Development Helpers (`local-dev-helpers/`)
Contains tools to make local development tasks easier.
See the "Running Fuzzers Locally" section below for further documentation and use cases related to files found here.
Running Fuzzers Locally
[!WARNING]
Some fuzz targets in this repository write to the filesystem during execution.
For that reason, it is strongly recommended to always use Docker when executing fuzz targets, even when it may be
possible to do so without it.Although I/O operations such as writing to disk are not considered best practice, the current implementation of at least one test requires it.
See the "Setting Up Your Local Environment" section above if you do not already have Docker installed on your machine.PRs that replace disk I/O with in-memory alternatives are very much welcomed!
Direct Execution of Fuzz Targets
Directly executing fuzz targets allows for quick iteration and testing of changes which can be helpful during early
development of new fuzz targets or for validating changes made to an existing test.
The Dockerfile located in the local-dev-helpers/ subdirectory provides a lightweight
container environment preconfigured with Atheris that makes it easy to execute a fuzz target directly.
From the root directory of your GitPython repository clone:
- Build the local development helper image:
docker build -f fuzzing/local-dev-helpers/Dockerfile -t gitpython-fuzzdev .- Then execute a fuzz target inside the image, for example:
docker run -it -v "$PWD":/src gitpython-fuzzdev python fuzzing/fuzz-targets/fuzz_config.py -atheris_runs=10000The above command executes fuzz_config.py and exits after 10000 runs, or earlier if
the fuzzer finds an error.
Docker CLI's -v flag specifies a volume mount in Docker that maps the directory in which the command is run (which
should be the root directory of your local GitPython clone) to a directory inside the container, so any modifications
made between invocations will be reflected immediately without the need to rebuild the image each time.
Running OSS-Fuzz Locally
This approach uses Docker images provided by OSS-Fuzz for building and running fuzz tests locally. It offers
comprehensive features but requires a local clone of the OSS-Fuzz repository and sufficient disk space for Docker
containers.
Build the Execution Environment
Clone the OSS-Fuzz repository and prepare the Docker environment:
git clone --depth 1 https://github.com/google/oss-fuzz.git oss-fuzz
cd oss-fuzz
python infra/helper.py build_image gitpython
python infra/helper.py build_fuzzers --sanitizer address gitpython[!TIP]
Thebuild_fuzzerscommand above accepts a local file path pointing to your GitPython repository clone as the last
argument.
This makes it easy to build fuzz targets you are developing locally in this repository without changing anything in
the OSS-Fuzz repo!
For example, if you have cloned this repository (or a fork of it) into:~/code/GitPython
Then running this command would build new or modified fuzz targets using the~/code/GitPython/fuzzing/fuzz-targets
directory:shellpython infra/helper.py build_fuzzers --sanitizer address gitpython ~/code/GitPython
Verify the build of your fuzzers with the optional check_build command:
python infra/helper.py check_build gitpythonRun a Fuzz Target
Setting an environment variable for the fuzz target argument of the execution command makes it easier to quickly select
a different target between runs:
# specify the fuzz target without the .py extension:
export FUZZ_TARGET=fuzz_configExecute the desired fuzz target:
python infra/helper.py run_fuzzer gitpython $FUZZ_TARGET -- -max_total_time=60 -print_final_stats=1[!TIP]
In the example above, the "-- -max_total_time=60 -print_final_stats=1" portion of the command is optional but quite
useful.Every argument provided after "
--" in the above command is passed to the fuzzing engine directly. In this case:
-max_total_time=60tells the LibFuzzer to stop execution after 60 seconds have elapsed.-print_final_stats=1tells the LibFuzzer to print a summary of useful metrics about the target run upon
completion.But almost any LibFuzzer option listed in the documentation should
work as well.
Next Steps
For detailed instructions on advanced features like reproducing OSS-Fuzz issues or using the Fuzz Introspector, refer
to the official OSS-Fuzz documentation.
LICENSE
All files located within the fuzzing/ directory are subject to the same license
as the other files in this repository with one exception:
fuzz_config.py was migrated to this repository from the OSS-Fuzz project's repository
where it was originally created. As such, fuzz_config.py retains its original license
and copyright notice (Apache License, Version 2.0 and Copyright 2023 Google LLC respectively) as in a header
comment, followed by a notice stating that it has have been modified contributors to GitPython.
LICENSE-APACHE contains the original license used by the OSS-Fuzz project repository at the time the
file was migrated.