Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: gitpython-developers/GitPython
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: fix/iterable-list-index-protocol
Choose a base ref
...
head repository: gitpython-developers/GitPython
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 18 commits
  • 19 files changed
  • 6 contributors

Commits on Oct 28, 2026

  1. 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)
    gavenren committed Oct 28, 2026
    Configuration menu
    Copy the full SHA
    19a61cd View commit details
    Browse the repository at this point in the history

Commits on Oct 29, 2026

  1. 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)
    gavenren authored and Byron committed Oct 29, 2026
    Configuration menu
    Copy the full SHA
    1268b32 View commit details
    Browse the repository at this point in the history
  2. review

    Byron committed Oct 29, 2026
    Configuration menu
    Copy the full SHA
    afbbabf View commit details
    Browse the repository at this point in the history
  3. Merge pull request #2325 from gitpython-developers/fix/current-direct…

    …ory-file-parent
    
    fix/current directory file parent
    Byron authored Oct 29, 2026
    Configuration menu
    Copy the full SHA
    e347d11 View commit details
    Browse the repository at this point in the history
  4. Merge pull request #2326 from gitpython-developers/fix/iterable-list-…

    …index-protocol
    
    fix/iterable list index protocol
    Byron authored Oct 29, 2026
    Configuration menu
    Copy the full SHA
    604f181 View commit details
    Browse the repository at this point in the history
  5. Merge pull request #2320 from gavenren/fix/tree-sequence-access

    fix(tree): support slices and reverse iteration
    Byron authored Oct 29, 2026
    Configuration menu
    Copy the full SHA
    44ad498 View commit details
    Browse the repository at this point in the history
  6. 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)
    gavenren authored and Byron committed Oct 29, 2026
    Configuration menu
    Copy the full SHA
    e313258 View commit details
    Browse the repository at this point in the history
  7. review

    - simplify test (remove threads)
    Byron committed Oct 29, 2026
    Configuration menu
    Copy the full SHA
    eb613ec View commit details
    Browse the repository at this point in the history
  8. Merge pull request #2327 from gitpython-developers/fix/stream-copy-sh…

    …ort-reads
    
    fix/stream copy short reads
    Byron authored Oct 29, 2026
    Configuration menu
    Copy the full SHA
    38992bc View commit details
    Browse the repository at this point in the history

Commits on Oct 30, 2026

  1. test(util): cover rmfile deleting 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]>
    EliahKagan and claude committed Oct 30, 2026
    Configuration menu
    Copy the full SHA
    d74c104 View commit details
    Browse the repository at this point in the history
  2. refactor(util): clear read-only in rmfile with stat.S_IWUSR

    On 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]>
    EliahKagan and claude committed Oct 30, 2026
    Configuration menu
    Copy the full SHA
    53f3c62 View commit details
    Browse the repository at this point in the history
  3. Merge pull request #2328 from EliahKagan/claude/rmfile-chmod-owner-write

    refactor(util): clear read-only in `rmfile` with `stat.S_IWUSR`
    EliahKagan authored Oct 30, 2026
    Configuration menu
    Copy the full SHA
    50d88aa View commit details
    Browse the repository at this point in the history
  4. 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.
    Keerthana-64 committed Oct 30, 2026
    Configuration menu
    Copy the full SHA
    ef120d7 View commit details
    Browse the repository at this point in the history

Commits on Oct 31, 2026

  1. Merge pull request #2329 from Keerthana-64/index-remove-literal-paths

    **fix(index): entries, blobs aur submodules ko literal path se remove karo**
    Byron authored Oct 31, 2026
    Configuration menu
    Copy the full SHA
    ad0420e View commit details
    Browse the repository at this point in the history

Commits on Nov 1, 2026

  1. 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]>
    dependabot[bot] authored Nov 1, 2026
    Configuration menu
    Copy the full SHA
    4a47f1f View commit details
    Browse the repository at this point in the history
  2. 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]>
    dependabot[bot] authored Nov 1, 2026
    Configuration menu
    Copy the full SHA
    6b3ac86 View commit details
    Browse the repository at this point in the history
  3. Merge pull request #2333 from gitpython-developers/dependabot/github_…

    …actions/github-actions-902eaec5db
    
    build(deps): bump the github-actions group with 3 updates
    Byron authored Nov 1, 2026
    Configuration menu
    Copy the full SHA
    a4ddab2 View commit details
    Browse the repository at this point in the history
  4. Merge pull request #2334 from gitpython-developers/dependabot/pre_com…

    …mit/pre-commit-eeac14499b
    
    build(deps): bump the pre-commit group with 2 updates
    Byron authored Nov 1, 2026
    Configuration menu
    Copy the full SHA
    7d5dcd2 View commit details
    Browse the repository at this point in the history
Loading