Repository navigation
Comparing changes
Open a pull request
base repository: gitpython-developers/GitPython
base: fix/iterable-list-index-protocol
head repository: gitpython-developers/GitPython
compare: main
- 18 commits
- 19 files changed
- 6 contributors
Commits on Oct 28, 2026
-
fix(tree): support slices and reverse iteration
Python 3 sends slices to `Tree.__getitem__`, but its legacy slice implementation only exists in `__getslice__`. `tree[:2]` therefore raises `TypeError`. `reversed(tree)` also raises because it applies `reversed` to a generator. Handle slices through the existing cache-to-object conversion and reverse cached entries before lazy conversion. Add return-type overloads, public API documentation and regressions for ordering, stride, negative/empty ranges, zero steps, independent results and nested paths. Validation: all eight new cases fail on the original CLI implementation. Afterward, the complete tree and typing modules pass 110 tests on each CLI/Gix backend with Python 3.12.14, Git 2.52.0 and GixPython 0.3.0 on Linux. Mypy (40 source files), basedpyright and applicable repository pre-commit hooks pass. Full suites and other platforms were not run. Assisted-by: OpenAI Codex (model: unknown, autonomous)
Configuration menu - View commit details
-
Copy full SHA for 19a61cd - Browse repository at this point
Copy the full SHA 19a61cdView commit details
Commits on Oct 29, 2026
-
fix: accept current-directory files in parent assurance
`assure_directory_exists("notes.txt", is_file=True)` attempted to create the empty dirname and raised `FileNotFoundError`, despite the current directory already being present. Interpret an empty parent as `os.curdir` for file inputs. Preserve the helper's return convention, nested parent creation and failures when a parent is an existing regular file. Use a native scripted filesystem fixture for string and pathlib inputs. Two current-directory cases fail before the fix, while six controls pass. All eight cases pass afterward; utility and typing modules pass on both backends (129 passed, 39 skipped each). Applicable pre-commit checks, including shellcheck, pass. Assisted-by: OpenAI Codex (model: unknown, autonomous)Configuration menu - View commit details
-
Copy full SHA for 1268b32 - Browse repository at this point
Copy the full SHA 1268b32View commit details -
Configuration menu - View commit details
-
Copy full SHA for afbbabf - Browse repository at this point
Copy the full SHA afbbabfView commit details -
Merge pull request #2325 from gitpython-developers/fix/current-direct…
…ory-file-parent fix/current directory file parent
Configuration menu - View commit details
-
Copy full SHA for e347d11 - Browse repository at this point
Copy the full SHA e347d11View commit details -
Merge pull request #2326 from gitpython-developers/fix/iterable-list-…
…index-protocol fix/iterable list index protocol
Configuration menu - View commit details
-
Copy full SHA for 604f181 - Browse repository at this point
Copy the full SHA 604f181View commit details -
Merge pull request #2320 from gavenren/fix/tree-sequence-access
fix(tree): support slices and reverse iteration
Configuration menu - View commit details
-
Copy full SHA for 44ad498 - Browse repository at this point
Copy the full SHA 44ad498View commit details -
fix: copy stream data through short reads
`stream_copy` stopped after any read shorter than `chunk_size`, truncating valid unbuffered streams. Continue until an empty chunk reports end of input, preserving the existing writer contract and byte count. Add binary/text short-read and empty-input regressions, plus a synchronized real POSIX pipe reproduction. The regressions fail before the fix; utility and typing modules pass with both CLI and Gix backends (126 passed, 39 skipped each). Applicable pre-commit checks pass. Assisted-by: OpenAI Codex (model: unknown, autonomous)
Configuration menu - View commit details
-
Copy full SHA for e313258 - Browse repository at this point
Copy the full SHA e313258View commit details -
Configuration menu - View commit details
-
Copy full SHA for eb613ec - Browse repository at this point
Copy the full SHA eb613ecView commit details -
Merge pull request #2327 from gitpython-developers/fix/stream-copy-sh…
…ort-reads fix/stream copy short reads
Configuration menu - View commit details
-
Copy full SHA for 38992bc - Browse repository at this point
Copy the full SHA 38992bcView commit details
Commits on Oct 30, 2026
-
test(util): cover
rmfiledeleting a read-only file`git.util.rmfile` exists so that a read-only file can be deleted on Windows, where `os.remove` fails on files with the read-only attribute. On Windows it calls `os.chmod` to clear that attribute before removing the file. Nothing tested this. Before this change, the only callers of `rmfile` were `LockFile._release_lock` and a lock-file helper in `test/test_repo.py`, and no test called either of them on a read-only file. Add `TestRmfile.test_deletes_readonly_file`, alongside the analogous `TestRmtree.test_deletes_dir_with_readonly_files`. Its initial state comes from a new fixture script, `tests/fixtures/rmfile.sh`. The script creates a file named `readonly` and removes its write permissions with `chmod a-w`, as `tests/fixtures/cleanup.sh` does for its read-only case. On Windows this should give the file the read-only attribute. The test uses a copy of the cached fixture output, which keeps the file's mode, so it needs no `execute=True`. The script is separate from `tests/fixtures/rmtree.sh`, whose cases are keyed by `TestRmtree` test names through the `tmp_path` fixture in `test/test_util.py`, and which that fixture runs in place for all but one of them. `rmfile` silently does nothing if the path is not a file, so the test would pass vacuously if the fixture made no file. It therefore first checks that the file exists and is not owner-writable, and only then that `rmfile` removes it. On Windows, `os.stat` reports the read-only attribute as the absence of write bits, so this also confirms that the fixture produced the condition the test is about, rather than assuming it. The test runs on every platform, but it is only meaningful on native Windows. Unlike the `rmtree` test, it is not skipped on Cygwin. That skip's reason, that Cygwin can't set the needed permissions, hasn't been checked for this test. On Cygwin `sys.platform` is `"cygwin"`, so `rmfile` uses no special handling there, and the test only checks that a read-only file can be removed, as on Unix. This adds coverage ahead of changing the mode `rmfile` passes to `os.chmod`: the test passes with the current `0o777`, and on Windows it would fail if the mode lacked the owner-write bit. Validation: on macOS with Python 3.12, the four `TestRmtree` and `TestRmfile` tests pass, the copied fixture file has mode `0o444`, and the precondition fails when the path does not exist. `shellcheck` passes on the new script. Neither Windows nor Cygwin was run locally. The `import-cygwin` workflow does not run the test suite, so Cygwin is not tested in CI either. Co-authored-by: Claude Opus 5.5 <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for d74c104 - Browse repository at this point
Copy the full SHA d74c104View commit details -
refactor(util): clear read-only in
rmfilewithstat.S_IWUSROn Windows, `git.util.rmfile` calls `os.chmod(path, 0o777)` before `os.remove` so that read-only files can be deleted. With the CodeQL `security-extended` suite now enabled for this repository, that call is reported as `py/overly-permissive-file` ("Overly permissive mask in chmod sets file to world writable"), at high severity. The finding is a false positive in effect. On Windows, `os.chmod` can only set or clear the read-only attribute, and the Python documentation says "All other bits are ignored". CPython's implementation confirms this. Despite its name, `Modules/posixmodule.c` is also the Windows implementation: `os` takes its functions from a built-in module that is `posix` on Unix and `nt` on Windows, and both are compiled from that file, with the Windows code under `MS_WINDOWS`. There, `chmod` tests only `mode & _S_IWRITE`, clearing `FILE_ATTRIBUTE_READONLY` when that bit is set and setting it otherwise. This is the same in 3.8, the oldest Python GitPython supports, as in `main`, including the newer handle-based path. `_S_IWRITE` is `0o200`, the same value as `stat.S_IWUSR` (and `stat.S_IWRITE`). The call is only reached when `sys.platform == "win32"`, so every bit in `0o777` except `0o200` was always ignored. Pass `stat.S_IWUSR` instead. On Windows this behaves identically: it clears the read-only attribute and does nothing else. It states the intent exactly, and it matches the `os.chmod(path, stat.S_IWUSR)` already used for the same purpose by the `rmtree` error handler a few lines above, which CodeQL does not flag. Behavior is unchanged on all platforms, so no test can fail before this change and pass after it. `TestRmfile.test_deletes_readonly_file` covers the behavior being preserved, and on Windows would fail if the mode lacked the owner-write bit. Validation: on macOS with Python 3.12, the `TestRmtree` and `TestRmfile` tests pass both before and after this change, and `ruff check` and `ruff format --check` pass. Windows, where the changed line actually runs, was not run locally and is left to CI. Co-authored-by: Claude Opus 5.5 <[email protected]>Configuration menu - View commit details
-
Copy full SHA for 53f3c62 - Browse repository at this point
Copy the full SHA 53f3c62View commit details -
Merge pull request #2328 from EliahKagan/claude/rmfile-chmod-owner-write
refactor(util): clear read-only in `rmfile` with `stat.S_IWUSR`
Configuration menu - View commit details
-
Copy full SHA for 50d88aa - Browse repository at this point
Copy the full SHA 50d88aaView commit details -
fix(index): remove entries, blobs and submodules by literal path
`IndexFile.remove()` passed every item to `git rm` as a pathspec. Path strings are documented to accept globs, but index entries, blobs and submodules name one exact path, and Git still expanded glob characters and pathspec magic in those names. The names are chosen by whoever authored the repository: - Removing the entry for a file named `*.txt` also removed `a.txt` and `b.txt`. - Removing the entry for `:(glob)**` removed every tracked path, and with `working_tree=True` deleted those files from disk. `Submodule.remove()` (for a submodule that is not checked out, or with `module=False`) and `Submodule.move(module=False)` passed the `.gitmodules` path string to the same call with `force=True`. A superproject declaring a submodule at path `*` therefore had every tracked file staged for deletion and the index written. The neighboring `git rm` and `git mv` calls in `Submodule` already run with `GIT_LITERAL_PATHSPECS=1`. Prefix the paths of entry, blob and submodule items with Git's `:(literal)` pathspec magic and leave path strings unchanged, so a mixed call keeps the documented glob behavior for its strings. The submodule callers now pass their index entry. `git mv` reads its sources literally, so `IndexFile.move()` needs no change. `git rm` has no native Gix handler and runs through the CLI on both backends, so `doc/gix-backend.md` is unchanged. Limitation: when a caller exports `GIT_LITERAL_PATHSPECS=1`, Git does not parse pathspec magic. Removing an entry, blob or submodule then fails with "did not match any files" and removes nothing; path strings stay literal in that environment as before. Add a `remove-literal` scenario to `tests/fixtures/index.sh`, a `glob-path` scenario to `tests/fixtures/submodule-special.sh`, and regression tests in `test/test_index.py` and `test/test_submodule.py`. The three new test cases fail before the change and pass after it with both `GIT_PYTHON_BACKEND=cli` and `GIT_PYTHON_BACKEND=gix` (Git 2.52.0, GixPython 0.3.0, Python 3.11.17, macOS). Full suites with the change: CLI 1,884 passed and Gix 1,987 passed. Each run also had 108 failures, and the same 108 tests fail on the unpatched tree. They need history and tags such as `0.1.6` and `0.3.2.1`, which the shallow local clone lacks. `ruff check`, `ruff format --check`, `mypy --python-version=3.11`, `basedpyright --warnings`, ShellCheck and `git diff --check` pass.
Configuration menu - View commit details
-
Copy full SHA for ef120d7 - Browse repository at this point
Copy the full SHA ef120d7View commit details
Commits on Oct 31, 2026
-
Merge pull request #2329 from Keerthana-64/index-remove-literal-paths
**fix(index): entries, blobs aur submodules ko literal path se remove karo**
Configuration menu - View commit details
-
Copy full SHA for ad0420e - Browse repository at this point
Copy the full SHA ad0420eView commit details
Commits on Nov 1, 2026
-
build(deps): bump the github-actions group with 3 updates
Bumps the github-actions group with 3 updates: [cygwin/cygwin-install-action](https://github.com/cygwin/cygwin-install-action), [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) and [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action). Updates `cygwin/cygwin-install-action` from 6.1 to 7 - [Release notes](https://github.com/cygwin/cygwin-install-action/releases) - [Commits](cygwin/cygwin-install-action@3f0a3f9...5a1b0cd) Updates `astral-sh/setup-uv` from 10.3.0 to 10.3.2 - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](astral-sh/setup-uv@1c37ad0...07a047e) Updates `zizmorcore/zizmor-action` from 0.7.1 to 0.8.0 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](zizmorcore/zizmor-action@85b2b9f...53290ba) --- updated-dependencies: - dependency-name: cygwin/cygwin-install-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: astral-sh/setup-uv dependency-version: 10.3.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: zizmorcore/zizmor-action dependency-version: 0.8.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 4a47f1f - Browse repository at this point
Copy the full SHA 4a47f1fView commit details -
build(deps): bump the pre-commit group with 2 updates
Bumps the pre-commit group with 2 updates: [https://github.com/astral-sh/ruff-pre-commit](https://github.com/astral-sh/ruff-pre-commit) and [https://github.com/abravalheri/validate-pyproject](https://github.com/abravalheri/validate-pyproject). Updates `https://github.com/astral-sh/ruff-pre-commit` from v0.17.1 to 0.17.2 - [Release notes](https://github.com/astral-sh/ruff-pre-commit/releases) - [Commits](astral-sh/ruff-pre-commit@v0.17.1...v0.17.2) Updates `https://github.com/abravalheri/validate-pyproject` from v0.25 to 0.27 - [Release notes](https://github.com/abravalheri/validate-pyproject/releases) - [Changelog](https://github.com/abravalheri/validate-pyproject/blob/main/CHANGELOG.rst) - [Commits](abravalheri/validate-pyproject@v0.25...v0.27) --- updated-dependencies: - dependency-name: https://github.com/astral-sh/ruff-pre-commit dependency-version: 0.17.2 dependency-type: direct:production dependency-group: pre-commit - dependency-name: https://github.com/abravalheri/validate-pyproject dependency-version: '0.27' dependency-type: direct:production dependency-group: pre-commit ... Signed-off-by: dependabot[bot] <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 6b3ac86 - Browse repository at this point
Copy the full SHA 6b3ac86View commit details -
Merge pull request #2333 from gitpython-developers/dependabot/github_…
…actions/github-actions-902eaec5db build(deps): bump the github-actions group with 3 updates
Configuration menu - View commit details
-
Copy full SHA for a4ddab2 - Browse repository at this point
Copy the full SHA a4ddab2View commit details -
Merge pull request #2334 from gitpython-developers/dependabot/pre_com…
…mit/pre-commit-eeac14499b build(deps): bump the pre-commit group with 2 updates
Configuration menu - View commit details
-
Copy full SHA for 7d5dcd2 - Browse repository at this point
Copy the full SHA 7d5dcd2View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff fix/iterable-list-index-protocol...main