Skip to content

Commit e96aece

Browse files
codexByron
authored andcommitted
feat(gix): initialize private indexes from trees natively
Use native empty/tree-derived indexes for fresh private `read-tree` destinations. Do not replace existing index metadata or emulate merge modes. Preserve configured non-v2 index selection by falling back because the native writer has no version setter (GIX-13). The staged version passes Ruff and Python syntax checks. Its SHA-1/SHA-256 native smoke and focused pytest selection pass: 13 passed in 2.63s.
1 parent 849bf59 commit e96aece

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

‎git/_backend.py‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,17 @@ def _update_index(repo: Any, args: List[str], kwargs: Dict[str, Any]) -> bytes:
354354
return str(_index(repo, kwargs).version()).encode("ascii") + b"\n"
355355

356356

357+
def _index_from_tree(repo: Any, tree: Any) -> Any:
358+
if not hasattr(repo, "index_from_tree"):
359+
raise _Unsupported("index feature disabled")
360+
if (
361+
repo.config_snapshot().integer("index.version") not in (None, 2)
362+
or os.environ.get("GIT_INDEX_VERSION", "2") != "2"
363+
):
364+
raise _Unsupported("new index version selection (GIX-13)")
365+
return repo.index_from_tree(tree)
366+
367+
357368
def _write(method: str, function: Callable[[], Any]) -> Any:
358369
"""Once a write starts, an error must not cause a second attempt through Git."""
359370
try:
@@ -466,6 +477,19 @@ def _mktree(repo: Any, args: List[str], kwargs: Dict[str, Any]) -> bytes:
466477
return oid.encode("ascii") + b"\n"
467478

468479

480+
def _read_tree(repo: Any, args: List[str], kwargs: Dict[str, Any]) -> bytes:
481+
if len(args) != 1 or (args[0] != "--empty" and args[0].startswith("-")):
482+
raise _Unsupported("index merge options")
483+
path = kwargs.get("env", {}).get("GIT_INDEX_FILE")
484+
if not path or os.path.exists(path):
485+
raise _Unsupported("existing index metadata")
486+
tree = repo.empty_tree() if args == ["--empty"] else repo.find_object(_oid(repo, args[0])).peel_to_tree()
487+
index = _index_from_tree(repo, tree)
488+
index.set_path(path)
489+
_write("read_tree", index.write)
490+
return b""
491+
492+
469493
_HANDLERS: Dict[str, Callable[[Any, List[str], Dict[str, Any]], bytes]] = {
470494
"rev_parse": _rev_parse,
471495
"ls_tree": _ls_tree,
@@ -476,6 +500,7 @@ def _mktree(repo: Any, args: List[str], kwargs: Dict[str, Any]) -> bytes:
476500
"update_index": _update_index,
477501
"hash_object": _hash_object,
478502
"mktree": _mktree,
503+
"read_tree": _read_tree,
479504
"config": _config,
480505
"worktree": _worktree,
481506
}

0 commit comments

Comments
 (0)