# What changed in gitpython

> 65 changes in gitpython 3 from its official release notes, upgrade guides and advisories: 1 breaking, 36 security, 1 new APIs and options. Each one cited. Sources checked 2026-10-18. HTML: https://unstale.sh/pypi/gitpython/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## gitpython 3

### Breaking changes

- Python 3.7 is no longer supported. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)

### Security

- Symbolic links that alias .gitmodules are rejected. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- URL credentials are redacted without corrupting the host. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Safety checks in Git command wrappers are completed. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- GitPython submodule update path traversal can write outside the repository (3.1.62) — [security advisory](https://github.com/advisories/GHSA-59CR-6R3X-644W)
- Unsafe submodule checkout paths are rejected. (3.1.62) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.1.62)
- GitPython: Denial of Service via catastrophic backtracking (ReDoS) in Actor.name_email_regex — commit author/committer field parsing (3.1.60) — [security advisory](https://github.com/advisories/GHSA-G5VV-9GXW-82HX)
- GitPython: --no-index bypasses diff unsafe-option protections and enables a blind local-file content oracle (3.1.60) — [security advisory](https://github.com/advisories/GHSA-WHH4-5Q6C-9V3X)
- GitPython: Repository content can impersonate the git directory, leading to arbitrary code execution (3.1.60) — [security advisory](https://github.com/advisories/GHSA-239G-WHFQ-7XJ9)
- GitPython: Arbitrary local file content disclosure via [include] directive in untrusted .gitmodules (SubmoduleConfigParser never disables merge_includes) (3.1.59) — [security advisory](https://github.com/advisories/GHSA-7833-FR7J-V32Q)
- GitPython: clone_from()/clone() omit --separate-git-dir from unsafe_git_clone_options, enabling arbitrary git-directory creation outside the destination (3.1.59) — [security advisory](https://github.com/advisories/GHSA-8MCC-HRX5-HVXC)
- GitPython: Dormant multi-line git-config values are corrupted into live injected directives (e.g. core.hooksPath) on any unrelated GitConfigParser write, enabling RCE (3.1.59) — [security advisory](https://github.com/advisories/GHSA-284H-M62Q-GF8W)
- GitPython: Incomplete unsafe_git_revision_options denylist omits --contents/-S, enabling arbitrary file read via Repo.blame() (3.1.59) — [security advisory](https://github.com/advisories/GHSA-5XXX-QHH7-9287)
- GitPython: TagReference.create positional reference bypasses kwargs-only --file guard, enabling arbitrary file read (incomplete fix of 3af0c251) (3.1.59) — [security advisory](https://github.com/advisories/GHSA-3WXW-XV34-2FRG)
- GitPython: Arbitrary file read via --pathspec-from-file in IndexFile.remove() and Head.checkout() (3.1.58) — [security advisory](https://github.com/advisories/GHSA-HH9P-6WH2-4MFC)
- GitPython: Arbitrary Git Repository Creation Outside the Working Tree via Unvalidated .gitmodules Submodule Name in GitPython (3.1.58) — [security advisory](https://github.com/advisories/GHSA-HMQ2-W58F-27JC)
- GitPython: git-config OPTION-name injection via =/#/whitespace bypasses name validator, enabling forged core.sshCommand/hooksPath (RCE) (3.1.58) — [security advisory](https://github.com/advisories/GHSA-JM78-9FVV-MHGR)
- GitPython: Unguarded git option forwarding in Repo.init enables arbitrary command execution via --template clone hooks (3.1.58) — [security advisory](https://github.com/advisories/GHSA-9RJ7-RF2P-W77R)
- GitPython: Unguarded git read-tree option forwarding in IndexFile.from_tree/reset/merge_tree enables arbitrary file overwrite (3.1.58) — [security advisory](https://github.com/advisories/GHSA-4GMW-GG2M-W46P)
- GitPython: Unsafe git option guard bypass via split_single_char_options=False short-option token smuggling enables command execution (3.1.58) — [security advisory](https://github.com/advisories/GHSA-WVPP-8HX9-P66J)
- GitPython: Incomplete unsafe_git_archive_options denylist omits --add-file / --add-virtual-file, enabling arbitrary file read via Repo.archive() (3.1.57) — [security advisory](https://github.com/advisories/GHSA-539M-9XH6-Q6RR)
- GitPython: Unguarded git option forwarding in IndexFile.checkout() and TagReference.create() enables arbitrary file overwrite and arbitrary file read (3.1.57) — [security advisory](https://github.com/advisories/GHSA-3F7W-8RR8-F37F)
- GitPython: Arbitrary file truncation via git rev-list --output argument injection in unguarded Commit.count (3.1.56) — [security advisory](https://github.com/advisories/GHSA-P538-C434-8V24)
- GitPython: Environment-variable exfiltration via Repo.create_remote() / Remote.add() URL (incomplete fix of GHSA-rwj8-pgh3-r573) (3.1.55) — [security advisory](https://github.com/advisories/GHSA-94P4-4CQ8-9G67)
- GitPython: Arbitrary file overwrite via git diff --output argument injection in Diffable.diff (key- and value-controlled) (3.1.54) — [security advisory](https://github.com/advisories/GHSA-FJR4-X663-MWXC)
- GitPython: Incomplete unsafe_git_clone_options denylist omits --template enabling arbitrary command execution via clone hooks (3.1.54) — [security advisory](https://github.com/advisories/GHSA-6P8H-3WGX-97GF)
- GitPython: Unsafe git option guard bypass via single-character kwarg value token smuggling enables arbitrary command execution (3.1.54) — [security advisory](https://github.com/advisories/GHSA-R9MR-M37C-5FR3)
- GitPython: git-config section-name injection enables arbitrary config directives (core.sshCommand RCE) (3.1.53) — [security advisory](https://github.com/advisories/GHSA-3RP5-JJMW-4WV2)
- GitPython: Environment-variable exfiltration via os.path.expandvars() on Repo.clone_from() URL (3.1.52) — [security advisory](https://github.com/advisories/GHSA-RWJ8-PGH3-R573)
- GitPython: Command Injection via git long-option prefix abbreviation bypass of CVE-2026-42215 blocklist (3.1.51) — [security advisory](https://github.com/advisories/GHSA-2F96-G7MH-G2HX)
- GitPython: command injection via unguarded Git options in `Repo.archive()`, `git.ls_remote()`, and arbitrary file overwrite via `Repo.iter_commits()` / `Repo.blame()` (3.1.51) — [security advisory](https://github.com/advisories/GHSA-956X-8GVW-WG5V)
- GitPython unsafe clone option gate bypass through joined short options (3.1.51) — [security advisory](https://github.com/advisories/GHSA-V396-V7Q4-X2QJ)
- GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath (3.1.50) — [security advisory](https://github.com/advisories/GHSA-MV93-W799-CJ2W)
- GitPython: Newline injection in config_writer().set_value() enables RCE via core.hooksPath (3.1.49) — [security advisory](https://github.com/advisories/GHSA-V87R-6Q3F-2J67)
- GitPython reference APIs has a path traversal vulnerability that allows arbitrary file write and delete outside the repository (3.1.48) — [security advisory](https://github.com/advisories/GHSA-7545-FCXQ-7J24)
- GitPython has Command Injection via Git options bypass (3.1.47) — [security advisory](https://github.com/advisories/GHSA-RPM5-65CW-6HJ4)
- GitPython: Unsafe option check validates multi_options before shlex.split transformation (3.1.47) — [security advisory](https://github.com/advisories/GHSA-X2QX-6953-8485)

### New APIs and options

- Submodule updates can be performed without fetching. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)

### Performance

- Accumulating gpgsig continuation lines now takes linear time. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)

### Behavior and default changes

- get_value reads Git's yes/no and on/off boolean values. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Worktrees created from bare repositories are kept non-bare. (3.1.62) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.1.62)

### Fixes and other changes

- Byte modes are decoded before their digits are read. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Accepts a single PathLike in checkout. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Identity fields that alter commit headers are rejected. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Exact large integer values are preserved. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Whitespace in filenames is preserved in stats. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Each stdin record contains one object name or path. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Names are resolved independently of list attributes. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Lock files are created in one exclusive step. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Stalled remote commands are stopped when their timeout expires. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Destinations are validated before mutation. (3.2.1) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.1)
- Actor and date parsing is bounded. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Object types are validated when loading binary SHAs. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Checkout positional reference options are validated. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- co_authors trailer parsing is bounded. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- High-level Git commands preserve positional operands. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Git config name matching is case-insensitive. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Implicit boolean config keys are preserved, and comments after them are rejected. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Inline config comments are stripped the way Git does. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Option-line parsing is bounded. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Literal separate Git directory paths are preserved. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Submodule move destinations through intermediate symlinks are rejected. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Timeout child-process lookup works on non-GNU systems. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- A UTF-8 BOM is skipped when reading config files. (3.2.0) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.2.0)
- Backslash line continuations are joined when reading config values. (3.1.62) — [release notes](https://github.com/gitpython-developers/GitPython/releases/tag/3.1.62)
