| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 170ece9 commit 4ecabd1
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -141,6 +141,7 @@ The historical full-suite counts above predate this correction. A constant | |||
| 141 | 141 | | Reference enumeration, `for_each_ref` | Sorted reference names and literal prefixes, preserving symbolic aliases | Dangling symbolic refs, root refs, glob patterns, other formats/options | | |
| 142 | 142 | | Managed `config --get KEY` | Merged repository config snapshot | Files/streams, enumeration, mutation; GIX-12 | | |
| 143 | 143 | | Submodule enumeration and cached fields | Dedicated native `.gitmodules` parser over the existing worktree/blob source, with raw path/URL/branch values | Other/duplicate sections, ambiguous brackets, missing/implicit fields and parser errors; GIX-12 | | |
| 144 | + | Commit hooks | No bound native lookup/execution API | All hooks, including absent hooks; GIX-23 | | ||
| 144 | 145 | | Worktree inventory, `worktree list` | Main and linked worktree metadata, including bare main repositories and locks | Prunable entries; GIX-14 | | |
| 145 | 146 | | `Repo.merge_base`, `Repo.is_ancestor` | Native graph queries for two revisions | Octopus/fork-point and other options | | |
| 146 | 147 | | `Commit.count` | Reachable commit count, skip/limit/first-parent | Path filters and other revision options | | |
@@ -449,6 +450,7 @@ below use the supplied `pygix` source and its pinned Gitoxide revision. | |||
| 449 | 450 | | GIX-20 | `Target.Symbolic(name)` validates full names but rejects standalone names accepted by `git check-ref-format --allow-onelevel`. Four of 430 audited calls differed: `refs` twice, `hellothere`, and `valid_one_level_refname`. Further probes include digits, punctuation and Unicode (`1`, `A1`, `HEAD_1`, `A-B`, `A.B`, `Ä`). | Expose Git-compatible partial/one-level name validation, or correct the native restriction where appropriate. This is a binding/behavior shortcoming to revisit upstream; standalone names rejected natively retain CLI validation. | | |
| 450 | 451 | | GIX-21 | Native snapshot overrides for `committer.name`, `committer.email` and `gitoxide.commit.committerDate` resolve correctly. Applying them to the retained repository would expose command-specific identity to other threads. GixPython 0.1.0 has no general independent repository clone: Python `copy`/`deepcopy` fail, while the binding's internal `RepoHandle::clone()` shares its `Arc` state. | Bind a cheap independent native clone with isolated config so native identity resolution can apply per-command overrides, including removal semantics. Reopening isolates state but repeats setup; `with_object_memory()` also changes object-write behavior and is not a general clone API. Keep native process/config identity and CLI for differing command overrides. Do not mutate process environment/shared snapshots or resolve identity fields in Python. Explicit canonical commit inputs may still be adapted to `gix.Signature`. | | |
| 451 | 452 | | GIX-22 | The native Git directory is sufficient for the two fixed metadata leaves used here: `modules` and `COMMIT_EDITMSG`. Git's `path.c` applies no special relocation to either, including in linked worktrees. The adapter appends only these names to the canonical native Git directory. | No new binding is needed for these ordinary paths. Other `--git-path` names and symlinked metadata leaves retain CLI resolution; a general resolver must handle config/environment overrides, common/private storage and canonical targets. `Repository.modules_path()` means `.gitmodules`, not the `modules` storage directory. | | |
| 453 | + | GIX-23 | No hook lookup or execution API is bound in GixPython 0.1.0. The removed absence fast path read config through Gix but used Python `os.stat()` to declare success. | Bind native hook lookup with configured/default path, linked-worktree, missing/nonexecutable-hook and diagnostic semantics, plus execution where needed. Until then all managed hook calls use Git, including `--ignore-missing` no-ops. A Python filesystem check is not a Gix implementation. | | ||
| 452 | 454 | ||
| 453 | 455 | For GIX-8, at fixture commit `44e0a8ec55c42559dfcdf5117710b26261a7c937`, | |
| 454 | 456 | compare `git rev-list HEAD` with | |
@@ -509,7 +511,7 @@ this investigation; this item does not claim a process reduction. | |||
| 509 | 511 | | Object enumeration and alternate-directory listing | No binding for complete ODB object iteration or alternate-store enumeration; `cat-file --batch-all-objects` / `count-objects` remain. | | |
| 510 | 512 | | Name-rev, trailer parsing, cherry | No equivalent bound operation. Native describe is not name-rev. | | |
| 511 | 513 | | Config-backed remote/submodule maintenance | Missing config enumeration/multivar/removal operations (GIX-12), plus filesystem and worktree lifecycle requirements. | | |
| 512 | - | Hook execution | Explicitly requested hooks retain the existing Git-managed behavior. Native operations retain GitPython's default hook/fsmonitor/maintenance restrictions. | | ||
| 514 | + | Hook execution | Every explicit hook request, including an absent hook, retains Git-managed lookup, execution and diagnostics until GIX-23 is addressed. Native operations retain GitPython's default hook/fsmonitor/maintenance restrictions. | | ||
| 513 | 515 | ||
| 514 | 516 | ## Maintaining the adapters | |
| 515 | 517 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,8 @@ | |||
| 11 | 11 | import pytest | |
| 12 | 12 | ||
| 13 | 13 | from git import Actor, Commit, Git, Reference, Repo, SymbolicReference, _backend | |
| 14 | - from git.exc import GitCommandError, InvalidGitRepositoryError | ||
| 14 | + from git.exc import GitCommandError, InvalidGitRepositoryError, UnsafeOptionError | ||
| 15 | + from git.index.fun import run_commit_hook | ||
| 15 | 16 | from git.index.typ import BaseIndexEntry | |
| 16 | 17 | from git.repo.fun import find_submodule_git_dir, find_worktree_git_dir, is_git_dir | |
| 17 | 18 | from gitdb import IStream | |
@@ -307,6 +308,33 @@ def test_native_tree_and_commit_bytes_match_cli(repo): | |||
| 307 | 308 | assert commit.replace(message="a changed message").hexsha == native.hexsha | |
| 308 | 309 | ||
| 309 | 310 | ||
| 311 | + def test_hooks_retain_cli_even_when_missing(repo, tmp_path): | ||
| 312 | + repo.index.commit("initial", skip_hooks=True) | ||
| 313 | + linked_path = tmp_path / "linked" | ||
| 314 | + repo.git.worktree("add", "--detach", str(linked_path)) | ||
| 315 | + with Repo(linked_path) as linked: | ||
| 316 | + linked.git.version_info | ||
| 317 | + count = _backend.statistics().get(("Git.execute", "CLI process"), 0) | ||
| 318 | + with patch.object(Git, "execute", autospec=True, side_effect=Git.execute) as cli: | ||
| 319 | + for current in (repo, linked): | ||
| 320 | + for name in ("pre-commit", "commit-msg", "post-commit"): | ||
| 321 | + run_commit_hook(name, current.index) | ||
| 322 | + with pytest.raises(UnsafeOptionError, match="NUL"): | ||
| 323 | + run_commit_hook("commit-msg", repo.index, "message\0path") | ||
| 324 | + assert cli.call_count == 6 | ||
| 325 | + assert _backend.statistics().get(("Git.execute", "CLI process"), 0) == count + 6 | ||
| 326 | + hook = Path(repo.common_dir, "hooks", "pre-commit") | ||
| 327 | + hook.parent.mkdir(exist_ok=True) | ||
| 328 | + hook.write_text("present, even without executable permission") | ||
| 329 | + with patch.object(Git, "execute", return_value="") as cli: | ||
| 330 | + run_commit_hook("pre-commit", linked.index) | ||
| 331 | + cli.assert_called_once() | ||
| 332 | + repo.git.config("core.hooksPath", "custom-hooks") | ||
| 333 | + with patch.object(Git, "execute", return_value="") as cli: | ||
| 334 | + run_commit_hook("post-commit", repo.index) | ||
| 335 | + cli.assert_called_once() | ||
| 336 | + | ||
| 337 | + | ||
| 310 | 338 | def test_native_submodule_inventory_and_cached_fields_match_cli(repo): | |
| 311 | 339 | first = repo.index.commit("initial", skip_hooks=True) | |
| 312 | 340 | config = Path(repo.working_dir, ".gitmodules") | |
| Back | FazBrowse Home | New Git URL |
0 commit comments