chore(deps): update rust crate gix to 0.87 - #31
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
renovate
Bot
force-pushed
the
renovate/gix-0.x
branch
from
March 29, 2026 11:25
5bd6ac0 to
5b4d360
Compare
Benchmark Results
Download full results from the workflow artifacts. |
renovate
Bot
force-pushed
the
renovate/gix-0.x
branch
from
April 24, 2026 14:54
5b4d360 to
507e30f
Compare
renovate
Bot
force-pushed
the
renovate/gix-0.x
branch
from
April 28, 2026 05:14
507e30f to
d61bf25
Compare
renovate
Bot
force-pushed
the
renovate/gix-0.x
branch
from
May 18, 2026 19:15
d61bf25 to
10f21c4
Compare
renovate
Bot
force-pushed
the
renovate/gix-0.x
branch
from
May 26, 2026 04:40
10f21c4 to
50efbf9
Compare
renovate
Bot
force-pushed
the
renovate/gix-0.x
branch
from
June 22, 2026 18:44
50efbf9 to
b334323
Compare
renovate
Bot
force-pushed
the
renovate/gix-0.x
branch
2 times, most recently
from
July 23, 2026 18:27
cb0fc45 to
e3938a2
Compare
renovate
Bot
force-pushed
the
renovate/gix-0.x
branch
from
August 11, 2026 22:57
e3938a2 to
796f139
Compare
renovate
Bot
force-pushed
the
renovate/gix-0.x
branch
from
August 22, 2026 22:28
796f139 to
98dd39b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
0.80→0.87Release Notes
GitoxideLabs/gitoxide (gix)
v0.87.0: gix v0.87.0Compare Source
Bug Fixes (BREAKING)
need-more-recent-msrvas it's not required anymoreIt was mostly meant to be internal, but the name didn't indicate
this, hence the breaking change.
Test
assert fetched pack contents rather than pack checksums
fetch_packandfetch_pack_without_local_destinationasserted thedata_hash/index_hashof a pack produced by the hostgit. Those coverthe pack's compressed bytes, so they silently encode which zlib
implementation that
gitis linked against: with a zlib-ng-linked git(Arch, among others) the 219-byte commit in that pack deflates to 152 bytes
where stock zlib produces 153, making the pack 268 bytes instead of 269 and
changing both checksums.
Nothing about the fetch itself differs — re-deflating the very same object
payloads with stock zlib and re-hashing reproduces the expected checksum
byte for byte, and every other assertion in both tests already passes.
Assert the pack's object ids instead, read back from the index that was just
written. They hash uncompressed content, so they are identical on every host,
and they are what the checksums were standing in for.
num_objects,pack_versionandindex_versionare untouched;Entry::crc32isdeliberately not used, as it too is computed over compressed bytes.
New Features (BREAKING)
add Git-compatible commit signature verification with
Commit::verify()Breaking because it also adds
config::tree::Key::default_value(), which givesAnya
default_valuefield.Expose repository-aware verification on commits while delegating verifier
execution and result parsing to gix-object plumbing. Resolve supported
signature formats, configured programs, trust thresholds, SSH allowed
signers and revocations, repository-relative paths, and commit verification
time according to Git configuration.
add
commit::Info::generationThat way it's evident if a commit-graph was present for this node.
Breaking, as it adds a new public field to a structure.
Changed (BREAKING)
remove the
tree-editorfeature toggleThe workspace MSRV now exceeds Rust 1.75, which stabilized the language feature
that originally required tree editing to be gated.
Make tree-editing APIs available unconditionally.
New Features
expose git notes in
gix::RepositoryAdd the notes feature and
Repository::notesas the porcelain layer overgix-notefor repeated queries and mutations.
Select the default notes ref from
core.notesRef, including theGIT_NOTES_REFenvironment override represented in
config::tree, and fall back torefs/notes/commits. Discover additional display refs fromnotes.displayReforGIT_NOTES_DISPLAY_REF, expand glob patterns, preserve display order, and avoidduplicates.
For mutations, accept conventional short notes-ref names, write note blobs and
notes commits, and update refs with compare-and-swap expectations so concurrent
changes are not silently overwritten.
add
Repository::delete_local_branches().asdf
Validate the entire batch before changing references, reject branches checked
out in any worktree, and delete references and reflogs in one transaction
without requiring commit traversal.
Remove matching local branch configuration under lock and report when
configuration cleanup fails after reference deletion. Share checked-out branch
discovery with fetch updates and use restricted repository opening throughout
the affected tests.
add Git-compatible commit signing via
Commit::sign()Expose repository-aware commit signing while delegating signature creation
to gix-object plumbing. Resolve gpg.format, per-format programs, signing
keys, committer identity fallback, and gpg.ssh.defaultKeyCommand from Git
configuration, including trusted paths and shell commands.
Add commit_signing_options_if_enabled() so porcelain callers honor
commit.gpgSign without resolving signer configuration while signing is
disabled. Preserve caller control over resolved program arguments and
environment, including non-interactive GPG operation.
add commit signature verification to gix-object via
commit::SignedData::verify()Add feature-gated plumbing for verifying OpenPGP, X.509, and SSH commit
signatures with fully resolved programs, arguments, environments, trust
thresholds, and SSH policy inputs. Keep repository configuration out of
the object crate while exposing Git-compatible status, identity, key, and
fingerprint results.
Stream signed commit data directly to OpenPGP and SSH verifiers without
reconstructing it. Use a temporary payload only where gpgsm requires a
file, and cover Git status parsing plus unsupported and mismatched formats.
expose Git quoting utilities in gix
expose Git-compatible editor selection
Add `Repository::editor()`` to resolve the interactive editor with Git's
precedence rules. Honor GIT_EDITOR ahead of trusted core.editor, consider VISUAL
only for capable terminals, fall back through EDITOR to vi, and report no editor
for an unconfigured dumb terminal.
Route GIT_EDITOR through the configuration environment-override framework
so isolated repositories and environment permissions remain effective. Cover
precedence, dumb terminals, the no-op editor, and isolation.
recognize SHA-256 commit signature headers
Teach commit parsing and signature extraction about the gpgsig-sha256
header used by Git when signing SHA-256 commits. Treat it like gpgsig
when locating the embedded signature while preserving the actual header
name when reconstructing the signed payload.
Cover both full commit parsing and token iteration so callers observe
the signature consistently through either API.
add support for
GIT_ALLOW_PROTOCOLhonor
GIT_INDEX_FILEwhen opening repositories viadiscover_with_environment_overrides()Map
GIT_INDEX_FILEto the newgitoxide.core.indexFileconfiguration keyand use it for index reads and writes, allowing to implement hooks for the first time.
As a fix, Repository-local environment overrides are no longer inherited when opening
submodules, linked worktrees, or their main repository. This prevents an
alternate index, worktree, or Git directory from leaking into another
repository.
The selected index path remains stable until the repository is reloaded, and
empty index-file overrides are rejected.
support cloning a single revision
A full object ID passed through with_ref_name() produced an object-ID refspec
mapping and panicked while clone assumed every mapping had a name. Branch and
tag checkout also retained ordinary clone tracking semantics instead of offering
a single-revision mode.
Add PrepareFetch::with_revision() and gix clone --revision for full refs, HEAD,
and full object IDs. Revision clones use a one source-only implicit refspec,
detach HEAD to the fetched commit, create no ordinary refs, persist no fetch
refspec, and disable tag following. Existing with_ref_name() and --ref behavior
stays unchanged.
This follows Git commit
3378556(builtin/clone: teach git-clone(1) the--revision= option) and its t/t5621-clone-revision.sh behavior.
add
config()functionFactor the non-repository portion of configuration initialization out of
repository opening and expose it as gix::config(). The new API accepts a future
git directory and the same open::Options used by open and clone, preserving
source permissions, conditional includes, environment handling, and override
precedence.
Chore
Normalize the precomputed diff fixture assets to LF before writing blobs,
populating the index, and creating commits. Git for Windows may check these
assets out with CRLF, which changes their object IDs and adds carriage returns
to index paths, causing fixture setup to fail at
git mv cli c.Prevent Git Bash from rewriting revision arguments before Git sees them, and
normalize the two pathspec baseline cases where Git for Windows applies native
path validation to repository-format paths. Exclude a glob baseline whose
backslash behavior is specific to Git for Windows rather than Git paths.
Generate pathological .gitmodules entries as configuration data instead
of trying to create module directories whose names cannot be represented
on Windows. Use Git Bash bundled Perl for binary fixture construction so
regeneration does not depend on a separately installed Python interpreter.
Also pass a literal carriage return to sed through Bash ANSI-C quoting when
normalizing the jj diff assets. Unlike GNU sed, BSD sed does not interpret
backslash-r in a single-quoted expression, so the previous spelling could remove
a trailing letter r on macOS instead of stripping CRLF endings.
Bug Fixes
don't limit
is_dirty()to the current working directoryresolve the empty pattern in
<rev>^{/}like Git, instead of skipping it.The parser dropped the
find()delegate call whenever the pattern in<rev>^{/<pattern>}was empty, turning the whole navigation step into ano-op on the grounds that an empty pattern matches everything.
That reasoning only holds for a commit anchor and a non-negated pattern.
Git routes
<rev>^{/...}throughGET_OID_COMMITTISHand searches fromthe peeled commit even when the pattern is empty - object-name.c notes
"$commit^{/}. Some regex implementation may reject empty regex, but this
is safe". Thus
git rev-parse 'b-tag^{/}'yields the commit theannotated tag points at, while
gixreturned the tag object itself. Anegated empty pattern matches no commit at all, so Git fails
HEAD^{/!-}while
gixsilently succeeded with HEAD.Now the parser always forwards the pattern to
Navigate::find(), whoseimplementation in
gixalready handles the empty case correctly on boththe
revparse-regexand the substring fallback paths: it peels theanchor to a commit first and treats an empty pattern as match-all, which
fails naturally when negated. The delegate behind
gix revision explainmakes no assumption about patterns and needs no change.
The
make_rev_spec_parse_reposfixture gains baselines for@^{/},@^{/!-}andb-tag^{/}; its archive needs regeneration.correctly handdle GIT_PROTOCOL_FROM_USER when evaluating protocol permissions
Align helper protocol permissions with Git by applying policy by transport
name, using the known-safe, ext, and user defaults, and parsing
GIT_PROTOCOL_FROM_USERas a Git boolean.peel annotated tags before navigating a rev-spec, like in Git.
<tag>^,<tag>^<n>,<tag>~<n>and<tag>^{/<text>}navigated from the tagobject itself rather than from the commit it points at. In a repository whose
annotated
b-tagnames the merge commitb, Git resolvesb-tag^tod,while
gixreported "Object212d0f0was a tag, but needed it to be a commit",and
b-tag^{/G}failed with a kind mismatch instead of resolving tog.Git routes these forms through
GET_OID_COMMITTISH, which dereferences tagsfirst. The three navigation sites now peel to a commit the way
^{commit}already did, keeping the original object id as the replacement key. Peeling is
the identity on a commit, so commit anchors resolve and fail exactly as before.
A blob or tree anchor now reports that it could not be peeled to a commit.
<tag>~0still yields the tag. The parser ingix-revisionskips the delegatecall entirely for a zero-length ancestor walk, which is correct for a commit
anchor and is pinned by a test there; changing it touches the public
Navigatecontract and belongs in its own change.
reject
./..revspec paths that leave the worktree, like in Git.At the worktree root,
HEAD:./../thisresolved to the blob atthiswhileHEAD:../thiscorrectly failed. Git rejects both:Containment is delegated to
Repository::normalize_path(), which normalizesagainst an empty
current_dirso that a..with nothing left to consumefails. In
gix_path'snormalize_inner()a leading.stays in the buffer,so
..pushes the emptycurrent_dironto it,pop()removes the.andsucceeds — where the same path without the leading
.pops an empty buffer,gets
false, and correctly yieldsNone. Only the worktree root is affected;from
some/very,HEAD:./../../thisalready resolved andHEAD:./../../../thisalready failed.Dropping the current-directory components before normalizing keeps the fix
inside the revspec parser.
The alternative is
normalize_inner()itself, which is a two-line change andwould make the documented promise of
Repository::normalize_path()— "Pathswhich traverse outside of the repository are rejected" — true for every
caller. I left it alone because it also changes callers unrelated to this
work:
gix_submodule::File::path()would start rejecting a.gitmodulespath = ./../evilthat it accepts today, andgix_pathspec::Pattern::normalize()would start rejecting
./../x. Both look like improvements, but they belongin a change against
gix-path, not in this one.resolve
./and../revspec paths against the current directory, like in Git.gitrevisions(7)states that a path starting with./or../is relative to thecurrent working directory and gets converted to be relative to the working tree's root
directory.
gixpassed these paths on verbatim, so in a repository withdir/g1.txtcommitted, and with the current directory being
dir/, git 2.50.1 and gix disagreed:HEAD:./g1.txtCould not find path "./g1.txt" in treeHEAD:../f1.txtCould not find path "../f1.txt" in tree:./g1.txtPath "./g1.txt" did not exist in index at stage 0HEAD:./dirdelegate.peel_until(Path("./")) failedgix-revision's parser forwards such paths intact on purpose, and theNavigatedelegate documentation promises the conversion, but the
giximplementation of itnever performed one.
The tree lookup in
peel_until()andindex_lookup()now route paths with eitherprefix through
Repository::normalize_path(). Like Git, this requires the currentdirectory to be inside a worktree, and paths traversing above the worktree stay
rejected.
respect filter driver configuration precedence
A filter driver declared in user configuration incorrectly won over a
repository-local declaration with the same name. A regression test demonstrates
both the local property override and inheritance of a user-level property that
is not overridden.
Merge repeated named filter sections in configuration order and replace
only the properties present in each later section. This matches Git's
read_convert_config() behavior in convert.c as inspected at
cf5497b.respect inherited core.symlinks when cloning.
Load global configuration with the clone open options before repository
initialization, and preserve an effective core.symlinks=false as a
high-precedence override. Combine that result with probed filesystem
capabilities so either source can disable symlinks.
Match Git initialization by persisting core.symlinks=false only when the
filesystem probe fails; never write a local true that masks inherited
configuration. Add a portable plumbing-built symlink fixture and cover both
configuration-false/probe-true and configuration-true/probe-false clones.
let GIT_WORK_TREE override core.bare
Commit Statistics
Commit Details
view details
ed9a650)b1174b6)ebe9095)7424676)gix::Repository(d934f5b)b2d919a)is_dirty()-to-the-current-working-directory (ea9a6d4)44ba4b4)is_dirty()to the current working directory (cb74ef6)f3bbfad)Repository::delete_local_branches(). (61c5e1e)gix-object(object signing) (723d3de)Commit::sign()(8017175)Commit::verify()(15809f9)commit::SignedData::verify()(5b90699)a9f090e)e1c56e4)a30f442)gix-testtools(0cbe539)e5452ba)gix-ref(5810922)dd8c759)gix-odb(1dc741f)gix-odb(a0b93a3)05f905e)566fea1)a8b1be5)<rev>^{/}like Git, instead of skipping it. (6746715)gix-date(613ff86)dbd162d)GIT_ALLOW_PROTOCOL(287ab8f)77b5848)gix-url(2648dc1)gix-url(62e140d)GIT_INDEX_FILE-via-gitoxide.core.indexFile(aa3b006)tree-editorfeature toggle (3a4350c)need-more-recent-msrvas it's not required anymore (f1c8911)GIT_INDEX_FILEwhen opening repositories viadiscover_with_environment_overrides()(f9b3891)GIT_INDEX_FILEviagitoxide.core.indexFile(e1856d0)ef41caa)gix-refspec. (9fa50a5)95e0213)gix-blame(93d4019)7a34c17)0760b60)368438c)d14aefb)e99f637)232dd1c)5510bce)dffd5ef)./..revspec paths that leave the worktree, like in Git. (92e3133)./and../revspec paths against the current directory, like in Git. (6171a05)cc3ee80)ab4fcb0)a7e0a2e)4f480b9)5708de4)make_clone_with_symlinkfixture archive (18e42fa)4a6cf9d)gix-packuses the parallel feature (79e3478)b049777)file://URL in the same fixture (3dabe4a)gitpath and the URL in the credential-helper baseline (951f40f)command -vrather thanwhichto locategitin a fixture (51afc13)50713b0)config()function (9923d76)da71d06)f03905e)275c26a)639535e)93ad8f9)03ef906)29aa7cd)4b3bf5a)commit::Info::generation(e768682)82711e1)75444cb)ae8845a)v0.86.0: gix v0.86.0Compare Source
New Features (BREAKING)
Changed (BREAKING)
replace
maybe-asyncwithbisync.Replace the globally feature-selected maybe-async dependency with bisync 0.3 and
re-export the locally selected macro mode from gix-protocol.
Also use it to deduplicate portions which previously couldn't be handled.
adapt to lifetime-free configuration files in
gix-configUpdate repository configuration storage, snapshots, overrides, and caches
to use the self-contained
gix_config::Filerepresentation. Configurationcan now move through repository initialization, cloning, and remote setup
without artificial input lifetimes or conversions to
'static.BString,PathBuf,OsString, andFullNamevaluesfrom configuration-derived lookups.
Option<Result<T, E>>toResult<Option<T>, E>, allowing errors to propagate naturally with?.AsBStrinconfiguration setters, converters, remote lookup, and remote saving.
Cowconstruction,into_owned(), and redundantcloning from configuration consumers.
enriching validation errors.
Adapt config-tree conversions for the new owned values and optional-result
shape, including booleans, integers, paths, URLs, refspecs, timeouts,
compression levels, and reference names.
Return owned remote names, default remote names, branch tracking
references, and submodule paths so these results are independent of the
repository configuration borrow. Protocol feature values likewise use
owned strings.
Update repository opening, initialization, cloning, remotes, filters,
status, submodules, and related tests to use the lifetime-free APIs.
Other
some/(a tree of only empty directories) now collapses to an emptydirectory and is skipped when empty directories aren't emitted, matching
Git which treats a tree with no files as clean. See #2490.
New Features
Repository::normalize_path()This way, one won't have to use the
Pattern + normalizeworkaround anymore.discover_opts()as sibling toopen_opts().This makes isolated discovery easier, at the cost of less control compared to itsgix::ThreadSafeRepository` counterpart.Understand and validate core.compression, core.looseCompression and pack.compression, including git's -1 mapping to the zlib default. Apply these settings when writing loose objects and receiving packs.
core.fscacheon WindowsConnection::configured_credentials_for_current_url().It extracts the URL from the input action, which is relevant in case
of redirects which changes the initial url.
Chore
let archived fixtures bypass Git version gates
Git-dependent fixture tests currently skip outright when the installed Git is
incompatible, even when a checked-in archive contains a known-good fixture that
could run safely. This also keeps 32-bit CI pinned to Debian 12 because Debian
13 ships affected Git 2.47.x.
Use the guarded scripted-fixture loaders for minimum-version worktree tests and
the shared rev-spec fixture, then return 32-bit CI to Debian stable.
Git
57fb139introduced reversed :/ traversal in 2.47.x; Git0ff919erestored youngest-first ordering in 2.48.0.
Bug Fixes
avoid treating symbolic remote names as URLs
--- agent
Configured remotes without an effective fetch URL exposed their symbolic name
as a local-path URL.
Only use a remote name as the missing fetch URL when remote-name classification,
a non-file transport, or native absolute-path detection identifies it as a URL.
Git baseline: remote.c:remotes_remote_get_1() adds the explicitly supplied name
as a URL when the remote has no configured URL; t/t5505-remote.sh covers remote
get-url behavior. This change intentionally diverges for symbolic names.
always treat submodule names as relative.
Previously it would assume they are relative, join them with
a base path, which could promptly be overridden by an absolute
submodule name, which is valid for Git as well.
Code handling submodule paths is now aware and won't accidentally
break out of the repository anymore.
honor credential.protectProtocol for helper exchanges
preserve multiple remote URLs
Configured remotes can have multiple remote..url or remote..pushUrl
values, but
gix::Remotekept only one value because lookup used the singularconfig accessor. That meant the most recent config value won, while Git exposes
every effective URL and uses the first one for the singular get-url form.
Add ordered URL storage to
gix::Remoteand exposeRemote::urls(Direction)forall effective URLs. Keep Remote::url(Direction) as the singular compatibility
API, now returning the first effective URL. Fetch URLs used as push fallbacks
try pushInsteadOf first and then insteadOf, matching Git behavior.
The regression fixture records Git 2.50.1 behavior with git remote get-url:
without --all it prints the first configured URL, and with --all it prints all
configured URLs in order for both fetch and push.
keep
core.worktree-derived worktree paths in the caller's path namespaceSince
b1c1cce, relativecore.worktreevalues from repository-ownedconfiguration were resolved against the symlink-resolved git dir whenever
that differed from the logical git dir. That is correct when the
.gitdirectory itself is reached through a symlink (#2052), but it also fired
when merely an ancestor directory is a symlink - like
/varon macOS,where
TMPDIRdefaults to a path inside the symlinked/var/folders.In that case a submodule repository opened through the symlinked path
would return a canonicalized
workdir()whileRepository::path()andall paths the caller holds remain in the symlinked namespace, breaking
prefix-based path logic such as
repo.workdir().strip_prefix(parent_worktree_dir).Now the symlink-resolved base is only used when resolving the relative
worktree path against the logical and the resolved git dir leads to
different directories on disk. If both denote the same directory, the
logical path is kept, so all paths of the opened repository remain
consistent with the path it was opened with.
consume open_path_as_is after resolving repository paths
Repository::kind()detects linked worktrees of bare repospass through the allocation limit
This is particularly important in untrusted repositories, which
get a reduced allocation limit.
gix::open()now handlesrepo.gitdirectories correctly.Previously they were incorrectly assumed to be the actual
.gitrepositoryand treated as such.
resolve relative core.worktree from real git dir
Chore (BREAKING)
gix-configMarked as breaking explicitly to as we know paramter types were
changed to use convenience traits.
Commit Statistics
Commit Details
view details
1568b31)319cec2)b1c1cce)5f244b3)cb6ec7d)f0ec710)443b401)31a94aa)2315ede)gix-filter(552402f)02cb162)Repository::normalize_path()(6fe97a9)discover_opts()as sibling toopen_opts().` (2f4c488)e7af50e)271454b)a3e9a77)9949e9f)4d47453)adf4b7a)maybe-asyncwithbisync. (c3f2244)5982dfe)gix-config(6aa934a)e70732a)gix-attributes(e11d7a2)c16b5a1)43ff87a)55b5158)gix-config(582d7b5)402babd)53515b6)299d16b)gix-credentials(f88cf10)cf3053a)d89bda0)27aec47)7056d62)432e2b1)6e1c4a2)f1ac335)6e5a5de)1cda1d1)core.worktree-derived worktree paths in the caller's path namespace (24293fc)d5cd537)1ff51ca)8f8d6ab)b36ca4c)Repository::kind()detects linked worktrees of bare repos (54a3c2a)6d95da6)gix-features, usegix-zlibaccordingly. (9c2977a)e9c973d)d533f0c)dc1fdc3)0052e42)0a5c62a)3e43c42)54b5393)a82b492)32cb1ad)core.fscacheon Windows (158f899)f2dfdd8)7de7a30)d8aeaac)Connection::configured_credentials_for_current_url(). (a5d4616)gix-transport(6a7a717)f77cb0a)gix::open()now handlesrepo.gitdirectories correctly. (9fe1050)c31dac2)596ab93)7e17fcf)a7625fa)1e3da34)1b1541e)v0.85.0: gix v0.85.0Compare Source
Bug Fixes (BREAKING)
avoid duplicate network connection when adopting a remote-controlled hash kind.
Connections can now be created from detached remotes, internally,
which makes them independent of the underlying repository.
This is breaking as it comes with a cleanup of
Connectionlifetimes,which will break anyone who stores them in a struct. So hopefully
nobody is affected.
bound the clone object-hash adoption retry
The clone fetch loop adopts the remote's object format and retries when
it differs from the freshly initialized local repository. Adoption makes
the next iteration's hashes match, but if the reopened repository somehow
still disagrees the loop would re-handshake forever. Track whether we
already retried and fail with IncompatibleObjectHash on a second mismatch
instead. The error variant is introduced here, as this is its only user.
Also silence clippy::never_loop on default (sha1) features, where the
sha256-gated
continueis absent and the loop always returns first pass.New Features (BREAKING)
add leaf-only tree-editor removal via
Editor::remove_leaf()Motivation comes from gitbutlerapp/gitbutler#14312,
where callers had to split tree-entry deletions from additions to avoid
accidentally deleting a newly-added subtree after adding A/one and then deleting
A.
Add Editor::remove_leaf() to gix-object and expose it through gix object tree
editors and cursors. The new API keeps remove() behavior unchanged, remains
tolerant of absent paths, but returns an error when the target entry exists and
is a tree.
Bug Fixes
adopt the remote's object format when cloning
A clone into a freshly initialized repository hit an
unimplemented!panic when the remote used sha256, since the local repository defaults
to sha1.
Reconfigure the still-empty local repository to the remote's object
format and retry the fetch, matching git's behavior of inheriting
the remote's hash on clone.
Without the sha256 feature gix_hash::Kind has a single variant, so the
local and remote hashes can never differ; the mismatch check is compiled
out entirely in that case.
write fetched remote symrefs as direct refs
Previously
gixhad made-up behaviour to 'improve' on standard Git,but it's clear this isn't backed up or tested well enough to be worth
the risk of introducing subtle or not so subtle bugs.
resolve remote HEAD fetches against remote refs
Fetching a local transport remote with a refspec like +HEAD:refs/test/repo could
write a symbolic local ref to the client repository's refs/heads/main when the
remote HEAD was symbolic and the client happened to have a same-named branch.
That made the fetched destination resolve to the local branch instead of the
remote HEAD object.
Add a fetch regression that creates distinct local and remote
repositories with matching HEAD target names but different commits, then fetches
+HEAD:refs/test/repo and asserts the destination is the remote object as a
direct ref.
Match Git behavior observed with the local Git checkout: git fetch
+HEAD:refs/test/repo creates refs/test/repo as the remote HEAD object, and Git's
remote.c resolves symrefs against the advertised remote ref list.
Fix the unmapped remote-symbolic-ref fallback to peel born remote symrefs to
their advertised object id instead of consulting local refs. Mapped symrefs
still rewrite to their corresponding local tracking ref, and unborn remote refs
remain symbolic.
set trust for GIT_DIR environment discovery
A Helix user reported that opening a repository with GIT_DIR set could panic in
gix while discovering a repository through environment overrides. The reported
reproductions used GIT_DIR=.git with Helix or git --git-dir=.git invoking an
editor, and the panic came from open_from_paths() expecting git-dir trust to
have already been determined.
The GIT_DIR override path in open_with_environment_overrides() already
determines ownership trust for the effective git directory and selects options
from the trust mapping, but it did not store that trust in the Options passed to
open_from_paths(). Store the determined trust there, matching discover_opts(),
so configuration loading receives an explicit trust value instead of reaching
the internal expect().
Git baseline:
git --git-dir=<repo/.git> --work-tree=<repo> status --shortexits successfully.reject implicit sha1 repos in sha256-only builds
A missing extensions.objectFormat means legacy Sha1.
In sha256-only builds, Kind::default() is Sha256, so such repos
were silently mislabeled as Sha256.
Resolve the implicit case to Sha1 when supported, else error
out to avoid any mislabeling.
Also reject extensions.objectFormat when repositoryFormatVersion is 0,
matching git, which treats it as an invalid v1-only extension.
handle loose ref path-prefix collisions
The GitButler branch creation flow reported that
repo.try_find_reference("refs/heads/A/new")could fail with a low-levelNotADirectoryerror whenrefs/heads/Aalready exists as a loose ref. Thatlookup is asking whether the longer ref exists; the path-prefix collision
matters to creation/update code, but find should report absence for that
candidate.
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.