pypi / gitpython
gitpython
What changed in gitpython 3, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.
1 breaking36 security1 new APIs and options1 performance2 behavior and defaults24 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initgitpython 365 changes
Breaking changes 1
Python 3.7 is no longer supported.
Security 36
Symbolic links that alias .gitmodules are rejected.
URL credentials are redacted without corrupting the host.
Safety checks in Git command wrappers are completed.
GitPython submodule update path traversal can write outside the repository
Unsafe submodule checkout paths are rejected.
GitPython: Denial of Service via catastrophic backtracking (ReDoS) in Actor.name_email_regex — commit author/committer field parsing
GitPython: --no-index bypasses diff unsafe-option protections and enables a blind local-file content oracle
GitPython: Repository content can impersonate the git directory, leading to arbitrary code execution
GitPython: Arbitrary local file content disclosure via [include] directive in untrusted .gitmodules (SubmoduleConfigParser never disables merge_includes)
GitPython: clone_from()/clone() omit --separate-git-dir from unsafe_git_clone_options, enabling arbitrary git-directory creation outside the destination
GitPython: Dormant multi-line git-config values are corrupted into live injected directives (e.g. core.hooksPath) on any unrelated GitConfigParser write, enabling RCE
GitPython: Incomplete unsafe_git_revision_options denylist omits --contents/-S, enabling arbitrary file read via Repo.blame()
GitPython: TagReference.create positional reference bypasses kwargs-only --file guard, enabling arbitrary file read (incomplete fix of 3af0c251)
GitPython: Arbitrary file read via --pathspec-from-file in IndexFile.remove() and Head.checkout()
GitPython: Arbitrary Git Repository Creation Outside the Working Tree via Unvalidated .gitmodules Submodule Name in GitPython
GitPython: git-config OPTION-name injection via =/#/whitespace bypasses name validator, enabling forged core.sshCommand/hooksPath (RCE)
GitPython: Unguarded git option forwarding in Repo.init enables arbitrary command execution via --template clone hooks
GitPython: Unguarded git read-tree option forwarding in IndexFile.from_tree/reset/merge_tree enables arbitrary file overwrite
GitPython: Unsafe git option guard bypass via split_single_char_options=False short-option token smuggling enables command execution
GitPython: Incomplete unsafe_git_archive_options denylist omits --add-file / --add-virtual-file, enabling arbitrary file read via Repo.archive()
GitPython: Unguarded git option forwarding in IndexFile.checkout() and TagReference.create() enables arbitrary file overwrite and arbitrary file read
GitPython: Arbitrary file truncation via git rev-list --output argument injection in unguarded Commit.count
GitPython: Environment-variable exfiltration via Repo.create_remote() / Remote.add() URL (incomplete fix of GHSA-rwj8-pgh3-r573)
GitPython: Arbitrary file overwrite via git diff --output argument injection in Diffable.diff (key- and value-controlled)
GitPython: Incomplete unsafe_git_clone_options denylist omits --template enabling arbitrary command execution via clone hooks
GitPython: Unsafe git option guard bypass via single-character kwarg value token smuggling enables arbitrary command execution
GitPython: git-config section-name injection enables arbitrary config directives (core.sshCommand RCE)
GitPython: Environment-variable exfiltration via os.path.expandvars() on Repo.clone_from() URL
GitPython: Command Injection via git long-option prefix abbreviation bypass of CVE-2026-42215 blocklist
GitPython: command injection via unguarded Git options in
Repo.archive(),git.ls_remote(), and arbitrary file overwrite viaRepo.iter_commits()/Repo.blame()GitPython unsafe clone option gate bypass through joined short options
GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath
GitPython: Newline injection in config_writer().set_value() enables RCE via core.hooksPath
GitPython reference APIs has a path traversal vulnerability that allows arbitrary file write and delete outside the repository
GitPython has Command Injection via Git options bypass
GitPython: Unsafe option check validates multi_options before shlex.split transformation
New APIs and options 1
Submodule updates can be performed without fetching.
Performance 1
Accumulating gpgsig continuation lines now takes linear time.
Behavior and default changes 2
get_value reads Git's yes/no and on/off boolean values.
Worktrees created from bare repositories are kept non-bare.
Fixes and other changes 24
Byte modes are decoded before their digits are read.
Accepts a single PathLike in checkout.
Identity fields that alter commit headers are rejected.
Exact large integer values are preserved.
Whitespace in filenames is preserved in stats.
Each stdin record contains one object name or path.
Names are resolved independently of list attributes.
Lock files are created in one exclusive step.
Stalled remote commands are stopped when their timeout expires.
Destinations are validated before mutation.
Actor and date parsing is bounded.
Object types are validated when loading binary SHAs.
Checkout positional reference options are validated.
co_authors trailer parsing is bounded.
High-level Git commands preserve positional operands.
Git config name matching is case-insensitive.
Implicit boolean config keys are preserved, and comments after them are rejected.
Inline config comments are stripped the way Git does.
Option-line parsing is bounded.
Literal separate Git directory paths are preserved.
Submodule move destinations through intermediate symlinks are rejected.
Timeout child-process lookup works on non-GNU systems.
A UTF-8 BOM is skipped when reading config files.
Backslash line continuations are joined when reading config values.