You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 6de90f1
Browse filesBrowse the repository at this point in the historyBrowse files
fix(refs): preserve full reference names in revision APIs
<!-- agent: Codex -->
Converting reference arguments to object IDs prevents same-named tags from
replacing branches, but loses the reference identity required by several Git
operations. Reflog walks then return no commits, fork-point lookup fails with
`No such ref`, and the default `upload-archive` server rejects the literal ID.
References inside nested `merge_base()` arguments also still became short names
and could select a shadowing tag.
Keep the exact-reference existence and symbolic-chain checks in
`Git._check_revision()`, then pass the validated full ref name. This preserves
Git's ref-dependent behavior without operation-specific conversion switches.
Strings retain Git's revision interpretation and commit objects retain their
IDs. Normalize `os.PathLike` operands through `os.fsdecode()` before validation
so their filesystem paths, including byte paths, are used instead of their
display strings. Flatten nested list/tuple merge-base arguments while preserving
reference objects until each operand is validated.
Extend `tests/fixtures/exact-refs.sh` with an upstream advance and rewind plus
a topic based on its old tip. Regressions compare branch, remote-tracking and
HEAD behavior with Git 2.54.0 across SHA-1/SHA-256 and files/reftable repositories.
They cover shadowing tags, missing refs, nested operands, option spellings,
remote archives and safe/unsafe `PathLike` values. Update the changelog and
document the retained CLI fallbacks: GixPython 0.3.0 exposes neither the required
reflog-walk/fork-point operations nor an upload-archive client.
Assisted-by: GPT 6.1 Sol
Co-authored-by: GPT 6.1 Sol <codex@openai.com>
Copy file name to clipboardExpand all lines: doc/gix-backend.md
+20-1Lines changed: 20 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -374,7 +374,7 @@ and predate the current fallback; they do not establish native coverage.
374
374
| Worktree inventory, `worktree list`| Main and linked worktree metadata, including bare main repositories and locks | Prunable entries; GIX-14 |
375
375
|`Repo.merge_base`, `Repo.is_ancestor`| Native graph queries for two revisions | Octopus/fork-point and other options |
376
376
|`Commit.count`| Reachable commit count, skip/limit/first-parent | Path filters and other revision options |
377
-
|`Commit.iter_items`, `Repo.iter_commits`| First-parent walks and a single tip |General history ordering; GIX-8 |
377
+
|`Commit.iter_items`, `Repo.iter_commits`| First-parent walks and a single tip |Reflog walks, general history ordering; GIX-8 |
378
378
| Index entry reads, `ls_files`| Stage/mode/OID/path and exposed index flags | Custom and sparse indexes; GIX-3/4 |
379
379
|`IndexFile.version`, `update_index` query | Native index version | Actual `update-index` mutations |
380
380
| Index editing and `IndexFile.write`| Opaque byte snapshots; atomic locked publication | Private-file edits always use Git: arbitrary native index loading and strict pathname validation are missing; GIX-3/4/13/26 |
@@ -392,6 +392,25 @@ and predate the current fallback; they do not establish native coverage.
392
392
|`Repo.untracked_files`| Native directory walk | Extra status options and non-root command directories |
393
393
|`Repo.ignored`| Native excludes with tracked-file suppression | Symlink/submodule traversal, unsupported path normalization, and unavailable path metadata |
394
394
395
+
Revision APIs preserve a reference object's validated full name. The shared
396
+
`Git._check_revision()` first uses the exact reference reader to verify existence
397
+
and the symbolic-reference chain; it passes the full name rather than the resolved
398
+
object ID. Strings retain Git's name guessing, and commit objects retain their IDs.
399
+
This prevents same-named tags from replacing branches without losing the ref
400
+
identity needed by reflog walks, fork-point lookups and remote archives.
401
+
`merge_base()` validates nested list/tuple operands before string conversion.
402
+
`exact-refs.sh` covers these paths with shadowing tags and missing references in
403
+
SHA-1/SHA-256 and files/reftable repositories on both backends.
404
+
405
+
These name-sensitive operations retain CLI fallback. GixPython 0.3.0's
406
+
`Repository.rev_walk()` has no Git-compatible reflog-walk mode,
407
+
`Repository.merge_base()` exposes graph merge bases rather than reflog-based
408
+
fork-point selection, and no upload-archive client API is exposed. The regressions
409
+
compare Git 2.54.0's reflog history, old fork point after an upstream rewind,
410
+
and default upload-archive server behavior, which rejects literal object IDs.
411
+
Native replacements must expose matching reflog walking and fork-point selection
412
+
and the upload-archive protocol; no Python implementation substitutes for them.
413
+
395
414
Reference reads require an exact name, unlike revision APIs that intentionally
396
415
apply Git's name guessing. `reference_info()` uses
397
416
`Repository.try_find_reference()` and verifies the returned name for `HEAD` and
0 commit comments