| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 30013e9 commit 46c4bed
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -50,6 +50,16 @@ The compatibility `entries` property projects those queries into a read-only | |||
| 50 | 50 | snapshot keyed by path and stage, preserving readers in dlt and Renku. It uses | |
| 51 | 51 | the same Gix-backed default-index query or documented Git fallback as | |
| 52 | 52 | `iter_entries()`; snapshots do not become editable index state. | |
| 53 | + | ||
| 54 | + Discovery distinguishes a checkout's `.git` file from an arbitrary gitfile | ||
| 55 | + operand. Gix reopens the canonical checkout gitfile through `gix.open_opts()` | ||
| 56 | + and returns `Repository.workdir()` for separate Git directories. Reopening only | ||
| 57 | + the administrative directory loses that checkout context. Standalone gitfile | ||
| 58 | + helpers still reopen the canonical native Git directory to avoid the known | ||
| 59 | + arbitrary-gitfile mismatch (GIX-14). The CLI path uses `rev-parse --show-toplevel` | ||
| 60 | + from the supplied checkout. Mistral Vibe 3.0.1 and scripted SHA-1/SHA-256, | ||
| 61 | + files/reftable regressions verify this adapter correction with Git 2.53.0 and | ||
| 62 | + GixPython 0.2.0; it does not close GIX-14's upstream compatibility bugs. | ||
| 53 | 63 | Deferred/virtual state consists of opaque file bytes, materialized before Git | |
| 54 | 64 | operates and read back only after success. Private edits use Git because native | |
| 55 | 65 | bindings cannot load an arbitrary existing index (GIX-3) or validate a checked | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,7 +57,7 @@ def _fallback(method: str, reason: str) -> Any: | |||
| 57 | 57 | return NotImplemented | |
| 58 | 58 | ||
| 59 | 59 | ||
| 60 | - def discover_repository(path: str, environment: Dict[str, Any]) -> Any: | ||
| 60 | + def discover_repository(path: str, environment: Dict[str, Any], *, from_worktree: bool = False) -> Any: | ||
| 61 | 61 | """Open one discovery candidate; the caller controls parent traversal.""" | |
| 62 | 62 | if gix is None: | |
| 63 | 63 | return NotImplemented | |
@@ -73,7 +73,11 @@ def discover_repository(path: str, environment: Dict[str, Any]) -> Any: | |||
| 73 | 73 | ) | |
| 74 | 74 | try: | |
| 75 | 75 | repo = gix.open_opts(path, options) | |
| 76 | - if os.path.isfile(path): | ||
| 76 | + if os.path.isfile(path) and from_worktree: | ||
| 77 | + # Canonicalize the supplied checkout path and let Gix resolve both | ||
| 78 | + # its Git directory and worktree from that .git file. | ||
| 79 | + repo = gix.open_opts(os.path.realpath(path), options) | ||
| 80 | + elif os.path.isfile(path): | ||
| 77 | 81 | # Reopening also makes Gix derive the worktree from its Git directory, | |
| 78 | 82 | # rather than retaining an arbitrary gitfile's location as a worktree. | |
| 79 | 83 | repo = gix.open_opts(os.path.realpath(repo.git_dir()), options) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -327,7 +327,7 @@ def __init__( | |||
| 327 | 327 | try: | |
| 328 | 328 | # Git resolves relative gitfile targets using the last forward | |
| 329 | 329 | # slash in this operand, including on Windows. | |
| 330 | - native = _backend.discover_repository(candidate, environment) | ||
| 330 | + native = _backend.discover_repository(candidate, environment, from_worktree=candidate == dotgit) | ||
| 331 | 331 | git_dir = ( | |
| 332 | 332 | probe._call_process_safe("rev_parse", "--resolve-git-dir", to_native_path_linux(candidate)) | |
| 333 | 333 | if native is NotImplemented | |
@@ -358,6 +358,14 @@ def __init__( | |||
| 358 | 358 | if git_dir is None: | |
| 359 | 359 | raise InvalidGitRepositoryError(epath) | |
| 360 | 360 | ||
| 361 | + checkout = None | ||
| 362 | + if native is NotImplemented and candidate == dotgit and osp.isfile(candidate): | ||
| 363 | + # Let Git select the checkout through the supplied .git file. Its | ||
| 364 | + # administrative directory alone need not identify the worktree. | ||
| 365 | + checkout_probe = self.GitCommandWrapperType(curpath) | ||
| 366 | + checkout_probe._environment.update(GIT_DIR=None, **environment) | ||
| 367 | + checkout = checkout_probe._call_process_safe("rev_parse", "--show-toplevel") | ||
| 368 | + | ||
| 361 | 369 | self.git_dir = git_dir | |
| 362 | 370 | probe.update_environment(GIT_DIR=git_dir) | |
| 363 | 371 | try: | |
@@ -388,7 +396,7 @@ def __init__( | |||
| 388 | 396 | # Gix's configured bare flag also applies to linked worktrees. | |
| 389 | 397 | self._bare = native.is_bare() and self._working_tree_dir is None | |
| 390 | 398 | else: | |
| 391 | - self._working_tree_dir = environment.get("GIT_WORK_TREE") | ||
| 399 | + self._working_tree_dir = environment.get("GIT_WORK_TREE") or checkout | ||
| 392 | 400 | if self._working_tree_dir is None and not self._bare and environment.get("GIT_COMMON_DIR") is None: | |
| 393 | 401 | try: | |
| 394 | 402 | probe._call_process_safe("config", "--get", "core.worktree") | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -36,7 +36,8 @@ def test_index_entries_readers_retain_pending_and_published_snapshots(object_for | |||
| 36 | 36 | @pytest.mark.parametrize("object_format", ["sha1", "sha256"]) | |
| 37 | 37 | @pytest.mark.parametrize("ref_format", ["files", "reftable"]) | |
| 38 | 38 | def test_git_directory_option_selects_the_requested_worktree(object_format, ref_format): | |
| 39 | - with fixture_repo("downstream-worktree.sh", object_format, ref_format, write=True) as repo: | ||
| 39 | + # Linked-worktree registration contains absolute paths that cannot be copied. | ||
| 40 | + with fixture_repo("downstream-worktree.sh", object_format, ref_format, write=True, execute=True) as repo: | ||
| 40 | 41 | root = Path(repo.working_tree_dir).parent | |
| 41 | 42 | linked = root / "linked" | |
| 42 | 43 | original_index = Path(repo.index.path).read_bytes() | |
@@ -55,11 +56,24 @@ def test_git_directory_option_selects_the_requested_worktree(object_format, ref_ | |||
| 55 | 56 | ||
| 56 | 57 | ||
| 57 | 58 | def test_git_directory_option_retains_explicit_environment(): | |
| 58 | - with fixture_repo("downstream-worktree.sh", "sha1", "files", write=True) as repo: | ||
| 59 | + # Linked-worktree registration contains absolute paths that cannot be copied. | ||
| 60 | + with fixture_repo("downstream-worktree.sh", "sha1", "files", write=True, execute=True) as repo: | ||
| 59 | 61 | root = Path(repo.working_tree_dir).parent | |
| 60 | 62 | other = root / "other" | |
| 61 | 63 | with repo.git.custom_environment(GIT_DIR=repo.git_dir, GIT_WORK_TREE=repo.working_tree_dir): | |
| 62 | 64 | assert repo.git(C=str(other)).show("HEAD:tracked") == "original" | |
| 63 | 65 | assert repo.git(C=str(other)).show("HEAD:tracked") == "other" | |
| 64 | 66 | assert repo.git(C=str(other)).show("HEAD:tracked", env={"GIT_DIR": repo.git_dir}) == "original" | |
| 65 | 67 | ||
| 68 | + | ||
| 69 | + @pytest.mark.parametrize("object_format", ["sha1", "sha256"]) | ||
| 70 | + @pytest.mark.parametrize("ref_format", ["files", "reftable"]) | ||
| 71 | + def test_separate_git_directory_retains_the_supplied_checkout(object_format, ref_format): | ||
| 72 | + with fixture_repo("downstream-separate-git-dir.sh", object_format, ref_format, write=True) as repo: | ||
| 73 | + assert Path(repo.working_tree_dir).name == "repo" | ||
| 74 | + assert Path(repo.git_dir).name == "metadata" | ||
| 75 | + assert repo.git.rev_parse("--show-toplevel") == repo.working_tree_dir | ||
| 76 | + assert repo.index.entry("tracked").to_blob(repo).data_stream.read() == b"tracked" | ||
| 77 | + Path(repo.working_tree_dir, "tracked").write_text("updated") | ||
| 78 | + repo.index.add(["tracked"]) | ||
| 79 | + assert repo.index.commit("updated").tree["tracked"].data_stream.read() == b"updated" | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,9 @@ | |||
| 1 | + #!/usr/bin/env bash | ||
| 2 | + set -eu | ||
| 3 | + git init -q --object-format="$1" --ref-format="$2" --separate-git-dir=metadata repo | ||
| 4 | + # Keep the fixture relocatable when copied into a writable test directory. | ||
| 5 | + printf 'gitdir: ../metadata\n' > repo/.git | ||
| 6 | + cd repo | ||
| 7 | + printf tracked > tracked | ||
| 8 | + git add tracked | ||
| 9 | + git commit -qm initial | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments