Support index diffs against the empty tree - #2155
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds IndexFile.diff(NULL_TREE) support so callers can diff the index against an “empty tree” (useful for initial index contents), and introduces a regression test to validate expected diff output.
Changes:
- Extends
IndexFile.diff()to accept and handleNULL_TREEas theotherdiff target. - Implements a custom
git diff --cached <empty-tree>invocation to produce raw/patch output for the NULL_TREE case. - Adds a test covering initial index diffing against
NULL_TREE, including path filtering and patch creation.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| test/test_index.py | Adds coverage for diffing an initial index against NULL_TREE and verifying raw + patch output. |
| git/index/base.py | Implements IndexFile.diff(NULL_TREE) by invoking git diff --cached against the empty-tree SHA. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Assisted-by: OpenAI GPT-5
4508774 to
3895682
Compare
Assisted-by: ChatGPT
|
AI agent on behalf of Puneet: pushed Verified:
|
Co-authored-by: OpenAI Codex <codex@openai.com>
Co-authored-by: OpenAI Codex <codex@openai.com>
Match the AutoInterrupt wait signature so diff parser tests can pass preserved stderr through finalize_process. Assisted-by: OpenAI GPT-5
|
It seems bots are running around and fixing to dos automatically. And in a way, it's fine. This seems to be addressing the TODO legitimately and the bots already hashed it out, so I'll just try rolling with it. The biggest problem GitPython has is that I don't think it has a human who knows what good Python is supposed to be like these days. So, agents will basically rule this place and all I can do is to apply high level quality constraints - better than nothing. |
This MR contains the following updates: | Package | Type | Update | Change | OpenSSF | |---|---|---|---|---| | [gitpython](https://github.com/gitpython-developers/GitPython) | dev | patch | `3.1.50` → `3.1.52` | [](https://securityscorecards.dev/viewer/?uri=github.com/gitpython-developers/GitPython) | --- ### Release Notes <details> <summary>gitpython-developers/GitPython (gitpython)</summary> ### [`v3.1.52`](https://github.com/gitpython-developers/GitPython/releases/tag/3.1.52): Security [Compare Source](gitpython-developers/GitPython@3.1.51...3.1.52) <GHSA-rwj8-pgh3-r573>: Environment-variable exfiltration via os.path.expandvars() on Repo.clone\_from() URL #### What's Changed - Skip cross-drive relative config test on Windows by [@​Byron](https://github.com/Byron) in [#​2171](gitpython-developers/GitPython#2171) - fix: preserve literal clone URLs by [@​Byron](https://github.com/Byron) in [#​2172](gitpython-developers/GitPython#2172) **Full Changelog**: <gitpython-developers/GitPython@3.1.51...3.1.52> ### [`v3.1.51`](https://github.com/gitpython-developers/GitPython/releases/tag/3.1.51): - Security [Compare Source](gitpython-developers/GitPython@3.1.50...3.1.51) #### What's Changed - Add AI-disclosure and quality requirements to the contribution guidelines by [@​Byron](https://github.com/Byron) in [#​2143](gitpython-developers/GitPython#2143) - docs(cmd): clarify Git.execute() string vs list command argument by [@​mvanhorn](https://github.com/mvanhorn) in [#​2144](gitpython-developers/GitPython#2144) - Rewrite Git.execute() command parameter docstring per [#​2146](gitpython-developers/GitPython#2146) by [@​EliahKagan](https://github.com/EliahKagan) in [#​2147](gitpython-developers/GitPython#2147) - Document init script behavior with multiple master remotes by [@​EliahKagan](https://github.com/EliahKagan) in [#​2148](gitpython-developers/GitPython#2148) - Bump git/ext/gitdb from `335c0f6` to `0a019a2` by [@​dependabot](https://github.com/dependabot)\[bot] in [#​2149](gitpython-developers/GitPython#2149) - Support relative worktree paths (git 2.48+ worktree.useRelativePaths) by [@​elovelan](https://github.com/elovelan) in [#​2151](gitpython-developers/GitPython#2151) - Defer xfail condition evaluation with xfail\_if\_raises context manager by [@​elovelan](https://github.com/elovelan) in [#​2153](gitpython-developers/GitPython#2153) - Run more submodule tests on Cygwin (fix flaky xfails) by [@​EliahKagan](https://github.com/EliahKagan) in [#​2154](gitpython-developers/GitPython#2154) - Cut xtrace noise from POSIX-ownership diagnostic steps by [@​EliahKagan](https://github.com/EliahKagan) in [#​2156](gitpython-developers/GitPython#2156) - Support index diffs against the empty tree by [@​puneetdixit200](https://github.com/puneetdixit200) in [#​2155](gitpython-developers/GitPython#2155) - refactor: seperate out Progress type by [@​LoeschMaximilian](https://github.com/LoeschMaximilian) in [#​2157](gitpython-developers/GitPython#2157) - Bump <https://github.com/astral-sh/ruff-pre-commit> from v0.15.12 to 0.15.15 in the pre-commit group by [@​dependabot](https://github.com/dependabot)\[bot] in [#​2160](gitpython-developers/GitPython#2160) - Bump actions/checkout from 6 to 7 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​2164](gitpython-developers/GitPython#2164) - Bump git/ext/gitdb from `0a019a2` to `4950ea9` by [@​dependabot](https://github.com/dependabot)\[bot] in [#​2165](gitpython-developers/GitPython#2165) - Bump <https://github.com/astral-sh/ruff-pre-commit> from v0.15.15 to 0.15.20 in the pre-commit group by [@​dependabot](https://github.com/dependabot)\[bot] in [#​2166](gitpython-developers/GitPython#2166) - Add Commit.is\_shallow property; document stats() limitation at shallow boundary by [@​harshitayadavv](https://github.com/harshitayadavv) in [#​2167](gitpython-developers/GitPython#2167) - Allow relative config paths with includes by [@​Byron](https://github.com/Byron) in [#​2169](gitpython-developers/GitPython#2169) - Reject abbreviated forms of unsafe git options by [@​Byron](https://github.com/Byron) in [#​2168](gitpython-developers/GitPython#2168) - guard unsafe git command options by [@​Byron](https://github.com/Byron) in [#​2163](gitpython-developers/GitPython#2163) #### New Contributors - [@​elovelan](https://github.com/elovelan) made their first contribution in [#​2151](gitpython-developers/GitPython#2151) - [@​puneetdixit200](https://github.com/puneetdixit200) made their first contribution in [#​2155](gitpython-developers/GitPython#2155) - [@​LoeschMaximilian](https://github.com/LoeschMaximilian) made their first contribution in [#​2157](gitpython-developers/GitPython#2157) - [@​harshitayadavv](https://github.com/harshitayadavv) made their first contribution in [#​2167](gitpython-developers/GitPython#2167) **Full Changelog**: <gitpython-developers/GitPython@3.1.50...3.1.51> </details> --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNzAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI3MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiLCJyZW5vdmF0ZSJdfQ==--> See merge request swiss-armed-forces/cyber-command/cea/loom!679 Co-authored-by: Loom MR Pipeline Trigger <group_103951964_bot_9504bb8dead6d4e406ad817a607f24be@noreply.gitlab.com>
Related to #2025.
IndexFile.diff()is documented as accepting the same targets asDiffable.diff(), includingNULL_TREE, but the index-specific implementation rejectedNULL_TREEbefore it could produce a diff. That leaves no direct API path for inspecting staged entries for an initial commit against the empty tree.This adds explicit
IndexFile.diff(NULL_TREE)handling usinggit diff --cachedagainst the empty tree object. I keptIndexFile.diff(None)as the existing index-vs-working-tree comparison, since that behavior is documented in the quick docs and existing tests.The regression test creates a new repository, stages a file, writes the index, constructs a fresh
IndexFile, and verifies thatindex.diff(NULL_TREE)reports the staged addition whileindex.diff(None)remains empty because the working tree matches the index.Validation:
.venv/bin/python -m pytest --no-cov test/test_index.py::TestIndex::test_index_file_diff_null_tree_with_initial_index -q.venv/bin/python -m ruff check git/index/base.py test/test_index.pyAI assistance disclosure: OpenAI GPT-5 helped draft and check this change; I reviewed the implementation and tests before submitting.