NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #1229 most downloaded on crates.io
A crate of the gitoxide project dealing paths and their conversions
Last release 13 days ago
25 Sep 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 43 of 43 stable releases
2 versions withdrawn
withdrawn after publishing
4 years old
45 releases · first in 2023
One column per quarter.
Adjustments due to breaking changes in git_path (`4420ae9`)
gix config with section and sub-section filtering.gix config lists all entries of all configuration files git considers.
Filters allow to narrow down the output.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
Clippy helped 3 times to make code idiomatic.
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
0c597fe)--show-ignore-patterns to gix repo exclude query (09f904b)exclude query (9cb8385)7d98b21)cb56f12)3ff991d)gix repo exclude query (a331314)50ff7aa)gix restructuring (59b95c9)gix config with section and sub-section filtering. (eda39ec)gix config lists all entries of all configuration files git considers. (d99453e)a437abe)8e5b796)5cf08ce)0ed65da)38a8350)72876f1)ac7d99a)c9c78e8)8967fcd)f99c3b2)83585bd)1cdecbc)141c5f1)f4e1810)faaf791)git_path (4420ae9)afecb63)48b3f4a)085e76b)0700b09)89ea12b)0e9df36)229dc91)41ea8ba)05eb340)7cb1972)251b6df)98da8ba)056e8d2)fdec111)4086335)e90d3fd)
</details>locate programs bundled with Git via env::installation_program()
locate programs bundled with Git via env::installation_program()
Expose env::installation_program() so callers can find tools distributed
with Git without knowing where a particular installation stores them. This is
especially needed on Git for Windows, where programs such as Vim live in bin or
usr/bin rather than the directory reported by git --exec-path, and may not be
available through PATH.
Reuse the existing Git for Windows root discovery and accept only bare program
names so lookup cannot escape the known installation directories.
in path::normalize...() skip current-directory components before resolving parent components. Previously, paths like ./../foo would yield foo as they
path::normalize...() skip current-directory components before resolving parent components.
Previously, paths like ./../foo would yield foo as they consumed ., instead of yielding None
or consuming a portion of the CWD.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
ebe9095)f3bbfad)a62774f)gix-testtools (0cbe539)5510bce)path::normalize...() skip current-directory components before resolving parent components. (80e2787)cc3ee80)
</details>increase acceptable timeout for slow CI
normalize_saturating()
That way, one can express another way with which Git handles worktrees.env::shell_command() to get a Git shell.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
ab4fcb0)da71d06)normalize_saturating() (6560a5a)5a88ee7)env::shell_command() to get a Git shell. (6125bc2)ae8845a)96efe08)
</details>add normalize_and_clean() While normalize() is optimised for keeping the look of paths the same, the new function truly wants to normalize.
normalize_and_clean()
While normalize() is optimised for keeping the look of paths the same,
the new function truly wants to normalize.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
f0ec710)02cb162)normalize_and_clean() (5e46d19)c16b5a1)43ff87a)cf3053a)
</details>local clones succeed even if git-upload-pack is not in PATH Local clones spawn the service program, like git-upload-pack, by name and would fail if it
<csr-id-82cdb47c7ac9853e48529b3d8341aa27e28b9df1/> local clones succeed even if git-upload-pack is not in PATH Local clones spawn the service program, like git-upload-pack, by name and would fail if it could not be found in PATH. This is common on Windows, where git can be installed such that git itself is available but its subcommands are not, for instance with scoop.
Now, when spawning the service program for a local repository fails because it cannot be found, find the same program in the directory that git --exec-path reports - the location git itself uses to run its subcommands - and run it from there. If it cannot be found there either, run the git binary that is always findable with the service as its subcommand, which it can always dispatch.
Remote transports are unaffected - they keep the standard invocation so servers can provide their own implementations - and no shell is involved in any of this.
The newly added gix_path::env::core_dir_program() provides the lookup and may serve other Git-provided programs in the future.
Git for Windows builds with SKIP_DASHED_BUILT_INS and thus does not provide programs for builtin subcommands like git-upload-pack in its core directory. The test now grounds itself in a listing of that directory instead, and the documentation of core_dir_program() points out the difference - such programs are still run through git itself thanks to the second fallback.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
82cdb47)27aec47)9884f48)151a0af)19bdf8a)7ef83ca)d5f3723)f7d4f33)
</details>6 commits contributed to the release over the course of 28 calendar days.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
10c58bb)ab2fee1)2cb17b2)e10d5f6)3675a8d)adb8328)
</details>preserve validation classifications after error conversion
ValidationError marker from reference, tag, submodule,gix::Error, including optional reference lookups.raise MSRV to Rust 1.88
The newly published dua-core 3.3 release used by linked-worktree removal
requires Rust 1.88, so raise every workspace crate and the advertised badge
together.
Keep the MSRV checks buildable by selecting the latest sysinfo and rusqlite
release lines that support Rust 1.88.
gix repo commit describe
It supports typical but basic flags mostly similar to the ones in git.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
<csr-id-91c854e7b9f41738d0fde825cd474b8c00c1a49b/> remove winnow and replace it with hand-implemented parsers everywhere.
This will allow for simplified maintenance and editing (both human and machine)
down the road, and enable additional performance optimisations.
Parser compbinators to me ultimately were a failed experiment as I couldn't maintain them anyway, with it being too difficult for me to grasp and express everything in its very own kind of language, with a lot of different things to consider.
Note that this also removes detailed errors from all parsers that previously
used winnow, with the option to re-add those if there is demand.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
53f880c)winnow and replace it with hand-implemented parsers everywhere. (91c854e)4d5ba23)
</details>add WASI (wasm32-wasip2) platform support Add compilation support for the wasm32-wasip2 target across four crates:
wasm32-wasip2 target across four crates:<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
f9fbcba)444a92b)package.include patterns more specific so they don't match ignored files (c2c917f)44020e0)9d04035)29c275e)b1102c2)fb0f694)ce9dcd7)915139f)98bae84)
</details>4 commits contributed to the release.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
c389a2c)6183fd0)6bdb331)9327b73)
</details>4 commits contributed to the release over the course of 19 calendar days.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
d66ac10)8bceefb)7ce3c55)f7d0975)
</details>Adapt to changes in gix-features which change Send + Sync to Send + Clone. This happens to allow non-sync implementations (i.e. thread-local), along w
<csr-id-4d2d433e7e98ac42db858688edac06e68ee4d10d/>
Adapt to changes in gix-features which change Send + Sync to Send + Clone. This happens to allow non-sync implementations (i.e. thread-local), along with Sync ones
which usually are Clone too as they are passed by immutable reference (which is Clone + Copy).
Option<impl Progress> in favor of impl ProgressArc around should_interrupt flagindex::verify::Mode::* variants
The hash is repository defined and not hard-codedgix mailmap verify commandein find --debug to learn why it is slow<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
6e0cd6d)bcde935)89428b2)c4c5678)d2bea27)Option<impl Progress> in favor of impl Progress (bf04644)Arc around should_interrupt flag (d851bed)index::verify::Mode::* variants (c2679a0)d04dc01)1ac2c21)34ea001)9277cf8)239e7b2)8bf585d)3fc1622)a8fa53a)07e9081)8cbe85d)89b628a)6c10e09)21c2dd5)e6a3d43)613483b)73a7393)29fb0c8)0e55fbb)a39d476)5388d80)5494fb3)f23b8d2)e90c123)25da30f)0090961)7cf3545)652a0ac)90c6c5a)ein find --debug to learn why it is slow (70109be)aa51e05)ad3c803)025f157)866530a)d6a72e7)338521b)7d2e20c)b0f7328)
</details><csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
562e684)
</details>use std::home_dir() and remove the home crate from dependencies.
std::env::home_dir() and remove the home crate from dependencies.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
std::env::home_dir() and remove the home crate from dependencies. (77e485d)82ff92f)cbb73ea)3313233)
</details>It may therefore be left over from a previous installation or migration, or even created by a local user as in the CVE-2024-40644 scenario patched in…
<csr-id-7e77d40fcae8dbca42459c42a1aacea2906a630c/> Extend ALTERNATIVE_LOCATIONS for per-user installations
When git is not found in a PATH search on Windows, common
locations where Git for Windows is often installed are checked.
But only systemwide installations had been checked before.
This extends the locations examined to include the current user's
own program files directory. This directory, if present, is
expected to be the Programs subdirectory of the user's local
application data directory, typically:
C:\Users<user>\AppData\Local\Programs
When Git for Windows is installed for a user rather than
systemwide, it is typically installed a Git subdirectory of that
Programs directory (much as it is typically installed in a Git
subdirectory of a directory such as C:\Program Files when
installed systemwide). This looks for a suitable Git for Windows
directory tree at such a location.
It is possible for Git for Windows installations to be present both in the current user's own program files directory and systemwide. If that happens, such that both kinds of installations are able to be found, then we choose the per-user installation.
This is based on the idea that an individual user may choose to install a newer or otherwise different version of Git for Windows, or that a developer may even test out a custom build by manually placing it in that directory. Because, in either case, the architecture of the Git for Windows executable may differ from what is currently installed systemwide or even from what is typically preferred, we will attempt to use a per-user build of any of the architectures Git for Windows has published, before then using the systemwide installations as done before.
Although the user program files directory is under the local rather than roaming application data directory, and is thus not shared across machines on a domain, it is possible that some techniques of backing up and restoring data may restore a per-user installation of Git for Windows that is for a different machine architecture that cannot run, or that the user would not want to be used. In that case, this enhancement may actually break something that was working before.
That seems fairly unlikely to occur, and it can be worked around by
making a git command available in a PATH search. Nonetheless,
if this is found to happen in practice, then further refinement of
the ALTERNATIVE_LOCATIONS enumeration order may be warranted.
<csr-id-2d2c11b50edb429cb9da62dd185e50d47bc1afd2/> Extend EXEPATH optimization to support ARM64 Windows
On Windows, the gix_path::env::system_prefix() function has two
strategies. The first is an optimization that doesn't always work,
where the EXEPATH environment variable is consulted. In Git Bash,
this variable is usually available, pointing somewhere into the
Git for Windows installation. Most commonly, but in practice not
universally, it points to the top-level directory of the Git for
Windows installation. system_prefix() on Windows looks for a
subdirectory of this directory that is named for one of the MSYS2
environment https://www.msys2.org/docs/environments prefixes, of
those Git for Windows has builds for. (Otherwise, it falls back to
traversing to such a location upward from what git --exec-path
reveals, which is often slower as git must sometimes be run.)
However, this EXEPATH optimization had only checked for the
mingw64 and mingw32 environment prefixes. This was ideal
before ARM64 builds of Git for Windows were released. But since
then, it is useful to allow the clangarm64 environment prefix
as well, to allow the EXEPATH optimization to work on ARM64
builds of Git for Windows. This makes that change.
<csr-id-1fa24cd9380cf063aa1a29e01136282ac3bc92c3/> <csr-id-b24783accba4bdd39c0821564060a3b4f3745903/>
<csr-id-9000a848cfd94fcb20f0c07b3c366fc55fa4eb3c/> Don't use EXEPATH unless it is absolute
The first of two strategies used by the system_prefix() function
on Windows is an optimization that looks for clangarm64,
mingw64, or mingw32 subdirectories of a directory whose path is
given by the value of the EXEPATH environment variable. If
EXEPATH is absent, can't be interpreted as a path, or can be
interpreted as a path but does not point to a directory that can be
verified to contain such a subdirectory, then this optimization was
already being skipped and the more reliable but sometimes slower
git --exec-path-based method used.
However, when EXEPATH contains a relative path, including in the
case where it is an empty string (which could be set by accident or
if it is being used with some meaning other than what we and Git
for Windows recognize), then it was still used, even though that
would not usually be correct and would sometimes not be safe.
Although an attacker is not expected to be able to control the
value of EXEPATH (nor most environment variables), a value such
as an empty string would cause clangarm64, mingw64, and
mingw32 subdirectories of the current directory to be used.
A user might intentionally set EXEPATH to a relative path to
leverage the EXEPATH optimization of system_prefix() with that
path. But EXEPATH is a short variable name with many plausible
meanings that is not named with a distinctive prefix such GIT_ or
GIX_. So it would not be a good tradeoff to continue recognizing
it for system_prefix() anytime it is non-absoliute.
Thus, as a stability fix and possible security enhancement, this
adds a check that the value of EXEPATH is an absolute path before
proceeding with the EXEPATH optimization.
<csr-id-5ac8cffb16bcbda3ff53513671d533b33bd35a4f/> Skip EXEPATH optimization if it finds no best path
The EXEPATH optimization for gix_path::env::system_prefix() on
Windows previously tried https://www.msys2.org/docs/environments
prefixes used by Git for Windows, returning a successful result on
the first subdirectory found. However, if EXEPATH points to a
directory that contains more than one such subdirectory, then the
subdirectory returned would not necessarily be the correct one.
Getting more than one subdirectory is unlikely. It is expected that
at most one of clangarm64, mingw64, and mingw32 will be
present. However, there are at least three ways it could happen:
EXEPATH has the intended meaning as the root of a Git for
Windows installation, but the directory it refers to contains
multiple directories left over from a previous installation. A
corresponding scenario applies to ALTERNATIVE_LOCATIONS, but
it is resolved by checking all the directories in a reasonable
order. Here, we are not checking the contents of the directories,
so no matter what order we look for them in, picking one when
there are others risks picking the wrong one.EXEPATH has the intended meaning as the root of a Git for
Windows installation, but it is a custom installation produced
from local build or custom distribution rather than an official
build, and it contains multiple such directories because it
carries binaries built against more than one of the targets (even
if only one of them has git itself). A corresponding scenario
is fairly unlikely for ALTERNATIVE_LOCATIONS, because a custom
MSYS2 tree, even if created using the Git for Windows SDK, would
probably not be installed in one of the common Git for Windows
installation locations, without considering the effects of doing
so. In contrast, EXEPATH will often be set in a Git Bash
environment even in a highly customized Git for Windows tree.
EXEPATH has a different meaning from what is intended. For
example, the user might set it to the root of an ordinary MSYS2
installation. (Note that it is also likely to have various other
meanings even more different from these, but those won't likely
cause the EXEPATH optimization to be used when it shouldn't,
because most possible meanings of EXEPATH won't involve a
subdirectory of any of the names we look for.
To limit production dependencies and code complexity, we have been examining only environment variables (and information available at build time) to ascertain which program files directories exist and whether they are 64-bit or 32-bit program files directories. At least for now, this preserves that general approach, continuing not to explicitly call Windows API functions or access the Windows registry, other than in tests.
But determining from environment variables whether the system is ARM64 or x86_64 is less straightforward than determining the program files directory locations, in one major case as well as various edge cases.
That process should make available all of the ProgramFiles,
ProgramW6432, ProgramFiles(x86), and ProgramFiles(ARM)
variables that exist in its own environment.
(This is because, on 64-bit Windows, the child ProgramFiles is
populated from the parent ProgramW6432, ProgramFiles(x86), or
ProgramFiles(ARM), depending on the architectures of the parent
and child, if the parent passes down the relevant variable.)
Even if the parent/ancestor is not designed with the WoW64 rules
in mind, it will likely pass down at least ProgramFiles.
This will then be used as the child ProgramFiles, if whichever
of ProgramFilesW6432, ProgramFiles(x86), or
ProgramFiles(ARM) is relevant is not passed down by the parent.
In contrast, the parent/ancestor may omit the variables
PROCESSOR_ARCHITECTURE and PROCESSOR_ARCHITEW6432, which are
not obviously needed for locating programs.
In and of itself, this is not necessarily a problem, because on ARM64 Windows, at least one of the two will still be set automatically. (Even if the parent process runs us with an explicitly empty environment, we will get one of these, on ARM64 Windows.)
However, in this case, as in others, it will generally be set according to our process architecture, rather than the system architecture.
Thus, even if PROCESSOR_ARCHITE* variables are preserved or set
correctly, there are common cases where they are not sufficient.
The main such case is when we are an x86_64 build, but the system
is ARM64, and Git for Windows is ARM64. gix-path is a library
crate, and it will sometimes to be used in an x86_64 program on
such a system.
Also, if gix-path is used in an Arm64EC program, then even
though its code may be ARM64 with the arm64ec-pc-windows-msvc
Rust target, the program would still be treated as an x86_64
program in its interactions with the system and other programs,
including in how its environment variables' values are populated
and how their values are affected by WoW64.
(gix-path may also be x86_64 code where the program is Arm64EC.
One way this happens is if gix-path is used in an x86_64 DLL,
and an Arm64EC program loads the DLL. Using x86_64 DLLs from
ARM64 code is one of the reasons a program may target Arm64EC.
In this case, the Rust target will be for x86_64, not ARM64 or
Arm64EC. So checking our own Rust build target can't fully check
if the program is Arm64EC.)
Although the PROCESSOR_IDENTIFIER variable is more reliable if
present--see actions/partner-runner-images#117 for an example of
where this is more reliable than PROCESSOR_ARCHITECTURE--it is
slightly more complex to parse. Much more importantly, unlike
PROCESSOR_ARCHITE*, the PROCESSOR_IDENTIFIER variable is not
set automatically in a child process whose parent/ancestor has
removed it. Whether or not a parent/ancestor passes down
PROCESSOR_ARCHITE* variables, it may still not choose to let
PROCESSOR_IDENTIFIER through, if it sanitizes the environment.
It would sometimes work to look for ProgramFiles(ARM). This
environment variable, if present, gives the 32-bit ARM program
files directory location on an ARM64 Windows system. If set, then
the Windows system could be treated as ARM64. However, a
parent/ancestor process may omit this even when passing down
program files related environment variables, including
ProgramFiles(x86). It may do so because the ProgramFiles(ARM)
environment variable is less well known. Or it may omit it
intentionally, if the parent process is only passing down
variables needed to find Git for Windows, for which one shouldn't
need to know the 32-bit ARM program files directory location,
since Git for Windows has never had 32-bit ARM builds.
Relatedly, augmenting the search by checking the filesystem for a
sibling (or hard-coded) directory named Program Files (ARM)
should not be done, because this directory has no special meaning
outside of ARM64 Windows. It may therefore be left over from a
previous installation or migration, or even created by a local
user as in the CVE-2024-40644 scenario patched in #1456.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
89fb308)4da2927)6cc8464)9365cc3)838ff95)2fffc50)ALTERNATIVE_LOCATIONS for per-user installations (7e77d40)known-folders usage to windows (082e22e)SHGetKnownFolderPath call (998fb48)UserProgramFiles with KF_FLAG_DONT_VERIFY for test (1c7a34e)c9ff0ac)cab4c85)9e71d55)e365244)PlatformBitness::current() (1f3edb5)eec407f)edc0f3c)locations_under_program_files_* assertions (35beea1)fd000f5)c2c8c2f)EXEPATH unless it is absolute (9000a84)EXEPATH doesn't trigger the optimization (f4bb773)84f9672)EXEPATH doesn't trigger the optimization (24c11ac)EXEPATH optimization if it finds no best path (5ac8cff)EXEPATH optimization to support ARM64 Windows (2d2c11b)d5f4c9f)EXEPATH optimization of system_prefix() (2b0639b)system_prefix() Windows strategies to helpers (3b304fa)expect() message in test helper (571ca6e)PlatformArchitecture helper PlatformBitness (5bf265b)rules loop in locations_under_program_files (2c6dcb2)rules loop in locations_under_program_files (d06b89d)ALTERNATIVE_LOCATIONS for ARM64 Windows (1fa24cd)4662233)ff3df53)e9770a7)gix_path::env::git comments (8d2c262)nul instead of NUL on Windows (b24783a)202bc6d)
</details>A maintenance release without user-facing changes.
A maintenance release without user-facing changes.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
d64f257)5e0122d)473fe52)428412c)784c046)
</details>6 commits contributed to the release over the course of 65 calendar days.
<csr-id-45b369c65e7d36d42c8250b020ea5523615046e3/>
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
normalize() documentation (45b369c)5a919c4)65037b5)dab97f7)a9a8ea1)c3f06ae)
</details>A maintenance release without user-facing changes.
A maintenance release without user-facing changes.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
Clippy helped 1 time to make code idiomatic.
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
d2b4c44)gix-index (bfc4880)28935a5)dbf65c9)8d4c4d1)
</details>3 commits contributed to the release.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
e104545)5f7f805)631f07a)
</details>Add &gix_path::RelativePath. It's a utility to assure functions get the right input, i.e. a type-safe version of what previously was &BStr
&gix_path::RelativePath.
It's a utility to assure functions get the right input, i.e. a type-safe
version of what previously was &BStr<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
cc5b696)49fa9f3)db0b095)0bf84db)3b1bef7)c3c6504)fdc06b1)294902e)&gix_path::RelativePath. (9f8a468)b5e9059)gix-path tests to changes in windows (2fc48a1)68e6b2e)420e730)
</details>Check prefix and prefer shim in gix_path::shell() This makes a few changes to make shell() more robust:
<csr-id-028635165ddd98322d8b902fe0714fe2d0699a3e/>
<csr-id-10af2d005fbe92a289be01492206c6e8a38ab0bd/>
<csr-id-1f269b0d5aa958f25423db1f83d144781bf22024/> Check prefix and prefer shim in gix_path::env::shell()
This makes a few changes to make shell() more robust:
git --exec-path
gave, to make sure they are libexec/git-core.Check the grandparent component (that ../.. would go to) of
the path git --exec-path gave, to make sure it is recognized
name of a platform-specific usr-like directory that has been
used in MSYS2.
This is to avoid traversing up out of less common directory trees that have some different and shallower structure than found in a typical Git for Windows or MSYS2 installation.
Instead of using only the (git root)/usr/bin/sh.exe non-shim,
prefer the (git root)/bin/sh.exe shim. If that is not found,
fall back to the (git root)/usr/bin/sh.exe non-shim, mainly to
support the Git for Windows SDK, which doesn't have the shim.
The reason to prefer the shim is that it sets environment
variables, including prepending bin directories that provide
tools one would expect to have when using it. Without this,
common POSIX commands may be unavailable, or different and
incompatible implementations of them may be found.
In particular, if they are found in a different MSYS2
installation whose msys-2.0.dll is of a different version or
otherwise a different build, then calling them directly may
produce strange behavior. See:
This makes things more robust overall than either preferring the
non-shim or just doing a path search for sh as was done before
that. But it exacerbates #1868 (as described there), so if the
Git for Windows sh.exe shim continues to work as it currently
does, then further improvements may be called for here.
Adding components with / separators. While in principle a \
should work, the path of the shell itself is used in shell
scripts (script files and sh -c operands) that may not account
for the presence of backslashes, and it is also harder to read
paths with \ in contexts where it appears escaped, which may
include various messages from Rust code and shell scripts.
The path before what we add will already use / and never \,
unless GIT_EXEC_PATH has been set to a strange value, because
it is based on git --exec-path, which by default gives a path
with / separators. Thus, ensuring that the part we add uses /
should be sufficient to get a path without \ in all cases when
it is clearly reasonable to do so. This therefore also usually
increases stylistic consistency of the path, which is another
factor that makes it more user-friendly in messages.
This is needed to get tests to pass since changing gix-command
to use gix_path::env::shell() on Windows, where a path is
formatted in away that sometimes quotes \ characters. Their
expectations could be adjusted, but it seems likely that various
other software, much of which may otherwise be working, has
similar expectations. Using / instead of \ works whether \
is expected to be displayed quoted or not.
Check that the path to the shell plausibly has a shell there, only using it if it a file or a non-broken file symlink. When this is not the case, the fallback short name is used instead.
The fallback short name is changed from sh to sh.exe, since
the .exe suffix is appended in other short names on Windows,
such as git.exe, as well as being part of the filename
component of the path we build for the shell when using the
implementation provided as part of Git for Windows.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
Clippy helped 1 time to make code idiomatic.
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
b41312b)38dff41)7b17da6)01bd76d)0ba3147)b70cdb1)git_for_windows_root() comments (c824b92)fb67059)find_git_associated_windows_executable future directions (56dc3cc)gix_path::env::auxiliary helpers (17b5c31)0a6a056)bd26745)9d9ec58)shell() helpers to a helper module (0b75b23)libexec/git-core in usr; refactor (83574e1)gix_path::env::shell() (1f269b0)gix_path::env docstrings for clarity (da7d70e)/ in gix_path::env::shell() and check existence (10af2d0)16a248b)8e96ed3)ad7a94e)bb64ee1)to_unix_separators{,_on_windows} relationship (42875c9)to_windows_separators docstring, revise others (0286351)path-slash to handle escapes (a810d1f)8df0db2)
</details>Note that this is not marked as breaking change as no release was made with the old name yet.
<csr-id-17835bccb066bbc47cc137e8ec5d9fe7d5665af0/>
env::core_dir()env::git_shell() to obtain the shell Git would be using.
This is particularly useful to execute Git hooks.<csr-id-51bbb8646287f0a6dfa9ff0fd3852c25e001aaf0/> rename env::login_shell() to shell() and explain what it is.
This assures we don't suggest the usage of actual login shells to ever
be used to execute hooks.
Note that this is not marked as breaking change as no release was made with the old name yet.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
dea106a)1f6390c)7ec21bb)rust-version to 1.70 (17835bc)851a7c4)5400320)sh.exe on Windows (0737c41)env::core_dir() (73ee27a)env::login_shell() to shell() and explain what it is. (51bbb86)1ca480a)env::git_shell() to obtain the shell Git would be using. (840c71d)4ef3a8d)e8b3b41)
</details>A maintenance release without user-facing changes.
A maintenance release without user-facing changes.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
8ce4912)bc9d994)7a40648)0f0e4fe)db5c9cf)
</details>…disadvantages. This is most likely a non-breaking change.
<csr-id-64ff0a77062d35add1a2dd422bb61075647d1a36/>
<csr-id-eb72d31a64b5041170e5903c328b246dab522067/> Don't read "installation" config from GIT_CONFIG
When gix-path runs git config -l ... to obtain the path of a
configuration file to regard as being associated with the git
installation itself, it now no longer allows GIT_CONFIG to affect
this path.
Previously, setting GIT_CONFIG would treat it as the path of a
GitInstallation configuration file. Although it is possible that
this may have been used intentionally, it was never documented, did
not work reliably on all platforms, and carried significant
disadvantages. This is most likely a non-breaking change.
The disadvantages of treating a path in GIT_CONFIG as the path
to a configuration file associated with the git installation
were:
git, the GIT_CONFIG environment variable only affects
git config commands, and not other commands that use
configuration variables (which are most git commands). But when
gix-path would obtain a path from git config -l ... that came
from GIT_CONFIG, that configuration file would be used
anywhere, and not only gix config commands.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
3f7e8ee)795962b)64ff0a7)ab8880f)git_cmd (1526b01)130db3b)GIT_CONFIG (eb72d31)never_from_git_config_env_var test (f8e38d0)GIT_CONFIG (340ff37)GIT_DIR related env vars in git config -l (01a412f)93e86f1)
</details>If the git command is an old and unpatched vulnerable version in which safe.directory is not yet implemented, or in which https://github.com/git/git/s…
<csr-id-7280a2d2f8b55a594ae134dd9a0a7a1668b7b56c/> <csr-id-650a1b5cf25e086197cc55a68525a411e1c28031/>
<csr-id-f70b904bc520b2962dd2a77c035b6d9c47bb1cb8/> Don't require usable temp dir to get installation config
When running git config -l ... to find the configuration file
path associated with the git installation itself, the current
working directory for the subprocess was set to the current
directory prior to #1523, and to /tmp or a /tmp-like directory
since #1523 (which improved performance and security).
This builds on #1523, as well as on subsequent changes to run git
in a way that its behavior depends less on its CWD, by making an
even more robust choice of CWD for the subprocess, so that the CWD
is less likely to be deeply nested or on network storage; more
likely to exist; and, on Unix-like systems, less likely to contain
a .git entry (though a git with security updates should refuse
to take any configuration from such a repository unless it is owned
by the user).
Due to a combination of other measures that harden against
malicious or unusual contents (especially setting GIT_DIR), the
most significant benefit of this change is to fix the problem that
a nonexistent temp dir would prevent the command from succeeding.
The main way that could happen is if TMPDIR on Unix-like systems,
or TMP or TEMP on Windows, is set to an incorrect value.
Because these variables are sometimes reasonable to customize for
specific purposes, it is plausible for them to be set to incorrect
values by accident.
Except on Windows, this always uses / as the CWD for the
subprocess.
On Windows, we use the Windows directory (usually C:\Windows)
rather than the root of the system drive (usually C:\), because:
The user profile directory may be more deeply nested.
The user profile directory may sometimes be on slow network storage when the discovered Windows directory is not.
In some situations, the user profile directory does not actually exist, or does not exist yet.
Overly sanitized environments are more likely to lack the
USERPROFILE vairable than the SystemRoot variable.
Users may occasionally choose to have their entire user profile directory be a Git repository.
It's no easier to avoid the problem of using C:\.git in a user
profile directory than in C:\Windows: they're usually both under
C:\, and are both not the same as C:\. (If the user profile
directory is a repository, then that will avoid that problem, yet
be its own problem, if not for other measures that prevent both.)
If the git command is an old and unpatched vulnerable version
in which safe.directory is not yet implemented, or in which
https://github.com/git/git/security/advisories/GHSA-j342-m5hw-rr3v
or other vulnerabilities where git would perform operations on
untrusted local repositories owned by other users are unpatched,
then a .git subdirectory of a shared /tmp or /tmp-like
directory could be created by another account, and its local
configuration would still have been used. (This is not a bug in
gitoxide per se; having vulnerable software installed that other
software may use is inherently insecure. But it is nice to offer
a small amount of protection against this when readily feasible.)
If the /tmp-like location is a Git repository owned by the
current user, then its local configuration would have been used.
https://github.com/dotnet/docs/issues/41193
https://github.com/python/cpython/pull/95486#issuecomment-1881469554
https://github.com/python/cpython/pull/95486#issuecomment-1882134234
Parsing is more reliable for paths containing unusual characters,
because -z/--null causes all paths to be output literally.
Previously, " characters were trimmed from the ends, but this
would not always extract a correct path, because when a path
contains characters that cause git to enclose it in double
quotes, those characters are usually represented in a symbolic
form, usually with \ escapes.
In some scenarios, such as usually on Windows when the escaped
character is itself a \ and not in the leading position, the
mangled path would be usable, but more often it would not.
The volume of output is less, because --name-only casues values
not to be included in the output.
The combination of -z/--null and --name-only makes the
output format simpler, and the parsing logic is accordingly
simpler.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
012a754)c759819)3cf9694)GIT_HIGHEST_SCOPE_CONFIG_PATH (0672576)adbaa2a)EXE_INFO to something that probably captures its contents better. (dd2d666)cargo fmt (b11f7db)EXE_NAME a const too (fb0b6d8)NULL_DEVICE a const, rather than a static item (9917d47)first_file_from_config_with_origin test with related ones (57e9a6f)7cd20bb)dd65e7b)exe_info tests (5ac5f74)git from (5200184)6160a83)2bce0d2)073e277)4e936bc)8f6d39d)b827813)git from a different directory (7fa5e35)598c487)os::windows error on non-Windows (1305114)ab0dcc1)8472447)f70b904)--system (29c6cca)--show-scope (f35e44c)15e7b67)c80d562)e60540f)56dab13)5c1b4c0)env::temp_dir() in both tests that set temp vars (79af259)703f882)60465a5)9641660)5723077)7280a2d)env::temp_dir() as desired (15cec4e)744bb38)287f267)65d5151)49e0715)fd065ac)5a300e6)1ee98bf)ccd0401)de2f35f)650a1b5)9df57aa)649f588)beba720)37ba461)2e0ce50)f992fb7)ec69c88)
</details>A maintenance release without user-facing changes.
A maintenance release without user-facing changes.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
d19af16)0f25841)83c9de0)--system from git config call as it fails on MacOS (6b1c243)git config -l in temp dir when looking up system config (20ef4e9)e2c747d)087594c)
</details>Don't assume program files folder locations This checks where *program files* directories are located on a Windows system, which are used for a fallba
<csr-id-15235bf7968042da0493d431bbc955d6f9f54188/> Don't assume program files folder locations
This checks where program files directories are located on a
Windows system, which are used for a fallback check after git
has not been found in a PATH search (to invoke git to find out
information such as the location of its system config file).
Previously, two hard-coded paths were used. These were correct for the vast majority of 64-bit Windows systems, but were in practice never correct on 32-bit Windows systems. Checking programmatically for the locations should thus enable detection to succeed on more systems and under more circumstances, and avoid other problems.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
15f1cf7)ffe6b60)73ed340)test::loc's use statements up (dd53408)dea1746)expect messages (76e3b28)464e0a2)super:: in non-Windows alternative_locations test (8ae54e8)15235bf)98db88b)d254e62)e990bcd)de7c49f)4d98535)c8b2eb3)Git component in the suffixes (1f0c3bf)00127a7)df175bc)mingw*/bin subdirs (c486a7d)167dc14)e9eabeb)671c476)5258f7a)ALTERNATIVE_LOCATIONS count and prefixes (dd1e5c8)3dd1d1f)95708dd)5701145)518fd27)5df0cf5)a5a5342)99a8eb3)5b206bc)edc1351)6af59ca)98b3d90)9eaa0d9)
</details>provide env::executable_invocation() to know how to invoke Git. That way we can make it easier to rely on Git even if finding it is a bit more involve
env::executable_invocation() to know how to invoke Git.
That way we can make it easier to rely on Git even if finding it is a bit
more involved.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
A maintenance release without user-facing changes.
A maintenance release without user-facing changes.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
b050327)52c3bbd)3e5c974)f8ce3d0)
</details>add relativize_with_prefix(). With it, a path 'a' with prefix 'b' will be '../a'.
relativize_with_prefix().
With it, a path 'a' with prefix 'b' will be '../a'.try_os_str_into_bstr(), with Cow<OsStr> as input.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
45b4470)f2e111f)bb48c4c)relativize_with_prefix(). (9ba8bca)face359)try_os_str_into_bstr(), with Cow<OsStr> as input. (c8ccbe5)
</details>always try HOME environment variable first when obtaining the home directory. This will fix issues like the one described here:
HOME environment variable first when obtaining the home directory.
This will fix issues like the one described here:<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
prevent very long path from using unbounded time in realpath(). It's possible to inject such paths using urls which can then end up being canonicalize
<csr-id-8d4bf403aecbe16ad2f4083f40c504c6fc4d7eab/> prevent very long path from using unbounded time in realpath().
It's possible to inject such paths using urls which can then end up
being canonicalized, causing very long runtimes with excessively long
paths due to is_symlink calls which will be slow.
Now the amount of components is limited to 4096/2, which should be a worst-case path at the border of realistic.
If this limitation becomes too arbitrary, one could consider making this cut-off value configurable.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
eb6aa8f)6a2e0be)db86fba)realpath(). (8d4bf40)5d176fc)gix_fs::current_dir(precompose_unicode). (7d8d167)b6c04c8)
</details>4 commits contributed to the release.
<csr-id-3bd09ef120945a9669321ea856db4079a5dab930/>
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
972241f)8c492d7)home to pass MRSV checks (e6706f2)rust-version manifest field back to 1.65. (3bd09ef)
</details>4 commits contributed to the release.
<csr-id-aea89c3ad52f1a800abb620e9a4701bdf904ff7d/>
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
e1aae19)e78a92b)4454c9d)aea89c3)
</details>safely split commands and ignore shebang options
safely split commands and ignore shebang options
Command preparation previously rejected every first word containing an equals
sign, so valid environment prefixes required a shell while executable names
such as tool=name could be misinterpreted as assignment-only commands. Its UTF-8
conversion also made the direct-versus-shell decision depend on encoding.
Git for Windows uses only the interpreter path from a shebang. Parsing the
suffix as shell words invented incompatible semantics and could let executable
contents supply additional interpreter options.
This provides two major fixes:
Reuse the parser in gix-diff and cover its full byte-input domain with focused
unit tests and a dedicated fuzz target.
Store the required command in Outcome::command, reserve Outcome::args for
actual arguments, and reject command lines that produce no executable. Command
preparation can now consume the parser result directly without another emptiness
check or first-element extraction.
The command-line parser is consumed primarily by process-launch code, yet it
returned byte strings that every caller had to convert before constructing
std::process::Command.
Return OsString for the required command and its arguments so callers can use
them directly while preserving arbitrary Unix bytes. Reject values that the host
cannot represent instead of risking a conversion panic; environment assignments
remain byte-oriented for parsing.
Manual argument splitting moved leading assignments into the process environment
and spawned the parsed program directly. On Windows, Rust's lookup can fall
outside the assigned PATH and cannot launch extensionless scripts through their
shebang.
Keep assignment-prefixed commands on the shell path on Windows while retaining
manual splitting for other commands and platforms.
invoke existing absolute paths directly
Shell detection treated metacharacters in every command as evidence that a
shell was needed. This caused resolved executable paths, notably Git for Windows
programs under Program Files, to be parsed as command text and split at spaces.
Recognize existing absolute files as already-resolved programs and bypass shell
detection for them.
Requiring an absolute path avoids promoting a relative path that happens to name
a file in the repository to a program and accidentally executing it.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
bc44497)55d386a)d3dcbe5)c372321)c0e72fb)b65a80b)
</details>This release pins beta versions of clap to avoid it to automatically fetch the latest one during installation.
This release pins beta versions of clap to avoid it to automatically fetch the latest one
during installation.
This is made possible due to clap itself pinning its dependency
to the clap-derive crate.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
dyn trait where possible.
This reduces compile time due to avoiding duplication.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
8bd0456)375db06)dynification (f658fcc)dyn trait where possible. (072ee32)363ee77)
</details>A first usable version of gix to make using gitoxide from your applications so much easier. It serves as a one-stop shop for application developers wi
A first usable version of gix to make using gitoxide from your applications so much easier. It serves as a one-stop shop for application developers without sacrificing performance by default while making common use-cases more convenient.
gix as hub crate for application development with focus on usability without sacrificing any knob to tune performance.async for gix-packetline, gix-transport and gix-protocol for fully async git clients, along with the light-async feature toggle to build a gix pack-receive with an async client instead of a blocking one.gix pack-create with the -s/--statistics flag to have data indicating the cost of the operation. Currently it's doing a lot of work that has to be avoided in order to be useable in production and the numbers underline that. Future iterations will cause key metrics to go down.gix-tempfile crategix-lock crategix-ref crate with complete loose-ref, packed-ref and transaction support.git.gix-object parsing is a few percent faster thanks a reworked error handling for objects. By default, error collection is disabled entirely making the error case zero-sized. If needed, verbose and stacked errors can be turned on using a feature toggle for applications who expect repositories with malformed objects and need detailed diagnostics.<csr-read-only-do-not-edit/>
<csr-id-229bd4899213f749a7cc124aa2b82a1368fba40f/> <csr-id-5b5983a9686e9fe61a29e9e1b9e905cd4dbd296a/>
Spec type in favor of gix-pathspec::Pattern.
The latter isn't included to keep concerns and crates separate.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
30b2761)f23ea88)229bd48)9f4dfe0)Spec type in favor of gix-pathspec::Pattern. (df83d74)normalize() does not touch duplicate path separators nor single .. (5b5983a)
</details>This is a maintenance release.
This is a maintenance release.
A maintenance release without user-facing changes.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
16295b5)5cb3589)2fc66b5)9064ea3)
</details>1 commit contributed to the release over the course of 8 calendar days.
<csr-read-only-do-not-edit/>
A maintenance release without user-facing changes.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
1 commit contributed to the release over the course of 1 calendar day.
<csr-read-only-do-not-edit/>
<csr-id-bcad5c22049d56a25ef69d6c7a3344e78f9a1d4d/>
tracing spans for common operations.
This is just the beginning and more crates will integrate with it over time.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
ea9f942)18b0a37)aa16c8c)2ab69c6)4f635fc)tracing spans for common operations. (3cffa26)fe59956)clippy::redundant-closure-for-method-calls lint (bcad5c2)
</details>42 commits contributed to the release over the course of 95 calendar days.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
Clippy helped 1 time to make code idiomatic.
A maintenance release without user-facing changes.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
9a9fa96)8f15cec)dbf8aa1)3ef5c90)9375cd7)b057500)facaaf6)
</details>A maintenance release without user-facing changes.
A maintenance release without user-facing changes.
home_dir() to env::home_dir() and env_var() to env::var().
Please note that this change was previously and erroneously not declared as breaking.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
7ebc9f7)0135158)43ebaf2)home_dir() to env::home_dir() and env_var() to env::var(). (94564df)
</details>YANKED due to accidental breaking changes.
YANKED due to accidental breaking changes.
join_bstr_unix_pathsep(base, component).
It's useful to have to avoid certain conversions to happen otherwise.xdg_config_home(), installation_configandinstallation_config_prefix()` functions.join_bstr_unix_pathsep() works more suitably if base path is empty.home in env::home_dir()home in env::home_dir().
This way it should work better on windows as it now uses the home_dir implementation
of a crate used by cargo.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
91134a1)30a1a71)f37a930)join_bstr_unix_pathsep() works more suitably if base path is empty. (bd1ae0d)3456c84)join_bstr_unix_pathsep(base, component). (1e73f3c)74cb5ee)home in env::home_dir() (13edfe9)home in env::home_dir()." (222ece2)5092c59)home in env::home_dir(). (ec049fe)5d2b5d0)23ee47f)3d47919)xdg_config_home(), installation_configandinstallation_config_prefix() functions. ([0d340f4`](https://github.com/GitoxideLabs/gitoxide/commit/0d340f4fdeff1576460d43ca2210b11f0641c5dd))
</details>4 commits contributed to the release.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
38eed1d)d47cebe)d1e5e12)d1bd513)
</details>compatibility with bstr v1.3, use *.as_bytes() instead of .as_ref(). as_ref() relies on a known target type which isn't always present. However, once
bstr v1.3, use *.as_bytes() instead of .as_ref().
as_ref() relies on a known target type which isn't always present. However, once
there is only one implementation, that's no problem, but when that changes compilation
fails due to ambiguity.<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
9604783)bstr v1.3, use *.as_bytes() instead of .as_ref(). (135d317)
</details>absolutize() now takes a mandatory current_dir() parameter and returns Option Previously the function was willing to return an empty path despite it b
<csr-id-37cab07f283a368f323604372c84475d73d6c258/> <csr-id-54801592488416ef2bb0f34c5061b62189c35c5e/> <csr-id-8ab47bbdac44c0fa738215d3cc457eb3b6f30504/> <csr-id-e4f4c4b2c75a63a40a174e3a006ea64ef8d78809/> <csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> <csr-id-533e887e80c5f7ede8392884562e1c5ba56fb9a8/>
<csr-id-7dbab1c62c49822983c59be0443478f7b4fecbca/> absolutize() now takes a mandatory current_dir() parameter and returns Option<path>
Previously the function was willing to return an empty path despite it
being invalid. With the current_dir being required, this won't be the
case anymore and will yield logically consistent results in all cases.
This forces the caller to deal with the relative path being invalid or crafted to produce some other path, maybe to bypass sanity checks.
<csr-id-c9933c0b0f51d21dc8244b2acc33d7dc8a33f6ce/> Remove git-config test utilities from git-path.
<csr-id-3d8fa8fef9800b1576beab8a5bc39b821157a5ed/> upgrade edition to 2021 in most crates. MSRV for this is 1.56, and we are now at 1.60 so should be compatible. This isn't more than a patch release as it should break nobody who is adhering to the MSRV, but let's be careful and mark it breaking.
Note that git-features and git-pack are still on edition 2018
as they make use of a workaround to support (safe) mutable access
to non-overlapping entries in a slice which doesn't work anymore
in edition 2021.
<csr-id-266d4379e9132fd7dd21e6c8fccb36e125069d6e/> Make realpath() easier to use by introducing realpath_opt().
That way there is consistency about how many symlinks to follow.
bstr to 1.0.1realpath() handles cwd internally
This makes for more convenient usage in the common case.<csr-id-745d92636f8a3436ded0c9da21beb92182341998/> . substitution is only done if the input was relative.
Previously it was possible to have /a/b/../b and a CWD of /a/b
replaced with . even though that clearly isn't what the user provided.
Now the . resubstitution only happens when it's in the interest
of the caller.
<csr-id-92d5d133e17c6b79400ec57b55ccd5337f3796b7/> normalize() would fail to interpret ../ correctly and end up in an invalid path.
This is now fixed and should never happen again thanks to the addition
of a missing test.
<csr-id-9171adb796b38b08cae9bdd375b16a59a8166a1c/> Handle . specifically in absolutize().
Previously, absolutizing ./../../ would lead to one path component
of the ../ to be ignored as . was popped successfully, not realizing
that it is a no-op.
This could lead to problems with repository discovery if . was passed.
<csr-id-25e795f4fe858d646ae7a3c4706e14a3837c3e66/> Add os_string_into_bstring() as sibling of os_str_into_bstr().
<csr-id-523418f69030faa0add6472b14333e9aafc69f56/> add support for wasi
This allows path conversions there to be just as efficient as on unix.
This was adopted from a PR in the hexlix-editor.
<csr-id-f58a043273b8e15afd01aac71f33652783baf462/> add is_absolute() for git-style absolute checks
This essentially means that starting slashes are always absolute, even
on windows.
<csr-id-35f146a8573dcc9a1de3230373c0cf0794c6b897/> Add absolutize_components()
It helps to cleanup paths a little which comes in handy when dealing
with commondir appended paths.
<csr-read-only-do-not-edit/>
<csr-read-only-do-not-edit/>
Clippy helped 5 times to make code idiomatic.
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
84cb256)absolutize_*(dir) is now absolutize(dir, Option<cwd>) (de87657)4800ebe)absolutize_components() (35f146a)0c597fe) now returns the shortest path. ([e4f4c4b`](https://github.com/GitoxideLabs/gitoxide/commit/e4f4c4b2c75a63a40a174e3a006ea64ef8d78809))exclude query (9cb8385)gix repo exclude query (a331314)21d4076)e868acc)5480159)9380e99)git-path crate instead of git_features::path (47e607d)725e198)8d13f81)realpath() handles cwd internally (dfa1e05)de2d587)rust-version to 1.64 (55066ce)6efd0d3)6ccc88a)c9275b9)git-testtools to gix-testtools (b65c33d)git-pack to gix-pack (1ee81ad)git-odb to gix-odb (476e2ad)git-index to gix-index (86db5e0)git-diff to gix-diff (49a163e)git-commitgraph to gix-commitgraph (f1dd0a3)git-mailmap to gix-mailmap (2e28c56)git-discover to gix-discover (53adfe1)git-chunk to gix-chunk (59194e3)git-bitmap to gix-bitmap (75f2a07)git-protocol to gix-protocol (823795a)git-refspec to gix-refspec (c958802)git-revision to gix-revision (ee0ee84)git-transport to gix-transport (b2ccf71)git-credentials to gix-credentials (6b18abc)git-prompt to gix-prompt (6a4654e)git-command to gix-command (d26b8e0)git-packetline to gix-packetline (5cbd22c)git-worktree to gix-worktree (73a1282)git-worktree to gix-worktree (108bb1a)git-url to gix-url (b50817a)git-date to gix-date (9a79ff2)git-pathspec to gix-pathspec (37f7c6b)git-attributes to gix-attributes (4a8b3b8)git-quote to gix-quote (648025b)git-config to gix-config (3a861c8)git-ref to gix-ref (1f5f695)git-lock to gix-lock (2028e78)git-tempfile to gix-tempfile (b6cc3eb)git-object to gix-object (fc86a1e)git-actor to gix-actor (4dc9b44)git-validate to gix-validate (5e40ad0)git-hash to gix-hash (4a9d025)git-features to gix-features (e2dd68a)git-glob to gix-glob (35b2a3a)git-sec to gix-sec (eabbb92)git-path to gix-path (d3bbcfc)git-path to gix-path (9fe8e83)git-config-value to gix-config-value (622b3e1)4bc19d1)0d4b804)c196d20)7c846d2)1e544e8)39ed9ed)bac57dd)e6b9906)7114bbb)c57bdde)083909b)f1160fb)747008d)6b9632e)689752e). substitution is only done if the input was relative. (745d926)normalize() would fail to interpret ../ correctly and end up in an invalid path. (92d5d13)805329a)8ab47bb)37cab07)os_string_into_bstring() as sibling of os_str_into_bstr(). (25e795f)bcd9654)b2c301e)e4648f8)5f908fb)b8f73aa)ea7c6a3)git-discover and git-path and git-odb (98c2501)absolutize() now takes a mandatory current_dir() parameter and returns Option<path> (7dbab1c)0e4462d)3d8fa8f)25a7726)29a043b)fd14489)5c05198)bc64b96)c48fb31)cfa1440)5e82346). specifically in absolutize(). (9171adb)e2ee3de)31c2351)f7f136d)533e887)ce885ad)9b9ea02)6da8250)7b61506)4737b1e)3c50625)085e76b)0700b09)4f8e3b1)7a2a31e)89ea12b)0e9df36)target_os = "windows" in favor of cfg(windows) and negations (91d5402)229dc91)efa1423)9496e55)41ea8ba)400c9be)9c00504)a520092)git-config test utilities from git-path. (c9933c0)a417177)bb424f5)c665aef)315c87e)realpath() easier to use by introducing realpath_opt(). (266d437)a22b1d8)b7399cc)2f74cb0)5ac8a3b)ceb6dff)cf24fbe)23acebb)229d938)git-path usable (496594d)598c853)654cf39)e043807)714db70)5d74404)0426f4d)b696849)8ade69f)c980014)da13aff)6bba054)9b83c2c)1ca0540)1f6ecd2)5efb972)353c245)realpath into its own module (d142e01)50583f0)real_path() to realpath() (478ff6c)8f1daf5)8a36810)1afb2da)c2f5db9)8dc33cc)070f8c7)cefc8fb)31a71f3)f2b46df)b1bfc8f)8bfd52a)e058bda)a084951)27f4bfc)ce0b408)25dd319)61bc0e7)05eb340)1723236)cfff300)real_path() (2bd7a44)c993d78)3890a61)7cb1972)251b6df)98da8ba)ca019fc)
</details>Your coding agent can read these notes before it upgrades. Set up the MCP server →