From de6d177aaa8ccd6d82576ab0b3de5074cf7647fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 18:05:41 +0000 Subject: [PATCH 01/13] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/alpine-test.yml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/cygwin-test.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/pythonpackage.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/alpine-test.yml b/.github/workflows/alpine-test.yml index ceba11fb8..a9c29117e 100644 --- a/.github/workflows/alpine-test.yml +++ b/.github/workflows/alpine-test.yml @@ -26,7 +26,7 @@ jobs: adduser runner docker shell: sh -exo pipefail {0} # Run this as root, not the "runner" user. - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 2bee952af..9191471c3 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -47,7 +47,7 @@ jobs: # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 # Add any setup steps before running the `github/codeql-action/init` action. # This includes steps like installing compilers or runtimes (`actions/setup-node` diff --git a/.github/workflows/cygwin-test.yml b/.github/workflows/cygwin-test.yml index cc9e1edf0..5c42c8583 100644 --- a/.github/workflows/cygwin-test.yml +++ b/.github/workflows/cygwin-test.yml @@ -34,7 +34,7 @@ jobs: git config --global core.autocrlf false # Affects the non-Cygwin git. shell: pwsh # Do this outside Cygwin, to affect actions/checkout. - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ceba0dd85..16978f9a8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: actions/setup-python@v5 with: diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 4457a341f..4e5d82a55 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -39,7 +39,7 @@ jobs: shell: bash --noprofile --norc -exo pipefail {0} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 From fe81519436a8ab8b735a40a3973c8c5bd9cfec47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 20:42:38 +0000 Subject: [PATCH 02/13] Bump git/ext/gitdb from `335c0f6` to `39d7dbf` Bumps [git/ext/gitdb](https://github.com/gitpython-developers/gitdb) from `335c0f6` to `39d7dbf`. - [Release notes](https://github.com/gitpython-developers/gitdb/releases) - [Commits](https://github.com/gitpython-developers/gitdb/compare/335c0f66173eecdc7b2597c2b6c3d1fde795df30...39d7dbf285df058e44ea501c23ea8d31ae8bce0e) --- updated-dependencies: - dependency-name: git/ext/gitdb dependency-version: 39d7dbf285df058e44ea501c23ea8d31ae8bce0e dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- git/ext/gitdb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/ext/gitdb b/git/ext/gitdb index 335c0f661..39d7dbf28 160000 --- a/git/ext/gitdb +++ b/git/ext/gitdb @@ -1 +1 @@ -Subproject commit 335c0f66173eecdc7b2597c2b6c3d1fde795df30 +Subproject commit 39d7dbf285df058e44ea501c23ea8d31ae8bce0e From ca51dad69071898af377c8e62210c69e8d211c69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Sep 2025 14:41:33 +0000 Subject: [PATCH 03/13] Bump actions/setup-python from 5 to 6 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/lint.yml | 2 +- .github/workflows/pythonpackage.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 16978f9a8..ed535a914 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v5 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: "3.x" diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 4e5d82a55..7088310e5 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -44,7 +44,7 @@ jobs: fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} allow-prereleases: ${{ matrix.experimental }} From 9f913ec0cb0c6f7ab3eea7245657d01048fd7065 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Sep 2025 15:00:47 +0000 Subject: [PATCH 04/13] Bump git/ext/gitdb from `39d7dbf` to `f8fdfec` Bumps [git/ext/gitdb](https://github.com/gitpython-developers/gitdb) from `39d7dbf` to `f8fdfec`. - [Release notes](https://github.com/gitpython-developers/gitdb/releases) - [Commits](https://github.com/gitpython-developers/gitdb/compare/39d7dbf285df058e44ea501c23ea8d31ae8bce0e...f8fdfec0fd0a0aed9171c6cf2c5cb8d73e2bb305) --- updated-dependencies: - dependency-name: git/ext/gitdb dependency-version: f8fdfec0fd0a0aed9171c6cf2c5cb8d73e2bb305 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- git/ext/gitdb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/ext/gitdb b/git/ext/gitdb index 39d7dbf28..f8fdfec0f 160000 --- a/git/ext/gitdb +++ b/git/ext/gitdb @@ -1 +1 @@ -Subproject commit 39d7dbf285df058e44ea501c23ea8d31ae8bce0e +Subproject commit f8fdfec0fd0a0aed9171c6cf2c5cb8d73e2bb305 From 7c55a2b839e05f10a9dc3cf2bc53785350372c88 Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Tue, 30 Sep 2025 17:47:14 +0300 Subject: [PATCH 05/13] Fix type hint for `SymbolicReference.reference` property Signed-off-by: Emmanuel Ferdman --- git/refs/symbolic.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 1b90a3115..74bb1fe0a 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -40,6 +40,7 @@ from git.config import GitConfigParser from git.objects.commit import Actor from git.refs.log import RefLogEntry + from git.refs.reference import Reference from git.repo import Repo @@ -404,7 +405,7 @@ def object(self) -> AnyGitObject: def object(self, object: Union[AnyGitObject, "SymbolicReference", str]) -> "SymbolicReference": return self.set_object(object) - def _get_reference(self) -> "SymbolicReference": + def _get_reference(self) -> "Reference": """ :return: :class:`~git.refs.reference.Reference` object we point to @@ -416,7 +417,7 @@ def _get_reference(self) -> "SymbolicReference": sha, target_ref_path = self._get_ref_info(self.repo, self.path) if target_ref_path is None: raise TypeError("%s is a detached symbolic reference as it points to %r" % (self, sha)) - return self.from_path(self.repo, target_ref_path) + return cast("Reference", self.from_path(self.repo, target_ref_path)) def set_reference( self, @@ -502,7 +503,7 @@ def set_reference( # Aliased reference @property - def reference(self) -> "SymbolicReference": + def reference(self) -> "Reference": return self._get_reference() @reference.setter From bcdcccdc7ea7d50ec5831aad961ba80df0f1379b Mon Sep 17 00:00:00 2001 From: Brunno Vanelli Date: Tue, 7 Oct 2025 20:49:46 +0200 Subject: [PATCH 06/13] feat: Add support for hasconfig git rule. --- git/config.py | 8 ++++++-- test/test_config.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/git/config.py b/git/config.py index 345290a39..ffe1c8ccd 100644 --- a/git/config.py +++ b/git/config.py @@ -66,7 +66,7 @@ CONFIG_LEVELS: ConfigLevels_Tup = ("system", "user", "global", "repository") """The configuration level of a configuration file.""" -CONDITIONAL_INCLUDE_REGEXP = re.compile(r"(?<=includeIf )\"(gitdir|gitdir/i|onbranch):(.+)\"") +CONDITIONAL_INCLUDE_REGEXP = re.compile(r"(?<=includeIf )\"(gitdir|gitdir/i|onbranch|hasconfig:remote\.\*\.url):(.+)\"") """Section pattern to detect conditional includes. See: https://git-scm.com/docs/git-config#_conditional_includes @@ -590,7 +590,11 @@ def _included_paths(self) -> List[Tuple[str, str]]: if fnmatch.fnmatchcase(branch_name, value): paths += self.items(section) - + elif keyword == "hasconfig:remote.*.url": + for remote in self._repo.remotes: + if fnmatch.fnmatch(remote.url, value): + paths += self.items(section) + break return paths def read(self) -> None: # type: ignore[override] diff --git a/test/test_config.py b/test/test_config.py index 8e1007d9e..56ac0f304 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -373,6 +373,41 @@ def test_conditional_includes_from_branch_name_error(self, rw_dir): assert not config._has_includes() assert config._included_paths() == [] + @with_rw_directory + def test_conditional_includes_remote_url(self, rw_dir): + # Initiate mocked repository. + repo = mock.Mock() + repo.remotes = [mock.Mock(url="https://github.com/foo/repo")] + + # Initiate config files. + path1 = osp.join(rw_dir, "config1") + path2 = osp.join(rw_dir, "config2") + template = '[includeIf "hasconfig:remote.*.url:{}"]\n path={}\n' + + # Ensure that config with hasconfig and full url is correct. + with open(path1, "w") as stream: + stream.write(template.format("https://github.com/foo/repo", path2)) + + with GitConfigParser(path1, repo=repo) as config: + assert config._has_includes() + assert config._included_paths() == [("path", path2)] + + # Ensure that config with hasconfig and incorrect url is incorrect. + with open(path1, "w") as stream: + stream.write(template.format("incorrect", path2)) + + with GitConfigParser(path1, repo=repo) as config: + assert not config._has_includes() + assert config._included_paths() == [] + + # Ensure that config with hasconfig and url using glob pattern is correct. + with open(path1, "w") as stream: + stream.write(template.format("**/**github.com*/**", path2)) + + with GitConfigParser(path1, repo=repo) as config: + assert config._has_includes() + assert config._included_paths() == [("path", path2)] + def test_rename(self): file_obj = self._to_memcache(fixture_path("git_config")) with GitConfigParser(file_obj, read_only=False, merge_includes=False) as cw: From 6cf863374820a1bcf1fa14b3c2ea87214752bf74 Mon Sep 17 00:00:00 2001 From: Brunno Vanelli Date: Tue, 7 Oct 2025 21:19:31 +0200 Subject: [PATCH 07/13] fix: Use fnmatch instead. --- git/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/config.py b/git/config.py index ffe1c8ccd..200c81bb7 100644 --- a/git/config.py +++ b/git/config.py @@ -592,7 +592,7 @@ def _included_paths(self) -> List[Tuple[str, str]]: paths += self.items(section) elif keyword == "hasconfig:remote.*.url": for remote in self._repo.remotes: - if fnmatch.fnmatch(remote.url, value): + if fnmatch.fnmatchcase(remote.url, value): paths += self.items(section) break return paths From a6247a585600c09894a9fae85e11f7581bfccbe0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 13:32:58 +0000 Subject: [PATCH 08/13] Bump github/codeql-action from 3 to 4 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v3...v4) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9191471c3..32d5e84e4 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -57,7 +57,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -85,6 +85,6 @@ jobs: exit 1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 with: category: "/language:${{matrix.language}}" From 9dd0081213d57f41919ed37e93656410277bfb0b Mon Sep 17 00:00:00 2001 From: Andreas Oberritter Date: Tue, 21 Oct 2025 11:11:16 +0200 Subject: [PATCH 09/13] Use actual return type in annotation for method submodule_update Fixes #2077 --- git/repo/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/repo/base.py b/git/repo/base.py index 7e918df8c..6ea96aad2 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -520,7 +520,7 @@ def iter_submodules(self, *args: Any, **kwargs: Any) -> Iterator[Submodule]: """ return RootModule(self).traverse(*args, **kwargs) - def submodule_update(self, *args: Any, **kwargs: Any) -> Iterator[Submodule]: + def submodule_update(self, *args: Any, **kwargs: Any) -> RootModule: """Update the submodules, keeping the repository consistent as it will take the previous state into consideration. From 74ff8e5e1cb814fbf3b916111d7181bd6e3f3906 Mon Sep 17 00:00:00 2001 From: Yikai Zhao Date: Sun, 2 Nov 2025 10:25:33 +0800 Subject: [PATCH 10/13] Support index format v3 --- git/index/fun.py | 16 +++++++++++----- git/index/typ.py | 15 ++++++++++++++- test/test_index.py | 25 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/git/index/fun.py b/git/index/fun.py index d03ec6759..0b3d79cf1 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -36,7 +36,7 @@ ) from git.util import IndexFileSHA1Writer, finalize_process -from .typ import BaseIndexEntry, IndexEntry, CE_NAMEMASK, CE_STAGESHIFT +from .typ import CE_EXTENDED, BaseIndexEntry, IndexEntry, CE_NAMEMASK, CE_STAGESHIFT from .util import pack, unpack # typing ----------------------------------------------------------------------------- @@ -158,7 +158,7 @@ def write_cache( write = stream_sha.write # Header - version = 2 + version = 3 if any(entry.extended_flags for entry in entries) else 2 write(b"DIRC") write(pack(">LL", version, len(entries))) @@ -172,6 +172,8 @@ def write_cache( plen = len(path) & CE_NAMEMASK # Path length assert plen == len(path), "Path %s too long to fit into index" % entry.path flags = plen | (entry.flags & CE_NAMEMASK_INV) # Clear possible previous values. + if entry.extended_flags: + flags |= CE_EXTENDED write( pack( ">LLLLLL20sH", @@ -185,6 +187,8 @@ def write_cache( flags, ) ) + if entry.extended_flags: + write(pack(">H", entry.extended_flags)) write(path) real_size = (tell() - beginoffset + 8) & ~7 write(b"\0" * ((beginoffset + real_size) - tell())) @@ -206,8 +210,7 @@ def read_header(stream: IO[bytes]) -> Tuple[int, int]: unpacked = cast(Tuple[int, int], unpack(">LL", stream.read(4 * 2))) version, num_entries = unpacked - # TODO: Handle version 3: extended data, see read-cache.c. - assert version in (1, 2), "Unsupported git index version %i, only 1 and 2 are supported" % version + assert version in (1, 2, 3), "Unsupported git index version %i, only 1, 2, and 3 are supported" % version return version, num_entries @@ -260,12 +263,15 @@ def read_cache( ctime = unpack(">8s", read(8))[0] mtime = unpack(">8s", read(8))[0] (dev, ino, mode, uid, gid, size, sha, flags) = unpack(">LLLLLL20sH", read(20 + 4 * 6 + 2)) + extended_flags = 0 + if flags & CE_EXTENDED: + extended_flags = unpack(">H", read(2))[0] path_size = flags & CE_NAMEMASK path = read(path_size).decode(defenc) real_size = (tell() - beginoffset + 8) & ~7 read((beginoffset + real_size) - tell()) - entry = IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size)) + entry = IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size, extended_flags)) # entry_key would be the method to use, but we save the effort. entries[(path, entry.stage)] = entry count += 1 diff --git a/git/index/typ.py b/git/index/typ.py index 974252528..4bcb604ab 100644 --- a/git/index/typ.py +++ b/git/index/typ.py @@ -32,6 +32,9 @@ CE_VALID = 0x8000 CE_STAGESHIFT = 12 +CE_EXT_SKIP_WORKTREE = 0x4000 +CE_EXT_INTENT_TO_ADD = 0x2000 + # } END invariants @@ -87,6 +90,8 @@ class BaseIndexEntryHelper(NamedTuple): uid: int = 0 gid: int = 0 size: int = 0 + # version 3 extended flags, only when (flags & CE_EXTENDED) is set + extended_flags: int = 0 class BaseIndexEntry(BaseIndexEntryHelper): @@ -102,7 +107,7 @@ def __new__( cls, inp_tuple: Union[ Tuple[int, bytes, int, PathLike], - Tuple[int, bytes, int, PathLike, bytes, bytes, int, int, int, int, int], + Tuple[int, bytes, int, PathLike, bytes, bytes, int, int, int, int, int, int], ], ) -> "BaseIndexEntry": """Override ``__new__`` to allow construction from a tuple for backwards @@ -134,6 +139,14 @@ def stage(self) -> int: """ return (self.flags & CE_STAGEMASK) >> CE_STAGESHIFT + @property + def skip_worktree(self) -> bool: + return (self.extended_flags & CE_EXT_SKIP_WORKTREE) > 0 + + @property + def intent_to_add(self) -> bool: + return (self.extended_flags & CE_EXT_INTENT_TO_ADD) > 0 + @classmethod def from_blob(cls, blob: Blob, stage: int = 0) -> "BaseIndexEntry": """:return: Fully equipped BaseIndexEntry at the given stage""" diff --git a/test/test_index.py b/test/test_index.py index cf3b90fa6..6d90d7965 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -1218,6 +1218,31 @@ def test_index_add_non_normalized_path(self, rw_repo): rw_repo.index.add(non_normalized_path) + @with_rw_directory + def test_index_version_v3(self, tmp_dir): + tmp_dir = Path(tmp_dir) + with cwd(tmp_dir): + subprocess.run(["git", "init", "-q"], check=True) + file = tmp_dir / "file.txt" + file.write_text("hello") + subprocess.run(["git", "add", "-N", "file.txt"], check=True) + + repo = Repo(tmp_dir) + + assert len(repo.index.entries) == 1 + entry = list(repo.index.entries.values())[0] + assert entry.path == "file.txt" + assert entry.intent_to_add + + file2 = tmp_dir / "file2.txt" + file2.write_text("world") + repo.index.add(["file2.txt"]) + repo.index.write() + + status_str = subprocess.check_output(["git", "status", "--porcelain"], text=True) + assert " A file.txt\n" in status_str + assert "A file2.txt\n" in status_str + class TestIndexUtils: @pytest.mark.parametrize("file_path_type", [str, Path]) From 3150ebdaa43df5be2c27e717807381724131b128 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 13:08:06 +0000 Subject: [PATCH 11/13] Bump git/ext/gitdb from `f8fdfec` to `65321a2` Bumps [git/ext/gitdb](https://github.com/gitpython-developers/gitdb) from `f8fdfec` to `65321a2`. - [Release notes](https://github.com/gitpython-developers/gitdb/releases) - [Commits](https://github.com/gitpython-developers/gitdb/compare/f8fdfec0fd0a0aed9171c6cf2c5cb8d73e2bb305...65321a28b586df60b9d1508228e2f53a35f938eb) --- updated-dependencies: - dependency-name: git/ext/gitdb dependency-version: 65321a28b586df60b9d1508228e2f53a35f938eb dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- git/ext/gitdb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/ext/gitdb b/git/ext/gitdb index f8fdfec0f..65321a28b 160000 --- a/git/ext/gitdb +++ b/git/ext/gitdb @@ -1 +1 @@ -Subproject commit f8fdfec0fd0a0aed9171c6cf2c5cb8d73e2bb305 +Subproject commit 65321a28b586df60b9d1508228e2f53a35f938eb From 8a884fea3ff91f1444a36785cc22c8d7fc6bf329 Mon Sep 17 00:00:00 2001 From: Yikai Zhao Date: Sat, 8 Nov 2025 14:01:41 +0800 Subject: [PATCH 12/13] improve unit test --- test/fixtures/index_extended_flags | Bin 0 -> 436 bytes test/test_index.py | 37 +++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 test/fixtures/index_extended_flags diff --git a/test/fixtures/index_extended_flags b/test/fixtures/index_extended_flags new file mode 100644 index 0000000000000000000000000000000000000000..f03713b684711d4a5aedab0bafd6b254137c9e5d GIT binary patch literal 436 zcmZ?q402{*U|l!>^Ob+tC2sPz z@}frL4{5V^!oJTI8&x~7IWT1AWtQlbFff4htEWE|gV7LkPHLi=!|-hGquHA-UUT;D z)?8N}b>q;Jp5TcNoDK}drAhjUDJiKbK+8Y?WR7Zr=1~|8b=Nnd%;P~auOvSoVcry8 zhad+>tlD0`4JmGI|5U?^ V?tRm?Z1&1ue!#pbGJMwrUjTmQph*A# literal 0 HcmV?d00001 diff --git a/test/test_index.py b/test/test_index.py index 6d90d7965..bb05d3108 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -1218,30 +1218,47 @@ def test_index_add_non_normalized_path(self, rw_repo): rw_repo.index.add(non_normalized_path) + def test_index_file_v3(self): + index = IndexFile(self.rorepo, fixture_path("index_extended_flags")) + assert index.entries + assert index.version == 3 + assert len(index.entries) == 4 + assert index.entries[('init.t', 0)].skip_worktree + + # Write the data - it must match the original. + with tempfile.NamedTemporaryFile() as tmpfile: + index.write(tmpfile.name) + assert Path(tmpfile.name).read_bytes() == Path(fixture_path("index_extended_flags")).read_bytes() + @with_rw_directory - def test_index_version_v3(self, tmp_dir): + def test_index_file_v3_with_git_command(self, tmp_dir): tmp_dir = Path(tmp_dir) with cwd(tmp_dir): - subprocess.run(["git", "init", "-q"], check=True) + git = Git(tmp_dir) + git.init() + file = tmp_dir / "file.txt" file.write_text("hello") - subprocess.run(["git", "add", "-N", "file.txt"], check=True) + git.add("--intent-to-add", "file.txt") # intent-to-add sets extended flag repo = Repo(tmp_dir) + index = repo.index - assert len(repo.index.entries) == 1 - entry = list(repo.index.entries.values())[0] + assert len(index.entries) == 1 + assert index.version == 3 + entry = list(index.entries.values())[0] assert entry.path == "file.txt" assert entry.intent_to_add file2 = tmp_dir / "file2.txt" file2.write_text("world") - repo.index.add(["file2.txt"]) - repo.index.write() + index.add(["file2.txt"]) + index.write() - status_str = subprocess.check_output(["git", "status", "--porcelain"], text=True) - assert " A file.txt\n" in status_str - assert "A file2.txt\n" in status_str + status_str = git.status(porcelain=True) + status_lines = status_str.splitlines() + assert " A file.txt" in status_lines + assert "A file2.txt" in status_lines class TestIndexUtils: From 107b1b44e91a19ebbe5e41cd7312ce7838534732 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 9 Nov 2025 08:41:10 +0100 Subject: [PATCH 13/13] make linter happy --- test/test_index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_index.py b/test/test_index.py index bb05d3108..711b43a0b 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -1223,7 +1223,7 @@ def test_index_file_v3(self): assert index.entries assert index.version == 3 assert len(index.entries) == 4 - assert index.entries[('init.t', 0)].skip_worktree + assert index.entries[("init.t", 0)].skip_worktree # Write the data - it must match the original. with tempfile.NamedTemporaryFile() as tmpfile: