From 1370420a589800a9a0e0918fb3f147f0175405fa Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Thu, 3 Apr 2025 21:10:00 -0400 Subject: [PATCH 001/193] Fix clippy This removes some extra unnecessary semicolons that `clippy` has recently begun to catch, causing CI to fail with errors such as: error: unnecessary semicolon --> gix-transport/src/client/blocking_io/http/traits.rs:30:18 | 30 | }; | ^ help: remove | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_semicolon = note: `-D clippy::unnecessary-semicolon` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]` While it looks like this might first have been observed in #1917, it is unrelated to any change there. It happens when the current tip of main (4660f7a) is rerun, as observed in: https://github.com/EliahKagan/gitoxide/actions/runs/14254079128/job/39958292846 This runs `just clippy-fix` and `etc/copy-packetline.sh` to fix it. --- gix-packetline-blocking/src/read/sidebands/async_io.rs | 6 +++--- gix-packetline/src/read/sidebands/async_io.rs | 6 +++--- gix-transport/src/client/blocking_io/http/traits.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gix-packetline-blocking/src/read/sidebands/async_io.rs b/gix-packetline-blocking/src/read/sidebands/async_io.rs index 9a9ddc9dff6..6ffe200590d 100644 --- a/gix-packetline-blocking/src/read/sidebands/async_io.rs +++ b/gix-packetline-blocking/src/read/sidebands/async_io.rs @@ -302,7 +302,7 @@ where "interrupted by user", ))) } - }; + } } BandRef::Error(d) => { let text = TextRef::from(d).0; @@ -314,9 +314,9 @@ where "interrupted by user", ))) } - }; + } } - }; + } } None => { break match line.as_slice() { diff --git a/gix-packetline/src/read/sidebands/async_io.rs b/gix-packetline/src/read/sidebands/async_io.rs index cd563bfc601..1a04a381254 100644 --- a/gix-packetline/src/read/sidebands/async_io.rs +++ b/gix-packetline/src/read/sidebands/async_io.rs @@ -300,7 +300,7 @@ where "interrupted by user", ))) } - }; + } } BandRef::Error(d) => { let text = TextRef::from(d).0; @@ -312,9 +312,9 @@ where "interrupted by user", ))) } - }; + } } - }; + } } None => { break match line.as_slice() { diff --git a/gix-transport/src/client/blocking_io/http/traits.rs b/gix-transport/src/client/blocking_io/http/traits.rs index b390eecc45a..df00b2a4bd8 100644 --- a/gix-transport/src/client/blocking_io/http/traits.rs +++ b/gix-transport/src/client/blocking_io/http/traits.rs @@ -27,7 +27,7 @@ impl crate::IsSpuriousError for Error { #[cfg(feature = "http-client-reqwest")] if let Some(err) = source.downcast_ref::() { return err.is_spurious(); - }; + } false } _ => false, From fb1b71da5fcd6f727f9bdd6cd1df575dc8bdac79 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 4 Apr 2025 10:14:37 +0800 Subject: [PATCH 002/193] update `gix-path` dependency in `gix-sec` to make compile succeed --- gix-sec/CHANGELOG.md | 26 +++++++++++++++++++++++++- gix-sec/Cargo.toml | 2 +- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/gix-sec/CHANGELOG.md b/gix-sec/CHANGELOG.md index b94a1e3bf99..17607aa722c 100644 --- a/gix-sec/CHANGELOG.md +++ b/gix-sec/CHANGELOG.md @@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +A maintenance release without user-facing changes. + +### Commit Statistics + + + + - 2 commits contributed to the release. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + + + +
view details + + * **Uncategorized** + - Update `gix-path` dependency in `gix-sec` to make compile succeed ([`010fb20`](https://github.com/GitoxideLabs/gitoxide/commit/010fb2063d5bc7def17d2ad9e6f114fab21e92c7)) + - Merge pull request #1778 from GitoxideLabs/new-release ([`8df0db2`](https://github.com/GitoxideLabs/gitoxide/commit/8df0db2f8fe1832a5efd86d6aba6fb12c4c855de)) +
+ ## 0.10.11 (2025-01-18) @@ -19,7 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 4 commits contributed to the release over the course of 55 calendar days. + - 5 commits contributed to the release over the course of 55 calendar days. - 55 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -31,6 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-utils v0.1.14, gix-actor v0.33.2, gix-hash v0.16.0, gix-trace v0.1.12, gix-features v0.40.0, gix-hashtable v0.7.0, gix-path v0.10.14, gix-validate v0.9.3, gix-object v0.47.0, gix-glob v0.18.0, gix-quote v0.4.15, gix-attributes v0.24.0, gix-command v0.4.1, gix-packetline-blocking v0.18.2, gix-filter v0.17.0, gix-fs v0.13.0, gix-chunk v0.4.11, gix-commitgraph v0.26.0, gix-revwalk v0.18.0, gix-traverse v0.44.0, gix-worktree-stream v0.19.0, gix-archive v0.19.0, gix-bitmap v0.2.14, gix-tempfile v16.0.0, gix-lock v16.0.0, gix-index v0.38.0, gix-config-value v0.14.11, gix-pathspec v0.9.0, gix-ignore v0.13.0, gix-worktree v0.39.0, gix-diff v0.50.0, gix-blame v0.0.0, gix-ref v0.50.0, gix-sec v0.10.11, gix-config v0.43.0, gix-prompt v0.9.1, gix-url v0.29.0, gix-credentials v0.27.0, gix-discover v0.38.0, gix-dir v0.12.0, gix-mailmap v0.25.2, gix-revision v0.32.0, gix-merge v0.3.0, gix-negotiate v0.18.0, gix-pack v0.57.0, gix-odb v0.67.0, gix-refspec v0.28.0, gix-shallow v0.2.0, gix-packetline v0.18.3, gix-transport v0.45.0, gix-protocol v0.48.0, gix-status v0.17.0, gix-submodule v0.17.0, gix-worktree-state v0.17.0, gix v0.70.0, gix-fsck v0.9.0, gitoxide-core v0.45.0, gitoxide v0.41.0, safety bump 42 crates ([`dea106a`](https://github.com/GitoxideLabs/gitoxide/commit/dea106a8c4fecc1f0a8f891a2691ad9c63964d25)) - Update all changelogs prior to release ([`1f6390c`](https://github.com/GitoxideLabs/gitoxide/commit/1f6390c53ba68ce203ae59eb3545e2631dd8a106)) - Merge pull request #1762 from GitoxideLabs/fix-1759 ([`7ec21bb`](https://github.com/GitoxideLabs/gitoxide/commit/7ec21bb96ce05b29dde74b2efdf22b6e43189aab)) - Bump `rust-version` to 1.70 ([`17835bc`](https://github.com/GitoxideLabs/gitoxide/commit/17835bccb066bbc47cc137e8ec5d9fe7d5665af0)) diff --git a/gix-sec/Cargo.toml b/gix-sec/Cargo.toml index 4ee0569226f..d43ca1aa75c 100644 --- a/gix-sec/Cargo.toml +++ b/gix-sec/Cargo.toml @@ -31,7 +31,7 @@ document-features = { version = "0.2.1", optional = true } libc = "0.2.123" [target.'cfg(windows)'.dependencies] -gix-path = { version = "^0.10.14", path = "../gix-path" } +gix-path = { version = "^0.10.15", path = "../gix-path" } windows-sys = { version = "0.52.0", features = [ "Win32_Foundation", "Win32_Security_Authorization", From ada5a9447dc3c210afbd8866fe939c3f3a024226 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 4 Apr 2025 10:17:37 +0800 Subject: [PATCH 003/193] Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 --- Cargo.lock | 30 +++++++++++++++--------------- gitoxide-core/CHANGELOG.md | 3 ++- gix-config/CHANGELOG.md | 23 ++++++++++++++++++++++- gix-config/Cargo.toml | 2 +- gix-credentials/CHANGELOG.md | 3 ++- gix-credentials/Cargo.toml | 2 +- gix-dir/CHANGELOG.md | 3 ++- gix-discover/CHANGELOG.md | 3 ++- gix-discover/Cargo.toml | 2 +- gix-fsck/CHANGELOG.md | 3 ++- gix-mailmap/CHANGELOG.md | 3 ++- gix-merge/CHANGELOG.md | 3 ++- gix-negotiate/CHANGELOG.md | 3 ++- gix-odb/CHANGELOG.md | 3 ++- gix-pack/CHANGELOG.md | 3 ++- gix-packetline/CHANGELOG.md | 3 ++- gix-prompt/CHANGELOG.md | 3 ++- gix-protocol/CHANGELOG.md | 3 ++- gix-refspec/CHANGELOG.md | 3 ++- gix-revision/CHANGELOG.md | 3 ++- gix-sec/CHANGELOG.md | 4 ++-- gix-sec/Cargo.toml | 2 +- gix-shallow/CHANGELOG.md | 3 ++- gix-status/CHANGELOG.md | 3 ++- gix-submodule/CHANGELOG.md | 3 ++- gix-transport/CHANGELOG.md | 3 ++- gix-transport/Cargo.toml | 2 +- gix-url/CHANGELOG.md | 3 ++- gix-worktree-state/CHANGELOG.md | 9 +++------ gix/CHANGELOG.md | 3 ++- gix/Cargo.toml | 2 +- 31 files changed, 90 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f33ebb2f637..9ec8dce0a24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1403,7 +1403,7 @@ dependencies = [ "gix-refspec", "gix-revision", "gix-revwalk 0.19.0", - "gix-sec 0.10.11", + "gix-sec 0.10.12", "gix-shallow", "gix-status", "gix-submodule", @@ -1634,7 +1634,7 @@ dependencies = [ "gix-glob 0.19.0", "gix-path 0.10.15", "gix-ref 0.51.0", - "gix-sec 0.10.11", + "gix-sec 0.10.12", "memchr", "once_cell", "serde", @@ -1654,7 +1654,7 @@ dependencies = [ "gix-config", "gix-path 0.10.15", "gix-ref 0.51.0", - "gix-sec 0.10.11", + "gix-sec 0.10.12", "gix-testtools", "serial_test", ] @@ -1682,7 +1682,7 @@ dependencies = [ "gix-config-value", "gix-path 0.10.15", "gix-prompt", - "gix-sec 0.10.11", + "gix-sec 0.10.12", "gix-testtools", "gix-trace 0.1.12", "gix-url", @@ -1796,7 +1796,7 @@ dependencies = [ "gix-hash 0.14.2", "gix-path 0.10.14", "gix-ref 0.44.1", - "gix-sec 0.10.11 (registry+https://github.com/rust-lang/crates.io-index)", + "gix-sec 0.10.11", "thiserror 1.0.69", ] @@ -1811,7 +1811,7 @@ dependencies = [ "gix-hash 0.17.0", "gix-path 0.10.15", "gix-ref 0.51.0", - "gix-sec 0.10.11", + "gix-sec 0.10.12", "gix-testtools", "is_ci", "serial_test", @@ -2585,25 +2585,25 @@ dependencies = [ [[package]] name = "gix-sec" version = "0.10.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d84dae13271f4313f8d60a166bf27e54c968c7c33e2ffd31c48cafe5da649875" dependencies = [ "bitflags 2.9.0", - "document-features", - "gix-path 0.10.15", + "gix-path 0.10.14", "libc", - "serde", - "tempfile", "windows-sys 0.52.0", ] [[package]] name = "gix-sec" -version = "0.10.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d84dae13271f4313f8d60a166bf27e54c968c7c33e2ffd31c48cafe5da649875" +version = "0.10.12" dependencies = [ "bitflags 2.9.0", - "gix-path 0.10.14", + "document-features", + "gix-path 0.10.15", "libc", + "serde", + "tempfile", "windows-sys 0.52.0", ] @@ -2775,7 +2775,7 @@ dependencies = [ "gix-pack", "gix-packetline", "gix-quote 0.5.0", - "gix-sec 0.10.11", + "gix-sec 0.10.12", "gix-url", "maybe-async", "pin-project-lite", diff --git a/gitoxide-core/CHANGELOG.md b/gitoxide-core/CHANGELOG.md index ef80cea17fb..153e33a8537 100644 --- a/gitoxide-core/CHANGELOG.md +++ b/gitoxide-core/CHANGELOG.md @@ -41,7 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 25 commits contributed to the release. + - 26 commits contributed to the release. - 7 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -58,6 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) - Adjust hash verification return types for the common interface ([`54e5764`](https://github.com/GitoxideLabs/gitoxide/commit/54e57649f0e0b15c0bd1d3233e41524cb91a8cb9)) diff --git a/gix-config/CHANGELOG.md b/gix-config/CHANGELOG.md index 615066aa914..83020dfca1e 100644 --- a/gix-config/CHANGELOG.md +++ b/gix-config/CHANGELOG.md @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 13 commits contributed to the release. + - 14 commits contributed to the release. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1826](https://github.com/GitoxideLabs/gitoxide/issues/1826) @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **[#1826](https://github.com/GitoxideLabs/gitoxide/issues/1826)** - Assure that sections can be deleted properly with `File::remove_section_filter()` ([`be80806`](https://github.com/GitoxideLabs/gitoxide/commit/be80806fa990f7992f2c334622cd3e4abb6c36ca)) * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) - Drop trailing `,` just before `)` on same line in function calls ([`66a5ae1`](https://github.com/GitoxideLabs/gitoxide/commit/66a5ae1b586d583066402c801213a55141e2aad6)) @@ -3677,6 +3678,24 @@ This is a maintenance release without functional changes. - `len` - `from_env` - `open` + - `len` + - `from_env` + - `open` + - `len` + - `from_env` + - `open` + - `len` + - `from_env` + - `open` +- `len` +- `from_env` +- `open` +- `len` +- `from_env` +- `open` +- `len` +- `from_env` +- `open` - `len` - `from_env` - `open` @@ -3883,11 +3902,13 @@ This is a maintenance release without functional changes. `ParserFromIoError` +lenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopen lenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopen lenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopen lenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopen + ## v0.1.1 (2021-05-09) diff --git a/gix-config/Cargo.toml b/gix-config/Cargo.toml index 28a7a4eb348..fee11339a6b 100644 --- a/gix-config/Cargo.toml +++ b/gix-config/Cargo.toml @@ -22,7 +22,7 @@ serde = ["dep:serde", "bstr/serde", "gix-sec/serde", "gix-ref/serde", "gix-glob/ gix-features = { version = "^0.41.0", path = "../gix-features" } gix-config-value = { version = "^0.14.12", path = "../gix-config-value" } gix-path = { version = "^0.10.15", path = "../gix-path" } -gix-sec = { version = "^0.10.11", path = "../gix-sec" } +gix-sec = { version = "^0.10.12", path = "../gix-sec" } gix-ref = { version = "^0.51.0", path = "../gix-ref" } gix-glob = { version = "^0.19.0", path = "../gix-glob" } diff --git a/gix-credentials/CHANGELOG.md b/gix-credentials/CHANGELOG.md index 1dd8a013def..c1b65904491 100644 --- a/gix-credentials/CHANGELOG.md +++ b/gix-credentials/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 8 commits contributed to the release. + - 9 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1862 from EliahKagan/run-ci/consistent-sh ([`0ba3147`](https://github.com/GitoxideLabs/gitoxide/commit/0ba31474968ddbe7f2b2d54a756eeeb8a28fbabf)) - Adjust `gix-credentials` tests for `gix-command` changes ([`b937171`](https://github.com/GitoxideLabs/gitoxide/commit/b9371714b74103c89d3ba9a241a92a1bd989fdad)) diff --git a/gix-credentials/Cargo.toml b/gix-credentials/Cargo.toml index 09cd67a165b..dc43bb99ddc 100644 --- a/gix-credentials/Cargo.toml +++ b/gix-credentials/Cargo.toml @@ -19,7 +19,7 @@ doctest = false serde = ["dep:serde", "bstr/serde", "gix-sec/serde"] [dependencies] -gix-sec = { version = "^0.10.11", path = "../gix-sec" } +gix-sec = { version = "^0.10.12", path = "../gix-sec" } gix-url = { version = "^0.30.0", path = "../gix-url" } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-command = { version = "^0.5.0", path = "../gix-command" } diff --git a/gix-dir/CHANGELOG.md b/gix-dir/CHANGELOG.md index 95b1471b9bf..2cdcc2fb8ae 100644 --- a/gix-dir/CHANGELOG.md +++ b/gix-dir/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 4 commits contributed to the release. + - 5 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -24,6 +24,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) - Drop trailing `,` just before `)` on same line in function calls ([`66a5ae1`](https://github.com/GitoxideLabs/gitoxide/commit/66a5ae1b586d583066402c801213a55141e2aad6)) diff --git a/gix-discover/CHANGELOG.md b/gix-discover/CHANGELOG.md index 65ae336afcb..c916a1cc3c2 100644 --- a/gix-discover/CHANGELOG.md +++ b/gix-discover/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 7 commits contributed to the release. + - 8 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) - Drop trailing `,` just before `)` on same line in function calls ([`66a5ae1`](https://github.com/GitoxideLabs/gitoxide/commit/66a5ae1b586d583066402c801213a55141e2aad6)) diff --git a/gix-discover/Cargo.toml b/gix-discover/Cargo.toml index 8cb509697b8..993cf007c3e 100644 --- a/gix-discover/Cargo.toml +++ b/gix-discover/Cargo.toml @@ -15,7 +15,7 @@ rust-version = "1.70" doctest = false [dependencies] -gix-sec = { version = "^0.10.11", path = "../gix-sec" } +gix-sec = { version = "^0.10.12", path = "../gix-sec" } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-ref = { version = "^0.51.0", path = "../gix-ref" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } diff --git a/gix-fsck/CHANGELOG.md b/gix-fsck/CHANGELOG.md index 5bd0ca659cd..d1ab838b2da 100644 --- a/gix-fsck/CHANGELOG.md +++ b/gix-fsck/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 2 commits contributed to the release. + - 3 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -24,6 +24,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1778 from GitoxideLabs/new-release ([`8df0db2`](https://github.com/GitoxideLabs/gitoxide/commit/8df0db2f8fe1832a5efd86d6aba6fb12c4c855de))
diff --git a/gix-mailmap/CHANGELOG.md b/gix-mailmap/CHANGELOG.md index 51a1d44a3ee..f8562d2ab1e 100644 --- a/gix-mailmap/CHANGELOG.md +++ b/gix-mailmap/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 4 commits contributed to the release. + - 5 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1854 from GitoxideLabs/montly-report ([`16a248b`](https://github.com/GitoxideLabs/gitoxide/commit/16a248beddbfbd21621f2bb57aaa82dca35acb19)) - Thanks clippy ([`8e96ed3`](https://github.com/GitoxideLabs/gitoxide/commit/8e96ed37db680855d194c10673ba2dab28655d95)) diff --git a/gix-merge/CHANGELOG.md b/gix-merge/CHANGELOG.md index a87463174c4..195a3e8e68c 100644 --- a/gix-merge/CHANGELOG.md +++ b/gix-merge/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 11 commits contributed to the release. + - 12 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) - Migrate `gix_object::{try_ =>}compute_hash` users ([`3d7e379`](https://github.com/GitoxideLabs/gitoxide/commit/3d7e379f26cbe53ddb430427b8e88ce0966be456)) diff --git a/gix-negotiate/CHANGELOG.md b/gix-negotiate/CHANGELOG.md index 1b8dd31a21b..a3c039dc308 100644 --- a/gix-negotiate/CHANGELOG.md +++ b/gix-negotiate/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 2 commits contributed to the release. + - 3 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -24,6 +24,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1778 from GitoxideLabs/new-release ([`8df0db2`](https://github.com/GitoxideLabs/gitoxide/commit/8df0db2f8fe1832a5efd86d6aba6fb12c4c855de))
diff --git a/gix-odb/CHANGELOG.md b/gix-odb/CHANGELOG.md index 8969b03d5d7..b95f6df0dea 100644 --- a/gix-odb/CHANGELOG.md +++ b/gix-odb/CHANGELOG.md @@ -26,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 13 commits contributed to the release. + - 14 commits contributed to the release. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) - Refactor ([`4501086`](https://github.com/GitoxideLabs/gitoxide/commit/4501086adc544e675b3043c4c23b78a6c6711d8b)) diff --git a/gix-pack/CHANGELOG.md b/gix-pack/CHANGELOG.md index 9a3894996ae..b9d41b09d0a 100644 --- a/gix-pack/CHANGELOG.md +++ b/gix-pack/CHANGELOG.md @@ -27,7 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 16 commits contributed to the release. + - 17 commits contributed to the release. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) - Refactor ([`4501086`](https://github.com/GitoxideLabs/gitoxide/commit/4501086adc544e675b3043c4c23b78a6c6711d8b)) diff --git a/gix-packetline/CHANGELOG.md b/gix-packetline/CHANGELOG.md index b9ce0ac95f7..c508114165f 100644 --- a/gix-packetline/CHANGELOG.md +++ b/gix-packetline/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 4 commits contributed to the release. + - 5 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1854 from GitoxideLabs/montly-report ([`16a248b`](https://github.com/GitoxideLabs/gitoxide/commit/16a248beddbfbd21621f2bb57aaa82dca35acb19)) - Thanks clippy ([`8e96ed3`](https://github.com/GitoxideLabs/gitoxide/commit/8e96ed37db680855d194c10673ba2dab28655d95)) diff --git a/gix-prompt/CHANGELOG.md b/gix-prompt/CHANGELOG.md index a71598a8b0f..34cf591ed78 100644 --- a/gix-prompt/CHANGELOG.md +++ b/gix-prompt/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 2 commits contributed to the release. + - 3 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -24,6 +24,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1778 from GitoxideLabs/new-release ([`8df0db2`](https://github.com/GitoxideLabs/gitoxide/commit/8df0db2f8fe1832a5efd86d6aba6fb12c4c855de))
diff --git a/gix-protocol/CHANGELOG.md b/gix-protocol/CHANGELOG.md index 46e4671ca87..be45399ca73 100644 --- a/gix-protocol/CHANGELOG.md +++ b/gix-protocol/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 10 commits contributed to the release. + - 11 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1909 from cruessler/take-to-components-in-fs-stack ([`5cb5337`](https://github.com/GitoxideLabs/gitoxide/commit/5cb5337efd7679d8a2ab4bd5e6a5da8c366f7f1a)) - Use `gix_fs::stack::ToNormalPathComponents` everywhere. ([`1f98edb`](https://github.com/GitoxideLabs/gitoxide/commit/1f98edbaa51caaf152eda289b769388676259a06)) diff --git a/gix-refspec/CHANGELOG.md b/gix-refspec/CHANGELOG.md index 62d4c0ffac5..fd9a3f8fac4 100644 --- a/gix-refspec/CHANGELOG.md +++ b/gix-refspec/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 6 commits contributed to the release. + - 7 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) - Drop trailing `,` just before `)` on same line in function calls ([`66a5ae1`](https://github.com/GitoxideLabs/gitoxide/commit/66a5ae1b586d583066402c801213a55141e2aad6)) diff --git a/gix-revision/CHANGELOG.md b/gix-revision/CHANGELOG.md index 5cfe059f9af..1664df50bb9 100644 --- a/gix-revision/CHANGELOG.md +++ b/gix-revision/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 8 commits contributed to the release. + - 9 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1914](https://github.com/GitoxideLabs/gitoxide/issues/1914) @@ -32,6 +32,7 @@ A maintenance release without user-facing changes. * **[#1914](https://github.com/GitoxideLabs/gitoxide/issues/1914)** - Add tests to get a clearer understanding about some special cases ([`12cb847`](https://github.com/GitoxideLabs/gitoxide/commit/12cb8473b38a3eed9f267609aeadaf1a57caacb0)) * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1916 from GitoxideLabs/fix-1914 ([`32b54b3`](https://github.com/GitoxideLabs/gitoxide/commit/32b54b3ab7f101c6b9cd7c3349153c2fc71e496d)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) diff --git a/gix-sec/CHANGELOG.md b/gix-sec/CHANGELOG.md index 17607aa722c..31b37810691 100644 --- a/gix-sec/CHANGELOG.md +++ b/gix-sec/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 0.10.12 (2025-04-04) A maintenance release without user-facing changes. @@ -24,7 +24,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** - - Update `gix-path` dependency in `gix-sec` to make compile succeed ([`010fb20`](https://github.com/GitoxideLabs/gitoxide/commit/010fb2063d5bc7def17d2ad9e6f114fab21e92c7)) + - Update `gix-path` dependency in `gix-sec` to make compile succeed ([`fb1b71d`](https://github.com/GitoxideLabs/gitoxide/commit/fb1b71da5fcd6f727f9bdd6cd1df575dc8bdac79)) - Merge pull request #1778 from GitoxideLabs/new-release ([`8df0db2`](https://github.com/GitoxideLabs/gitoxide/commit/8df0db2f8fe1832a5efd86d6aba6fb12c4c855de))
diff --git a/gix-sec/Cargo.toml b/gix-sec/Cargo.toml index d43ca1aa75c..f0b5b28affd 100644 --- a/gix-sec/Cargo.toml +++ b/gix-sec/Cargo.toml @@ -2,7 +2,7 @@ lints.workspace = true [package] name = "gix-sec" -version = "0.10.11" +version = "0.10.12" repository = "https://github.com/GitoxideLabs/gitoxide" license = "MIT OR Apache-2.0" description = "A crate of the gitoxide project providing a shared trust model" diff --git a/gix-shallow/CHANGELOG.md b/gix-shallow/CHANGELOG.md index 0b015a4276e..4694efd3381 100644 --- a/gix-shallow/CHANGELOG.md +++ b/gix-shallow/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 2 commits contributed to the release. + - 3 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -24,6 +24,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1778 from GitoxideLabs/new-release ([`8df0db2`](https://github.com/GitoxideLabs/gitoxide/commit/8df0db2f8fe1832a5efd86d6aba6fb12c4c855de))
diff --git a/gix-status/CHANGELOG.md b/gix-status/CHANGELOG.md index f2c988a2bc3..72f7175a1ea 100644 --- a/gix-status/CHANGELOG.md +++ b/gix-status/CHANGELOG.md @@ -22,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 16 commits contributed to the release. + - 17 commits contributed to the release. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) - Refactor ([`4501086`](https://github.com/GitoxideLabs/gitoxide/commit/4501086adc544e675b3043c4c23b78a6c6711d8b)) diff --git a/gix-submodule/CHANGELOG.md b/gix-submodule/CHANGELOG.md index 0a3dd6e24df..e1a590c8ede 100644 --- a/gix-submodule/CHANGELOG.md +++ b/gix-submodule/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 6 commits contributed to the release. + - 7 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) - Use raw literals for more strings with backslashes ([`01bd76d`](https://github.com/GitoxideLabs/gitoxide/commit/01bd76dcacb69d9c21f2fc6063e273a01aebf94f)) diff --git a/gix-transport/CHANGELOG.md b/gix-transport/CHANGELOG.md index 399896ae359..bbd266c7ae2 100644 --- a/gix-transport/CHANGELOG.md +++ b/gix-transport/CHANGELOG.md @@ -46,7 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 16 commits contributed to the release. + - 17 commits contributed to the release. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -63,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) - Drop trailing `,` just before `)` on same line in function calls ([`66a5ae1`](https://github.com/GitoxideLabs/gitoxide/commit/66a5ae1b586d583066402c801213a55141e2aad6)) diff --git a/gix-transport/Cargo.toml b/gix-transport/Cargo.toml index 00ae587a890..1cc27d1f11a 100644 --- a/gix-transport/Cargo.toml +++ b/gix-transport/Cargo.toml @@ -84,7 +84,7 @@ required-features = ["async-client"] gix-command = { version = "^0.5.0", path = "../gix-command" } gix-features = { version = "^0.41.0", path = "../gix-features" } gix-url = { version = "^0.30.0", path = "../gix-url" } -gix-sec = { version = "^0.10.11", path = "../gix-sec" } +gix-sec = { version = "^0.10.12", path = "../gix-sec" } gix-packetline = { version = "^0.18.4", path = "../gix-packetline" } gix-credentials = { version = "^0.28.0", path = "../gix-credentials", optional = true } gix-quote = { version = "^0.5.0", path = "../gix-quote" } diff --git a/gix-url/CHANGELOG.md b/gix-url/CHANGELOG.md index 6e4f3e48880..e9a94d64221 100644 --- a/gix-url/CHANGELOG.md +++ b/gix-url/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 8 commits contributed to the release. + - 9 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) - Use raw literals for more strings with backslashes ([`01bd76d`](https://github.com/GitoxideLabs/gitoxide/commit/01bd76dcacb69d9c21f2fc6063e273a01aebf94f)) diff --git a/gix-worktree-state/CHANGELOG.md b/gix-worktree-state/CHANGELOG.md index 4b4111a6aa8..56f1dbf7f97 100644 --- a/gix-worktree-state/CHANGELOG.md +++ b/gix-worktree-state/CHANGELOG.md @@ -22,8 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 In practice, currently, on Unix-like systems: - `File::metadata` either: - - * calls `fstat`, or +* calls `fstat`, or * calls `statx` in a way that causes it to operate similarly to `fstat` (this is used on Linux, in versions with `statx`). - No longer require `gix-worktree-state` to depend directly on @@ -41,7 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 20 commits contributed to the release. + - 21 commits contributed to the release. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -58,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1909 from cruessler/take-to-components-in-fs-stack ([`5cb5337`](https://github.com/GitoxideLabs/gitoxide/commit/5cb5337efd7679d8a2ab4bd5e6a5da8c366f7f1a)) - Use `gix_fs::stack::ToNormalPathComponents` everywhere. ([`1f98edb`](https://github.com/GitoxideLabs/gitoxide/commit/1f98edbaa51caaf152eda289b769388676259a06)) @@ -80,9 +80,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Merge pull request #1778 from GitoxideLabs/new-release ([`8df0db2`](https://github.com/GitoxideLabs/gitoxide/commit/8df0db2f8fe1832a5efd86d6aba6fb12c4c855de))
- -This is not explicitly documented, though calling stat orlstat, or calling statx in a way that would cause it tobehave like stat or lstat rather than fstat, would notpreserve the documented behavior of File::metadata, whichoperates on a File and does not take a path.File::set_permissions calls fchmod.This is explicitly documented and fchmod is listed as an aliasfor documentation purposes. But it is noted as an implementationdetail that may change without warning. However, calling chmodor lchmod would not preserve the documented behavior ofFile::set_permissions, which (like File::metadata) operateson a File and does not take a path.While these details can, in principle, change without warning, perhttps://doc.rust-lang.org/stable/std/io/index.html#platform-specific-behavior,it seems that, in preserving the documented semantics of operatingon the file referenced by the file descriptor (rather than a path),the behavior would still have to be correct for our use here.The change in this commit intends to maintain the effect of #1803with two minor improvements for maintainability and clarity:Importantly, this continues to differ from the pre-#1803 behaviorof using functions that operated on paths.For reading metadata on a file on Unix-like systems, the currentgeneral correspondence between Rust std, POSIX functions, andstatx, where the rightmost three columns pertain to how statxis called, is:std::fs::*POSIXfdpathdistinctive flagsmetadatastatAT_FDCWDpath(none)symlink_metadatalstatAT_FDCWDpathAT_SYMLINK_NOFOLLOWFile::metadatafstatfile“”AT_EMPTY_PATHFor writing metadata on a file on Unix-like systems, the currentcorrespondence between Rust std and POSIX functions is:std::fs::*POSIXset_permissionschmod(none)lchmodFile::set_permissionsfchmodIt may be that some uses of rustix::fs facilities can besimilarly replaced in gix_fs, but this commit does not includeany such changes. Get mode before +x using open file descriptor, not pathThis uses fstat rather than a method that delegates to lstat,to get the current mode bits of the still-open file using the openfile descriptor (obtained from the File object) rather thanopening the path, which could be a different file in the case ofconcurrent modification by code outside gitoxide.This is half of the change to using the file descriptor rather thanthe path for the operations that adjust the mode by addingexecutable bitsi. (As before, they are added for whoever alreadyhad read bits, and we remove setuid, setgid, and sticky bits, sothat +x does not cause a security problem or other potentiallyunexpected effects.)The other half of this change was already done, appearing in arecent change: commit. It consisted of setting the mode usingfchmod instead of a method that delegated to chmod. With onlythat change, the overall effect would be worse, since possiblerace conditions could introduce even greater inconsistency. Withboth changes, the effect is consistent. Race conditions can stilloccur, but their effect is probably less severe than before eitherof the changes were made.One of the ways this may be less subject to race conditions isthat, because neither obtaining the old mode nor setting the newone uses a path, but only the open file descriptor, an unexpectedtypechange will not occur: having opened a regular file, the openfile will not turn into a directory, symlink, or anything else,as seen by the open file descriptor. The file may be moved orreplaced, but the open file descriptor “follows” the move and doesnot alias the separate file that now has the original path.Because we only intend to add executable bits to regular files, itis no longer necessary to handle this as a race condition and keepgoing. Attempting to add +x to any other type of thing should nowonly be possible if there is a bug in the caller. So the check forthat, and the associated Option<…> logic used to keep thingstestable, is not needed.This still does the check, but panics if the file descriptor doesnot represent a regular file. The tests of this are mostly removed,but two tests that it does panic for the kinds of non-regular fileswe are most likely to encounter are added. (It may eventually makesense check this and panic only in debug builds, or not at all.)There are now two fstat calls: the one that is added to check thest_mode to figure out what to pass to fchmod, and thepreexisting higher level invocation (that delegates to fstat)done just before closing the file, to update entry.stat. Usingthe same call for both and accounting for any effect of fchmodmight be more complicated, but more importantly, it does not seemlike it would be correct. If attempting to set the permissionsreports success but has an unexpected effect, perhaps due torestrictions of the underlying filesystem or how it is mounted(which we may not be guarnateed to have detected in a probe todecide if +x is supported), we would want the real stat.Because this no longer uses Permissions and PermissionsExtfacilities to check the mode before adding executable bits or toadd the executable bits, it also includes some refactoring that ispossible now that they are not being used. Set +x via open file descriptor, not pathWhen executable permissions were set on a file being checked out,and when it was done after the file was already created, this wasdone on its path, using chmod (via a higher level abstraction).But we have an open File object for it already, at that point.This uses fchmod on the existing open file descriptor (obtainedfrom the File object), instead of chmod on the path.(Since #1764, the file mode has also been read first, to figure outwhat new mode to set it to for +x. That uses lstat (via a higherlevel abstraction). The change here is therefore really only halfof what should be done. To complete it, and also to avoid newproblems due to a new inconsistency, that should be done withfstat on the file descriptor instead of lstat on the path. Thatwill be done in a directly fortcoming commit – after portabilityissues in the type of the st_mode field, which is not actuallyu32 on all systems, are examined.) - ## 0.17.0 (2025-01-18) diff --git a/gix/CHANGELOG.md b/gix/CHANGELOG.md index d75151cf355..9f899e4b5ee 100644 --- a/gix/CHANGELOG.md +++ b/gix/CHANGELOG.md @@ -74,7 +74,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 55 commits contributed to the release. + - 56 commits contributed to the release. - 17 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1829](https://github.com/GitoxideLabs/gitoxide/issues/1829), [#1914](https://github.com/GitoxideLabs/gitoxide/issues/1914) @@ -95,6 +95,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **[#1914](https://github.com/GitoxideLabs/gitoxide/issues/1914)** - Don't panic when rev-parsing `^^^` and similar ([`aa8daf8`](https://github.com/GitoxideLabs/gitoxide/commit/aa8daf89bcc3c26baeb7d850c19bb9a5d403f555)) * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) - Migrate `gix_object::{try_ =>}compute_hash` users ([`3d7e379`](https://github.com/GitoxideLabs/gitoxide/commit/3d7e379f26cbe53ddb430427b8e88ce0966be456)) diff --git a/gix/Cargo.toml b/gix/Cargo.toml index 6a9bf21f7d9..8df05077e1a 100644 --- a/gix/Cargo.toml +++ b/gix/Cargo.toml @@ -319,7 +319,7 @@ gix-discover = { version = "^0.39.0", path = "../gix-discover" } gix-tempfile = { version = "^17.0.0", path = "../gix-tempfile", default-features = false } gix-lock = { version = "^17.0.0", path = "../gix-lock" } gix-validate = { version = "^0.9.4", path = "../gix-validate" } -gix-sec = { version = "^0.10.11", path = "../gix-sec" } +gix-sec = { version = "^0.10.12", path = "../gix-sec" } gix-date = { version = "^0.9.4", path = "../gix-date" } gix-refspec = { version = "^0.29.0", path = "../gix-refspec" } gix-filter = { version = "^0.18.0", path = "../gix-filter", optional = true } From d248e3d87d45ca3983cb9fd7c6143dacbd8301cc Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 4 Apr 2025 10:20:11 +0800 Subject: [PATCH 004/193] Release gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 --- gitoxide-core/CHANGELOG.md | 3 ++- gix-dir/CHANGELOG.md | 3 ++- gix-fsck/CHANGELOG.md | 3 ++- gix-mailmap/CHANGELOG.md | 3 ++- gix-merge/CHANGELOG.md | 3 ++- gix-negotiate/CHANGELOG.md | 3 ++- gix-odb/CHANGELOG.md | 3 ++- gix-pack/CHANGELOG.md | 3 ++- gix-packetline/CHANGELOG.md | 3 ++- gix-protocol/CHANGELOG.md | 3 ++- gix-refspec/CHANGELOG.md | 3 ++- gix-revision/CHANGELOG.md | 3 ++- gix-shallow/CHANGELOG.md | 3 ++- gix-status/CHANGELOG.md | 3 ++- gix-submodule/CHANGELOG.md | 3 ++- gix-transport/CHANGELOG.md | 3 ++- gix-worktree-state/CHANGELOG.md | 3 ++- gix/CHANGELOG.md | 3 ++- 18 files changed, 36 insertions(+), 18 deletions(-) diff --git a/gitoxide-core/CHANGELOG.md b/gitoxide-core/CHANGELOG.md index 153e33a8537..93a3c9c8ae9 100644 --- a/gitoxide-core/CHANGELOG.md +++ b/gitoxide-core/CHANGELOG.md @@ -41,7 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 26 commits contributed to the release. + - 27 commits contributed to the release. - 7 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -58,6 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) diff --git a/gix-dir/CHANGELOG.md b/gix-dir/CHANGELOG.md index 2cdcc2fb8ae..2b7cdb7ffe6 100644 --- a/gix-dir/CHANGELOG.md +++ b/gix-dir/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 5 commits contributed to the release. + - 6 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -24,6 +24,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) diff --git a/gix-fsck/CHANGELOG.md b/gix-fsck/CHANGELOG.md index d1ab838b2da..228421dfad3 100644 --- a/gix-fsck/CHANGELOG.md +++ b/gix-fsck/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 3 commits contributed to the release. + - 4 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -24,6 +24,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1778 from GitoxideLabs/new-release ([`8df0db2`](https://github.com/GitoxideLabs/gitoxide/commit/8df0db2f8fe1832a5efd86d6aba6fb12c4c855de)) diff --git a/gix-mailmap/CHANGELOG.md b/gix-mailmap/CHANGELOG.md index f8562d2ab1e..6613d180cb4 100644 --- a/gix-mailmap/CHANGELOG.md +++ b/gix-mailmap/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 5 commits contributed to the release. + - 6 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1854 from GitoxideLabs/montly-report ([`16a248b`](https://github.com/GitoxideLabs/gitoxide/commit/16a248beddbfbd21621f2bb57aaa82dca35acb19)) diff --git a/gix-merge/CHANGELOG.md b/gix-merge/CHANGELOG.md index 195a3e8e68c..ad1b236c973 100644 --- a/gix-merge/CHANGELOG.md +++ b/gix-merge/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 12 commits contributed to the release. + - 13 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) diff --git a/gix-negotiate/CHANGELOG.md b/gix-negotiate/CHANGELOG.md index a3c039dc308..bfecfd04b26 100644 --- a/gix-negotiate/CHANGELOG.md +++ b/gix-negotiate/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 3 commits contributed to the release. + - 4 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -24,6 +24,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1778 from GitoxideLabs/new-release ([`8df0db2`](https://github.com/GitoxideLabs/gitoxide/commit/8df0db2f8fe1832a5efd86d6aba6fb12c4c855de)) diff --git a/gix-odb/CHANGELOG.md b/gix-odb/CHANGELOG.md index b95f6df0dea..d1cd954c8f5 100644 --- a/gix-odb/CHANGELOG.md +++ b/gix-odb/CHANGELOG.md @@ -26,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 14 commits contributed to the release. + - 15 commits contributed to the release. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) diff --git a/gix-pack/CHANGELOG.md b/gix-pack/CHANGELOG.md index b9d41b09d0a..b072655d78a 100644 --- a/gix-pack/CHANGELOG.md +++ b/gix-pack/CHANGELOG.md @@ -27,7 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 17 commits contributed to the release. + - 18 commits contributed to the release. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) diff --git a/gix-packetline/CHANGELOG.md b/gix-packetline/CHANGELOG.md index c508114165f..c9c75e9630b 100644 --- a/gix-packetline/CHANGELOG.md +++ b/gix-packetline/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 5 commits contributed to the release. + - 6 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1854 from GitoxideLabs/montly-report ([`16a248b`](https://github.com/GitoxideLabs/gitoxide/commit/16a248beddbfbd21621f2bb57aaa82dca35acb19)) diff --git a/gix-protocol/CHANGELOG.md b/gix-protocol/CHANGELOG.md index be45399ca73..fa34c3e636a 100644 --- a/gix-protocol/CHANGELOG.md +++ b/gix-protocol/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 11 commits contributed to the release. + - 12 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1909 from cruessler/take-to-components-in-fs-stack ([`5cb5337`](https://github.com/GitoxideLabs/gitoxide/commit/5cb5337efd7679d8a2ab4bd5e6a5da8c366f7f1a)) diff --git a/gix-refspec/CHANGELOG.md b/gix-refspec/CHANGELOG.md index fd9a3f8fac4..89fd907da42 100644 --- a/gix-refspec/CHANGELOG.md +++ b/gix-refspec/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 7 commits contributed to the release. + - 8 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) diff --git a/gix-revision/CHANGELOG.md b/gix-revision/CHANGELOG.md index 1664df50bb9..d0d8e75764d 100644 --- a/gix-revision/CHANGELOG.md +++ b/gix-revision/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 9 commits contributed to the release. + - 10 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1914](https://github.com/GitoxideLabs/gitoxide/issues/1914) @@ -32,6 +32,7 @@ A maintenance release without user-facing changes. * **[#1914](https://github.com/GitoxideLabs/gitoxide/issues/1914)** - Add tests to get a clearer understanding about some special cases ([`12cb847`](https://github.com/GitoxideLabs/gitoxide/commit/12cb8473b38a3eed9f267609aeadaf1a57caacb0)) * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1916 from GitoxideLabs/fix-1914 ([`32b54b3`](https://github.com/GitoxideLabs/gitoxide/commit/32b54b3ab7f101c6b9cd7c3349153c2fc71e496d)) diff --git a/gix-shallow/CHANGELOG.md b/gix-shallow/CHANGELOG.md index 4694efd3381..9d375a1cbf3 100644 --- a/gix-shallow/CHANGELOG.md +++ b/gix-shallow/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 3 commits contributed to the release. + - 4 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -24,6 +24,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1778 from GitoxideLabs/new-release ([`8df0db2`](https://github.com/GitoxideLabs/gitoxide/commit/8df0db2f8fe1832a5efd86d6aba6fb12c4c855de)) diff --git a/gix-status/CHANGELOG.md b/gix-status/CHANGELOG.md index 72f7175a1ea..1f71dda67fc 100644 --- a/gix-status/CHANGELOG.md +++ b/gix-status/CHANGELOG.md @@ -22,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 17 commits contributed to the release. + - 18 commits contributed to the release. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) diff --git a/gix-submodule/CHANGELOG.md b/gix-submodule/CHANGELOG.md index e1a590c8ede..da2ffaf5827 100644 --- a/gix-submodule/CHANGELOG.md +++ b/gix-submodule/CHANGELOG.md @@ -13,7 +13,7 @@ A maintenance release without user-facing changes. - - 7 commits contributed to the release. + - 8 commits contributed to the release. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -30,6 +30,7 @@ A maintenance release without user-facing changes.
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) diff --git a/gix-transport/CHANGELOG.md b/gix-transport/CHANGELOG.md index bbd266c7ae2..56c439c0dab 100644 --- a/gix-transport/CHANGELOG.md +++ b/gix-transport/CHANGELOG.md @@ -46,7 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 17 commits contributed to the release. + - 18 commits contributed to the release. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -63,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1907 from EliahKagan/run-ci/raw ([`7b17da6`](https://github.com/GitoxideLabs/gitoxide/commit/7b17da6ca1dce275de0d32d0b0d6c238621e6ee3)) diff --git a/gix-worktree-state/CHANGELOG.md b/gix-worktree-state/CHANGELOG.md index 56f1dbf7f97..35933d25522 100644 --- a/gix-worktree-state/CHANGELOG.md +++ b/gix-worktree-state/CHANGELOG.md @@ -40,7 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 21 commits contributed to the release. + - 22 commits contributed to the release. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1909 from cruessler/take-to-components-in-fs-stack ([`5cb5337`](https://github.com/GitoxideLabs/gitoxide/commit/5cb5337efd7679d8a2ab4bd5e6a5da8c366f7f1a)) diff --git a/gix/CHANGELOG.md b/gix/CHANGELOG.md index 9f899e4b5ee..f351b13446a 100644 --- a/gix/CHANGELOG.md +++ b/gix/CHANGELOG.md @@ -74,7 +74,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 56 commits contributed to the release. + - 57 commits contributed to the release. - 17 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1829](https://github.com/GitoxideLabs/gitoxide/issues/1829), [#1914](https://github.com/GitoxideLabs/gitoxide/issues/1914) @@ -95,6 +95,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **[#1914](https://github.com/GitoxideLabs/gitoxide/issues/1914)** - Don't panic when rev-parsing `^^^` and similar ([`aa8daf8`](https://github.com/GitoxideLabs/gitoxide/commit/aa8daf89bcc3c26baeb7d850c19bb9a5d403f555)) * **Uncategorized** + - Release gix-sec v0.10.12, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0 ([`ada5a94`](https://github.com/GitoxideLabs/gitoxide/commit/ada5a9447dc3c210afbd8866fe939c3f3a024226)) - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) From 039319dcbe2d4b6adf34ad764f1219792b9c9c19 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Fri, 4 Apr 2025 19:07:28 -0400 Subject: [PATCH 005/193] Fix `cargo deny` commands so they scan the whole workspace When `cargo deny` commands are run from the top-level directory of a workspace, and no `--manifest-path` option is pased, they implicitly use the top-level `Cargo.toml` file as their manifest. In workspaces where this is a virtual manifest, i.e. those where the top-level `Cargo.toml` defines only the workspace and not also a specific crate, running `cargo deny` without specifying any roots implicitly acts as though `--workspace` has been passed. (See https://embarkstudios.github.io/cargo-deny/cli/common.html for details.) In that situation, `--workspace` can be omitted and all crates in the workspace are still treated as roots for the scan. But the gitoxide repository's top-level workspace's `Cargo.toml` file is not a virtual manifest. It defines a workspace, but it also defines the `gitoxide` crate. As a result, `cargo deny` commands, as run on CI in the `cargo-deny` and `cargo-deny-advisories` jobs, and locally via `just audit`, were not guaranteed to check the entire workspace. They used only the `gitoxide` crate as a root for scanning, rather than using all crates defined in the workspace as roots as when `--workspace` is used or implied. It looks like this was not detected for three reasons: 1. Most of the workspace was usually covered, especially on CI where, since no `arguments` were passed, `cargo-deny-action` used the defualt of `--all-features`. *Most* transitive dependencies inside and outside of the gitoxide project seem to be used by the `gitoxide` crate by in some feature configuration. 2. The distinction between virtual and non-virtual top-level manifests of workspaces is subtle and not highlighted in the `cargo deny` documentation. 3. In `EmbarkStudios/cargo-deny-action`, the default value of `arguments` contains `--all-features` but not `--workspace` (nor any other options). Intuitively it feels like the default value would scan all crates in the repository that the action is being run on. That does happen in the perhaps more common case that the top-level `Cargo.toml` defines no crate, but not here. This was discovered in connection with #1924. It is why the `cargo-deny-advisories` job didn't catch RUSTSEC-2025-0022 (GHSA-4fcv-w3qc-ppgg) even as Dependabot did. To fix it, this adds `--workspace` explicitly in both `cargo deny` jobs run on CI, as well as in the `justfile`. This also adds `--all-features`: - On CI, adding `--all-features` is itself no change from before, since it is the implicit value of `arguments`. It has to be passed explicitly now that `arguments` has an explicit value. - In the `justfile`, adding `--all-features` does (at least in principle) make a difference. --- .github/workflows/ci.yml | 2 ++ justfile | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26d4755da19..a5c58d4e01a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -344,6 +344,7 @@ jobs: - uses: actions/checkout@v4 - uses: EmbarkStudios/cargo-deny-action@v2 with: + arguments: --workspace --all-features command: check advisories cargo-deny: @@ -353,6 +354,7 @@ jobs: - uses: actions/checkout@v4 - uses: EmbarkStudios/cargo-deny-action@v2 with: + arguments: --workspace --all-features command: check bans licenses sources wasm: diff --git a/justfile b/justfile index f143bc06abc..bf059b8e410 100755 --- a/justfile +++ b/justfile @@ -240,7 +240,7 @@ nix-shell-macos: # Run various auditing tools to help us stay legal and safe audit: - cargo deny check advisories bans licenses sources + cargo deny --workspace --all-features check advisories bans licenses sources # Run tests with `cargo nextest` (all unit-tests, no doc-tests, faster) nextest *FLAGS='--workspace': From a168807b2d354bdcd51f1c4758d2407dab98362f Mon Sep 17 00:00:00 2001 From: Pierre Chevalier Date: Fri, 14 Mar 2025 11:34:43 +0000 Subject: [PATCH 006/193] fix!: Hide the internal representation of EntryMode Change the gix-object API so that client code can't explicitely rely on the internal representation of `EntryMode`. This is necessary as we need to change it to allow round-trip behaviour for modes like `b"040000"` and `b"40000"` which currently share the `0o40000u16` representation. Use the opportunity to sprinkle a couple of optimizations in the parsing of the EntryMode since we had to go deep in understanding this code anyway, so may as well. Mostly, don't `reverse` the bytes when parsing. ``` TreeRefIter() time: [46.251 ns 46.390 ns 46.549 ns] change: [-17.685% -16.512% -15.664%] (p = 0.00 < 0.05) Performance has improved. Found 1 outliers among 100 measurements (1.00%) ``` Also add a test that shows the current incorrect behaviour. --- gix-object/src/tree/mod.rs | 136 +++++++++++++++------ gix-object/src/tree/ref_iter.rs | 42 +------ gix-object/tests/object/tree/entry_mode.rs | 39 +++--- 3 files changed, 125 insertions(+), 92 deletions(-) diff --git a/gix-object/src/tree/mod.rs b/gix-object/src/tree/mod.rs index f5889b2ea9a..cf5105f58c4 100644 --- a/gix-object/src/tree/mod.rs +++ b/gix-object/src/tree/mod.rs @@ -44,11 +44,98 @@ pub struct Editor<'a> { /// create it by converting [`EntryKind`] into `EntryMode`. #[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct EntryMode(pub u16); +pub struct EntryMode { + // Represents the value read from Git, except that "040000" is represented with 0o140000 but + // "40000" is represented with 0o40000 + internal: u16, +} + +impl TryFrom for tree::EntryMode { + type Error = u32; + fn try_from(mode: u32) -> Result { + Ok(match mode { + 0o40000 | 0o120000 | 0o160000 => EntryMode { internal: mode as u16 }, + blob_mode if blob_mode & 0o100000 == 0o100000 => EntryMode { internal: mode as u16 }, + _ => return Err(mode), + }) + } +} + +impl EntryMode { + /// Expose the value as a u16 (lossy, unlike the internal representation that is hidden) + pub const fn value(self) -> u16 { + self.internal + } + + /// Return the representation as used in the git internal format, which is octal and written + /// to the `backing` buffer. The respective sub-slice that was written to is returned. + pub fn as_bytes<'a>(&self, backing: &'a mut [u8; 6]) -> &'a BStr { + if self.internal == 0 { + std::slice::from_ref(&b'0') + } else { + for (idx, backing_octet) in backing.iter_mut().enumerate() { + let bit_pos = 3 /* because base 8 and 2^3 == 8*/ * (6 - idx - 1); + let oct_mask = 0b111 << bit_pos; + let digit = (self.internal & oct_mask) >> bit_pos; + *backing_octet = b'0' + digit as u8; + } + if backing[1] == b'4' { + &backing[1..6] + } else { + &backing[0..6] + } + } + .into() + } + + /// Construct an EntryMode from bytes represented as in the git internal format + /// Return the mode and the remainder of the bytes + pub(crate) fn extract_from_bytes(i: &[u8]) -> Option<(Self, &'_ [u8])> { + let mut mode = 0; + let mut idx = 0; + let mut space_pos = 0; + if i.is_empty() { + return None; + } + // const fn, this is why we can't have nice things (like `.iter().any()`) + while idx < i.len() { + let b = i[idx]; + // Delimiter, return what we got + if b == b' ' { + space_pos = idx; + break; + } + // Not a pure octal input + // Performance matters here, so `!(b'0'..=b'7').contains(&b)` won't do + #[allow(clippy::manual_range_contains)] + if b < b'0' || b > b'7' { + return None; + } + // More than 6 octal digits we must have hit the delimiter or the input was malformed + if idx > 6 { + return None; + } + mode = (mode << 3) + (b - b'0') as u16; + idx += 1; + } + Some((Self { internal: mode }, &i[(space_pos + 1)..])) + } + + /// Construct an EntryMode from bytes represented as in the git internal format + pub fn from_bytes(i: &[u8]) -> Option { + Self::extract_from_bytes(i).map(|(mode, _rest)| mode) + } +} impl std::fmt::Debug for EntryMode { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "EntryMode({:#o})", self.0) + write!(f, "EntryMode(0o{})", self.as_bytes(&mut Default::default())) + } +} + +impl std::fmt::Octal for EntryMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_bytes(&mut Default::default())) } } @@ -74,7 +161,7 @@ pub enum EntryKind { impl From for EntryMode { fn from(value: EntryKind) -> Self { - EntryMode(value as u16) + EntryMode { internal: value as u16 } } } @@ -100,22 +187,14 @@ impl EntryKind { } } -impl std::ops::Deref for EntryMode { - type Target = u16; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - const IFMT: u16 = 0o170000; impl EntryMode { /// Discretize the raw mode into an enum with well-known state while dropping unnecessary details. pub const fn kind(&self) -> EntryKind { - let etype = self.0 & IFMT; + let etype = self.value() & IFMT; if etype == 0o100000 { - if self.0 & 0o000100 == 0o000100 { + if self.value() & 0o000100 == 0o000100 { EntryKind::BlobExecutable } else { EntryKind::Blob @@ -131,27 +210,27 @@ impl EntryMode { /// Return true if this entry mode represents a Tree/directory pub const fn is_tree(&self) -> bool { - self.0 & IFMT == EntryKind::Tree as u16 + self.value() & IFMT == EntryKind::Tree as u16 } /// Return true if this entry mode represents the commit of a submodule. pub const fn is_commit(&self) -> bool { - self.0 & IFMT == EntryKind::Commit as u16 + self.value() & IFMT == EntryKind::Commit as u16 } /// Return true if this entry mode represents a symbolic link pub const fn is_link(&self) -> bool { - self.0 & IFMT == EntryKind::Link as u16 + self.value() & IFMT == EntryKind::Link as u16 } /// Return true if this entry mode represents anything BUT Tree/directory pub const fn is_no_tree(&self) -> bool { - self.0 & IFMT != EntryKind::Tree as u16 + self.value() & IFMT != EntryKind::Tree as u16 } /// Return true if the entry is any kind of blob. pub const fn is_blob(&self) -> bool { - self.0 & IFMT == 0o100000 + self.value() & IFMT == 0o100000 } /// Return true if the entry is an executable blob. @@ -178,27 +257,6 @@ impl EntryMode { Commit => "commit", } } - - /// Return the representation as used in the git internal format, which is octal and written - /// to the `backing` buffer. The respective sub-slice that was written to is returned. - pub fn as_bytes<'a>(&self, backing: &'a mut [u8; 6]) -> &'a BStr { - if self.0 == 0 { - std::slice::from_ref(&b'0') - } else { - let mut nb = 0; - let mut n = self.0; - while n > 0 { - let remainder = (n % 8) as u8; - backing[nb] = b'0' + remainder; - n /= 8; - nb += 1; - } - let res = &mut backing[..nb]; - res.reverse(); - res - } - .into() - } } impl TreeRef<'_> { diff --git a/gix-object/src/tree/ref_iter.rs b/gix-object/src/tree/ref_iter.rs index 9833a3c2c31..72f3233defc 100644 --- a/gix-object/src/tree/ref_iter.rs +++ b/gix-object/src/tree/ref_iter.rs @@ -171,38 +171,7 @@ impl<'a> TryFrom<&'a [u8]> for tree::EntryMode { type Error = &'a [u8]; fn try_from(mode: &'a [u8]) -> Result { - mode_from_decimal(mode) - .map(|(mode, _rest)| tree::EntryMode(mode as u16)) - .ok_or(mode) - } -} - -fn mode_from_decimal(i: &[u8]) -> Option<(u32, &[u8])> { - let mut mode = 0u32; - let mut spacer_pos = 1; - for b in i.iter().take_while(|b| **b != b' ') { - if *b < b'0' || *b > b'7' { - return None; - } - mode = (mode << 3) + u32::from(b - b'0'); - spacer_pos += 1; - } - if i.len() < spacer_pos { - return None; - } - let (_, i) = i.split_at(spacer_pos); - Some((mode, i)) -} - -impl TryFrom for tree::EntryMode { - type Error = u32; - - fn try_from(mode: u32) -> Result { - Ok(match mode { - 0o40000 | 0o120000 | 0o160000 => tree::EntryMode(mode as u16), - blob_mode if blob_mode & 0o100000 == 0o100000 => tree::EntryMode(mode as u16), - _ => return Err(mode), - }) + tree::EntryMode::from_bytes(mode).ok_or(mode) } } @@ -210,15 +179,10 @@ mod decode { use bstr::ByteSlice; use winnow::{error::ParserError, prelude::*}; - use crate::{ - tree, - tree::{ref_iter::mode_from_decimal, EntryRef}, - TreeRef, - }; + use crate::{tree, tree::EntryRef, TreeRef}; pub fn fast_entry(i: &[u8]) -> Option<(&[u8], EntryRef<'_>)> { - let (mode, i) = mode_from_decimal(i)?; - let mode = tree::EntryMode::try_from(mode).ok()?; + let (mode, i) = tree::EntryMode::extract_from_bytes(i)?; let (filename, i) = i.split_at(i.find_byte(0)?); let i = &i[1..]; const HASH_LEN_FIXME: usize = 20; // TODO(SHA256): know actual/desired length or we may overshoot diff --git a/gix-object/tests/object/tree/entry_mode.rs b/gix-object/tests/object/tree/entry_mode.rs index 0fe4c17fc59..4cf5b7eca23 100644 --- a/gix-object/tests/object/tree/entry_mode.rs +++ b/gix-object/tests/object/tree/entry_mode.rs @@ -16,11 +16,14 @@ fn is_methods() { } assert!(mode(EntryKind::Blob).is_blob()); - assert!(EntryMode(0o100645).is_blob()); - assert_eq!(EntryMode(0o100645).kind(), EntryKind::Blob); - assert!(!EntryMode(0o100675).is_executable()); - assert!(EntryMode(0o100700).is_executable()); - assert_eq!(EntryMode(0o100700).kind(), EntryKind::BlobExecutable); + assert!(EntryMode::from_bytes(b"100645").unwrap().is_blob()); + assert_eq!(EntryMode::from_bytes(b"100645").unwrap().kind(), EntryKind::Blob); + assert!(!EntryMode::from_bytes(b"100675").unwrap().is_executable()); + assert!(EntryMode::from_bytes(b"100700").unwrap().is_executable()); + assert_eq!( + EntryMode::from_bytes(b"100700").unwrap().kind(), + EntryKind::BlobExecutable + ); assert!(!mode(EntryKind::Blob).is_link()); assert!(mode(EntryKind::BlobExecutable).is_blob()); assert!(mode(EntryKind::BlobExecutable).is_executable()); @@ -29,17 +32,19 @@ fn is_methods() { assert!(!mode(EntryKind::Link).is_blob()); assert!(mode(EntryKind::Link).is_link()); - assert!(EntryMode(0o121234).is_link()); - assert_eq!(EntryMode(0o121234).kind(), EntryKind::Link); + assert!(EntryMode::from_bytes(b"121234").unwrap().is_link()); + assert_eq!(EntryMode::from_bytes(b"121234").unwrap().kind(), EntryKind::Link); assert!(mode(EntryKind::Link).is_blob_or_symlink()); assert!(mode(EntryKind::Tree).is_tree()); - assert!(EntryMode(0o040101).is_tree()); - assert_eq!(EntryMode(0o040101).kind(), EntryKind::Tree); + assert!(EntryMode::from_bytes(b"040101").unwrap().is_tree()); + assert_eq!(EntryMode::from_bytes(b"040101").unwrap().kind(), EntryKind::Tree); + assert!(EntryMode::from_bytes(b"40101").unwrap().is_tree()); + assert_eq!(EntryMode::from_bytes(b"40101").unwrap().kind(), EntryKind::Tree); assert!(mode(EntryKind::Commit).is_commit()); - assert!(EntryMode(0o167124).is_commit()); - assert_eq!(EntryMode(0o167124).kind(), EntryKind::Commit); + assert!(EntryMode::from_bytes(b"167124").unwrap().is_commit()); + assert_eq!(EntryMode::from_bytes(b"167124").unwrap().kind(), EntryKind::Commit); assert_eq!( - EntryMode(0o000000).kind(), + EntryMode::from_bytes(b"000000").unwrap().kind(), EntryKind::Commit, "commit is really 'anything else' as `kind()` can't fail" ); @@ -58,13 +63,19 @@ fn as_bytes() { (EntryKind::Link.into(), EntryKind::Link.as_octal_str()), (EntryKind::Commit.into(), EntryKind::Commit.as_octal_str()), ( - EntryMode::try_from(b"100744 ".as_ref()).expect("valid"), + EntryMode::from_bytes(b"100744 ".as_ref()).expect("valid"), "100744".into(), ), ( - EntryMode::try_from(b"100644 ".as_ref()).expect("valid"), + EntryMode::from_bytes(b"100644 ".as_ref()).expect("valid"), "100644".into(), ), + // Show incorrect behaviour: b"040000" doesn't round-trip + ( + EntryMode::from_bytes(b"040000".as_ref()).expect("valid"), + "40000".into(), + ), + (EntryMode::from_bytes(b"40000".as_ref()).expect("valid"), "40000".into()), ] { assert_eq!(mode.as_bytes(&mut buf), expected); } From 8969245a6b5874d8524f508569ae1266e48d100e Mon Sep 17 00:00:00 2001 From: Pierre Chevalier Date: Sat, 5 Apr 2025 09:50:35 +0800 Subject: [PATCH 007/193] adapt to changes in gix-object --- examples/ls-tree.rs | 4 ++-- gitoxide-core/src/repository/diff.rs | 8 ++++---- gix-index/src/entry/mode.rs | 3 ++- gix-merge/tests/merge/tree/baseline.rs | 4 ++-- gix/src/object/tree/iter.rs | 4 ++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/examples/ls-tree.rs b/examples/ls-tree.rs index 17af144040f..fdce7c14cb4 100644 --- a/examples/ls-tree.rs +++ b/examples/ls-tree.rs @@ -54,8 +54,8 @@ fn run(args: Args) -> anyhow::Result<()> { for entry in entries { writeln!( out, - "{:06o} {:4} {} {}", - *entry.mode, + "{:>6o} {:4} {} {}", + entry.mode, entry.mode.as_str(), entry.hash, entry.path diff --git a/gitoxide-core/src/repository/diff.rs b/gitoxide-core/src/repository/diff.rs index 9e6c6d2edae..600eaf2efff 100644 --- a/gitoxide-core/src/repository/diff.rs +++ b/gitoxide-core/src/repository/diff.rs @@ -49,7 +49,7 @@ fn write_changes( } => { writeln!(out, "A: {}", typed_location(location, entry_mode))?; writeln!(out, " {}", id.attach(repo).shorten_or_id())?; - writeln!(out, " -> {:o}", entry_mode.0)?; + writeln!(out, " -> {entry_mode:o}")?; } gix::diff::tree_with_rewrites::Change::Deletion { location, @@ -59,7 +59,7 @@ fn write_changes( } => { writeln!(out, "D: {}", typed_location(location, entry_mode))?; writeln!(out, " {}", id.attach(repo).shorten_or_id())?; - writeln!(out, " {:o} ->", entry_mode.0)?; + writeln!(out, " {entry_mode:o} ->")?; } gix::diff::tree_with_rewrites::Change::Modification { location, @@ -76,7 +76,7 @@ fn write_changes( id = id.attach(repo).shorten_or_id() )?; if previous_entry_mode != entry_mode { - writeln!(out, " {:o} -> {:o}", previous_entry_mode.0, entry_mode.0)?; + writeln!(out, " {previous_entry_mode:o} -> {entry_mode:o}")?; } } gix::diff::tree_with_rewrites::Change::Rewrite { @@ -101,7 +101,7 @@ fn write_changes( id = id.attach(repo).shorten_or_id() )?; if source_entry_mode != entry_mode { - writeln!(out, " {:o} -> {:o}", source_entry_mode.0, entry_mode.0)?; + writeln!(out, " {source_entry_mode:o} -> {entry_mode:o}")?; } } } diff --git a/gix-index/src/entry/mode.rs b/gix-index/src/entry/mode.rs index ec839d5335e..817d7a06e0e 100644 --- a/gix-index/src/entry/mode.rs +++ b/gix-index/src/entry/mode.rs @@ -71,7 +71,8 @@ impl Mode { impl From for Mode { fn from(value: gix_object::tree::EntryMode) -> Self { - Self::from_bits_truncate(u32::from(value.0)) + let value: u16 = value.value(); + Self::from_bits_truncate(u32::from(value)) } } diff --git a/gix-merge/tests/merge/tree/baseline.rs b/gix-merge/tests/merge/tree/baseline.rs index e8e399f138c..32df03ffcb3 100644 --- a/gix-merge/tests/merge/tree/baseline.rs +++ b/gix-merge/tests/merge/tree/baseline.rs @@ -262,7 +262,7 @@ fn parse_conflict_file_info(line: &str) -> Option<(Entry, Side)> { Entry { location: path.to_owned(), id: gix_hash::ObjectId::from_hex(hex_id.as_bytes()).unwrap(), - mode: EntryMode(gix_utils::btoi::to_signed_with_radix::(oct_mode.as_bytes(), 8).unwrap() as u16), + mode: EntryMode::try_from(oct_mode.as_bytes()).unwrap(), }, match stage { "1" => Side::Ancestor, @@ -339,7 +339,7 @@ pub fn visualize_tree( mode = if mode.is_tree() { "".into() } else { - format!("{:o}:", mode.0) + format!("{mode:o}:") } ) } diff --git a/gix/src/object/tree/iter.rs b/gix/src/object/tree/iter.rs index 00519e6cef5..572f0a71f90 100644 --- a/gix/src/object/tree/iter.rs +++ b/gix/src/object/tree/iter.rs @@ -50,8 +50,8 @@ impl std::fmt::Display for EntryRef<'_, '_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, - "{:06o} {:>6} {}\t{}", - *self.mode(), + "{:>6o} {:>6} {}\t{}", + self.mode(), self.mode().as_str(), self.id().shorten_or_id(), self.filename() From 5bfc2f540aac5be997159e93783d56ed147b0a2f Mon Sep 17 00:00:00 2001 From: Pierre Chevalier Date: Fri, 4 Apr 2025 12:23:33 +0100 Subject: [PATCH 008/193] fix!: Allow round-tripping for Trees Change the internal representation of `EntryMode` to fix a round-trip issue. Prior to this change, both `b"040000"` and `b"40000"` mapped to `0o40000u16`. After this change, * `b"040000"` is represented by `0o140000` * `b"40000"` is represented by `0o40000` *Tests*: We can see in the `as_bytes` test that the behaviour is fixed now. We also add a test to show we now can round-trip on the existing test fixtures which contain examples of this situation. *Performance*: We pay a cost for this compared to the parent commit: ``` TreeRefIter() time: [50.403 ns 50.611 ns 50.830 ns] change: [+8.6240% +9.0871% +9.5776%] (p = 0.00 < 0.05) Performance has regressed. ``` but we already did enough optimizations to pay for this earlier in this PR: * `main`: `~55 ns` * `parent`: `~46 ns` * `this commit`: `~50 ns` Fixes 1887 --- gix-object/src/tree/mod.rs | 20 ++++++++++++++++++-- gix-object/tests/object/tree/entry_mode.rs | 3 +-- gix-object/tests/object/tree/from_bytes.rs | 4 ++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/gix-object/src/tree/mod.rs b/gix-object/src/tree/mod.rs index cf5105f58c4..60399de4d32 100644 --- a/gix-object/src/tree/mod.rs +++ b/gix-object/src/tree/mod.rs @@ -64,7 +64,13 @@ impl TryFrom for tree::EntryMode { impl EntryMode { /// Expose the value as a u16 (lossy, unlike the internal representation that is hidden) pub const fn value(self) -> u16 { - self.internal + // Demangle the hack: In the case where the second leftmost octet is 4 (Tree), the leftmost bit is + // there to represent whether the bytes representation should have 5 or 6 octets + if self.internal & IFMT == 0o140000 { + 0o040000 + } else { + self.internal + } } /// Return the representation as used in the git internal format, which is octal and written @@ -79,8 +85,14 @@ impl EntryMode { let digit = (self.internal & oct_mask) >> bit_pos; *backing_octet = b'0' + digit as u8; } + // Hack: `0o140000` represents `"040000"`, `0o40000` represents `"40000"` if backing[1] == b'4' { - &backing[1..6] + if backing[0] == b'1' { + backing[0] = b'0'; + &backing[0..6] + } else { + &backing[1..6] + } } else { &backing[0..6] } @@ -118,6 +130,10 @@ impl EntryMode { mode = (mode << 3) + (b - b'0') as u16; idx += 1; } + // Hack: `0o140000` represents `"040000"`, `0o40000` represents `"40000"` + if mode == 0o040000 && i[0] == b'0' { + mode += 0o100000; + } Some((Self { internal: mode }, &i[(space_pos + 1)..])) } diff --git a/gix-object/tests/object/tree/entry_mode.rs b/gix-object/tests/object/tree/entry_mode.rs index 4cf5b7eca23..b218128b831 100644 --- a/gix-object/tests/object/tree/entry_mode.rs +++ b/gix-object/tests/object/tree/entry_mode.rs @@ -70,10 +70,9 @@ fn as_bytes() { EntryMode::from_bytes(b"100644 ".as_ref()).expect("valid"), "100644".into(), ), - // Show incorrect behaviour: b"040000" doesn't round-trip ( EntryMode::from_bytes(b"040000".as_ref()).expect("valid"), - "40000".into(), + "040000".into(), ), (EntryMode::from_bytes(b"40000".as_ref()).expect("valid"), "40000".into()), ] { diff --git a/gix-object/tests/object/tree/from_bytes.rs b/gix-object/tests/object/tree/from_bytes.rs index 97b68d8daa0..d546ac3d226 100644 --- a/gix-object/tests/object/tree/from_bytes.rs +++ b/gix-object/tests/object/tree/from_bytes.rs @@ -101,6 +101,10 @@ fn special_trees() -> crate::Result { expected_entry_count, "{name}" ); + // Show we can roundtrip + let mut buf: Vec = Default::default(); + actual.write_to(&mut buf).expect("Failed to write bytes to buffer"); + assert_eq!(buf, fixture); } Ok(()) } From 103819dbe2d86790a6ac4c6be3f21e5d4455dfd2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 5 Apr 2025 09:54:40 +0800 Subject: [PATCH 009/193] refactor (#1917) --- gix-object/src/tree/mod.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/gix-object/src/tree/mod.rs b/gix-object/src/tree/mod.rs index 60399de4d32..b7ae614965b 100644 --- a/gix-object/src/tree/mod.rs +++ b/gix-object/src/tree/mod.rs @@ -24,7 +24,7 @@ pub mod write; pub struct Editor<'a> { /// A way to lookup trees. find: &'a dyn crate::FindExt, - /// The kind of hashes to produce + /// The kind of hashes to produce> object_hash: gix_hash::Kind, /// All trees we currently hold in memory. Each of these may change while adding and removing entries. /// null-object-ids mark tree-entries whose value we don't know yet, they are placeholders that will be @@ -46,7 +46,7 @@ pub struct Editor<'a> { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct EntryMode { // Represents the value read from Git, except that "040000" is represented with 0o140000 but - // "40000" is represented with 0o40000 + // "40000" is represented with 0o40000. internal: u16, } @@ -62,10 +62,10 @@ impl TryFrom for tree::EntryMode { } impl EntryMode { - /// Expose the value as a u16 (lossy, unlike the internal representation that is hidden) + /// Expose the value as u16 (lossy, unlike the internal representation that is hidden). pub const fn value(self) -> u16 { // Demangle the hack: In the case where the second leftmost octet is 4 (Tree), the leftmost bit is - // there to represent whether the bytes representation should have 5 or 6 octets + // there to represent whether the bytes representation should have 5 or 6 octets. if self.internal & IFMT == 0o140000 { 0o040000 } else { @@ -85,7 +85,7 @@ impl EntryMode { let digit = (self.internal & oct_mask) >> bit_pos; *backing_octet = b'0' + digit as u8; } - // Hack: `0o140000` represents `"040000"`, `0o40000` represents `"40000"` + // Hack: `0o140000` represents `"040000"`, `0o40000` represents `"40000"`. if backing[1] == b'4' { if backing[0] == b'1' { backing[0] = b'0'; @@ -101,7 +101,7 @@ impl EntryMode { } /// Construct an EntryMode from bytes represented as in the git internal format - /// Return the mode and the remainder of the bytes + /// Return the mode and the remainder of the bytes. pub(crate) fn extract_from_bytes(i: &[u8]) -> Option<(Self, &'_ [u8])> { let mut mode = 0; let mut idx = 0; @@ -109,7 +109,7 @@ impl EntryMode { if i.is_empty() { return None; } - // const fn, this is why we can't have nice things (like `.iter().any()`) + // const fn, this is why we can't have nice things (like `.iter().any()`). while idx < i.len() { let b = i[idx]; // Delimiter, return what we got @@ -117,27 +117,27 @@ impl EntryMode { space_pos = idx; break; } - // Not a pure octal input - // Performance matters here, so `!(b'0'..=b'7').contains(&b)` won't do + // Not a pure octal input. + // Performance matters here, so `!(b'0'..=b'7').contains(&b)` won't do. #[allow(clippy::manual_range_contains)] if b < b'0' || b > b'7' { return None; } - // More than 6 octal digits we must have hit the delimiter or the input was malformed + // More than 6 octal digits we must have hit the delimiter or the input was malformed. if idx > 6 { return None; } mode = (mode << 3) + (b - b'0') as u16; idx += 1; } - // Hack: `0o140000` represents `"040000"`, `0o40000` represents `"40000"` + // Hack: `0o140000` represents `"040000"`, `0o40000` represents `"40000"`. if mode == 0o040000 && i[0] == b'0' { mode += 0o100000; } Some((Self { internal: mode }, &i[(space_pos + 1)..])) } - /// Construct an EntryMode from bytes represented as in the git internal format + /// Construct an EntryMode from bytes represented as in the git internal format. pub fn from_bytes(i: &[u8]) -> Option { Self::extract_from_bytes(i).map(|(mode, _rest)| mode) } @@ -158,7 +158,7 @@ impl std::fmt::Octal for EntryMode { /// A discretized version of ideal and valid values for entry modes. /// /// Note that even though it can represent every valid [mode](EntryMode), it might -/// loose information due to that as well. +/// lose information due to that as well. #[derive(Clone, Copy, PartialEq, Eq, Debug, Ord, PartialOrd, Hash)] #[repr(u16)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] From 5ac310263d612921719d444fcdcc7fe1b16aeea5 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Fri, 4 Apr 2025 22:04:38 -0400 Subject: [PATCH 010/193] Add missing `apt-get update` in CI `test` job The CI `test` job's "Setup dependencies" step had `apt-get install` without having previously run `apt-get update`. This often does not work, and in a CI environment one should not typically expect it to work because package indexes in a virtual machine just provisioned from an image, if present at all, may be very outdated. But for some reason it had been working until recently, when breakages were observed, including in #1924 (though the breakage is not related to the changes in that PR). This runs `apt-get update` before `apt-get install` in that CI job, as had already been done in the other CI jobs and as had likely always been intended. This should make the "Setup dependencies" step work again. --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5c58d4e01a..726ca26243e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -133,7 +133,9 @@ jobs: - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: Setup dependencies - run: sudo apt-get install -y --no-install-recommends liblzma-dev + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends liblzma-dev - uses: extractions/setup-just@v3 - uses: taiki-e/install-action@v2 with: From ee6ee9923e56e4f454defa1fe442bfee1ff1dd9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 02:29:59 +0000 Subject: [PATCH 011/193] build(deps): bump openssl in the cargo group across 1 directory Bumps the cargo group with 1 update in the / directory: [openssl](https://github.com/sfackler/rust-openssl). Updates `openssl` from 0.10.71 to 0.10.72 - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.71...openssl-v0.10.72) --- updated-dependencies: - dependency-name: openssl dependency-version: 0.10.72 dependency-type: indirect dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ec8dce0a24..6ad802139d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4006,9 +4006,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.71" +version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ "bitflags 2.9.0", "cfg-if", @@ -4038,9 +4038,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.106" +version = "0.9.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" dependencies = [ "cc", "libc", From a20b3d053b43d4613127e36994f181868cafb730 Mon Sep 17 00:00:00 2001 From: Pierre Chevalier Date: Fri, 4 Apr 2025 15:59:12 +0100 Subject: [PATCH 012/193] fix: Make email with spaces roundtrip. We see this situation in commits in the wild. --- gix-actor/src/signature/decode.rs | 22 +++++++++++++--------- gix-actor/tests/identity/mod.rs | 7 +++---- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/gix-actor/src/signature/decode.rs b/gix-actor/src/signature/decode.rs index dc07accbfdb..fecdfaf773b 100644 --- a/gix-actor/src/signature/decode.rs +++ b/gix-actor/src/signature/decode.rs @@ -79,11 +79,7 @@ pub(crate) mod function { StrContext::Label("Closing '>' not found"), )))?; let i_name_and_email = &i[..right_delim_idx]; - let skip_from_right = i_name_and_email - .iter() - .rev() - .take_while(|b| b.is_ascii_whitespace() || **b == b'>') - .count(); + let skip_from_right = i_name_and_email.iter().rev().take_while(|b| **b == b'>').count(); let left_delim_idx = i_name_and_email .find_byte(b'<') .ok_or(ErrMode::Cut(E::from_input(i).add_context( @@ -91,10 +87,7 @@ pub(crate) mod function { &start, StrContext::Label("Opening '<' not found"), )))?; - let skip_from_left = i[left_delim_idx..] - .iter() - .take_while(|b| b.is_ascii_whitespace() || **b == b'<') - .count(); + let skip_from_left = i[left_delim_idx..].iter().take_while(|b| **b == b'<').count(); let mut name = i[..left_delim_idx].as_bstr(); name = name.strip_suffix(b" ").unwrap_or(name).as_bstr(); @@ -164,6 +157,17 @@ mod tests { ); } + #[test] + fn email_with_space() { + assert_eq!( + decode + .parse_peek(b"Sebastian Thiel <\tbyronimo@gmail.com > 1528473343 +0230") + .expect("parse to work") + .1, + signature("Sebastian Thiel", "\tbyronimo@gmail.com ", 1528473343, Sign::Plus, 9000) + ); + } + #[test] fn negative_offset_0000() { assert_eq!( diff --git a/gix-actor/tests/identity/mod.rs b/gix-actor/tests/identity/mod.rs index 72d9421bd84..2dd82f722e6 100644 --- a/gix-actor/tests/identity/mod.rs +++ b/gix-actor/tests/identity/mod.rs @@ -5,6 +5,9 @@ use gix_actor::Identity; fn round_trip() -> gix_testtools::Result { static DEFAULTS: &[&[u8]] = &[ b"Sebastian Thiel ", + b"Sebastian Thiel < byronimo@gmail.com>", + b"Sebastian Thiel ", + b"Sebastian Thiel <\tbyronimo@gmail.com \t >", ".. ☺️Sebastian 王知明 Thiel🙌 .. ".as_bytes(), b".. whitespace \t is explicitly allowed - unicode aware trimming must be done elsewhere " ]; @@ -25,10 +28,6 @@ fn lenient_parsing() -> gix_testtools::Result { ] { let identity = gix_actor::IdentityRef::from_bytes::<()>(input.as_bytes()).unwrap(); assert_eq!(identity.name, "First Last"); - assert_eq!( - identity.email, "fl Date: Fri, 4 Apr 2025 16:02:41 +0100 Subject: [PATCH 013/193] adapt to changes in gix-actor. Stop trimming the email at parsing time. We see poorly formatted emails with a space at the end in real Git repos and we wish for the gitoxide representation for such commits to roundtrip. Propagate the fix from `gix-actor` and add a test to show we now roundtrip. --- gix-object/tests/fixtures/commit/email-with-space.txt | 5 +++++ gix-object/tests/object/encode/mod.rs | 1 + 2 files changed, 6 insertions(+) create mode 100644 gix-object/tests/fixtures/commit/email-with-space.txt diff --git a/gix-object/tests/fixtures/commit/email-with-space.txt b/gix-object/tests/fixtures/commit/email-with-space.txt new file mode 100644 index 00000000000..d61b3e6a4ac --- /dev/null +++ b/gix-object/tests/fixtures/commit/email-with-space.txt @@ -0,0 +1,5 @@ +tree 1b2dfb4ac5e42080b682fc676e9738c94ce6d54d +author Sebastian Thiel 1592437401 +0800 +committer Sebastian Thiel 1592437401 +0800 + +In the author line, the email is followed by a space diff --git a/gix-object/tests/object/encode/mod.rs b/gix-object/tests/object/encode/mod.rs index d7a028b0c7a..81cb9c73160 100644 --- a/gix-object/tests/object/encode/mod.rs +++ b/gix-object/tests/object/encode/mod.rs @@ -87,6 +87,7 @@ mod commit { round_trip!( gix_object::Commit, gix_object::CommitRef, + "commit/email-with-space.txt", "commit/signed-whitespace.txt", "commit/two-multiline-headers.txt", "commit/mergetag.txt", From b2bccbc4d2ebb085a7958a0d077d65946369210d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 5 Apr 2025 10:36:45 +0800 Subject: [PATCH 014/193] doc: inform about untrimmed name and email --- gix-actor/src/lib.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/gix-actor/src/lib.rs b/gix-actor/src/lib.rs index e582541cb1a..ec182e96d1d 100644 --- a/gix-actor/src/lib.rs +++ b/gix-actor/src/lib.rs @@ -28,9 +28,13 @@ pub mod signature; #[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Identity { - /// The actors name. + /// The actors name, potentially with whitespace as parsed. + /// + /// Use [IdentityRef::trim()] or trim manually to be able to clean it up. pub name: BString, - /// The actor's email. + /// The actor's email, potentially with whitespace and garbage as parsed. + /// + /// Use [IdentityRef::trim()] or trim manually to be able to clean it up. pub email: BString, } @@ -38,10 +42,14 @@ pub struct Identity { #[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct IdentityRef<'a> { - /// The actors name. + /// The actors name, potentially with whitespace as parsed. + /// + /// Use [IdentityRef::trim()] or trim manually to be able to clean it up. #[cfg_attr(feature = "serde", serde(borrow))] pub name: &'a BStr, - /// The actor's email. + /// The actor's email, potentially with whitespace and garbage as parsed. + /// + /// Use [IdentityRef::trim()] or trim manually to be able to clean it up. pub email: &'a BStr, } @@ -51,9 +59,13 @@ pub struct IdentityRef<'a> { #[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Signature { - /// The actors name. + /// The actors name, potentially with whitespace as parsed. + /// + /// Use [SignatureRef::trim()] or trim manually to be able to clean it up. pub name: BString, - /// The actor's email. + /// The actor's email, potentially with whitespace and garbage as parsed. + /// + /// Use [SignatureRef::trim()] or trim manually to be able to clean it up. pub email: BString, /// The time stamp at which the signature is performed. pub time: Time, @@ -65,10 +77,14 @@ pub struct Signature { #[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SignatureRef<'a> { - /// The actor's name. + /// The actors name, potentially with whitespace as parsed. + /// + /// Use [SignatureRef::trim()] or trim manually to be able to clean it up. #[cfg_attr(feature = "serde", serde(borrow))] pub name: &'a BStr, - /// The actor's email. + /// The actor's email, potentially with whitespace and garbage as parsed. + /// + /// Use [SignatureRef::trim()] or trim manually to be able to clean it up. pub email: &'a BStr, /// The time stamp at which the signature was performed. pub time: gix_date::Time, From 39e35a30453f8860bb115a254c25a83b85cfd820 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 5 Apr 2025 10:42:24 +0800 Subject: [PATCH 015/193] Bring back test-case to show how trailing slashes are handled (#1438) --- gix-actor/tests/identity/mod.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/gix-actor/tests/identity/mod.rs b/gix-actor/tests/identity/mod.rs index 2dd82f722e6..d3787d9a732 100644 --- a/gix-actor/tests/identity/mod.rs +++ b/gix-actor/tests/identity/mod.rs @@ -22,12 +22,22 @@ fn round_trip() -> gix_testtools::Result { #[test] fn lenient_parsing() -> gix_testtools::Result { - for input in [ - "First Last<> >", - "First Last>\n", + for (input, expected_email) in [ + ( + "First Last<> >", + "fl > ", + ), + ( + "First Last>\n", + "fl (input.as_bytes()).unwrap(); assert_eq!(identity.name, "First Last"); + assert_eq!( + identity.email, expected_email, + "emails are parsed but left as is for round-tripping" + ); let signature: Identity = identity.into(); let mut output = Vec::new(); let err = signature.write_to(&mut output).unwrap_err(); From 3cfd7fa035bb71aaf75f93d415d008b54e30e472 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sat, 5 Apr 2025 00:15:42 -0400 Subject: [PATCH 016/193] Delist LicenseRef-ring, as ring no longer uses it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this change, we get a warning: $ cargo deny --workspace --all-features check licenses warning[license-not-encountered]: license was not encountered ┌─ /home/ek/source/repos/gitoxide/deny.toml:32:6 │ 32 │ "LicenseRef-ring", │ ━━━━━━━━━━━━━━━ unmatched license allowance licenses ok The same warning is shown in the `cargo-deny` job check on CI. This happens because `ring` no longer uses a custom/nonstandard license, instead using `Apache-2.0 AND ISC` since version 0.17.10. (See https://github.com/briansmith/ring/pull/2402 and https://crates.io/crates/ring/versions for details.) Nothing in this workspace depends directly or directly on old versions of `ring` that use that license, so this removes it from the list of licenses in `deny.toml`. --- deny.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/deny.toml b/deny.toml index a82e3b44407..dd76f31372f 100644 --- a/deny.toml +++ b/deny.toml @@ -29,7 +29,6 @@ allow = [ "MIT", "MIT-0", "ISC", - "LicenseRef-ring", "OpenSSL", "Zlib", "MPL-2.0", From f8fb226950f9e5f3dc6898c28cf735dd0ec0da1b Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sat, 5 Apr 2025 00:29:31 -0400 Subject: [PATCH 017/193] Use "reason" field to explain ignored advisory This turns the comment in `cargo.deny` explaining why we currently ignore the informational advisory RUSTSEC-2024-0436 in `paste` into data that could be parsed and displayed by tools, by using the form with `id` and `reason` fields, where the old comment text is the value of the `reason` field. This is one of the forms documented in: https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html#the-ignore-field-optional --- deny.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deny.toml b/deny.toml index dd76f31372f..26587fb91b6 100644 --- a/deny.toml +++ b/deny.toml @@ -9,8 +9,7 @@ # https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html [advisories] ignore = [ - # `paste` - macro crate without replacement - "RUSTSEC-2024-0436" + { id = "RUSTSEC-2024-0436", reason = "`paste` - macro crate without replacement" }, ] From 7ad29e68f8096c08564febe1de78c2dba2e0a131 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sat, 5 Apr 2025 01:20:35 -0400 Subject: [PATCH 018/193] Reorder `with` subkeys in `cargo-deny-*` CI for clarity This is only a minor improvement in clarity now, but the benefit will be greater with the immediately forthcoming change, and doing this separately makes it so the next commit can be reverted by itself once it is no longer needed. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 726ca26243e..1752d8d356d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -346,8 +346,8 @@ jobs: - uses: actions/checkout@v4 - uses: EmbarkStudios/cargo-deny-action@v2 with: - arguments: --workspace --all-features command: check advisories + arguments: --workspace --all-features cargo-deny: runs-on: ubuntu-latest @@ -356,8 +356,8 @@ jobs: - uses: actions/checkout@v4 - uses: EmbarkStudios/cargo-deny-action@v2 with: - arguments: --workspace --all-features command: check bans licenses sources + arguments: --workspace --all-features wasm: name: WebAssembly From 67d9bf494315a6b5b172bd81b330b1c60d16d46d Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sat, 5 Apr 2025 01:34:21 -0400 Subject: [PATCH 019/193] On CI, have `cargo deny` allow RUSTSEC-2025-0021 via gix-testtools This splits the `EmbarkStudios/cargo-deny-action` step in `cargo-deny-advisories` into two such steps: - Scan the workspace except prune `gix-testtools` and everything reachable through it (following it neither as a root, nor when it is found as dev dependency of another crate). This doesn't get to its obsolete dependencies, while still ensuring that nothing in the workspace *except* what we reach through `gix-testtools` is affected by RUSTSEC-2025-0021. - Scan the whole workspace, including `gix-testtools` and all its dependencies, including the obsolete version of `gix-features` that is affected by RUSTSEC-2025-0021. But ignore that advisory. To support this, steps are added to install the `yq`-associated `tomlq` command and use it to produce the modified configuration file for the second scan in a way that shouldn't break under any changes to comments, spacing, style, or ordering in `deny.toml`. --- .github/workflows/ci.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1752d8d356d..c1df7e2d27f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -344,10 +344,28 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: EmbarkStudios/cargo-deny-action@v2 + - name: Install tomlq + run: | + # The runner already has the `yq` command but not its associated `tomlq` command. + sudo apt-get update + sudo apt-get install yq + - name: Strict check, but omit gix-testtools + uses: EmbarkStudios/cargo-deny-action@v2 + with: + command: check advisories + arguments: --workspace --all-features --exclude gix-testtools + - name: Configure less strict check + run: | + filter='.advisories.ignore += [ + { id: "RUSTSEC-2025-0021", reason: "gix-testtools can’t upgrade from old gix-features yet" } + ]' + tomlq "$filter" deny.toml --toml-output > deny-but-ignore-RUSTSEC-2025-0021.toml + - name: Less strict check, but include gix-testtools + uses: EmbarkStudios/cargo-deny-action@v2 with: command: check advisories arguments: --workspace --all-features + command-arguments: --config deny-but-ignore-RUSTSEC-2025-0021.toml cargo-deny: runs-on: ubuntu-latest From 11bd59f794811e11e48ef8de4db59035434f9da6 Mon Sep 17 00:00:00 2001 From: Sizhe Zhao Date: Sat, 5 Apr 2025 19:42:19 +0800 Subject: [PATCH 020/193] fix: cargo-auditable build error Use `futures-lite` instead of `dep:futures-lite` in gix-packetline and gix-protocol. See-Also: https://github.com/rust-secure-code/cargo-auditable/issues/124 --- gix-packetline/Cargo.toml | 3 ++- gix-protocol/Cargo.toml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gix-packetline/Cargo.toml b/gix-packetline/Cargo.toml index 1aaa73e628e..35929a31b99 100644 --- a/gix-packetline/Cargo.toml +++ b/gix-packetline/Cargo.toml @@ -24,7 +24,8 @@ default = [] ## If set, all IO will become blocking. The same types will be used preventing side-by-side usage of blocking and non-blocking IO. blocking-io = [] ## Implement IO traits from `futures-io`. -async-io = ["dep:futures-io", "dep:futures-lite", "dep:pin-project-lite"] +# no `dep:` for futures-lite (https://github.com/rust-secure-code/cargo-auditable/issues/124) +async-io = ["dep:futures-io", "futures-lite", "dep:pin-project-lite"] #! ### Other ## Data structures implement `serde::Serialize` and `serde::Deserialize`. diff --git a/gix-protocol/Cargo.toml b/gix-protocol/Cargo.toml index 09a728e7d29..0c5c9e237ae 100644 --- a/gix-protocol/Cargo.toml +++ b/gix-protocol/Cargo.toml @@ -30,11 +30,12 @@ blocking-client = [ "fetch" ] ## As above, but provides async implementations instead. +# no `dep:` for futures-lite (https://github.com/rust-secure-code/cargo-auditable/issues/124) async-client = [ "gix-transport/async-client", "dep:async-trait", "dep:futures-io", - "dep:futures-lite", + "futures-lite", "handshake", "fetch" ] From c151b8d2c4a36db76e8a63729e5b42584abbbb6d Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Sat, 5 Apr 2025 23:10:41 +0900 Subject: [PATCH 021/193] add minimal test for sorting issues of loose refs (#1928) --- .../make_repo_for_1928_repro.tar | Bin 0 -> 53760 bytes .../fixtures/make_repo_for_1928_repro.sh | 17 ++++++++ gix-ref/tests/refs/file/store/iter.rs | 39 ++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 gix-ref/tests/fixtures/generated-archives/make_repo_for_1928_repro.tar create mode 100755 gix-ref/tests/fixtures/make_repo_for_1928_repro.sh diff --git a/gix-ref/tests/fixtures/generated-archives/make_repo_for_1928_repro.tar b/gix-ref/tests/fixtures/generated-archives/make_repo_for_1928_repro.tar new file mode 100644 index 0000000000000000000000000000000000000000..5b7540170fabaea1608430d297efe451df691ee7 GIT binary patch literal 53760 zcmeHQ{aYJHlFqNvU(p%s7U7^zz}(_M*1^t(JIDC3@pnf$ z->UA>Xaq=LaIzcm?8cI&KdY;%tKO>asn))_^}jm)wl+7v;=lOI|0};W>KpeO^=7@f zF3-2to10&4-ulSU!8jTDLt{R>E16nma-ZGcmuaBYIu1wihp-d0`oYL=wQiwXlICjb z-)L?&x0dUF3u}>Ya%TN&;D^flV3>q)lrMbE?_B?T8yk7Kci-y}`md(tzp=5k)%>b{ z&Hk=b?N2WMSZ!lh+cc{if34PwS0dlC@V_<%X5}ASK{N_SXE!&mx$@uGnvwtYd$0p; zZU`5*^e319#$WGkZEkHe?`>4ZQTX9vIxV04TT-Bk4dAvXM)|**{a4@G+H5ZEzuR6I zw9oagwd1H89^YDT^YnjXeIu{`8%^v9OZ|UqOOiJHsvQr5H^ss*7{m!Y!Qojq9`^l_ zvk7-hy;$gmy`Ud=0<&XA!*Nh79Qi|j>H56{-+J+}-|G#7?s(AgM?vC>rJXE4{9!2| z@*hUs_!dWab^YI{Z`GIh&n+%V+H|`9wcta$H|_-Klbic6Pyf@_&-wq&_4TFxzqu8- zxTQOW2tY5XP{${xQi(?=0Dtho@L-oLP<6bX54Wnao8jpJ&a}=QT zaU6F{5{yjTMGJN?X5f!T!7xfpc^ugu*hJriU2_(X&8Z)a%qTYFB#_@%w^8|S^;PV@ z;fH@N!Hpa%$ikk)@w+7V;0C{5L;qs~SnB^9T!IUmnyi0Kt+#68_XoWj-3I2Y{}$pt zdHugGc=3g!zQG57a{TAc*R`WCswF4IJ5Z1hB4}D!e?y&MlJ+nhh(bN;#qD=y9Qjcc zk6`3?%*a1Z3^xY@H6IM2zNzZ>;0fU2(V6kMu?&ND5WWv81Hb*w(+$EO9*<>b*v8Xt zyLY&+(~eTT`gJ}p(^Q<8A~VV1tY}Vj^~U-%5irTiq8(?vjzdTF6^GoAB4}| zP2WEw38Yd88u(qTylD>ue}r&RH8XRW6ByvqxgQPvs144$bRp8|YiXDqH%9_M-DfiT zV4{$G&+DG6_}uRXBaH4OXum7MB6?*i|7X0?-}et&5BHyW z=FNSMC@L0$_6fx1q44E!%yD8MR@gs5IaaV>}sEKTa)ncAi z=QWWpKQ#)-^1S*oYaIeg+uEtNSg3YddX)?+TnSr$XrdVUQMnCTqiFpC{)A=|sFg}! zRvN#qOjx&;DetWo+dj;Duav3iK^+&p7ZEpyPDbRsyXH6Jp^9bsyLa!Jr`8Y2v}t53 zIq?%!)Pd{;(`-?=f4>+ce%r~~9)-+s?GsE6@=#Ltqe#=>saC7}XU&A86$rUV6SxL@ zh7uJ&fuXC#{|kn(r6&46sl-R(BvmTOr~?=2TTK0ZEgEC*`3>NkS$S2j{MD~?->jIG z`pT+`hiCitfV_DnwwMtD9ac-YRJ$$)0^4ODSeEuj;s=__$W3QegwPV)N#L66P+Aq* z13>I1HE>E&ySqls5spCg!X50Rl_{G6KPD&faMZGm?UX*+Pj~K2+W3TGqQJaTUi>`s zHD*a1GBe3SW_=H#yYjuRnbK6RSe68QIC9#T-l!E*=X<*QB z(9Qb_Grn|`=vs%EU)St{rLsRYO7oY$2;P8=3nt+ZCN50G%#!3tFjAl z2)eJhD!>^4I{Te7*sNg!q~V+u`$^23E6^a*$oWJ#L63PJx5h)tvTkFVNF!LqE9F(P zi0dVcyeD>*te^I96{fv>^yhF|eiE4tKp#!5q_ZTltCQikn;NfLTzPtrhHxjisOgwf zNt#qRXNt4+vMj3=u0GdXtDm(@MZtS!Q90YEiB`}=n+tCk$MwHFe6 z5gTM1`tMy7pF*c$e*%JL)I;L#19_VW9iB)DyMI`9E|%UzRpmCmAHpb1PGIATE?cGx z-5?h6J2aKSf07{T1bsj3Ro?r(kdeF_!h&cAT@wG_*r?CMfA2LK$QS$)^jP9Q7XN`2 zdolduI0B{wAo%u)DZ?|Y!RXO%3GkmFSp_x#Lx_k7d5QW9w$l61H^Np5&(JzkZ0ST? zM$sY?If&w@Lfe(mgwYr_vw#a>l8j~lj*LH`MKuh;ndqV)By{X(dZQNt|Im^#q71=% z08&(#+HD!*5})=cU^^Ju$c|)Td}&rPEY>tZdT8e>FcC)t2-G`ZY=i?5DwRp0HgG1! zH{d4|K#8HE7muuM4_x7#3Bcic1Le~nhTDX_zypN#Ax;up5amDIS5YZHw*$VK-^0W0nR zJj=#ztUvtT#{vPgOWaf$!@;_=Py7h0m7S#S)!5XCm)I}do+PBi7!sm5z!_tq*4c!R zXd7mA7$qY_cTm*`yD5)3MtvqwjVW7#Ze!lzaTu*$TKpM0pVavA(SwI5j~dT{LCjBVsrh!kK72u^WPq9EuXBvy38Y_(%#TC`xN6G$ts znva@op>Pk}Cw8};4&b7$%0czGYLYHsBytDm0ijpxXE~Mug zX+dREo#GVxp>6s>V9?4sEL*zIp84%Jtm0@q1i-ZDz{PJO_$2+Yo=!z3A-`1zy>n-x zjA}`CweA9dyg+;{uTMJtbsWN_KN^R<&Kmr6S-NC&hLSQINJTJeSF@vm76Knyq*?Li z&-!nX{yZ{hMxZG{wC9hWJbd)igZ;;?ANC(VYV94ocyjm%K;90(F{}~@tzwghW1JdM zrpNe>A%v+Gt2*veAz6i2CVuEetxyo=v;oP{W}MDITm5&Vpg$l$)*p1jp{X#QJ7Z$} zL;tikdCIk5{0@+yF8*H;@{|9(l6&eI52_-m>HL!#oI+x={I~1Lgr+b$xb>9a3Y?nB zAW}NKw8}Hvz6D8Ke|g%RPf*toQ4@*-q*)F0*@<6pm`DHEKNPk|XQc{+@Ya_wGykZ4WbA(``!nH!N(RegjO}}7#%GlZ-@9Ien&{WUcfEYxfK|)100~JLMl>~{Al}!|#4Xr{=(kQ5WfKp4F;5G;7GiXo$So+xb z#w-2J`&8UsK(l4!e=x={M{&B_-k1iMBmbMs^~>e|ZQ@MIQvScF{6i`(_Wvz@h%go% z+n`gSHAa7v9xRgeAVOpxC)_aTt*pUMeIKI&GeRf{*@TdCW0mO^5nX3EyYy<|DWMdG z!q(^+TI4c8fi4ixs2$Lshs_jXYw7w=~r7?;!Yon17eOb2Y;7>fV$h0^*7-oAs zM61k4v@PUb+AnC`}py7D8n^AWXayd_c?Adsm}3LkEKxB1Vq{6qtKTFV(}M z;M`o%Kz6pOQSR$n93cU8PXBOv00E(qOruuO3UF{H37|T8F>Iy0lt#=Eq~`Ka`G$kZ zRCHacnvvs}2TKRA#K8b`m4`TWCMB%CI)lInvP`8^WW1Fiu;DI}&OL9MW@$u5En9HJu`tmP8{>Mbo4 z7&tu%vC13}rt8+tavcY+%!K7XMvqu+ov~o~oo%~c?35Y|JMRPk;eN`{jv@gFVNPRa zsIF`zJ&F*OorrZ}2~{VtU{!qppArGpNS%}y?jl0O;b!>{K5r*PAVP2h@n{euz_xSO zgM*`yCb%be%)yYd%t7{H5(pzk$N&RS2Z%}$Ad$y>`zmlQol1v6N-(R8gXxnltb~|- zI0WkuBBUD+<-wolkT%1LEDa`1*_DEoC1?hKRDt~g>Wuj6* ztcb8y#-`FY;x&u6g!F(2R0UYXX$1XokAtVqM7oYJ2Vg=f0JMaX93nwXhDYHyBW0Rd z62#yjnNHI};VG|;PGjvAP)eWt#S;0kh|Pm#027BWeH2SWq9>LJjE4#d8plX5SAG-a zAR1nhyXBeij&dtguuhnJ_bvzqc745^}Y zUM!u_Sx3R>G_Z^7I)yc*n4=0c2)?BXM@s{wTD#Dp?8p$#q>Wk!%?$XYZSLSfEeO4h)5Ty>C!va zl3)@-@PH{Md63n%a@G^z6-pE~BW&ehR$6sqCRwJ*Sd*>J@&rz5tyxm0g|g&cGfAA! ziXVXD!X@}11WK@d+i6VKm0WrzJVLc%kbq!2J`zERVya?I!Oh+oU@@SNXa-w6FdH(2 z2Q;FJP&)W&obZQXz!gDLv~LN3Vw3w?cui%qqB0MpqEZQuBd%&PK7wi*>!}1NwPAog z9h3s-MP1~*7;teIrc!>jK#J$G#-V{Z7R7&Hjv!AQ`@Whg{*jmmVyr69 zV7KBPkjwwqXEyU6d7o+We-@EJW*&}xq4LBK%iFb=#e!4BCge#mXv{PgoJWDwWM4S! z3q0Nm1d$x5DK)KJ>RN@@B#|g$=}nZfk@Pj)scf7wtDIrSMNdJMe-1Es|GWT$TY(k<{Kh3 zBQZ~GUN7uhgp0)ZcprzI^TvMPh5OM62;R>I`eBM-yW&(}T}{lVs(FdTfDf?Mz$tvx z6{FEc>d_7o45E=7JHbAVh&8sXA+QD;$xm>Sg$9R@6f}lx#eax8HVQmK=n!NBtGt4D zBqVnPnaZA%NW>j8Z2`i~rJV|M7YGY`ggJrvBYAUZbSPLO9LixP*cy_;V52g2$#e(I z58E^xqcyQ#2gtAWkHQ{q@gV`8$337EiD}ef)z-$zP>%eJhO4jl8>v>0ym`eVFJGCOYQqS9wmb<)Rf)rs}C?rP<9T=m-|TZya97 zwLu{j-%PFQ?PAfWza~eX#Dz%ooRi}^k>esst#Y zMeRRi`fbdd|J>MUEaQJSy3iLiHf{gy#e*~CNu7*L89KI!Ya7@2-~TlKh0DQWvuA$v zaU={74phh?b_|aulJbnF2nIA1VXR+>E^0QQI|xd~^4xAJ3J#4B#s4KfQuv;_E}Onb z<54sX51FFXh)4oJ2AYZdNI(p2K-XpS1{GZ4=p2d+V2T+Qf}e4po7^{mbPK3tY(j~; z>7@p|SW$av0v;>aT%%KfWiU_}%^>7LbGOuV6%?hyoE7fiY&)h*@KCHdfhvVke9lHK z25b>vAgoGM5KvEG1G$P%8AmzgK9J(R&zxxbO@sV61fD?!?7leAJUHaAV;N?11*S9rjw} z{FNk{%7#5v3|8&qD9I_ScLLd@ufc89-^dQHV&~8%G0etsejam4} zdgnjll3dt@UX}slCzB)pgqyi;tepUf)Rs|c$7R-Tno+Q9f>ug^ppTTyUrF@6}i?nxJtk7!Yh?COdty`bc zM=L^~VCN>V;eXClZ(dLx*{}BRoa&CcUMVvUJta8#0RjgS09Li+7b@p^^U^`;3jSQ= z@w}OpQ$~X?Anj@Hn?{P#rE?l&jQk9og_JN30~^{d*2@~IS6i@xsthZx%%OFM9F;w} z0=X&8GG~T>PG&IA)L{Z>-jk!L7-Rp;=&C`Nl^#6%`~SSEzrkTX`5g%xJcoJLm0(C# zaS%8J_QcwRnPkbGM&EuNdA6DIf7s>V&{xr5AGvPGCoB|dZ_Dlw=r^mT#`1+ScCMXW z(^%!VPsjv@?^mw9j%qmgD8p;Kkw=VsaO^l4*f-_0$y}S|>fP0nHe7h6Eti@yzjNDe zzFC#PV1YbQ{#w*ff&-)z(tnf=E4!f5CtFm?mYCe4vnmwS=Xiej@X@nphEHT>g#w&l zo>@wN;MvezX-{W_4jOMP2@5QS|ML{FvL!xbhQuUD`!!`fQTBT591i8fgS{5=Z>^tb zH)XLY5}dO?hOZ2_U-?=!sN0VvW^#n^mD>`n!I0{FY_Ac}GB}_bBI`0p?c<;W4=-D7 zMCb0VIe>ef-#KW4*qb*zJM=ZGW9h*SVU1m*JCt|F1w>g=Q!@XZaxY2NnLQ81@hkG> z2^X<`;16*?0?dki1fgWOr10Vqx6RUHiWaY+$i>-Lgh({&h*#eev^Z-3AIGJ>MbITean_-994{9Q~ZtX5l z2fm0Vu~BKOx(Vufff_ij)8j-XfRA7GSO?Nvco7R87Tt9c_SR60mGQ7JfjwM&Nlh;2 zs0o^ot@U;YwI|)>T*N!T-c0|&DS5&zIopUDQ^-gmay*uj0ZaJ55TIj{Y>FQ+VY(0^ zehISefEhaWk!{*qwTM8fc$l_a`+}XwdMcJwpr<+{at4!B1i~b(l4V4&*>#rp6%TR? zD8m4O$u{6EwcXSK0TL?X_5rIPN(^?jP?A7PnA-QSNMcI8u818Hkv;O1OhFppP#i&r z0d7x2NE-G=vE00jszT7b^_0qnG<*mimc9gfk~?bHvN1m)Dr=DQKyZ;6Q#zuF?IX3% z5o~x=**Su<5GS_#pq+tK)vzkrC&EE`i5RQ05K$J}8GIoL%2;WK7lJCH>rxGv4Sb8b z>5hk7aTm6g>=%f?wG~IPbWY_#fwK%%#%2%X)4{s&Dk2nqz z!5X+&QICM7&YtsU-YPY@V_i_f@`RL7KjI|75F|?wIaVU+BwJ>Jz#v$hlBCni4yHLf z7$t1As(Y*L1SF*p5|438U}{mg!`Kx80iF4G0dV$j@^c3NRUhSs&wh|hbK?Jvdw6Y9 zF8>?x|Mg}5_ZQ%?Y5ey=YDFq|I=TN(!%o~Fl})neKjy{#sYG4iUvnrW5N31o7*+zL zWsNMgS#2Noh&L4JAv#vq>!MTRXab(XymRAFnCG4vcbNicMf=Y738f**Q>~GkJTEd4 zIc6B#F)y;0+G5+FUkI(llaRi7j)*HW?~%|35M1yyJmZo$I-!M!nnlb=A#|pnV&J|x zLW&lWr+xl@3^!%y_fq_e@G_4c+H?o%0JP=sb0%2=DMXM^d^ehz#Hybkd~Z_%kT@Wx z5+A%c{PEyfYyaV+Cx?WvP`(nGm8ACeH6VrE*Q?dLrP|aqw$1BCZGd~Ma1SwtfTM~D z&MKDBv>sCAAxb?#slV;+!fnUdMUx}X4osl;4lxwK9HB#b~C~qP_?(OOySMl2LD^@tl-+Z9Jc!K@^QFe?5E#7 z9GcPp;DL(R6E~d&Hb?*C-C#5Ne-np-miqq>r2ns(|0VqNh0?#^$#D;0e$j=;0cAW+ z#a|;GEGr-99Pd*=oTv2cA?+GDB;-KPZRyE-bsy3BJ!`lAQcAnf->N z|8woX=H~4A-;Ksn{y%SF7py(8{~$aUn}3&xKUoI3pC*_3iRSpkbJzH&CoE-W-c(_R?kvk zn&_RkobtvC5F>{3?Cfij0%>{#ACb)mAb^(IKHl%bm-_HXjLqCl4S7_M6KazACs48y ziKCb6eC3{J09pFB2kKZZ9#)MP5AhrfGdp2Z@>h1_4m^CTCxU=4;C^5Ij4V!kw&T_Z z_6wg(R^_q;2%#(}uj-VeXBrzj&z?xf@Q}2Lu}ad1_j3QKXUdYuhmj)D52jy|FxH{{ zYmUNr*uw{eLqGRY)}kJdB7URiqIlV<{lrXG?NolWAMtAuN2Ai9s#g+^%p>DHN{!O`tW79n`bVEycv z@IY7Ix*jR~1V@9(JJzO01={g4c;5b-QU%2($4YWnj7p^X2T8h}bV$~=!^0x32`FXd zlEG?c$rt2CSBzX_{a@#9#LWKRP5Lo1({Y;al-?9luWrZ^xZM74G#dA2?*F*gtS{gH zv)~r~S;esbyM%D&H{gyTY$h5Ny)U0n{UP)268*OSbZ>k6014sE`}DytHW(1L432Tg zFfcDIGog6-WHcHi+qD{U?gN}0ct`F#86Q={xaN4ShC2ZmMPwEevQ zL3t**{Ef*f!deq3j2l2FI2s@0{yxG|Q+XmDUMAogJ*Q1c20F9YsfEBn#M>y9Z zoP)qBMGCQR86NWNn34mAZ*e(WvX(o*==3{Ewve4sM*fbJLq;7Aq~ZoR`~8e$A&(QS%eJ z@A)|DeA05FD?`MwT?p0G?`)YfjM2F(+Y(B$h9m-o$z<-@UeGC*Vw+c_Vh4MP`Kb80 zviq?Od*t1xHS@QR@>L}5(o2`*TP(A%cSV*6w9S! zwk@(~%rh}%PO5u?pFW93(l0*$O8I{ zKGv?VqDnS5gO)Vo)(*5E#JGMAm4E$^Dr*i5OzllGugBCe5uG2>yX|;io)(7v3pZqC zx=JcBg*oCvWT*6<9RDFL^u9@xvUg<{dqZWH#I5Xha64)zDC0^%9Xr+`KS$w0H%BIn z?8wqK%dhY5{rLD{O9*T~?>|{HD~>v*@(ZlZD7G1{K(GsxA|6a9Z!~!ifJ`1Q9{Jj8 zgE>=ECfrv~N(Y8>YIIcSw`nloG+5!GokWyAxsCa0`n-1!AUb!*O--wEJtc0WtknE zh4Tu?TjZb%uRQsc>SuLwZUfzR_1VxxUjD(EuLjM+U`D$U5V zq-*CkUCH50g-q*RxbZGvt4?jc7_ZgKAeu8T=k33!bP1vJjHYFsF};v!Agz;aE)mg` zB07F4J74iwIl@1pc=AdH-(OleR0!7Zo%&}?;^K|i8F!EeeW3fg;SeWeRA(pHolxHv zm8ZOx-D3`{eGv#42C8;+=9z8}FTuf9$o-o92R(%v(m*-@ZB`E9u_SCS6z275>Ra=? zF^;a_l#;%lZ{VLvefHeO+j)t3S^rz|7vX;6dOiT!*t6e<9pK8c5o5;`KAp1b#mE!8 z{<5V;&74yCthLs)IoClbdo^#B7Wnl3DjuhZd+JOG*QgJb_h4YnQ4u(EvyRWOBrl)B z9BWTxDdkqX^z_Em3eS0eR&&Yq*VZA#7{qCPdq8!$(ofD3oR9y_lXlFW9-5Cr0l8?vpdKC+vI9c9 z_;q``ZJQ*8?7XtYIK|I`td^B;kOCRR26t(WDhkNl5b$fqc{%=DuQ#_gXY&8zW=GdwT%BPx`v-q z?yB;yCL%8;&&JykT*#$=*l?{){bDV`1TJhLFitk(7xgu)>vCCnk&%7THUb%}pM71c zjeckq)U^q)IB%2S_(B_RK}s`*@!McLgi^uTB?;W*@^>e-)uxrBitJCIePVbQWtZ^! z%?vrvI&v!*CAey+#p>2f@~vhAONOhBSG0R$JB$#B)kotSTffyCW z=G`$*alj1|$F;9Ky(rebES*aj<{h25A9dgeXh)8M`erFu{AtHnJiWyW#Fuxw^Tr=y zpjcPDtX5L5D?<+*%aKL)X1iINx(&l1y`2Kw#@mbe zcHTBTHT7a}#0kZKI#{oU*H_7l2^}xFtp^}~FAR`OBv~IU`w+P^IOd0I(BoKhtg&zH9sKkYUeNN>^S{fxdw7Mj{ptC^ zi)VX}c1q16uln36trv?^F<4Uxt4IDjq)sE#Sg|VwNXq@%TZ9KMU(;H(ieh(4wN)lS zXMvp_EhqpjgWG=w+k5`XiJ*}>gj=MCQAmJRd<_(VRqw=vJ=q3hJ} zrljkpqJ!TUz#c*}N4Q;?Kt5jdg{x1aio8b%AMLN8u}xN=AvFXcdqu(&y(uOT1o9P* z#$_Y$>FSfX8JeQ4ua!bALbcy~a~_4z98yrOvL8(E|CPxLEN*D;=UC?K|Mh#Dv-#ia z%lAKCWf`wscG3MGHuv27Kf!%WI!Iq5q`@U0XNvv+Z-CL{kj1?aWNc4na!#r@RD+ry z$c>x#CKr^ooBPz8T+$}8Z*s}}c(pgVT#p5E^3QM`uIau(;h!)6IQlmu{~Me4mghgN zx1v|8wW$0{D1mWZSbv&=J7797O)N3BooQuXioi2lJfshcDO+0YDM`*%8*YUKnHaM} zLqbDWzaTz5sft$8*F4~!Fh2CMZPKd8xUOS#yO+^Wy3?(i`Jp_J@$|*>A6o}c5BCqA z=zAC4ElJ@{y;#r$Up-A$3O!T7J!u!#D=@RSAjq zNL~$YUneL>;?mGP)r%F}3f%<+;66$dckb?dvM&)V@QN}5*d!nmVke2KVn-oE78$kW z(0qe9Hl9lw>lJN@t8w14^dEr&qW?3l^=*ua_TRk?yw6Mj^8eP60i4Hwo6W8I^8DXz zEJm))7ZLsUES!7aScC+MRdAY>4126F@+e3S-S`OxT)mRhksHJE>+eSak$>Kcd5c4s zC;#>4O#G+5vDsY8|1GYGYZ_--wjsyq?WcU7^-`7{b^iVT75R_lEfdLY&6e`NwYiz! z_uY3s&hP(?jr#gmo3}NfY`ZvSf!ixg_NQxo<}C2%CUvbgeuqlg^{+9gdJAJ9U9PzP z&2^j!U#|ZxEJm)$sr6@QKll75zFuqn@&51S`ricgFKkIx()vGV9*Q*GI$p38#z8%Ol^nZN|n9x%HUu7k)S2kV$8s2SsE82g4 z{1^O@*Z+-s8(YiuzuuBwsn%ru-)oriD@6-N_{NKVbuA%>%&Bjvy-@;PNG&!^WwWFCb zpZmjg^#8^>;>Dla@gnvAzX&t^>y??2|635c>&Sm|YnlJ|CAg`*;NMdI Uzr<=R`&d$7Nr5E=z8nSqAN08Ky#N3J literal 0 HcmV?d00001 diff --git a/gix-ref/tests/fixtures/make_repo_for_1928_repro.sh b/gix-ref/tests/fixtures/make_repo_for_1928_repro.sh new file mode 100755 index 00000000000..445f4107f99 --- /dev/null +++ b/gix-ref/tests/fixtures/make_repo_for_1928_repro.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -eu -o pipefail + +git init -q + +mkdir -p .git/refs/heads/a +cat <.git/packed-refs +# pack-refs with: peeled fully-peeled sorted +1111111111111111111111111111111111111111 refs/heads/a- +2222222222222222222222222222222222222222 refs/heads/a/b +3333333333333333333333333333333333333333 refs/heads/a0 +EOF + +mkdir -p .git/refs/heads/a +echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >.git/refs/heads/a- +echo bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb >.git/refs/heads/a/b +echo cccccccccccccccccccccccccccccccccccccccc >.git/refs/heads/a0 diff --git a/gix-ref/tests/refs/file/store/iter.rs b/gix-ref/tests/refs/file/store/iter.rs index 1d32428f07e..b406d23ccdf 100644 --- a/gix-ref/tests/refs/file/store/iter.rs +++ b/gix-ref/tests/refs/file/store/iter.rs @@ -464,6 +464,45 @@ fn overlay_iter_reproduce_1850() -> crate::Result { Ok(()) } +#[test] +fn overlay_iter_reproduce_1928() -> crate::Result { + let store = store_at("make_repo_for_1928_repro.sh")?; + let ref_names = store + .iter()? + .all()? + .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) + .collect::, _>>()?; + insta::assert_debug_snapshot!(ref_names, @r#" + [ + ( + "refs/heads/a-", + Object( + Sha1(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa), + ), + ), + ( + "refs/heads/a/b", + Object( + Sha1(2222222222222222222222222222222222222222), + ), + ), + ( + "refs/heads/a0", + Object( + Sha1(cccccccccccccccccccccccccccccccccccccccc), + ), + ), + ( + "refs/heads/a/b", + Object( + Sha1(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb), + ), + ), + ] + "#); + Ok(()) +} + #[test] fn overlay_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { let store = store_with_packed_refs()?; From d1487bd04467c29791612c19755253c5ae07c713 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sat, 5 Apr 2025 13:08:09 -0400 Subject: [PATCH 022/193] Test 32-bit Windows build Since it is still running in a 64-bit environment, and running the whole test suite is slow on Windows, this will likely not be worth keeping in full. It may subsequently be modified to run only some restricted subset of the tests, so that it completes faster. --- .github/workflows/ci.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1df7e2d27f..2a713c36057 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -309,6 +309,26 @@ jobs: GIX_TEST_IGNORE_ARCHIVES: '1' run: cargo nextest run --workspace --no-fail-fast + test-32bit-windows: + runs-on: windows-latest + + env: + TARGET: i686-pc-windows-msvc + + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ env.TARGET }} + - uses: Swatinem/rust-cache@v2 + - name: cargo check default features + run: cargo check --target $env:TARGET --workspace --bins --examples + - uses: taiki-e/install-action@v2 + with: + tool: nextest + - name: Test (nextest) + run: cargo nextest run --target $env:TARGET --workspace --no-fail-fast + lint: runs-on: ubuntu-latest @@ -504,6 +524,7 @@ jobs: - test-fast - test-fixtures-windows - test-32bit + - test-32bit-windows - lint - cargo-deny - check-packetline From cb45d896222d1f1581dba3e58684116f3055c7b7 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sat, 5 Apr 2025 13:54:30 -0400 Subject: [PATCH 023/193] Try building with the 32-bit toolchain To see if it produces build failures or new test failures on CI. --- .github/workflows/ci.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a713c36057..3d9e28e96dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -312,22 +312,19 @@ jobs: test-32bit-windows: runs-on: windows-latest - env: - TARGET: i686-pc-windows-msvc - steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master with: - targets: ${{ env.TARGET }} + toolchain: stable-i686-pc-windows-msvc - uses: Swatinem/rust-cache@v2 - name: cargo check default features - run: cargo check --target $env:TARGET --workspace --bins --examples + run: cargo check --workspace --bins --examples - uses: taiki-e/install-action@v2 with: tool: nextest - name: Test (nextest) - run: cargo nextest run --target $env:TARGET --workspace --no-fail-fast + run: cargo nextest run --workspace --no-fail-fast lint: runs-on: ubuntu-latest From cfb9bea4d9d42efa70bc0d3e4139f04e354a0d08 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sat, 5 Apr 2025 14:24:00 -0400 Subject: [PATCH 024/193] Go back to cross compiling and only run size tests - Use platform-default Windows toolchain with 32-bit target again. - Remove the "cargo check default features" step. - Filter the tests so only those with "size" in their name are run. - Rename job from to `test-32bit-windows-size`. --- .github/workflows/ci.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d9e28e96dd..f80297f737c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -309,22 +309,23 @@ jobs: GIX_TEST_IGNORE_ARCHIVES: '1' run: cargo nextest run --workspace --no-fail-fast - test-32bit-windows: + test-32bit-windows-size: runs-on: windows-latest + env: + TARGET: i686-pc-windows-msvc + steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@master + - uses: dtolnay/rust-toolchain@stable with: - toolchain: stable-i686-pc-windows-msvc + targets: ${{ env.TARGET }} - uses: Swatinem/rust-cache@v2 - - name: cargo check default features - run: cargo check --workspace --bins --examples - uses: taiki-e/install-action@v2 with: tool: nextest - name: Test (nextest) - run: cargo nextest run --workspace --no-fail-fast + run: cargo nextest run --target $env:TARGET --workspace --no-fail-fast size lint: runs-on: ubuntu-latest @@ -521,7 +522,7 @@ jobs: - test-fast - test-fixtures-windows - test-32bit - - test-32bit-windows + - test-32bit-windows-size - lint - cargo-deny - check-packetline From 4cea38bb093717b63cacb910c49e57840d07a1de Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sat, 5 Apr 2025 15:13:42 -0400 Subject: [PATCH 025/193] Fix `size_of_hasher` test for 32-bit Windows Due to ABI differences between different 32-bit targets, the `size_of_hasher` test wrongly failed on `i686-pc-windows-msvc`. Although the test case with that name was introduced in #1915, the failure is actually long-standing, in that an analogous faiure occurred in the old `size_of_sha1` test that preceded it and on which it is based. That failure only happened when the old `fast-sha1` feature was enabled, and not with the old `rustsha1` feature. It was not detected earlier as that target is irregularly tested, and built with `--no-default-features --features max-pure` more often than other targets due to difficulties building some other non-Rust dependencies on it (when not cross-compiling). Since #1915, the failure is easier to detect, since we now use only one SHA-1 implementation, `sha1-checked`, so the test always fails on `i686-pc-windows-msvc`. This is only a bug in the test itself, not in any of the code under test. This commit changes the test to use `gix_testtools::size_ok`, which makes a `==` comparison on 64-bit targets but a `<=` comparison on 32-bit targets where there tends to be more variation in data structures' sizes. This is similar to some of the size assertion fixes in #1687 (77c3c59, fc13fc3). --- gix-hash/tests/hash/hasher.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gix-hash/tests/hash/hasher.rs b/gix-hash/tests/hash/hasher.rs index 282b7c8666f..ee73631d69c 100644 --- a/gix-hash/tests/hash/hasher.rs +++ b/gix-hash/tests/hash/hasher.rs @@ -1,12 +1,15 @@ use gix_hash::{Hasher, ObjectId}; +use gix_testtools::size_ok; #[test] fn size_of_hasher() { - assert_eq!( - std::mem::size_of::(), - if cfg!(target_arch = "x86") { 820 } else { 824 }, - "The size of this type may be relevant when hashing millions of objects,\ - and shouldn't change unnoticed. The DetectionState alone clocks in at 724 bytes." + let actual = std::mem::size_of::(); + let expected = 824; + assert!( + size_ok(actual, expected), + "The size of this type may be relevant when hashing millions of objects, and shouldn't\ + change unnoticed: {actual} <~ {expected}\ + (The DetectionState alone clocked in at 724 bytes when last examined.)" ); } From 38b63c2fc9d407b3c634d8b0c72d4d0c104aa5ad Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Sat, 5 Apr 2025 21:22:06 +0900 Subject: [PATCH 026/193] fix: make `fs::walkdir_sorted_new()` sort entries by paths literally (#1928) This follows up 7b1b5bf864e74706aefeb1213e8bdb0545d5464a. Since packed-refs appears to be sorted by full ref name, loose-refs should also be emitted in that order. The comparison function is copied from gix::diff::object::tree::EntryRef. Non-utf8 file names are simply mapped to "" on Windows. We could add some fallback, but callers can't handle such file names anyway. --- Cargo.lock | 1 + gix-features/Cargo.toml | 3 ++- gix-features/src/fs.rs | 20 ++++++++++---------- gix-ref/tests/refs/file/store/iter.rs | 24 +++++++++--------------- gix-submodule/tests/file/baseline.rs | 4 ++-- gix/tests/gix/repository/reference.rs | 2 +- 6 files changed, 25 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ad802139d5..7986bb76e46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1845,6 +1845,7 @@ dependencies = [ "crossbeam-channel", "document-features", "flate2", + "gix-path 0.10.15", "gix-trace 0.1.12", "gix-utils 0.2.0", "libc", diff --git a/gix-features/Cargo.toml b/gix-features/Cargo.toml index d30d39f2501..29cdad0d9ec 100644 --- a/gix-features/Cargo.toml +++ b/gix-features/Cargo.toml @@ -48,7 +48,7 @@ parallel = ["dep:crossbeam-channel", "dep:parking_lot"] once_cell = ["dep:once_cell"] ## Makes facilities of the `walkdir` crate partially available. ## In conjunction with the **parallel** feature, directory walking will be parallel instead behind a compatible interface. -walkdir = ["dep:walkdir", "dep:gix-utils"] +walkdir = ["dep:walkdir", "dep:gix-path", "dep:gix-utils"] #* an in-memory unidirectional pipe using `bytes` as efficient transfer mechanism. io-pipe = ["dep:bytes"] ## provide a proven and fast `crc32` implementation. @@ -106,6 +106,7 @@ required-features = ["io-pipe"] gix-trace = { version = "^0.1.12", path = "../gix-trace" } # for walkdir +gix-path = { version = "^0.10.15", path = "../gix-path", optional = true } gix-utils = { version = "^0.2.0", path = "../gix-utils", optional = true } # 'parallel' feature diff --git a/gix-features/src/fs.rs b/gix-features/src/fs.rs index 5cf5b7e1afa..f4c4cab97f5 100644 --- a/gix-features/src/fs.rs +++ b/gix-features/src/fs.rs @@ -217,19 +217,19 @@ pub mod walkdir { /// /// Use `precompose_unicode` to represent the `core.precomposeUnicode` configuration option. pub fn walkdir_sorted_new(root: &Path, _: Parallelism, precompose_unicode: bool) -> WalkDir { - fn ft_to_number(ft: std::fs::FileType) -> usize { - if ft.is_file() { - 1 - } else { - 2 - } - } WalkDir { inner: WalkDirImpl::new(root) .sort_by(|a, b| { - ft_to_number(a.file_type()) - .cmp(&ft_to_number(b.file_type())) - .then_with(|| a.file_name().cmp(b.file_name())) + // Ignore non-utf8 file name on Windows, which would probably be rejected by caller. + let a_name = gix_path::os_str_into_bstr(a.file_name()).unwrap_or("".as_ref()); + let b_name = gix_path::os_str_into_bstr(b.file_name()).unwrap_or("".as_ref()); + // "common." < "common/" < "common0" + let common = a_name.len().min(b_name.len()); + a_name[..common].cmp(&b_name[..common]).then_with(|| { + let a = a_name.get(common).or_else(|| a.file_type().is_dir().then_some(&b'/')); + let b = b_name.get(common).or_else(|| b.file_type().is_dir().then_some(&b'/')); + a.cmp(&b) + }) }) .into(), precompose_unicode, diff --git a/gix-ref/tests/refs/file/store/iter.rs b/gix-ref/tests/refs/file/store/iter.rs index b406d23ccdf..211332cddb7 100644 --- a/gix-ref/tests/refs/file/store/iter.rs +++ b/gix-ref/tests/refs/file/store/iter.rs @@ -31,8 +31,8 @@ mod with_namespace { .map(|r: gix_ref::Reference| r.name) .collect::>(); let expected_namespaced_refs = vec![ - "refs/namespaces/bar/refs/multi-link", "refs/namespaces/bar/refs/heads/multi-link-target1", + "refs/namespaces/bar/refs/multi-link", "refs/namespaces/bar/refs/remotes/origin/multi-link-target3", "refs/namespaces/bar/refs/tags/multi-link-target2", ]; @@ -50,8 +50,8 @@ mod with_namespace { .map(|r| r.name.into_inner()) .collect::>(), [ - "refs/namespaces/bar/refs/multi-link", "refs/namespaces/bar/refs/heads/multi-link-target1", + "refs/namespaces/bar/refs/multi-link", "refs/namespaces/bar/refs/tags/multi-link-target2" ] ); @@ -149,8 +149,8 @@ mod with_namespace { let packed = ns_store.open_packed_buffer()?; let expected_refs = vec![ - "refs/multi-link", "refs/heads/multi-link-target1", + "refs/multi-link", "refs/remotes/origin/multi-link-target3", "refs/tags/multi-link-target2", ]; @@ -198,8 +198,8 @@ mod with_namespace { .map(|r| r.name.into_inner()) .collect::>(), [ - "refs/multi-link", "refs/heads/multi-link-target1", + "refs/multi-link", "refs/tags/multi-link-target2", ], "loose iterators have namespace support as well" @@ -214,8 +214,8 @@ mod with_namespace { .map(|r| r.name.into_inner()) .collect::>(), [ - "refs/namespaces/bar/refs/multi-link", "refs/namespaces/bar/refs/heads/multi-link-target1", + "refs/namespaces/bar/refs/multi-link", "refs/namespaces/bar/refs/tags/multi-link-target2", "refs/namespaces/foo/refs/remotes/origin/HEAD" ], @@ -291,14 +291,14 @@ fn loose_iter_with_broken_refs() -> crate::Result { ref_paths, vec![ "d1", - "loop-a", - "loop-b", - "multi-link", "heads/A", "heads/d1", "heads/dt1", "heads/main", "heads/multi-link-target1", + "loop-a", + "loop-b", + "multi-link", "remotes/origin/HEAD", "remotes/origin/main", "remotes/origin/multi-link-target3", @@ -483,7 +483,7 @@ fn overlay_iter_reproduce_1928() -> crate::Result { ( "refs/heads/a/b", Object( - Sha1(2222222222222222222222222222222222222222), + Sha1(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb), ), ), ( @@ -492,12 +492,6 @@ fn overlay_iter_reproduce_1928() -> crate::Result { Sha1(cccccccccccccccccccccccccccccccccccccccc), ), ), - ( - "refs/heads/a/b", - Object( - Sha1(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb), - ), - ), ] "#); Ok(()) diff --git a/gix-submodule/tests/file/baseline.rs b/gix-submodule/tests/file/baseline.rs index 8d03b89804f..6971cdb33a7 100644 --- a/gix-submodule/tests/file/baseline.rs +++ b/gix-submodule/tests/file/baseline.rs @@ -24,10 +24,10 @@ fn common_values_and_names_by_path() -> crate::Result { "recursive-clone/submodule/.gitmodules", "relative-clone/.gitmodules", "relative-clone/submodule/.gitmodules", - "super/.gitmodules", - "super/submodule/.gitmodules", "super-clone/.gitmodules", "super-clone/submodule/.gitmodules", + "super/.gitmodules", + "super/submodule/.gitmodules", "top-only-clone/.gitmodules" ] .into_iter() diff --git a/gix/tests/gix/repository/reference.rs b/gix/tests/gix/repository/reference.rs index acea4e016ed..94e9e8574d2 100644 --- a/gix/tests/gix/repository/reference.rs +++ b/gix/tests/gix/repository/reference.rs @@ -102,10 +102,10 @@ mod iter_references { "refs/heads/d1", "refs/heads/dt1", "refs/heads/main", + "refs/heads/multi-link-target1", "refs/loop-a", "refs/loop-b", "refs/multi-link", - "refs/heads/multi-link-target1", "refs/remotes/origin/HEAD", "refs/remotes/origin/main", "refs/remotes/origin/multi-link-target3", From 7e6e7518c78ba925382c0d4654b9e11b4cd641e9 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 6 Apr 2025 10:37:36 +0800 Subject: [PATCH 027/193] refactor - make sure we fallback to something *probably* better than the empty string. --- gix-features/src/fs.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/gix-features/src/fs.rs b/gix-features/src/fs.rs index f4c4cab97f5..5fc1a62021b 100644 --- a/gix-features/src/fs.rs +++ b/gix-features/src/fs.rs @@ -4,8 +4,7 @@ //! along with runtime costs for maintaining a global [`rayon`](https://docs.rs/rayon) thread pool. //! //! For information on how to use the [`WalkDir`] type, have a look at -//! * [`jwalk::WalkDir`](https://docs.rs/jwalk/0.5.1/jwalk/type.WalkDir.html) if `parallel` feature is enabled -//! * [walkdir::WalkDir](https://docs.rs/walkdir/2.3.1/walkdir/struct.WalkDir.html) otherwise +// TODO: Move all this to `gix-fs` in a breaking change. #[cfg(feature = "walkdir")] mod shared { @@ -220,9 +219,22 @@ pub mod walkdir { WalkDir { inner: WalkDirImpl::new(root) .sort_by(|a, b| { - // Ignore non-utf8 file name on Windows, which would probably be rejected by caller. - let a_name = gix_path::os_str_into_bstr(a.file_name()).unwrap_or("".as_ref()); - let b_name = gix_path::os_str_into_bstr(b.file_name()).unwrap_or("".as_ref()); + let storage_a; + let storage_b; + let a_name = match gix_path::os_str_into_bstr(a.file_name()) { + Ok(f) => f, + Err(_) => { + storage_a = a.file_name().to_string_lossy(); + storage_a.as_ref().into() + } + }; + let b_name = match gix_path::os_str_into_bstr(b.file_name()) { + Ok(f) => f, + Err(_) => { + storage_b = b.file_name().to_string_lossy(); + storage_b.as_ref().into() + } + }; // "common." < "common/" < "common0" let common = a_name.len().min(b_name.len()); a_name[..common].cmp(&b_name[..common]).then_with(|| { From fc5faf24dfc6d6e1580308ec5e7c12e96e0ccb41 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 6 Apr 2025 14:13:01 +0800 Subject: [PATCH 028/193] Release gix-features v0.41.1 --- Cargo.lock | 54 +++++++++++++++++----------------- Cargo.toml | 2 +- gix-config/Cargo.toml | 2 +- gix-features/CHANGELOG.md | 39 +++++++++++++++++++++++- gix-features/Cargo.toml | 2 +- gix-fs/Cargo.toml | 2 +- gix-glob/Cargo.toml | 2 +- gix-hash/Cargo.toml | 2 +- gix-index/Cargo.toml | 2 +- gix-object/Cargo.toml | 2 +- gix-odb/Cargo.toml | 2 +- gix-pack/Cargo.toml | 2 +- gix-protocol/Cargo.toml | 2 +- gix-ref/Cargo.toml | 2 +- gix-status/Cargo.toml | 2 +- gix-transport/Cargo.toml | 2 +- gix-url/Cargo.toml | 2 +- gix-worktree-state/Cargo.toml | 2 +- gix-worktree-stream/Cargo.toml | 2 +- gix-worktree/Cargo.toml | 2 +- gix/Cargo.toml | 2 +- 21 files changed, 84 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7986bb76e46..e3cadd7edae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1311,7 +1311,7 @@ dependencies = [ "futures-lite", "gitoxide-core", "gix", - "gix-features 0.41.0", + "gix-features 0.41.1", "is-terminal", "once_cell", "prodash 29.0.1", @@ -1380,7 +1380,7 @@ dependencies = [ "gix-diff", "gix-dir", "gix-discover 0.39.0", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-filter", "gix-fs 0.14.0", "gix-glob 0.19.0", @@ -1630,7 +1630,7 @@ dependencies = [ "criterion", "document-features", "gix-config-value", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-glob 0.19.0", "gix-path 0.10.15", "gix-ref 0.51.0", @@ -1836,7 +1836,7 @@ dependencies = [ [[package]] name = "gix-features" -version = "0.41.0" +version = "0.41.1" dependencies = [ "bstr", "bytes", @@ -1900,7 +1900,7 @@ dependencies = [ "bstr", "crossbeam-channel", "fastrand", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-path 0.10.15", "gix-utils 0.2.0", "is_ci", @@ -1939,7 +1939,7 @@ dependencies = [ "bitflags 2.9.0", "bstr", "document-features", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-path 0.10.15", "gix-testtools", "serde", @@ -1961,7 +1961,7 @@ version = "0.17.0" dependencies = [ "document-features", "faster-hex", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-testtools", "serde", "sha1-checked", @@ -2054,7 +2054,7 @@ dependencies = [ "filetime", "fnv", "gix-bitmap 0.2.14", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-fs 0.14.0", "gix-hash 0.17.0", "gix-lock 17.0.0", @@ -2079,7 +2079,7 @@ version = "0.0.0" dependencies = [ "bstr", "filetime", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-hash 0.17.0", "gix-index 0.39.0", "gix-object 0.48.0", @@ -2214,7 +2214,7 @@ dependencies = [ "document-features", "gix-actor 0.34.0", "gix-date 0.9.4", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-hash 0.17.0", "gix-hashtable 0.8.0", "gix-odb", @@ -2238,7 +2238,7 @@ dependencies = [ "arc-swap", "document-features", "gix-date 0.9.4", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-fs 0.14.0", "gix-hash 0.17.0", "gix-hashtable 0.8.0", @@ -2260,7 +2260,7 @@ dependencies = [ "filetime", "gix-actor 0.34.0", "gix-date 0.9.4", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-hash 0.17.0", "gix-object 0.48.0", "gix-odb", @@ -2278,7 +2278,7 @@ dependencies = [ "document-features", "gix-chunk 0.4.11", "gix-diff", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-hash 0.17.0", "gix-hashtable 0.8.0", "gix-object 0.48.0", @@ -2299,7 +2299,7 @@ name = "gix-pack-tests" version = "0.0.0" dependencies = [ "bstr", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-hash 0.17.0", "gix-object 0.48.0", "gix-odb", @@ -2413,7 +2413,7 @@ dependencies = [ "futures-lite", "gix-credentials", "gix-date 0.9.4", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-hash 0.17.0", "gix-lock 17.0.0", "gix-negotiate", @@ -2485,7 +2485,7 @@ dependencies = [ "document-features", "gix-actor 0.34.0", "gix-date 0.9.4", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-fs 0.14.0", "gix-hash 0.17.0", "gix-lock 17.0.0", @@ -2508,7 +2508,7 @@ dependencies = [ "gix-actor 0.34.0", "gix-date 0.9.4", "gix-discover 0.39.0", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-fs 0.14.0", "gix-hash 0.17.0", "gix-lock 17.0.0", @@ -2632,7 +2632,7 @@ dependencies = [ "filetime", "gix-diff", "gix-dir", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-filter", "gix-fs 0.14.0", "gix-hash 0.17.0", @@ -2653,7 +2653,7 @@ dependencies = [ "filetime", "gix-diff", "gix-dir", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-filter", "gix-fs 0.14.0", "gix-hash 0.17.0", @@ -2674,7 +2674,7 @@ version = "0.18.0" dependencies = [ "bstr", "gix-config", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-path 0.10.15", "gix-pathspec", "gix-refspec", @@ -2771,7 +2771,7 @@ dependencies = [ "futures-lite", "gix-command", "gix-credentials", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-hash 0.17.0", "gix-pack", "gix-packetline", @@ -2841,7 +2841,7 @@ dependencies = [ "assert_matches", "bstr", "document-features", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-path 0.10.15", "gix-testtools", "percent-encoding", @@ -2914,7 +2914,7 @@ dependencies = [ "bstr", "document-features", "gix-attributes 0.25.0", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-fs 0.14.0", "gix-glob 0.19.0", "gix-hash 0.17.0", @@ -2931,7 +2931,7 @@ name = "gix-worktree-state" version = "0.18.0" dependencies = [ "bstr", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-filter", "gix-fs 0.14.0", "gix-glob 0.19.0", @@ -2949,7 +2949,7 @@ name = "gix-worktree-state-tests" version = "0.0.0" dependencies = [ "gix-discover 0.39.0", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-filter", "gix-fs 0.14.0", "gix-hash 0.17.0", @@ -2968,7 +2968,7 @@ name = "gix-worktree-stream" version = "0.20.0" dependencies = [ "gix-attributes 0.25.0", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-filter", "gix-fs 0.14.0", "gix-hash 0.17.0", @@ -2989,7 +2989,7 @@ dependencies = [ "bstr", "gix-attributes 0.25.0", "gix-discover 0.39.0", - "gix-features 0.41.0", + "gix-features 0.41.1", "gix-fs 0.14.0", "gix-glob 0.19.0", "gix-hash 0.17.0", diff --git a/Cargo.toml b/Cargo.toml index 384db8e423c..a22f1745259 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,7 +168,7 @@ gitoxide-core-async-client = ["gitoxide-core/async-client", "futures-lite"] anyhow = "1.0.42" gitoxide-core = { version = "^0.46.0", path = "gitoxide-core" } -gix-features = { version = "^0.41.0", path = "gix-features" } +gix-features = { version = "^0.41.1", path = "gix-features" } gix = { version = "^0.71.0", path = "gix", default-features = false } clap = { version = "4.1.1", features = ["derive", "cargo"] } diff --git a/gix-config/Cargo.toml b/gix-config/Cargo.toml index fee11339a6b..07a20a66fa6 100644 --- a/gix-config/Cargo.toml +++ b/gix-config/Cargo.toml @@ -19,7 +19,7 @@ autotests = false serde = ["dep:serde", "bstr/serde", "gix-sec/serde", "gix-ref/serde", "gix-glob/serde", "gix-config-value/serde"] [dependencies] -gix-features = { version = "^0.41.0", path = "../gix-features" } +gix-features = { version = "^0.41.1", path = "../gix-features" } gix-config-value = { version = "^0.14.12", path = "../gix-config-value" } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-sec = { version = "^0.10.12", path = "../gix-sec" } diff --git a/gix-features/CHANGELOG.md b/gix-features/CHANGELOG.md index 799a5f63c31..a2ee806565e 100644 --- a/gix-features/CHANGELOG.md +++ b/gix-features/CHANGELOG.md @@ -5,6 +5,42 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.41.1 (2025-04-06) + +### Bug Fixes + + - make `fs::walkdir_sorted_new()` sort entries by paths literally + This follows up 7b1b5bf864e74706aefeb1213e8bdb0545d5464a. Since packed-refs + appears to be sorted by full ref name, loose-refs should also be emitted in + that order. + + The comparison function is copied from gix::diff::object::tree::EntryRef. + Non-utf8 file names are simply mapped to "" on Windows. We could add some + fallback, but callers can't handle such file names anyway. + +### Commit Statistics + + + + - 4 commits contributed to the release over the course of 2 calendar days. + - 2 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 1 unique issue was worked on: [#1928](https://github.com/GitoxideLabs/gitoxide/issues/1928) + +### Commit Details + + + +
view details + + * **[#1928](https://github.com/GitoxideLabs/gitoxide/issues/1928)** + - Make `fs::walkdir_sorted_new()` sort entries by paths literally ([`38b63c2`](https://github.com/GitoxideLabs/gitoxide/commit/38b63c2fc9d407b3c634d8b0c72d4d0c104aa5ad)) + * **Uncategorized** + - Merge pull request #1931 from yuja/push-klrqpplwxrkx ([`7502b4a`](https://github.com/GitoxideLabs/gitoxide/commit/7502b4abde6196b982cf66344c0df992e99493cb)) + - Refactor ([`7e6e751`](https://github.com/GitoxideLabs/gitoxide/commit/7e6e7518c78ba925382c0d4654b9e11b4cd641e9)) + - Merge pull request #1919 from GitoxideLabs/release ([`420e730`](https://github.com/GitoxideLabs/gitoxide/commit/420e730f765b91e1d17daca6bb1f99bdb2e54fda)) +
+ ## 0.41.0 (2025-04-04) ### Changed (BREAKING) @@ -32,7 +68,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 16 commits contributed to the release. + - 17 commits contributed to the release. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -49,6 +85,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
view details * **Uncategorized** + - Release gix-date v0.9.4, gix-utils v0.2.0, gix-actor v0.34.0, gix-features v0.41.0, gix-hash v0.17.0, gix-hashtable v0.8.0, gix-path v0.10.15, gix-validate v0.9.4, gix-object v0.48.0, gix-glob v0.19.0, gix-quote v0.5.0, gix-attributes v0.25.0, gix-command v0.5.0, gix-packetline-blocking v0.18.3, gix-filter v0.18.0, gix-fs v0.14.0, gix-commitgraph v0.27.0, gix-revwalk v0.19.0, gix-traverse v0.45.0, gix-worktree-stream v0.20.0, gix-archive v0.20.0, gix-tempfile v17.0.0, gix-lock v17.0.0, gix-index v0.39.0, gix-config-value v0.14.12, gix-pathspec v0.10.0, gix-ignore v0.14.0, gix-worktree v0.40.0, gix-diff v0.51.0, gix-blame v0.1.0, gix-ref v0.51.0, gix-config v0.44.0, gix-prompt v0.10.0, gix-url v0.30.0, gix-credentials v0.28.0, gix-discover v0.39.0, gix-dir v0.13.0, gix-mailmap v0.26.0, gix-revision v0.33.0, gix-merge v0.4.0, gix-negotiate v0.19.0, gix-pack v0.58.0, gix-odb v0.68.0, gix-refspec v0.29.0, gix-shallow v0.3.0, gix-packetline v0.18.4, gix-transport v0.46.0, gix-protocol v0.49.0, gix-status v0.18.0, gix-submodule v0.18.0, gix-worktree-state v0.18.0, gix v0.71.0, gix-fsck v0.10.0, gitoxide-core v0.46.0, gitoxide v0.42.0, safety bump 48 crates ([`b41312b`](https://github.com/GitoxideLabs/gitoxide/commit/b41312b478b0d19efb330970cf36dba45d0fbfbd)) - Update changelogs prior to release ([`38dff41`](https://github.com/GitoxideLabs/gitoxide/commit/38dff41d09b6841ff52435464e77cd012dce7645)) - Merge pull request #1915 from emilazy/push-qvyqmopsoltr ([`4660f7a`](https://github.com/GitoxideLabs/gitoxide/commit/4660f7a6f71873311f68f170b0f1f6659a02829d)) - Refactor ([`4501086`](https://github.com/GitoxideLabs/gitoxide/commit/4501086adc544e675b3043c4c23b78a6c6711d8b)) diff --git a/gix-features/Cargo.toml b/gix-features/Cargo.toml index 29cdad0d9ec..e38432028ee 100644 --- a/gix-features/Cargo.toml +++ b/gix-features/Cargo.toml @@ -4,7 +4,7 @@ lints.workspace = true name = "gix-features" description = "A crate to integrate various capabilities using compile-time feature flags" repository = "https://github.com/GitoxideLabs/gitoxide" -version = "0.41.0" +version = "0.41.1" authors = ["Sebastian Thiel "] license = "MIT OR Apache-2.0" edition = "2021" diff --git a/gix-fs/Cargo.toml b/gix-fs/Cargo.toml index 580ea2f5edf..fda6c347bab 100644 --- a/gix-fs/Cargo.toml +++ b/gix-fs/Cargo.toml @@ -21,7 +21,7 @@ serde = ["dep:serde"] [dependencies] bstr = "1.5.0" gix-path = { version = "^0.10.15", path = "../gix-path" } -gix-features = { version = "^0.41.0", path = "../gix-features", features = ["fs-read-dir"] } +gix-features = { version = "^0.41.1", path = "../gix-features", features = ["fs-read-dir"] } gix-utils = { version = "^0.2.0", path = "../gix-utils" } thiserror = "2.0.0" serde = { version = "1.0.114", optional = true, default-features = false, features = ["std", "derive"] } diff --git a/gix-glob/Cargo.toml b/gix-glob/Cargo.toml index 1c7dc199a01..94009462e12 100644 --- a/gix-glob/Cargo.toml +++ b/gix-glob/Cargo.toml @@ -20,7 +20,7 @@ serde = ["dep:serde", "bstr/serde", "bitflags/serde"] [dependencies] gix-path = { version = "^0.10.15", path = "../gix-path" } -gix-features = { version = "^0.41.0", path = "../gix-features" } +gix-features = { version = "^0.41.1", path = "../gix-features" } bstr = { version = "1.3.0", default-features = false, features = ["std"] } bitflags = "2" serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } diff --git a/gix-hash/Cargo.toml b/gix-hash/Cargo.toml index c4d88e612c2..89e06071865 100644 --- a/gix-hash/Cargo.toml +++ b/gix-hash/Cargo.toml @@ -20,7 +20,7 @@ test = false serde = ["dep:serde"] [dependencies] -gix-features = { version = "^0.41.0", path = "../gix-features", features = ["progress"] } +gix-features = { version = "^0.41.1", path = "../gix-features", features = ["progress"] } thiserror = "2.0.0" faster-hex = { version = "0.9.0" } diff --git a/gix-index/Cargo.toml b/gix-index/Cargo.toml index 900502e09b0..e860d4d4dcf 100644 --- a/gix-index/Cargo.toml +++ b/gix-index/Cargo.toml @@ -22,7 +22,7 @@ test = true serde = ["dep:serde", "smallvec/serde", "gix-hash/serde"] [dependencies] -gix-features = { version = "^0.41.0", path = "../gix-features", features = [ +gix-features = { version = "^0.41.1", path = "../gix-features", features = [ "progress", ] } gix-hash = { version = "^0.17.0", path = "../gix-hash" } diff --git a/gix-object/Cargo.toml b/gix-object/Cargo.toml index 3981ddb8be5..cdb28c16028 100644 --- a/gix-object/Cargo.toml +++ b/gix-object/Cargo.toml @@ -41,7 +41,7 @@ serde = [ verbose-object-parsing-errors = ["winnow/std"] [dependencies] -gix-features = { version = "^0.41.0", path = "../gix-features", features = [ +gix-features = { version = "^0.41.1", path = "../gix-features", features = [ "progress", ] } gix-hash = { version = "^0.17.0", path = "../gix-hash" } diff --git a/gix-odb/Cargo.toml b/gix-odb/Cargo.toml index af3a9acc3c4..69e82121e83 100644 --- a/gix-odb/Cargo.toml +++ b/gix-odb/Cargo.toml @@ -20,7 +20,7 @@ doctest = false serde = ["dep:serde", "gix-hash/serde", "gix-object/serde", "gix-pack/serde"] [dependencies] -gix-features = { version = "^0.41.0", path = "../gix-features", features = ["walkdir", "zlib", "crc32"] } +gix-features = { version = "^0.41.1", path = "../gix-features", features = ["walkdir", "zlib", "crc32"] } gix-hashtable = { version = "^0.8.0", path = "../gix-hashtable" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-date = { version = "^0.9.4", path = "../gix-date" } diff --git a/gix-pack/Cargo.toml b/gix-pack/Cargo.toml index 1080dae4dc8..9a1a80e64f0 100644 --- a/gix-pack/Cargo.toml +++ b/gix-pack/Cargo.toml @@ -34,7 +34,7 @@ serde = ["dep:serde", "gix-object/serde"] wasm = ["gix-diff?/wasm"] [dependencies] -gix-features = { version = "^0.41.0", path = "../gix-features", features = ["crc32", "progress", "zlib"] } +gix-features = { version = "^0.41.1", path = "../gix-features", features = ["crc32", "progress", "zlib"] } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-chunk = { version = "^0.4.11", path = "../gix-chunk" } diff --git a/gix-protocol/Cargo.toml b/gix-protocol/Cargo.toml index 0c5c9e237ae..b820147a0e0 100644 --- a/gix-protocol/Cargo.toml +++ b/gix-protocol/Cargo.toml @@ -68,7 +68,7 @@ path = "tests/async-protocol.rs" required-features = ["async-client"] [dependencies] -gix-features = { version = "^0.41.0", path = "../gix-features", features = [ +gix-features = { version = "^0.41.1", path = "../gix-features", features = [ "progress", ] } gix-transport = { version = "^0.46.0", path = "../gix-transport" } diff --git a/gix-ref/Cargo.toml b/gix-ref/Cargo.toml index 35b3cdcfae6..e76a8e2a480 100644 --- a/gix-ref/Cargo.toml +++ b/gix-ref/Cargo.toml @@ -21,7 +21,7 @@ test = true serde = ["dep:serde", "gix-hash/serde", "gix-actor/serde", "gix-object/serde"] [dependencies] -gix-features = { version = "^0.41.0", path = "../gix-features", features = ["walkdir"] } +gix-features = { version = "^0.41.1", path = "../gix-features", features = ["walkdir"] } gix-fs = { version = "^0.14.0", path = "../gix-fs" } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } diff --git a/gix-status/Cargo.toml b/gix-status/Cargo.toml index c9a0b7853e5..1d61ae95d09 100644 --- a/gix-status/Cargo.toml +++ b/gix-status/Cargo.toml @@ -25,7 +25,7 @@ gix-fs = { version = "^0.14.0", path = "../gix-fs" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-object = { version = "^0.48.0", path = "../gix-object" } gix-path = { version = "^0.10.15", path = "../gix-path" } -gix-features = { version = "^0.41.0", path = "../gix-features", features = ["progress"] } +gix-features = { version = "^0.41.1", path = "../gix-features", features = ["progress"] } gix-filter = { version = "^0.18.0", path = "../gix-filter" } gix-worktree = { version = "^0.40.0", path = "../gix-worktree", default-features = false, features = ["attributes"] } gix-pathspec = { version = "^0.10.0", path = "../gix-pathspec" } diff --git a/gix-transport/Cargo.toml b/gix-transport/Cargo.toml index 1cc27d1f11a..0851ea0fffe 100644 --- a/gix-transport/Cargo.toml +++ b/gix-transport/Cargo.toml @@ -82,7 +82,7 @@ required-features = ["async-client"] [dependencies] gix-command = { version = "^0.5.0", path = "../gix-command" } -gix-features = { version = "^0.41.0", path = "../gix-features" } +gix-features = { version = "^0.41.1", path = "../gix-features" } gix-url = { version = "^0.30.0", path = "../gix-url" } gix-sec = { version = "^0.10.12", path = "../gix-sec" } gix-packetline = { version = "^0.18.4", path = "../gix-packetline" } diff --git a/gix-url/Cargo.toml b/gix-url/Cargo.toml index d3ab256380f..6bb03e9690b 100644 --- a/gix-url/Cargo.toml +++ b/gix-url/Cargo.toml @@ -19,7 +19,7 @@ doctest = false serde = ["dep:serde", "bstr/serde"] [dependencies] -gix-features = { version = "^0.41.0", path = "../gix-features" } +gix-features = { version = "^0.41.1", path = "../gix-features" } gix-path = { version = "^0.10.15", path = "../gix-path" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["std", "derive"] } diff --git a/gix-worktree-state/Cargo.toml b/gix-worktree-state/Cargo.toml index 62495b34a9d..ca8acedae47 100644 --- a/gix-worktree-state/Cargo.toml +++ b/gix-worktree-state/Cargo.toml @@ -23,7 +23,7 @@ gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-object = { version = "^0.48.0", path = "../gix-object" } gix-glob = { version = "^0.19.0", path = "../gix-glob" } gix-path = { version = "^0.10.15", path = "../gix-path" } -gix-features = { version = "^0.41.0", path = "../gix-features" } +gix-features = { version = "^0.41.1", path = "../gix-features" } gix-filter = { version = "^0.18.0", path = "../gix-filter" } io-close = "0.3.7" diff --git a/gix-worktree-stream/Cargo.toml b/gix-worktree-stream/Cargo.toml index e36176d8ad7..a1e2992b6f4 100644 --- a/gix-worktree-stream/Cargo.toml +++ b/gix-worktree-stream/Cargo.toml @@ -15,7 +15,7 @@ include = ["src/**/*", "LICENSE-*"] doctest = false [dependencies] -gix-features = { version = "^0.41.0", path = "../gix-features", features = ["progress", "io-pipe"] } +gix-features = { version = "^0.41.1", path = "../gix-features", features = ["progress", "io-pipe"] } gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-object = { version = "^0.48.0", path = "../gix-object" } gix-attributes = { version = "^0.25.0", path = "../gix-attributes" } diff --git a/gix-worktree/Cargo.toml b/gix-worktree/Cargo.toml index 1330b499d39..9e9ae3a62f9 100644 --- a/gix-worktree/Cargo.toml +++ b/gix-worktree/Cargo.toml @@ -32,7 +32,7 @@ gix-path = { version = "^0.10.15", path = "../gix-path" } gix-attributes = { version = "^0.25.0", path = "../gix-attributes", optional = true } gix-validate = { version = "^0.9.4", path = "../gix-validate", optional = true } gix-ignore = { version = "^0.14.0", path = "../gix-ignore" } -gix-features = { version = "^0.41.0", path = "../gix-features" } +gix-features = { version = "^0.41.1", path = "../gix-features" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } bstr = { version = "1.3.0", default-features = false } diff --git a/gix/Cargo.toml b/gix/Cargo.toml index 8df05077e1a..ee8a57b048e 100644 --- a/gix/Cargo.toml +++ b/gix/Cargo.toml @@ -344,7 +344,7 @@ gix-traverse = { version = "^0.45.0", path = "../gix-traverse" } gix-diff = { version = "^0.51.0", path = "../gix-diff", default-features = false } gix-merge = { version = "^0.4.0", path = "../gix-merge", default-features = false, optional = true } gix-mailmap = { version = "^0.26.0", path = "../gix-mailmap", optional = true } -gix-features = { version = "^0.41.0", path = "../gix-features", features = [ +gix-features = { version = "^0.41.1", path = "../gix-features", features = [ "progress", "once_cell", ] } From f952c101cc8686e685074e8604e0f332c06d6767 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 7 Apr 2025 03:27:44 +0000 Subject: [PATCH 029/193] doc: Add missing command docs + small style fixups Changes that affect the help/usage text shown at runtime: - Add descriptions for a few `gix` commands that didn't have it: `gix is-clean`, `gix is-changed`, and `gix env`. - Add a description of the debug-only `ein panic` command. - Small spacing and capitalization improvements for consistency. - Add a line break in a `///` block for brevity of the top line. Changes to code style that do not affect what is shown at runtime: - Add `.` at the end of some `///` first lines. (This doesn't affect runtime behavior because `clap` normalizes this away.) - Put `///` above all `#[...]` in a few places where it wasn't. - Adjust comment wrapping in a couple of places for clarity. --- src/plumbing/options/mod.rs | 65 ++++++++++++++++++++----------------- src/porcelain/options.rs | 9 ++--- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/plumbing/options/mod.rs b/src/plumbing/options/mod.rs index b93a8af4469..a9b48f739bf 100644 --- a/src/plumbing/options/mod.rs +++ b/src/plumbing/options/mod.rs @@ -22,10 +22,10 @@ pub struct Args { #[clap(long, short = 'c', value_parser = crate::shared::AsBString)] pub config: Vec, - #[clap(long, short = 't')] /// The amount of threads to use for some operations. /// /// If unset, or the value is 0, there is no limit and all logical cores can be used. + #[clap(long, short = 't')] pub threads: Option, /// Display verbose messages and progress information @@ -41,7 +41,7 @@ pub struct Args { #[clap(long, conflicts_with("verbose"))] pub no_verbose: bool, - /// Bring up a terminal user interface displaying progress visually + /// Bring up a terminal user interface displaying progress visually. #[cfg(feature = "prodash-render-tui")] #[clap(long, conflicts_with("verbose"))] pub progress: bool, @@ -80,13 +80,13 @@ pub struct Args { #[derive(Debug, clap::Subcommand)] pub enum Subcommands { - /// Subcommands for creating worktree archives + /// Subcommands for creating worktree archives. #[cfg(feature = "gitoxide-core-tools-archive")] Archive(archive::Platform), - /// Remove untracked files from the working tree + /// Remove untracked files from the working tree. #[cfg(feature = "gitoxide-core-tools-clean")] Clean(clean::Command), - /// Subcommands for interacting with commit-graph files + /// Subcommands for interacting with commit-graph files. #[clap(subcommand)] CommitGraph(commitgraph::Subcommands), /// Interact with the object database. @@ -111,10 +111,10 @@ pub enum Subcommands { /// A program just like `git credential`. #[clap(subcommand)] Credential(credential::Subcommands), - /// Fetch data from remotes and store it in the repository + /// Fetch data from remotes and store it in the repository. #[cfg(feature = "gitoxide-core-blocking-client")] Fetch(fetch::Platform), - /// Clone a repository into a new directory + /// Clone a repository into a new directory. #[cfg(feature = "gitoxide-core-blocking-client")] Clone(clone::Platform), /// Interact with the mailmap. @@ -129,7 +129,7 @@ pub enum Subcommands { /// Interact with the exclude files like .gitignore. #[clap(subcommand)] Exclude(exclude::Subcommands), - /// Interact with a worktree index like .git/index + /// Interact with a worktree index like .git/index. #[clap(subcommand)] Index(index::Subcommands), /// Interact with submodules. @@ -140,7 +140,9 @@ pub enum Subcommands { /// The object to print to stdout. revspec: String, }, + /// Check for changes in the repository, treating this as an error. IsClean, + /// Check for changes in the repository, treating their absence as an error. IsChanged, /// Show which git configuration values are used or planned. ConfigTree, @@ -150,14 +152,15 @@ pub enum Subcommands { Corpus(corpus::Platform), MergeBase(merge_base::Command), Merge(merge::Platform), + /// Print paths relevant to the Git installation. Env, Diff(diff::Platform), Log(log::Platform), Worktree(worktree::Platform), - /// Subcommands that need no git repository to run. + /// Subcommands that need no Git repository to run. #[clap(subcommand)] Free(free::Subcommands), - /// Blame lines in a file + /// Blame lines in a file. Blame { /// Print additional statistics to help understanding performance. #[clap(long, short = 's')] @@ -271,7 +274,7 @@ pub mod status { } #[derive(Debug, clap::Parser)] - #[command(about = "compute repository status similar to `git status`")] + #[command(about = "Compute repository status similar to `git status`")] pub struct Platform { /// The way status data is displayed. #[clap(long, short = 'f')] @@ -318,7 +321,7 @@ pub mod worktree { #[derive(Debug, clap::Subcommand)] pub enum SubCommands { - /// List all worktrees, along with some accompanying information + /// List all worktrees, along with some accompanying information. List, } } @@ -328,7 +331,7 @@ pub mod corpus { use std::path::PathBuf; #[derive(Debug, clap::Parser)] - #[command(about = "run algorithms on a corpus of git repositories and store their results for later analysis")] + #[command(about = "Run algorithms on a corpus of git repositories and store their results for later analysis")] pub struct Platform { /// The path to the database to read and write depending on the sub-command. #[arg(long, default_value = "corpus.db")] @@ -441,7 +444,7 @@ pub mod merge { } #[derive(Debug, clap::Parser)] - #[command(about = "perform merges of various kinds")] + #[command(about = "Perform merges of various kinds")] pub struct Platform { #[clap(subcommand)] pub cmd: SubCommands, @@ -499,7 +502,7 @@ pub mod merge { pub mod diff { use gix::bstr::BString; - /// Print all changes between two objects + /// Print all changes between two objects. #[derive(Debug, clap::Parser)] pub struct Platform { #[clap(subcommand)] @@ -532,7 +535,7 @@ pub mod diff { pub mod log { use gix::bstr::BString; - /// List all commits in a repository, optionally limited to those that change a given path + /// List all commits in a repository, optionally limited to those that change a given path. #[derive(Debug, clap::Parser)] pub struct Platform { /// The git path specification to show a log for. @@ -544,7 +547,7 @@ pub mod log { pub mod config { use gix::bstr::BString; - /// Print all entries in a configuration file or access other sub-commands + /// Print all entries in a configuration file or access other sub-commands. #[derive(Debug, clap::Parser)] #[clap(subcommand_required(false))] pub struct Platform { @@ -942,7 +945,7 @@ pub mod credential { pub mod commitgraph { #[derive(Debug, clap::Subcommand)] pub enum Subcommands { - /// Verify the integrity of a commit graph file + /// Verify the integrity of a commit graph file. Verify { /// output statistical information about the graph. #[clap(long, short = 's')] @@ -975,7 +978,7 @@ pub mod revision { Git, /// The version that would be checked out into the worktree, including filters. Worktree, - /// The version that would be diffed (Worktree + Text-Conversion) + /// The version that would be diffed (Worktree + Text-Conversion). Diff, /// The version that would be diffed if there is a text-conversion, or the one stored in Git otherwise. DiffOrGit, @@ -1037,10 +1040,10 @@ pub mod attributes { #[derive(Debug, clap::Subcommand)] pub enum Subcommands { - /// Run `git check-attr` and `git check-ignore` on all files of the index or all files passed via stdin and validate that - /// we get the same outcome when computing attributes. + /// Run `git check-attr` and `git check-ignore` on all files of the index or all files + /// passed via stdin and validate that we get the same outcome when computing attributes. ValidateBaseline { - /// Print various statistics to stderr + /// Print various statistics to stderr. #[clap(long, short = 's')] statistics: bool, /// Don't validated excludes as obtaining them with `check-ignore` can be very slow. @@ -1049,10 +1052,10 @@ pub mod attributes { }, /// List all attributes of the given path-specs and display the result similar to `git check-attr`. Query { - /// Print various statistics to stderr + /// Print various statistics to stderr. #[clap(long, short = 's')] statistics: bool, - /// The git path specifications to list attributes for, or unset to read from stdin one per line. + /// The Git path specifications to list attributes for, or unset to read from stdin one per line. #[clap(value_parser = CheckPathSpec)] pathspec: Vec, }, @@ -1069,7 +1072,7 @@ pub mod exclude { pub enum Subcommands { /// Check if path-specs are excluded and print the result similar to `git check-ignore`. Query { - /// Print various statistics to stderr + /// Print various statistics to stderr. #[clap(long, short = 's')] statistics: bool, /// Show actual ignore patterns instead of un-excluding an entry. @@ -1108,7 +1111,7 @@ pub mod index { #[derive(Debug, clap::Subcommand)] pub enum Subcommands { - /// Print all entries to standard output + /// Print all entries to standard output. Entries { /// How to output index entries. #[clap(long, short = 'f', default_value = "simple", value_enum)] @@ -1124,7 +1127,7 @@ pub mod index { /// Display submodule entries as well if their repository exists. #[clap(long, short = 'r')] recurse_submodules: bool, - /// Print various statistics to stderr + /// Print various statistics to stderr. #[clap(long, short = 's')] statistics: bool, /// The git path specifications to match entries to print. @@ -1138,8 +1141,10 @@ pub mod index { #[clap(long, short = 'f')] force: bool, /// Path to the index file to be written. - /// If none is given it will be kept in memory only as a way to measure performance. One day we will probably write the index - /// back by default, but that requires us to write more of the index to work. + /// + /// If none is given it will be kept in memory only as a way to measure performance. + /// One day we will probably write the index back by default, but that requires us to + /// write more of the index to work. #[clap(long, short = 'i')] index_output_path: Option, /// Don't write the trailing hash for a performance gain. @@ -1160,7 +1165,7 @@ pub mod submodule { #[derive(Debug, clap::Subcommand)] pub enum Subcommands { - /// Print all direct submodules to standard output + /// Print all direct submodules to standard output. List { /// Set the suffix to append if the repository is dirty (not counting untracked files). #[clap(short = 'd', long)] diff --git a/src/porcelain/options.rs b/src/porcelain/options.rs index 6fee59f0332..d1e1b9d82eb 100644 --- a/src/porcelain/options.rs +++ b/src/porcelain/options.rs @@ -5,11 +5,11 @@ use std::path::PathBuf; #[clap(name = "ein", about = "The rusty git", version = option_env!("GIX_VERSION"))] #[clap(subcommand_required = true)] pub struct Args { - /// Do not display verbose messages and progress information + /// Do not display verbose messages and progress information. #[clap(long, short = 'q')] pub quiet: bool, - /// Bring up a terminal user interface displaying progress visually + /// Bring up a terminal user interface displaying progress visually. #[clap(long, conflicts_with("quiet"))] pub progress: bool, /// The amount of threads to use. If unset, use all cores, if 0 use al physical cores. @@ -36,8 +36,8 @@ pub enum Subcommands { /// Defaults to the current working directory. directory: Option, }, + /// A selection of useful tools. #[cfg(feature = "gitoxide-core-tools")] - /// A selection of useful tools #[clap(subcommand)] Tool(ToolCommands), /// Generate shell completions to stdout or a directory. @@ -49,6 +49,7 @@ pub enum Subcommands { /// The output directory in case multiple files are generated. If not provided, will write to stdout. out_dir: Option, }, + /// Panic immediately, to test panic behavior. #[cfg(debug_assertions)] Panic, } @@ -117,7 +118,7 @@ pub mod tools { /// This is an expensive option, and typically cuts speed in half. #[arg(long, short = 'C')] pub find_copies_harder: bool, - /// path to the git repository to generate the database for + /// Path to the Git repository to generate the database for. #[arg(default_value = ".")] pub repo_dir: std::path::PathBuf, #[clap(subcommand)] From 4687e6dbb6f913ac886616dcbcbf7b216ec4e62f Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Tue, 4 Mar 2025 04:35:17 +0000 Subject: [PATCH 030/193] Start toward testing s390x via cross --- Cross.toml | 2 ++ etc/docker/Dockerfile.test-cross-s390x | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 Cross.toml create mode 100644 etc/docker/Dockerfile.test-cross-s390x diff --git a/Cross.toml b/Cross.toml new file mode 100644 index 00000000000..b7c1890604b --- /dev/null +++ b/Cross.toml @@ -0,0 +1,2 @@ +[target.s390x-unknown-linux-gnu] +image = "cross-rs-gitoxide/s390x-unknown-linux-gnu" diff --git a/etc/docker/Dockerfile.test-cross-s390x b/etc/docker/Dockerfile.test-cross-s390x new file mode 100644 index 00000000000..d248d5695b1 --- /dev/null +++ b/etc/docker/Dockerfile.test-cross-s390x @@ -0,0 +1,11 @@ +FROM ghcr.io/cross-rs/s390x-unknown-linux-gnu:latest + +RUN apt-get update && \ + apt-get install apt-transport-https && \ + echo 'deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu xenial main' > \ + /etc/apt/sources.list.d/git-core-ubuntu-ppa-xenial.list && \ + apt-key adv --keyserver keyserver.ubuntu.com \ + --recv-keys F911AB184317630C59970973E363C90F8F1B6217 && \ + apt-get update && \ + apt-get install --no-install-recommends -y git && \ + rm -rf /var/lib/apt/lists/* From a7db5888749899df8b2ebf2ce8636290ddd57565 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Tue, 4 Mar 2025 05:23:22 +0000 Subject: [PATCH 031/193] Add `system`-scope config var in container So installation_config tests can pass. This also adjusts the RUN script in the dockerfile to show each command before it runs and to make sure it is not overwriting files unintentionally, and adds a convenience script outside for building the image. --- etc/docker/Dockerfile.test-cross-s390x | 6 ++++-- etc/docker/build-test-cross-s390x-image.sh | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100755 etc/docker/build-test-cross-s390x-image.sh diff --git a/etc/docker/Dockerfile.test-cross-s390x b/etc/docker/Dockerfile.test-cross-s390x index d248d5695b1..e6f7c138d83 100644 --- a/etc/docker/Dockerfile.test-cross-s390x +++ b/etc/docker/Dockerfile.test-cross-s390x @@ -1,6 +1,7 @@ FROM ghcr.io/cross-rs/s390x-unknown-linux-gnu:latest -RUN apt-get update && \ +RUN set -xC && \ + apt-get update && \ apt-get install apt-transport-https && \ echo 'deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu xenial main' > \ /etc/apt/sources.list.d/git-core-ubuntu-ppa-xenial.list && \ @@ -8,4 +9,5 @@ RUN apt-get update && \ --recv-keys F911AB184317630C59970973E363C90F8F1B6217 && \ apt-get update && \ apt-get install --no-install-recommends -y git && \ - rm -rf /var/lib/apt/lists/* + rm -rf /var/lib/apt/lists/* && \ + git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue diff --git a/etc/docker/build-test-cross-s390x-image.sh b/etc/docker/build-test-cross-s390x-image.sh new file mode 100755 index 00000000000..41ef43dbcba --- /dev/null +++ b/etc/docker/build-test-cross-s390x-image.sh @@ -0,0 +1,5 @@ +#!/bin/sh +set -e +mkdir empty-context +docker build -f etc/docker/Dockerfile.test-cross-s390x \ + -t cross-rs-gitoxide/s390x-unknown-linux-gnu empty-context From 3a296aefa67f8983beeba3b717e50f2904b35ca2 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Tue, 4 Mar 2025 20:03:17 +0000 Subject: [PATCH 032/193] Add `jq` to container; simplify container build command Installing `jq` in the container allows the `ask::askpass_only` and `ask::username_password` to pass (they use `jq`). --- etc/docker/Dockerfile.test-cross-s390x | 2 +- etc/docker/build-test-cross-s390x-image.sh | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/etc/docker/Dockerfile.test-cross-s390x b/etc/docker/Dockerfile.test-cross-s390x index e6f7c138d83..775700a62e2 100644 --- a/etc/docker/Dockerfile.test-cross-s390x +++ b/etc/docker/Dockerfile.test-cross-s390x @@ -8,6 +8,6 @@ RUN set -xC && \ apt-key adv --keyserver keyserver.ubuntu.com \ --recv-keys F911AB184317630C59970973E363C90F8F1B6217 && \ apt-get update && \ - apt-get install --no-install-recommends -y git && \ + apt-get install --no-install-recommends -y git jq && \ rm -rf /var/lib/apt/lists/* && \ git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue diff --git a/etc/docker/build-test-cross-s390x-image.sh b/etc/docker/build-test-cross-s390x-image.sh index 41ef43dbcba..ce47c05bb2a 100755 --- a/etc/docker/build-test-cross-s390x-image.sh +++ b/etc/docker/build-test-cross-s390x-image.sh @@ -1,5 +1,2 @@ #!/bin/sh -set -e -mkdir empty-context -docker build -f etc/docker/Dockerfile.test-cross-s390x \ - -t cross-rs-gitoxide/s390x-unknown-linux-gnu empty-context +docker build -t cross-rs-gitoxide/s390x-unknown-linux-gnu - Date: Tue, 4 Mar 2025 22:17:16 +0000 Subject: [PATCH 033/193] Put experiment details (except dockerfile) in a script --- etc/docker/build-test-cross-s390x-image.sh | 2 -- etc/run-cross-experiment.sh | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) delete mode 100755 etc/docker/build-test-cross-s390x-image.sh create mode 100755 etc/run-cross-experiment.sh diff --git a/etc/docker/build-test-cross-s390x-image.sh b/etc/docker/build-test-cross-s390x-image.sh deleted file mode 100755 index ce47c05bb2a..00000000000 --- a/etc/docker/build-test-cross-s390x-image.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -docker build -t cross-rs-gitoxide/s390x-unknown-linux-gnu - Date: Wed, 5 Mar 2025 09:38:38 +0000 Subject: [PATCH 034/193] Use image:tag naming style for image; let more env through This changes the style of how we name the custom Docker image for `cross` testing, so it is not looked up on Docker Hub (it is not there, and the text before the `/` in the old name was not intended to have a meaning related to resolving the image in any registry). This also allows through the environment varibles that currently have special meaning to gitoxide or its test suite -- including `GIX_TEST_IGNORE_ARCHIVES` to test the fixture scripts in the container, if it is set for the `cross` process -- or that the test suite may reasonably use to detect CI in general or GitHub Actions in particular. (Most GitHub Actions environment variables continue not to be passed through, because some of them would hold paths that couldn't necessarily be resolved properly in the container, while the presence of others would wrongly create the appearance that all GitHub Actions environment variables would be usable.) --- Cross.toml | 16 +++++++++++++++- etc/run-cross-experiment.sh | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Cross.toml b/Cross.toml index b7c1890604b..37877834e2e 100644 --- a/Cross.toml +++ b/Cross.toml @@ -1,2 +1,16 @@ +[build.env] +passthrough = [ + "CI", + "GITHUB_ACTIONS", + "GIX_CREDENTIALS_HELPER_STDERR", + "GIX_EXTERNAL_COMMAND_STDERR", + "GIX_OBJECT_CACHE_MEMORY", + "GIX_PACK_CACHE_MEMORY", + "GIX_TEST_CREATE_ARCHIVES_EVEN_ON_CI", + "GIX_TEST_EXPECT_REDUCED_TRUST", + "GIX_TEST_IGNORE_ARCHIVES", + "GIX_VERSION", +] + [target.s390x-unknown-linux-gnu] -image = "cross-rs-gitoxide/s390x-unknown-linux-gnu" +image = "cross-rs-gitoxide:s390x-unknown-linux-gnu" diff --git a/etc/run-cross-experiment.sh b/etc/run-cross-experiment.sh index eb55b4646d3..323d9316007 100755 --- a/etc/run-cross-experiment.sh +++ b/etc/run-cross-experiment.sh @@ -2,7 +2,7 @@ set -ex # Build the customized `cross` container image. -docker build -t cross-rs-gitoxide/s390x-unknown-linux-gnu \ +docker build -t cross-rs-gitoxide:s390x-unknown-linux-gnu \ - Date: Sat, 8 Mar 2025 11:08:19 +0000 Subject: [PATCH 035/193] Start toward testing armv7-linux-androideabi --- Cross.toml | 3 +++ etc/docker/Dockerfile.test-cross | 15 +++++++++++++++ etc/docker/Dockerfile.test-cross-s390x | 13 ------------- etc/run-cross-experiment.sh | 15 +++++++++++---- 4 files changed, 29 insertions(+), 17 deletions(-) create mode 100644 etc/docker/Dockerfile.test-cross delete mode 100644 etc/docker/Dockerfile.test-cross-s390x diff --git a/Cross.toml b/Cross.toml index 37877834e2e..b891146c831 100644 --- a/Cross.toml +++ b/Cross.toml @@ -12,5 +12,8 @@ passthrough = [ "GIX_VERSION", ] +[target.armv7-linux-androideabi] +image = "cross-rs-gitoxide:armv7-linux-androideabi" + [target.s390x-unknown-linux-gnu] image = "cross-rs-gitoxide:s390x-unknown-linux-gnu" diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross new file mode 100644 index 00000000000..704c4d593be --- /dev/null +++ b/etc/docker/Dockerfile.test-cross @@ -0,0 +1,15 @@ +ARG TARGET + +FROM ghcr.io/cross-rs/${TARGET}:latest + +RUN apt-get update && \ + apt-get install --no-install-recommends -y apt-transport-https gnupg && \ + release="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release)" && \ + echo "deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $release main" \ + >/etc/apt/sources.list.d/git-core-ubuntu-ppa.list && \ + apt-key adv --keyserver keyserver.ubuntu.com \ + --recv-keys F911AB184317630C59970973E363C90F8F1B6217 && \ + apt-get update && \ + apt-get install --no-install-recommends -y git jq && \ + rm -rf /var/lib/apt/lists/* && \ + git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue diff --git a/etc/docker/Dockerfile.test-cross-s390x b/etc/docker/Dockerfile.test-cross-s390x deleted file mode 100644 index 775700a62e2..00000000000 --- a/etc/docker/Dockerfile.test-cross-s390x +++ /dev/null @@ -1,13 +0,0 @@ -FROM ghcr.io/cross-rs/s390x-unknown-linux-gnu:latest - -RUN set -xC && \ - apt-get update && \ - apt-get install apt-transport-https && \ - echo 'deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu xenial main' > \ - /etc/apt/sources.list.d/git-core-ubuntu-ppa-xenial.list && \ - apt-key adv --keyserver keyserver.ubuntu.com \ - --recv-keys F911AB184317630C59970973E363C90F8F1B6217 && \ - apt-get update && \ - apt-get install --no-install-recommends -y git jq && \ - rm -rf /var/lib/apt/lists/* && \ - git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue diff --git a/etc/run-cross-experiment.sh b/etc/run-cross-experiment.sh index 323d9316007..863d49d71ce 100755 --- a/etc/run-cross-experiment.sh +++ b/etc/run-cross-experiment.sh @@ -1,15 +1,22 @@ #!/bin/sh -set -ex + +# Usage: +# +# etc/run-cross-experiment.sh armv7-linux-androideabi +# etc/run-cross-experiment.sh s390x-unknown-linux-gnu + +set -eux +target="$1" # Build the customized `cross` container image. -docker build -t cross-rs-gitoxide:s390x-unknown-linux-gnu \ - - Date: Sun, 9 Mar 2025 03:58:23 +0000 Subject: [PATCH 036/193] feat: Show unexpected stderr in `umask` panic message Because `gix_testtools::umask()` is only suitable for use in tests, where signaling an error with a panic is typically acceptable, it panics rather than returning an `Error` to indicate errors. To avoid leading to the use of a potentially inaccurate umask value, it treats as an error any departure from the typical output of the `umask` command: in addition to treating a nonzero exit status as an error, it also treats anything it cannot strictly parse on stdout as an error, as well as anything at all written to stderr as an error. The latter is to avoid a situation where a warning is printed that is could be significant to some umask use cases. Warnings from `umask` are rare, as well as from the shell that is used as an intermediary for running the command (since no external `umask` command need exist and, often, does not) when it is used just to run `umask`. When they do occur, they are sometimes from the dynamic linker, such as a warning about a shared library listed in the `LD_PRELOAD` environment variable that cannot be used by the shell program. To understand and distinguish such errors, it is useful to show the text that was sent to stderr, since tests are sometimes run in environments that are nontrivial to reproduce otherwise. For example, running tests with `cross` produces an environment that is not in all respects the same as what one gets with `docker exec -it `, even if `` is the same still-running container being used to run the tests. This modifies `gix_testtools::umask()` so that when it panics due anything being written to stderr, it shows what was written. --- tests/tools/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tools/src/lib.rs b/tests/tools/src/lib.rs index cbe2b42b948..a9c2938a56f 100644 --- a/tests/tools/src/lib.rs +++ b/tests/tools/src/lib.rs @@ -992,7 +992,7 @@ pub fn umask() -> u32 { .output() .expect("can execute `sh -c umask`"); assert!(output.status.success(), "`sh -c umask` failed"); - assert!(output.stderr.is_empty(), "`sh -c umask` unexpected message"); + assert_eq!(output.stderr.as_bstr(), "", "`sh -c umask` unexpected message"); let text = output.stdout.to_str().expect("valid Unicode").trim(); u32::from_str_radix(text, 8).expect("parses as octal number") } From 8d596b4179f37fbecf09291f29c15103851b63f2 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 9 Mar 2025 04:08:48 +0000 Subject: [PATCH 037/193] Add `env` testtools subcommand to show the environment (This is only temporarily in `gix-testtools` and shall either be moved to `internal-tools` or removed altogether.) It is useful to be able to observe environment variables that are set when running code with tools such as `cargo` or `cross`. This is therefore not intended for general-purpose use. A system command like `printenv` or `env` or a shell facility should be preferred where applicable, since it is considered a feature rather than a bug that commands like `cargo run -p gix-testtools env` include changes to the environment from `cargo` itself. Since one use for checking environment variables is to investigate the effects of environments that contain variable names or values that are not valid Unicode, this avoids requiring that environment variables all be Unicode. Any name or value that is not Unicode is shown in its Rust debug representation. This is always quoted, and to decrease ambiguity any name or (more likely) value that contains literal double quotes is likewise shown in its debug representation so that it is always clear if a quotation mark is just for display. Each name and value is otherwise shown literally. In either case the name or its representation is separated by a `=` from the value or its representation. --- tests/tools/src/main.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/tools/src/main.rs b/tests/tools/src/main.rs index 66a485dd360..420fd7778b1 100644 --- a/tests/tools/src/main.rs +++ b/tests/tools/src/main.rs @@ -9,6 +9,19 @@ fn bash_program() -> io::Result<()> { Ok(()) } +fn env() -> io::Result<()> { + fn repr(text: &std::ffi::OsStr) -> String { + text.to_str() + .filter(|s| !s.contains('"')) + .map(ToOwned::to_owned) + .unwrap_or_else(|| format!("{text:?}")) + } + for (name, value) in std::env::vars_os() { + println!("{}={}", repr(&name), repr(&value)); + } + Ok(()) +} + fn mess_in_the_middle(path: PathBuf) -> io::Result<()> { let mut file = fs::OpenOptions::new().read(false).write(true).open(path)?; file.seek(io::SeekFrom::Start(file.metadata()?.len() / 2))?; @@ -27,6 +40,7 @@ fn main() -> Result<(), Box> { let scmd = args.next().expect("sub command"); match &*scmd { "bash-program" | "bp" => bash_program()?, + "env" => env()?, "mess-in-the-middle" => mess_in_the_middle(PathBuf::from(args.next().expect("path to file to mess with")))?, #[cfg(unix)] "umask" => umask()?, From ab2b26c8e0fb3b9c2bae956f07c17e960c98f0a0 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 9 Mar 2025 06:25:50 +0000 Subject: [PATCH 038/193] Recognize `NO_PRELOAD_CXX` to not preload Android C++ library This further customizes the `cross` Dockerfile so it patches the `/android-runner` script in the image so, when the script runs, it checks if something like `NO_PRELOAD_CXX=1` is set (specifically, if `NO_PRELOAD_CXX` exists with a value other than the empty string or `0`) and, if so, refrains from setting `LD_PRELOAD` to the path of an Android C++ standard library implementation. (This also adds `NO_PRELOAD_CXX` to the list of variables `cross` allows to pass from host to container environment, so it can be set easily.) The problem this solves is warnings, which appear to be errors based on their wording but which do not inherently cause failure, that a library cannot be loaded into executables that are for a different architecture. `ld.so` issues these when running x86-64 executables in the `cross` container for `armv7-linux-androideabi`. Currently that includes shells (`sh`, `bash`) and `git`. ERROR: ld.so: object '/android-ndk/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored. While the warnings do not inherently cause failure, removing them is not just to decrease noise in the output of test runs. Because the messages are sent to stderr, they are picked up in code that expects stderr to be of a particular form, including test cases that include assertions about what is written to standard error. In addition to not representing actual bugs, the resulting test failures are confusing because they consist of a message that a library cannot be preloaded for a platform-related reason ("wrong ELF class"), followed by the failure of a test that exercises code that runs an external command (or possibly, in some cases, tests that capture stderr in a fixture script to set up a test). That creates the appearance that the external command could not be run, when actually the problem is that the external command ran, often with no problems at all, but its captured stderr contained one or (if it ran its own subprocesses) more extra lines describing themselves as errors. In e94526e and 094023a (both in #1687), I had claimed in comments that the reason to test `gix-hashtable` rather than `gix` in the `armv7-linux-androideabi` job (since removed) was that, in `armv7-linux-androideabi`, some `gix` tests needed to be able to run `git`, and needed ARMv7 `git`. This is technically true, but misleading (and while the logs have expired so I cannot check what I saw at that time, I suspect I was myself misled). They have relied on ARMv7 `git` on such a platform in the sense that the x86-64 `git` is completely usable but causes "wrong ELF class" warnings, which appear to be errors, to be written to stderr, breaking tests or test fixtures that examine stderr (as well as any test that attempts to read a `once_cell::sync::Lazy` that a previous test run in the same process tried to initialize by running code that panicked due to such a failure -- when control exits a `Lazy` initializer due to unwinding *from a panic*, the cell enters a "poisoned" state and subsequent uses of it fail). If an ARMv7 `git` were to be used, then the shared library -- even if `git` didn't use the library -- would presumably be preloaded, which would avoid the warning. But the problem was not inherent to the architecture or build of binares like `git`, instead arising from the incompatible `LD_PRELOAD` value. (Also, as far as I know, we have so far never used an ARMv7 build of `git` in any `cross` test... though it is used in the current `test-32bit` arm32v7 job.) Avoiding setting `LD_PRELOAD`, as done here, fixes that. However, this is not an ideal solution, because the library may be needed if an external command is built for the Android target architecture and is written in C++. It might be ideal to suppress the warnings while still attempting to load the library, but it's not clear if a reasonably simple way to do so is available: - `LD_PRELOAD` paths support `$LIB`, but I am not sure it can be used here, because the library name, and not just the directory prefix, differs. (Also, when not attempting to link to the C++ stdlib for Android, nothing would *ordinarily* be added to `LD_PRELOAD` at all.) - glibc issue https://sourceware.org/bugzilla/show_bug.cgi?id=20172 proposes a new environment variable `LD_PRELOAD_IGNORE_ERRORS`, but no patch with that feature has been merged into any version of glibc at this time (so certainly not the fairly old glibc in the `cross` image). The other reason this is not an ideal solution is that, at least if testing with `cross` is to become fully useful, some external commands in the `cross` container *should* be built for the target architecture, because in practice those are the builds (or in some cases, ports) that gitoxide would have to be compatible with. That includes `git` and, if feasible, `sh`, and maybe some others such as `gpg` and (if sufficiently tested to matter) `ssh`. So while the existing workaround makes it so ARMv7 `git` is not necessary to keep the tests from failing when they should pass, it remains potentially necessary to keep the tests from passing when they should fail. (This also applies to other architectures tested with `cross`, particularly s390x, where failure occurring in native runs, mentioned in #1687 and discused in #1698 comments, have not yet been reproducible when testing with `cross`. The reason is *possibly* some difference between the behavior of x86-64 and s390x `git`.) However, even if that can be achieved, it will likely also be an incomplete solution on its own, because as long as we may ever capture stderr from *some* external command where the warning is issued, we have to suppress or tolerate the warning in some way. --- Cross.toml | 1 + etc/docker/Dockerfile.test-cross | 1 + etc/run-cross-experiment.sh | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cross.toml b/Cross.toml index b891146c831..88913f12fcc 100644 --- a/Cross.toml +++ b/Cross.toml @@ -10,6 +10,7 @@ passthrough = [ "GIX_TEST_EXPECT_REDUCED_TRUST", "GIX_TEST_IGNORE_ARCHIVES", "GIX_VERSION", + "NO_PRELOAD_CXX", ] [target.armv7-linux-androideabi] diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index 704c4d593be..edbc978a7e8 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -12,4 +12,5 @@ RUN apt-get update && \ apt-get update && \ apt-get install --no-install-recommends -y git jq && \ rm -rf /var/lib/apt/lists/* && \ + sed -i.orig 's/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' /android-runner && \ git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue diff --git a/etc/run-cross-experiment.sh b/etc/run-cross-experiment.sh index 863d49d71ce..e716d7e99a2 100755 --- a/etc/run-cross-experiment.sh +++ b/etc/run-cross-experiment.sh @@ -17,6 +17,6 @@ cargo clean gix clean -xd -m '*generated*' -e # Run the test suite. -cross test --workspace --no-fail-fast --target "$target" \ +NO_PRELOAD_CXX=1 cross test --workspace --no-fail-fast --target "$target" \ --no-default-features --features max-pure \ -- --skip realpath::fuzzed_timeout From b26c2a2205553fcb6df10706ce3404db62125cd3 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 9 Mar 2025 08:08:26 +0000 Subject: [PATCH 039/193] Only patch `/android-runner` if it exists So the `cross` Dockerfile can continue to be used for both Android and non-Android targets. --- etc/docker/Dockerfile.test-cross | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index edbc978a7e8..cad60f0bc29 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -12,5 +12,7 @@ RUN apt-get update && \ apt-get update && \ apt-get install --no-install-recommends -y git jq && \ rm -rf /var/lib/apt/lists/* && \ - sed -i.orig 's/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' /android-runner && \ + to_patch=/android-runner && \ + patcher='s/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' && \ + if test -f "$to_patch"; then sed -i.orig "$patcher" -- "$to_patch"; fi && \ git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue From 35627b5146c6cbf72a41b1ef4cd6b3d64010c0bc Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 9 Mar 2025 08:15:36 +0000 Subject: [PATCH 040/193] Change `interpolate_user` tests to cover Android `interpolate_user()` gives `UserInterpolationUnsupported` on both Windows and Android, which is intentional. But the tests treated Windows as the only platform under which this was the case, thereby failing on Android tests. This may have been obscured by prior difficulties running tests on Android builds of `gix-config-value`. --- gix-config-value/tests/value/path.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gix-config-value/tests/value/path.rs b/gix-config-value/tests/value/path.rs index 94259d6355b..999c07b06f9 100644 --- a/gix-config-value/tests/value/path.rs +++ b/gix-config-value/tests/value/path.rs @@ -89,16 +89,16 @@ mod interpolate { Ok(()) } - #[cfg(windows)] + #[cfg(any(target_os = "windows", target_os = "android"))] #[test] - fn tilde_with_given_user_is_unsupported_on_windows() { + fn tilde_with_given_user_is_unsupported_on_windows_and_android() { assert!(matches!( interpolate_without_context("~baz/foo/bar"), Err(gix_config_value::path::interpolate::Error::UserInterpolationUnsupported) )); } - #[cfg(not(windows))] + #[cfg(not(any(target_os = "windows", target_os = "android")))] #[test] fn tilde_with_given_user() -> crate::Result { let home = std::env::current_dir()?; From c19bf1de76a3d6afc7740bdbc35181276bfcb58d Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 9 Mar 2025 08:40:30 +0000 Subject: [PATCH 041/193] Test `gix_testtools::umask()` on Android targets Rather than only on non-Android Linux-based systems. Like most Linux-based systems, Android has `/proc`, so the test can get the umask expected value using its `/proc`-based approach that is independent of the approach used in the code under test. --- tests/tools/tests/umask.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/tools/tests/umask.rs b/tests/tools/tests/umask.rs index 0a4cc04250b..5463b57ad49 100644 --- a/tests/tools/tests/umask.rs +++ b/tests/tools/tests/umask.rs @@ -1,6 +1,9 @@ #[test] #[cfg(unix)] -#[cfg_attr(not(target_os = "linux"), ignore = "The test itself uses /proc")] +#[cfg_attr( + not(any(target_os = "linux", target_os = "android")), + ignore = "The test itself uses /proc" +)] fn umask() { use std::fs::File; use std::io::{BufRead, BufReader}; From d3a9f5ff5771d4d91ddb8a8cdddbc51a03c4667f Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 9 Mar 2025 11:19:55 +0000 Subject: [PATCH 042/193] Move `cross` testing commands into `justfile` --- etc/run-cross-experiment.sh | 22 ---------------------- justfile | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 22 deletions(-) delete mode 100755 etc/run-cross-experiment.sh diff --git a/etc/run-cross-experiment.sh b/etc/run-cross-experiment.sh deleted file mode 100755 index e716d7e99a2..00000000000 --- a/etc/run-cross-experiment.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -# Usage: -# -# etc/run-cross-experiment.sh armv7-linux-androideabi -# etc/run-cross-experiment.sh s390x-unknown-linux-gnu - -set -eux -target="$1" - -# Build the customized `cross` container image. -docker build --build-arg "TARGET=$target" -t "cross-rs-gitoxide:$target" \ - - Date: Sun, 9 Mar 2025 11:23:17 +0000 Subject: [PATCH 043/193] Ensure `cross` test images have `patch` For `armv7-linux-androideabi`, in GIX_TEST_IGNORE_ARCHIVES=1 cross test ... as tested by running GIX_TEST_IGNORE_ARCHIVES=1 just cross-test-android the `id::ancestors::pre_epoch` test failed with: /project/gix/tests/fixtures/make_pre_epoch_repo.sh: line 12: patch: command not found This fixes it by making sure `patch` is installed in the container. --- etc/docker/Dockerfile.test-cross | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index cad60f0bc29..83ae0c3e3f6 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -10,7 +10,7 @@ RUN apt-get update && \ apt-key adv --keyserver keyserver.ubuntu.com \ --recv-keys F911AB184317630C59970973E363C90F8F1B6217 && \ apt-get update && \ - apt-get install --no-install-recommends -y git jq && \ + apt-get install --no-install-recommends -y git jq patch && \ rm -rf /var/lib/apt/lists/* && \ to_patch=/android-runner && \ patcher='s/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' && \ From 239eee49ba4d14d03886c84c55a8636fe81df1dc Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 9 Mar 2025 12:15:09 +0000 Subject: [PATCH 044/193] Keep the `cross` test config from affecting other `cross` usage Since we also use `cross` to build some of the releases. --- Cross.toml => etc/docker/test-cross.toml | 4 ++++ justfile | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) rename Cross.toml => etc/docker/test-cross.toml (68%) diff --git a/Cross.toml b/etc/docker/test-cross.toml similarity index 68% rename from Cross.toml rename to etc/docker/test-cross.toml index 88913f12fcc..ce921b42b21 100644 --- a/Cross.toml +++ b/etc/docker/test-cross.toml @@ -1,3 +1,7 @@ +# `cross` configuration for running tests. Treated like `Cross.toml` if enabled +# with `CROSS_CONFIG=etc/docker/test-cross.toml`. This avoids affecting other +# `cross` usage, e.g. in `release.yml`. See `cross-test` recipes in `justfile`. + [build.env] passthrough = [ "CI", diff --git a/justfile b/justfile index 0f2f19f2a1c..58f78b525f5 100755 --- a/justfile +++ b/justfile @@ -231,7 +231,8 @@ cross-image target: # Test another platform with `cross` cross-test target: (cross-image target) - NO_PRELOAD_CXX=1 cross test --workspace --no-fail-fast --target "{{ target }}" \ + CROSS_CONFIG=etc/docker/test-cross.toml NO_PRELOAD_CXX=1 \ + cross test --workspace --no-fail-fast --target "{{ target }}" \ --no-default-features --features max-pure \ -- --skip realpath::fuzzed_timeout From 2fb7db84dd6679b8c4c410afc0121be37497f6eb Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 9 Mar 2025 22:22:40 +0000 Subject: [PATCH 045/193] Remove potentially misleading "(limited)" for Android This removes "(limited)" from the description of the `justfile` recipe `cross-test-android`. It *is* very limited, but that label is misleading, since currently `cross-test-s390x` (as well as other `cross` testing targets that could be run through the parameterized `cross-test` recipe) are limited in all the same ways. In particular, we are not currently testing them with any external components built for the target architecture. For example, `git` built for the host has been upgraded in the container and the environment has been configured so `gix-path`, `gix-testtools`, any test cases throughout the workspace can use it without problems (either directly or through a shell). In the future, some `cross` targets may gain a richer target environment to interact with when testing, by installing target builds of `git`, by installing target builds of libraries that facilitate more features than `max-pure`, or in other ways. At that point, convenience recipes for specific targets in the `justfile` that are more limited than other targets could be marked "(limited)". --- justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/justfile b/justfile index 58f78b525f5..ce5ba3666d9 100755 --- a/justfile +++ b/justfile @@ -239,7 +239,7 @@ cross-test target: (cross-image target) # Test s390x with `cross` cross-test-s390x: (cross-test 's390x-unknown-linux-gnu') -# Test Android with `cross` (limited) +# Test Android with `cross` cross-test-android: (cross-test 'armv7-linux-androideabi') # Run `cargo diet` on all crates to see that they are still in bounds From 809fb2f3fa2ceaef7fbcad5222ec6b892a086a9b Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 10 Mar 2025 03:07:51 +0000 Subject: [PATCH 046/193] Move `env` subcommand to `internal-tools` From `gix-testtools`, where it was originally placed. This also adapts and improves the original description from the commit message that had introduced the subcommand, to make clear when it makes sense to use this (given that operating systems and shells already supply facilities for listing environment variables). --- tests/it/src/args.rs | 17 +++++++++++++++++ tests/it/src/commands/env.rs | 15 +++++++++++++++ tests/it/src/commands/mod.rs | 3 +++ tests/it/src/main.rs | 1 + tests/tools/src/main.rs | 14 -------------- 5 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 tests/it/src/commands/env.rs diff --git a/tests/it/src/args.rs b/tests/it/src/args.rs index e0ccc820ae6..7d9f9a5ef53 100644 --- a/tests/it/src/args.rs +++ b/tests/it/src/args.rs @@ -73,6 +73,23 @@ pub enum Subcommands { /// current repository. Its main use is checking that fixture scripts are have correct modes. #[clap(visible_alias = "cm")] CheckMode {}, + /// Print environment variables as `NAME=value` lines. + /// + /// It is useful to be able to observe environment variables that are set when running code + /// with tools such as `cargo` or `cross`. Commands like `cargo run -p internal-tools -- env` + /// include environment changes from `cargo` itself. With `cross`, changes are more extensive, + /// due to the effect of `build.env.passthrough`, container customization, and existing special + /// cases in wrapper scripts shipped in default `cross` containers (such as to `LD_PRELOAD`). + /// + /// Since one use for checking environment variables is to investigate the effects of + /// environments that contain variable names or values that are not valid Unicode, this avoids + /// requiring that environment variables all be Unicode. Any name or value that is not Unicode + /// is shown in its Rust debug representation. This is always quoted, and to decrease ambiguity + /// any name or (more likely) value that contains literal double quotes is likewise shown in + /// its debug representation so that it is always clear if a quotation mark is just for + /// display. Each name and value is otherwise shown literally. + #[clap(visible_alias = "e")] + Env {}, } #[derive(Clone)] diff --git a/tests/it/src/commands/env.rs b/tests/it/src/commands/env.rs new file mode 100644 index 00000000000..0f95ed90221 --- /dev/null +++ b/tests/it/src/commands/env.rs @@ -0,0 +1,15 @@ +pub(super) mod function { + pub fn env() -> anyhow::Result<()> { + for (name, value) in std::env::vars_os() { + println!("{}={}", repr(&name), repr(&value)); + } + Ok(()) + } + + fn repr(text: &std::ffi::OsStr) -> String { + text.to_str() + .filter(|s| !s.contains('"')) + .map(ToOwned::to_owned) + .unwrap_or_else(|| format!("{text:?}")) + } +} diff --git a/tests/it/src/commands/mod.rs b/tests/it/src/commands/mod.rs index adc7a6decb2..ae00a26a8d7 100644 --- a/tests/it/src/commands/mod.rs +++ b/tests/it/src/commands/mod.rs @@ -6,3 +6,6 @@ pub use git_to_sh::function::git_to_sh; pub mod check_mode; pub use check_mode::function::check_mode; + +pub mod env; +pub use env::function::env; diff --git a/tests/it/src/main.rs b/tests/it/src/main.rs index 847978481df..f18dd3450be 100644 --- a/tests/it/src/main.rs +++ b/tests/it/src/main.rs @@ -32,6 +32,7 @@ fn main() -> anyhow::Result<()> { patterns, } => commands::copy_royal(dry_run, &worktree_root, destination_dir, patterns), Subcommands::CheckMode {} => commands::check_mode(), + Subcommands::Env {} => commands::env(), } } diff --git a/tests/tools/src/main.rs b/tests/tools/src/main.rs index 420fd7778b1..66a485dd360 100644 --- a/tests/tools/src/main.rs +++ b/tests/tools/src/main.rs @@ -9,19 +9,6 @@ fn bash_program() -> io::Result<()> { Ok(()) } -fn env() -> io::Result<()> { - fn repr(text: &std::ffi::OsStr) -> String { - text.to_str() - .filter(|s| !s.contains('"')) - .map(ToOwned::to_owned) - .unwrap_or_else(|| format!("{text:?}")) - } - for (name, value) in std::env::vars_os() { - println!("{}={}", repr(&name), repr(&value)); - } - Ok(()) -} - fn mess_in_the_middle(path: PathBuf) -> io::Result<()> { let mut file = fs::OpenOptions::new().read(false).write(true).open(path)?; file.seek(io::SeekFrom::Start(file.metadata()?.len() / 2))?; @@ -40,7 +27,6 @@ fn main() -> Result<(), Box> { let scmd = args.next().expect("sub command"); match &*scmd { "bash-program" | "bp" => bash_program()?, - "env" => env()?, "mess-in-the-middle" => mess_in_the_middle(PathBuf::from(args.next().expect("path to file to mess with")))?, #[cfg(unix)] "umask" => umask()?, From c9b0abe352de9aadffaddeb14202a7206a1fb966 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 10 Mar 2025 04:06:42 +0000 Subject: [PATCH 047/193] Have `it env` use quoted/debug form when newlines are present In addition to any invalid Unicode and double quotes, as before. + Revise its documentation. --- tests/it/src/args.rs | 9 ++++----- tests/it/src/commands/env.rs | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/it/src/args.rs b/tests/it/src/args.rs index 7d9f9a5ef53..537842ed328 100644 --- a/tests/it/src/args.rs +++ b/tests/it/src/args.rs @@ -78,16 +78,15 @@ pub enum Subcommands { /// It is useful to be able to observe environment variables that are set when running code /// with tools such as `cargo` or `cross`. Commands like `cargo run -p internal-tools -- env` /// include environment changes from `cargo` itself. With `cross`, changes are more extensive, - /// due to the effect of `build.env.passthrough`, container customization, and existing special + /// due to effects of `build.env.passthrough`, container customization, and preexisting special /// cases in wrapper scripts shipped in default `cross` containers (such as to `LD_PRELOAD`). /// /// Since one use for checking environment variables is to investigate the effects of /// environments that contain variable names or values that are not valid Unicode, this avoids /// requiring that environment variables all be Unicode. Any name or value that is not Unicode - /// is shown in its Rust debug representation. This is always quoted, and to decrease ambiguity - /// any name or (more likely) value that contains literal double quotes is likewise shown in - /// its debug representation so that it is always clear if a quotation mark is just for - /// display. Each name and value is otherwise shown literally. + /// is shown in its Rust debug representation. This is always quoted. To decrease ambiguity, + /// any name or value containing a literal double quote or newline is also shown in its debug + /// representation. Names and values without such content are shown literally and not quoted. #[clap(visible_alias = "e")] Env {}, } diff --git a/tests/it/src/commands/env.rs b/tests/it/src/commands/env.rs index 0f95ed90221..ef610c341de 100644 --- a/tests/it/src/commands/env.rs +++ b/tests/it/src/commands/env.rs @@ -8,7 +8,7 @@ pub(super) mod function { fn repr(text: &std::ffi::OsStr) -> String { text.to_str() - .filter(|s| !s.contains('"')) + .filter(|s| !s.chars().any(|c| c == '"' || c == '\n')) .map(ToOwned::to_owned) .unwrap_or_else(|| format!("{text:?}")) } From a6afbfbf315c9424bfc35ac8e1d3913f5510191c Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 17 Mar 2025 23:26:10 +0000 Subject: [PATCH 048/193] Let backtrace-related env vars into the `cross` container --- etc/docker/test-cross.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/docker/test-cross.toml b/etc/docker/test-cross.toml index ce921b42b21..31c5e671b5b 100644 --- a/etc/docker/test-cross.toml +++ b/etc/docker/test-cross.toml @@ -15,6 +15,8 @@ passthrough = [ "GIX_TEST_IGNORE_ARCHIVES", "GIX_VERSION", "NO_PRELOAD_CXX", + "RUST_BACKTRACE", + "RUST_LIB_BACKTRACE", ] [target.armv7-linux-androideabi] From eeb52791c26beb4a90fcfa6b4d18cda24e6670f8 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 17 Mar 2025 23:51:51 +0000 Subject: [PATCH 049/193] Start on `test-cross` CI job definition This *should* be able to run as written, but it can be improved. --- .github/workflows/ci.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f80297f737c..8eed4bf90d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -327,6 +327,31 @@ jobs: - name: Test (nextest) run: cargo nextest run --target $env:TARGET --workspace --no-fail-fast size + # TODO: If this is kept, then remove `fail-fast: false`; run only a subset of the tests, unless + # building and running the whole test suite is fast; install the cross target early via + # `dtolnay/rust-toolchain`, listing it as an additional target; and add a `Swatinem/rust-cache` + # step to cache dependencies. + test-cross: + runs-on: ubuntu-latest + + strategy: + matrix: + moniker: [ android, s390x ] + fail-fast: false + + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: extractions/setup-just@v3 + - name: Install cross + uses: taiki-e/install-action@v2 + with: + tool: cross + - name: Test (unit) + env: + RUST_BACKTRACE: '1' + run: just cross-test-${{ matrix.moniker }} + lint: runs-on: ubuntu-latest @@ -484,6 +509,7 @@ jobs: env: # List all jobs that are intended NOT to block PR auto-merge here. EXPECTED_NONBLOCKING_JOBS: |- + test-cross cargo-deny-advisories wasm tests-pass From cfeb06dc2653f04a308d651c5abcafe74ab062a7 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 17 Mar 2025 23:58:57 +0000 Subject: [PATCH 050/193] Divide up the `test-cross` CI steps better Rather than having the last step build the image through the `justfile` recipe dependency, and rather than having it install the `cross` target implicitly due to `cross` finding that it is not yet installed, this performs those actions in preceding steps. --- .github/workflows/ci.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8eed4bf90d9..fab665ab119 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -327,30 +327,34 @@ jobs: - name: Test (nextest) run: cargo nextest run --target $env:TARGET --workspace --no-fail-fast size - # TODO: If this is kept, then remove `fail-fast: false`; run only a subset of the tests, unless - # building and running the whole test suite is fast; install the cross target early via - # `dtolnay/rust-toolchain`, listing it as an additional target; and add a `Swatinem/rust-cache` - # step to cache dependencies. + # FIXME: *If* this is kept, then remove `fail-fast: false`, run only a subset of the tests unless + # building and running the whole test suite is fast, and add a `Swatinem/rust-cache` step. test-cross: runs-on: ubuntu-latest strategy: matrix: - moniker: [ android, s390x ] + target: [ armv7-linux-androideabi, s390x-unknown-linux-gnu ] fail-fast: false steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable + - name: Install Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + targets: ${{ matrix.target }} - uses: extractions/setup-just@v3 - name: Install cross uses: taiki-e/install-action@v2 with: tool: cross + - name: Build cross image + run: just cross-image ${{ matrix.target }} - name: Test (unit) env: RUST_BACKTRACE: '1' - run: just cross-test-${{ matrix.moniker }} + run: just cross-test ${{ matrix.target }} lint: runs-on: ubuntu-latest From 7d66f9e2e945cb8effb42dd2de94f41a3df07c15 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Tue, 18 Mar 2025 00:40:07 +0000 Subject: [PATCH 051/193] Thanks clippy --- tests/it/src/commands/env.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/it/src/commands/env.rs b/tests/it/src/commands/env.rs index ef610c341de..ed0cf5a9909 100644 --- a/tests/it/src/commands/env.rs +++ b/tests/it/src/commands/env.rs @@ -9,7 +9,6 @@ pub(super) mod function { fn repr(text: &std::ffi::OsStr) -> String { text.to_str() .filter(|s| !s.chars().any(|c| c == '"' || c == '\n')) - .map(ToOwned::to_owned) - .unwrap_or_else(|| format!("{text:?}")) + .map_or_else(|| format!("{text:?}"), ToOwned::to_owned) } } From c40ead98728e645e74bfb7a9b75b1f1ad81a55a2 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Tue, 18 Mar 2025 13:13:35 -0400 Subject: [PATCH 052/193] Configure binfmt_misc for QEMU on CI As in: https://docs.gitlab.com/omnibus/development/s390x/ --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fab665ab119..a873c13e7e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -349,6 +349,8 @@ jobs: uses: taiki-e/install-action@v2 with: tool: cross + - name: Configure binfmt_misc for QEMU + run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - name: Build cross image run: just cross-image ${{ matrix.target }} - name: Test (unit) From db8697b3888b367ccb3eff4d75a89ec9b52ad6ad Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 9 Mar 2025 22:20:34 +0000 Subject: [PATCH 053/193] Start on trying to get an s390x `git` in the s390x cross container Currently this fails with: Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: git:s390x : Depends: perl:s390x but it is not going to be installed Depends: liberror-perl:s390x but it is not installable Or, in some variations, the (same) error is expressed as: E: Package 'liberror-perl:s390x' has no installation candidate --- etc/docker/Dockerfile.test-cross | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index 83ae0c3e3f6..d81c5def254 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -2,7 +2,15 @@ ARG TARGET FROM ghcr.io/cross-rs/${TARGET}:latest -RUN apt-get update && \ +ARG TARGET + +RUN set -uC && \ + apt_suffix= && \ + if target_arch="$(dpkg-architecture --host-type "$TARGET" --query DEB_HOST_ARCH)"; then \ + dpkg --add-architecture "$target_arch" && \ + apt_suffix=":$target_arch"; \ + fi && \ + apt-get update && \ apt-get install --no-install-recommends -y apt-transport-https gnupg && \ release="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release)" && \ echo "deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $release main" \ @@ -10,9 +18,10 @@ RUN apt-get update && \ apt-key adv --keyserver keyserver.ubuntu.com \ --recv-keys F911AB184317630C59970973E363C90F8F1B6217 && \ apt-get update && \ - apt-get install --no-install-recommends -y git jq patch && \ + apt-get install --no-install-recommends -y "git$apt_suffix" jq patch && \ rm -rf /var/lib/apt/lists/* && \ - to_patch=/android-runner && \ - patcher='s/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' && \ - if test -f "$to_patch"; then sed -i.orig "$patcher" -- "$to_patch"; fi && \ + if test -f /android-runner; then \ + sed -i.orig 's/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' \ + /android-runner; \ + fi && \ git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue From 154b1a65573ff3d6329b8fa20224c2d29f143465 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 10 Mar 2025 09:27:49 +0000 Subject: [PATCH 054/193] Try to enable ports APT sources unconditionally This does not work as written, at least on s390x, because the ports list is already written there from the base image. The existing file is actually better than what this writes, though what this writes is simpler and so might potentially be easier to debug or reason about. Unfortunately, if we clobber the existing file with this one, the error installing `git:s390x` is unchanged. Uninstalling the old `amd64` `git` package first (not shown here) and packages installed as its dependencies doesn't help either. --- etc/docker/Dockerfile.test-cross | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index d81c5def254..9b5383bc413 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -5,14 +5,17 @@ FROM ghcr.io/cross-rs/${TARGET}:latest ARG TARGET RUN set -uC && \ + apt-get update && \ + apt-get install --no-install-recommends -y apt-transport-https gnupg && \ apt_suffix= && \ if target_arch="$(dpkg-architecture --host-type "$TARGET" --query DEB_HOST_ARCH)"; then \ dpkg --add-architecture "$target_arch" && \ apt_suffix=":$target_arch"; \ fi && \ - apt-get update && \ - apt-get install --no-install-recommends -y apt-transport-https gnupg && \ release="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release)" && \ + for pocket in "$release" "$release-security" "$release-updates" "$release-backports"; do \ + echo "deb http://ports.ubuntu.com/ubuntu-ports/ $pocket main universe"; \ + done >/etc/apt/sources.list.d/ports.list && \ echo "deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $release main" \ >/etc/apt/sources.list.d/git-core-ubuntu-ppa.list && \ apt-key adv --keyserver keyserver.ubuntu.com \ From ec63b31ba2dcc3a3e3432a261f260a138294d482 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 10 Mar 2025 10:24:33 +0000 Subject: [PATCH 055/193] Show that the problem still happens with `add-apt-repository` Thus, the lightweight manual approach used before isn't the cause. --- etc/docker/Dockerfile.test-cross | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index 9b5383bc413..7e65f58cd37 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -5,23 +5,18 @@ FROM ghcr.io/cross-rs/${TARGET}:latest ARG TARGET RUN set -uC && \ - apt-get update && \ - apt-get install --no-install-recommends -y apt-transport-https gnupg && \ apt_suffix= && \ if target_arch="$(dpkg-architecture --host-type "$TARGET" --query DEB_HOST_ARCH)"; then \ dpkg --add-architecture "$target_arch" && \ apt_suffix=":$target_arch"; \ fi && \ - release="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release)" && \ - for pocket in "$release" "$release-security" "$release-updates" "$release-backports"; do \ - echo "deb http://ports.ubuntu.com/ubuntu-ports/ $pocket main universe"; \ - done >/etc/apt/sources.list.d/ports.list && \ - echo "deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $release main" \ - >/etc/apt/sources.list.d/git-core-ubuntu-ppa.list && \ - apt-key adv --keyserver keyserver.ubuntu.com \ - --recv-keys F911AB184317630C59970973E363C90F8F1B6217 && \ + apt-get update && \ + apt-get install --no-install-recommends -y software-properties-common && \ + add-apt-repository -y ppa:git-core/ppa && \ apt-get update && \ apt-get install --no-install-recommends -y "git$apt_suffix" jq patch && \ + apt-get purge --autoremove software-properties-common && \ + apt-get clean && \ rm -rf /var/lib/apt/lists/* && \ if test -f /android-runner; then \ sed -i.orig 's/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' \ From a3fed7707ede3469cd89eadff508c5cd2d86deff Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 10 Mar 2025 20:29:05 +0000 Subject: [PATCH 056/193] Convert the problem to failure to install perl:s390x The following packages have unmet dependencies: perl : Conflicts: perl:s390x but 5.22.1-9ubuntu0.9 is to be installed perl:s390x : Depends: perl-base:s390x (= 5.22.1-9ubuntu0.9) but it is not going to be installed Depends: libperl5.22:s390x (= 5.22.1-9ubuntu0.9) but it is not going to be installed Conflicts: perl but 5.22.1-9ubuntu0.9 is to be installed --- etc/docker/Dockerfile.test-cross | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index 7e65f58cd37..190e0ababba 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -14,7 +14,11 @@ RUN set -uC && \ apt-get install --no-install-recommends -y software-properties-common && \ add-apt-repository -y ppa:git-core/ppa && \ apt-get update && \ - apt-get install --no-install-recommends -y "git$apt_suffix" jq patch && \ + apt-get install --no-install-recommends -y "libc6$apt_suffix" "libcurl3-gnutls$apt_suffix" \ + "libexpat1$apt_suffix" "libpcre2-8-0$apt_suffix" "zlib1g$apt_suffix" "perl$apt_suffix" \ + liberror-perl git-man patch jq && \ + apt-get download "git$apt_suffix" && \ + dpkg --ignore-depends="liberror-perl$apt_suffix" -i ./git[-_]*.deb && \ apt-get purge --autoremove software-properties-common && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* && \ From f0773eecd4798eda2eb3e7f1348afd67cc09e8c7 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 10 Mar 2025 20:44:35 +0000 Subject: [PATCH 057/193] Install host-arch `perl` deps, force target arch `git` to use them This does cause `git:s390x` to install in the s390x cross container but the changes are not finished -- container creation still fails due to a subsequent attempt to fix missing packages. Assuming `git` can use `perl` from a different architecture, which seems likely since it is invoking it as an interpreter (rather than linking to it), this should be fine, but to limit container bloat some other changes are needed to make it so we don't need the `autoremove` operation to get rid of files only used in setting up the PPA. --- etc/docker/Dockerfile.test-cross | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index 190e0ababba..e0323ca1efe 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -15,10 +15,12 @@ RUN set -uC && \ add-apt-repository -y ppa:git-core/ppa && \ apt-get update && \ apt-get install --no-install-recommends -y "libc6$apt_suffix" "libcurl3-gnutls$apt_suffix" \ - "libexpat1$apt_suffix" "libpcre2-8-0$apt_suffix" "zlib1g$apt_suffix" "perl$apt_suffix" \ - liberror-perl git-man patch jq && \ + "libexpat1$apt_suffix" "libpcre2-8-0$apt_suffix" "zlib1g$apt_suffix" perl liberror-perl \ + git-man patch jq && \ apt-get download "git$apt_suffix" && \ - dpkg --ignore-depends="liberror-perl$apt_suffix" -i ./git[-_]*.deb && \ + dpkg --ignore-depends="perl$apt_suffix,liberror-perl$apt_suffix" -i git[-_]*.deb && \ + echo INSTALLED/UPGRADED GIT && \ + rm git[-_]*.deb && \ apt-get purge --autoremove software-properties-common && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* && \ From 9be7e99e79c4f2e9813a932aabdd67fa137d2b3a Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 10 Mar 2025 21:32:23 +0000 Subject: [PATCH 058/193] Manually set up PPA + other fixups This avoids installing `software-properties-common` in the container, instead manually setting up the PPA again. Accordingly, it is not necessary to uninstall any packages to avoid high bloat in the image, so that is removed. Other cleanup is still done. This also removes the old `git` and packages that were marked as automatically installed that were only needed as its dependencies, and shows details about the `git` that is installed. For s390x, this works to cause the test suite to use a s390x build of `git`, at a reasonably new version as provided by the PPA. That should happen for some other targets, but not all. This therefore shows the `git` version as well as examining the executable to report its architecture while the container is being built. Note that this does not yet appear sufficient to produce the s390x test failures mentioned in #1687 and discused in #1698 comments. (That might relate to how this is still just testing `max-pure`.) --- etc/docker/Dockerfile.test-cross | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index e0323ca1efe..704a18529c4 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -11,17 +11,23 @@ RUN set -uC && \ apt_suffix=":$target_arch"; \ fi && \ apt-get update && \ - apt-get install --no-install-recommends -y software-properties-common && \ - add-apt-repository -y ppa:git-core/ppa && \ + apt-get install --no-install-recommends -y apt-transport-https gnupg && \ + release="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release)" && \ + echo "deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $release main" \ + >/etc/apt/sources.list.d/git-core-ubuntu-ppa.list && \ + apt-key adv --keyserver keyserver.ubuntu.com \ + --recv-keys F911AB184317630C59970973E363C90F8F1B6217 && \ apt-get update && \ + apt-get purge --autoremove -y git && \ apt-get install --no-install-recommends -y "libc6$apt_suffix" "libcurl3-gnutls$apt_suffix" \ "libexpat1$apt_suffix" "libpcre2-8-0$apt_suffix" "zlib1g$apt_suffix" perl liberror-perl \ - git-man patch jq && \ + git-man file jq patch && \ apt-get download "git$apt_suffix" && \ dpkg --ignore-depends="perl$apt_suffix,liberror-perl$apt_suffix" -i git[-_]*.deb && \ - echo INSTALLED/UPGRADED GIT && \ + git version --build-options && \ + git="$(command -v git)" && \ + file -- "$git" && \ rm git[-_]*.deb && \ - apt-get purge --autoremove software-properties-common && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* && \ if test -f /android-runner; then \ From 6e7122f4d8ce28e269ecb89452fce9a20b73df69 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Tue, 11 Mar 2025 01:21:30 +0000 Subject: [PATCH 059/193] Make sure we actually have `dpkg-architecture` It is provided by `dpkg-dev`, which is installed already in some but not all `cross` images. This commit also: - Allows more configuration to occur by installing `apt-utils`. Without this, `gnupg` warns about skipping some debconf configuration. - Sets up the environment in which commands like `apt-get` and `dpkg` run so configuring packages never prompts. Passing `-y` is not sufficient to achieve this. (The problem currently does not occur, but it would happen in at least the Android image if a new dependency brings in `tzdata` indirectly, as will occur if attempting to install dependencies to test more than `max-pure`.) --- etc/docker/Dockerfile.test-cross | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index 704a18529c4..60a29d10cf1 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -5,13 +5,16 @@ FROM ghcr.io/cross-rs/${TARGET}:latest ARG TARGET RUN set -uC && \ + export DEBIAN_FRONTEND=noninteractive TZ=UTC && \ + apt-get update && \ + apt-get install --no-install-recommends -y apt-utils && \ + apt-get install --no-install-recommends -y apt-transport-https dpkg-dev gnupg && \ + type dpkg-architecture && \ apt_suffix= && \ if target_arch="$(dpkg-architecture --host-type "$TARGET" --query DEB_HOST_ARCH)"; then \ dpkg --add-architecture "$target_arch" && \ apt_suffix=":$target_arch"; \ fi && \ - apt-get update && \ - apt-get install --no-install-recommends -y apt-transport-https gnupg && \ release="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release)" && \ echo "deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $release main" \ >/etc/apt/sources.list.d/git-core-ubuntu-ppa.list && \ From 1df389496b0479732e81336aaad64c6fd687a50e Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Tue, 11 Mar 2025 01:42:54 +0000 Subject: [PATCH 060/193] Let `apt-get download` drop privileges for the download + Adjust whitespace style by letting short closely related commands appear on the same line. Broadly speaking, this style is often not clearer, but in this case, especially with the new commands here, it seems to improve clarity. (Though maybe not as much as breaking the `RUN` contents out into a script file, where they could instead be easily grouped with whitespace and comments.) --- etc/docker/Dockerfile.test-cross | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index 60a29d10cf1..6dd9ba1189f 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -25,14 +25,11 @@ RUN set -uC && \ apt-get install --no-install-recommends -y "libc6$apt_suffix" "libcurl3-gnutls$apt_suffix" \ "libexpat1$apt_suffix" "libpcre2-8-0$apt_suffix" "zlib1g$apt_suffix" perl liberror-perl \ git-man file jq patch && \ - apt-get download "git$apt_suffix" && \ - dpkg --ignore-depends="perl$apt_suffix,liberror-perl$apt_suffix" -i git[-_]*.deb && \ - git version --build-options && \ - git="$(command -v git)" && \ - file -- "$git" && \ - rm git[-_]*.deb && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* && \ + mkdir /tmp/dl && chown _apt /tmp/dl && \ + (cd /tmp/dl && apt-get download "git$apt_suffix") && \ + dpkg --ignore-depends="perl$apt_suffix,liberror-perl$apt_suffix" -i /tmp/dl/git[-_]*.deb && \ + git version --build-options && git="$(command -v git)" && file -- "$git" && \ + apt-get clean && rm -rf /tmp/dl /var/lib/apt/lists/* && \ if test -f /android-runner; then \ sed -i.orig 's/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' \ /android-runner; \ From 6e3e0686df2a0dec414bc89a60015ade091475db Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Tue, 11 Mar 2025 03:37:47 +0000 Subject: [PATCH 061/193] Test max on s390x (and potentially elsewhere supported) This modifies the `cross` dockerfile and associated `justfile` recipes to install dependencies needed for testing beyond max-pure. This works when installing packages for the cross target is already working, which is the same scenario where the upgraded `git` (from the git-core PPA) is installed for the `cross` target. But unlike `git`, when testing max-pure it is not necessary to install these libraries. Yet the current approach does install them... but native builds of them. This is inefficient in the Android test where there may be no immediately forthcoming way to install appropriate `cross`-target builds of the libraries. This extra work should probably be eliminated. But the best way to do that will depend on whether the two cases of cross targets (those we can install packages for and those we cannot) remain only two cases, and whether a single `RUN` script continues to be used, versus splitting it (or creating multiple `cross` dockerfiles). This also gives the `cross-test` recipe a `*cargo-test-args` parameter, and moves `--no-default-features --features max-pure` out of `cross-test` and into the arguments `cross-test-android` passes to `cross-test` (causing `*cargo-test-args` to receive it). The reason for doing this rather than having a parameter that is put in place of `max-pure`, for which `cross-test-s390x` could pass `max`, is that it is not obvious that `--no-default-features` is free of undesired effects when `--workspace` is used: it seems like it may suppress some features of some tested `gix-*` crate projects that do not individually recognize `max`. (This differs from the situation with the journey tests, which test the `ein` and `gix` executables from by the `gitoxide` crate, which recognizes `max-pure`.) The intuitive effect of "testing max" is currently to run the entire test suite with all default features enabled, so this strives to do that. This still does not appear sufficient to produce the s390x test failures mentioned in #1687 and discused in #1698 comments, even though this is now running s390x tests with the same full default features as were used when those failures were observed. --- etc/docker/Dockerfile.test-cross | 3 ++- justfile | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index 6dd9ba1189f..8fd1b3fc102 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -24,7 +24,8 @@ RUN set -uC && \ apt-get purge --autoremove -y git && \ apt-get install --no-install-recommends -y "libc6$apt_suffix" "libcurl3-gnutls$apt_suffix" \ "libexpat1$apt_suffix" "libpcre2-8-0$apt_suffix" "zlib1g$apt_suffix" perl liberror-perl \ - git-man file jq patch && \ + git-man ca-certificates cmake "curl$apt_suffix" file jq "libc-dev$apt_suffix" \ + "libssl-dev$apt_suffix" patch pkgconf && \ mkdir /tmp/dl && chown _apt /tmp/dl && \ (cd /tmp/dl && apt-get download "git$apt_suffix") && \ dpkg --ignore-depends="perl$apt_suffix,liberror-perl$apt_suffix" -i /tmp/dl/git[-_]*.deb && \ diff --git a/justfile b/justfile index ce5ba3666d9..86cf6cf9a26 100755 --- a/justfile +++ b/justfile @@ -230,17 +230,17 @@ cross-image target: - Date: Tue, 11 Mar 2025 09:51:54 +0000 Subject: [PATCH 062/193] Start toward moving the dense `RUN` to a commented script --- etc/docker/customize-test-cross-image.sh | 112 +++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100755 etc/docker/customize-test-cross-image.sh diff --git a/etc/docker/customize-test-cross-image.sh b/etc/docker/customize-test-cross-image.sh new file mode 100755 index 00000000000..52a0ded0c30 --- /dev/null +++ b/etc/docker/customize-test-cross-image.sh @@ -0,0 +1,112 @@ +#!/bin/bash +set -euxC + +target="$1" + +# Arrange for the indirect `tzdata` dependency to be installed and configured +# without prompting for the time zone. (Passing `-y` is not enough.) +export DEBIAN_FRONTEND=noninteractive TZ=UTC + +# Install tools for setting up APT repositores. Install `apt-utils` before the +# others, so the installation of `gnupg` can use it for debconf. +apt-get update +apt-get install --no-install-recommends -y apt-utils +apt-get install --no-install-recommends -y apt-transport-https dpkg-dev gnupg +type dpkg-architecture # Make sure we really have this. + +# Decide what architecture to use for `git`, shared libraries for gitoxide when +# attempting to build `max`, and shared libraries used by `git` itself. +apt_suffix= +if target_arch="$(dpkg-architecture --host-type "$target" --query DEB_HOST_ARCH)"; then + dpkg --add-architecture "$target_arch" + apt_suffix=":$target_arch" +fi + +# Add the git-core PPA manually. (Faster than installing `add-apt-repository`.) +release="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release)" +echo "deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $release main" \ + >/etc/apt/sources.list.d/git-core-ubuntu-ppa.list +apt-key adv --keyserver keyserver.ubuntu.com \ + --recv-keys F911AB184317630C59970973E363C90F8F1B6217 +apt-get update + +# Remove the old `git` and associated packages. +apt-get purge --autoremove -y git + +# Git dependencies. These are for the desired architecture, except `git-man` is +# the same package for all architectures, and we can't always install `perl` or +# `liberror-perl` for the desired architecture (at least in s390x). +# TODO(maint): Resolve these dynamically to support future `cross` base images. +git_deps=( + git-man + "libc6$apt_suffix" + "libcurl3-gnutls$apt_suffix" + "libexpat1$apt_suffix" + liberror-perl + "libpcre2-8-0$apt_suffix" + "zlib1g$apt_suffix" + perl +) + +# Other dependencies for running the gitoxide test suite and fixture scripts, +# and for building and testing gitoxide for feature sets beyond `max-pure`. +gix_test_deps=( + ca-certificates + cmake + "curl$apt_suffix" + jq + "libc-dev$apt_suffix" + "libssl-dev$apt_suffix" + patch + pkgconf +) + +# Install everything we need except `git` (and what we already have). We can't +# necessarily install `git` this way, because it insists on `perl` and +# `liberror-perl` dependencies of the same architecture as it. These may not be +# possible to install in a mixed environment, where most packages are a +# different architecture, and where `perl` is a dependency of other important +# packages. So we will install everything else first (then manually add `git`). +apt-get install --no-install-recommends -y \ + "${git_deps[@]}" "${gix_test_deps[@]}" file + +# Add `git` by manually downloading it and installing it with `dpkg`, forcing +# installation to proceed even if its `perl` and `liberror-perl` dependencies, +# as declared by `git`, are absent. (We have already installed them, but in a +# possibly different architecture. `git` can still use them, because its use is +# to run scripts, rather than to link to a shared library they provide.) It is +# preferred to let `apt-get download` drop privileges to the `_apt` user during +# download, so we download it inside `/tmp`. But we create a subdirectory so it +# is safe to make assumptions about what files globs can expand to, even if +# `/tmp` is mounted to an outside share temp dir on a multi-user system. +mkdir /tmp/dl # Don't use `-p`; if it exists already, we cannot trust it. +chown _apt /tmp/dl # Use owner, as the container may not have an `_apt` group. +(cd /tmp/dl && apt-get download "git$apt_suffix") +dpkg --ignore-depends="perl$apt_suffix,liberror-perl$apt_suffix" \ + -i /tmp/dl/git[-_]*.deb + +# Show information about the newly installed `git` (and ensure it can run). +git version --build-options +git="$(command -v git)" +file -- "$git" + +# Clean up files related to package management that we won't need anymore. +apt-get clean +rm -rf /tmp/dl /var/lib/apt/lists/* + +# If this is an Android-related image or otherwise has a runner script `cross` +# uses for Android, then patch the script to add the ability to suppress its +# customization of `LD_PRELOAD`. This runner script sets `LD_PRELOAD` to the +# path of `libc++_shared.so` in the vendored Android NDK. But this causes a +# problem for us because, when a non-Android (i.e. a host-architecture) program +# is run, `ld.so` shows a message about the "wrong ELF class". Such programs +# can still run, but when we make an assertion about, parse, or otherwise rely +# on their output to standard error, we get test failures. (That especially +# affects fixtures.) This change lets us pass `NO_PRELOAD_CXX=1` to avoid that. +if test -f /android-runner; then + sed -i.orig 's/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' + /android-runner +fi + +# Ensure a nonempty Git `system` scope (for the `installation_config` tests). +git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue From c3ea44bf3a768d3c11583daf4e24f8bbfa074198 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Wed, 12 Mar 2025 08:33:04 +0000 Subject: [PATCH 063/193] Finish moving the dense `RUN` to a commented script - Clarify and expand comments. - Adjust style for greater consistency within the script. - Have the script tolerate leading whitespace when it patches the Android runner script, since it looks like future releases of `cross` may have it undented under an `if` check for the Android version (not all versions have a C++ library in the NDK). - Move the script into a subdirectory that will be used as context. - Replace the old `RUN` step with a command to run the script. - Modify the build command in the `justfile` to use the context. --- etc/docker/Dockerfile.test-cross | 37 ++------------- .../customize.sh} | 47 ++++++++++++------- justfile | 5 +- 3 files changed, 36 insertions(+), 53 deletions(-) rename etc/docker/{customize-test-cross-image.sh => test-cross-context/customize.sh} (69%) diff --git a/etc/docker/Dockerfile.test-cross b/etc/docker/Dockerfile.test-cross index 8fd1b3fc102..7d420c754d0 100644 --- a/etc/docker/Dockerfile.test-cross +++ b/etc/docker/Dockerfile.test-cross @@ -1,38 +1,7 @@ ARG TARGET - FROM ghcr.io/cross-rs/${TARGET}:latest ARG TARGET - -RUN set -uC && \ - export DEBIAN_FRONTEND=noninteractive TZ=UTC && \ - apt-get update && \ - apt-get install --no-install-recommends -y apt-utils && \ - apt-get install --no-install-recommends -y apt-transport-https dpkg-dev gnupg && \ - type dpkg-architecture && \ - apt_suffix= && \ - if target_arch="$(dpkg-architecture --host-type "$TARGET" --query DEB_HOST_ARCH)"; then \ - dpkg --add-architecture "$target_arch" && \ - apt_suffix=":$target_arch"; \ - fi && \ - release="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release)" && \ - echo "deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $release main" \ - >/etc/apt/sources.list.d/git-core-ubuntu-ppa.list && \ - apt-key adv --keyserver keyserver.ubuntu.com \ - --recv-keys F911AB184317630C59970973E363C90F8F1B6217 && \ - apt-get update && \ - apt-get purge --autoremove -y git && \ - apt-get install --no-install-recommends -y "libc6$apt_suffix" "libcurl3-gnutls$apt_suffix" \ - "libexpat1$apt_suffix" "libpcre2-8-0$apt_suffix" "zlib1g$apt_suffix" perl liberror-perl \ - git-man ca-certificates cmake "curl$apt_suffix" file jq "libc-dev$apt_suffix" \ - "libssl-dev$apt_suffix" patch pkgconf && \ - mkdir /tmp/dl && chown _apt /tmp/dl && \ - (cd /tmp/dl && apt-get download "git$apt_suffix") && \ - dpkg --ignore-depends="perl$apt_suffix,liberror-perl$apt_suffix" -i /tmp/dl/git[-_]*.deb && \ - git version --build-options && git="$(command -v git)" && file -- "$git" && \ - apt-get clean && rm -rf /tmp/dl /var/lib/apt/lists/* && \ - if test -f /android-runner; then \ - sed -i.orig 's/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' \ - /android-runner; \ - fi && \ - git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue +COPY customize.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/customize.sh && \ + /usr/local/bin/customize.sh "$TARGET" diff --git a/etc/docker/customize-test-cross-image.sh b/etc/docker/test-cross-context/customize.sh similarity index 69% rename from etc/docker/customize-test-cross-image.sh rename to etc/docker/test-cross-context/customize.sh index 52a0ded0c30..31396e3ee2e 100755 --- a/etc/docker/customize-test-cross-image.sh +++ b/etc/docker/test-cross-context/customize.sh @@ -2,6 +2,7 @@ set -euxC target="$1" +test -n "$target" # Arrange for the indirect `tzdata` dependency to be installed and configured # without prompting for the time zone. (Passing `-y` is not enough.) @@ -14,16 +15,30 @@ apt-get install --no-install-recommends -y apt-utils apt-get install --no-install-recommends -y apt-transport-https dpkg-dev gnupg type dpkg-architecture # Make sure we really have this. -# Decide what architecture to use for `git`, shared libraries for gitoxide when -# attempting to build `max`, and shared libraries used by `git` itself. +# Decide what architecture to use for `git`, shared libraries `git` links to, +# and shared libraries gitoxide links to when building `max`. Instead of this +# custom logic, we could use `$CROSS_DEB_ARCH`, which `cross` tries to provide +# (https://github.com/cross-rs/cross/blob/v0.2.5/src/lib.rs#L268), and which is +# available for roughly the same architectures where this logic gets a nonempty +# value. But using `$CROSS_DEB_ARCH` may make it harder to build and test the +# image manually. In particular, if it is not passed, we would conclude that we +# should install the versions of those packages with the host's architecture. apt_suffix= -if target_arch="$(dpkg-architecture --host-type "$target" --query DEB_HOST_ARCH)"; then +if target_arch="$(dpkg-architecture --host-type "$target" --query DEB_HOST_ARCH)" +then dpkg --add-architecture "$target_arch" apt_suffix=":$target_arch" + printf 'INFO: Using target architecture for `git` and libs in container.\n' + printf 'INFO: This architecture is %s.\n' "$target_arch" +else + apt_suffix='' + printf 'WARNING: Using HOST architecture for `git` and libs in container.\n' fi -# Add the git-core PPA manually. (Faster than installing `add-apt-repository`.) +# Get release codename. Like `lsb_release -sc`. (`lsb_release` may be absent.) release="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release)" + +# Add the git-core PPA manually. (Faster than installing `add-apt-repository`.) echo "deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $release main" \ >/etc/apt/sources.list.d/git-core-ubuntu-ppa.list apt-key adv --keyserver keyserver.ubuntu.com \ @@ -94,19 +109,17 @@ file -- "$git" apt-get clean rm -rf /tmp/dl /var/lib/apt/lists/* -# If this is an Android-related image or otherwise has a runner script `cross` -# uses for Android, then patch the script to add the ability to suppress its -# customization of `LD_PRELOAD`. This runner script sets `LD_PRELOAD` to the -# path of `libc++_shared.so` in the vendored Android NDK. But this causes a -# problem for us because, when a non-Android (i.e. a host-architecture) program -# is run, `ld.so` shows a message about the "wrong ELF class". Such programs -# can still run, but when we make an assertion about, parse, or otherwise rely -# on their output to standard error, we get test failures. (That especially -# affects fixtures.) This change lets us pass `NO_PRELOAD_CXX=1` to avoid that. -if test -f /android-runner; then - sed -i.orig 's/^export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' - /android-runner -fi +# If this image has a runner script `cross` uses for Android, patch the script +# to add the ability to suppress its customization of `LD_PRELOAD`. The runner +# script sets `LD_PRELOAD` to the path of `libc++_shared.so` in the Android NDK +# (https://github.com/cross-rs/cross/blob/v0.2.5/docker/android-runner#L34). +# But this causes a problem for us. When a host-architecture program is run, +# `ld.so` shows a message about the "wrong ELF class". Such programs can still +# run, but when we rely on their specific output to stderr, fixtures and tests +# fail. The change we make here lets us set `NO_PRELOAD_CXX=1` to avoid that. +runner=/android-runner +patch='s/^[[:blank:]]*export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' +if test -f "$runner"; then sed -i.orig "$patch" -- "$runner"; fi # Ensure a nonempty Git `system` scope (for the `installation_config` tests). git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue diff --git a/justfile b/justfile index 86cf6cf9a26..7fcc4da5b86 100755 --- a/justfile +++ b/justfile @@ -226,8 +226,9 @@ journey-tests-async: dbg # Build a customized `cross` container image for testing cross-image target: - docker build --build-arg "TARGET={{ target }}" -t "cross-rs-gitoxide:{{ target }}" \ - - Date: Wed, 19 Mar 2025 15:21:51 +0000 Subject: [PATCH 064/193] Only install `git` strangely when there is reason to do so We install `git` in the `cross` container, intending that it come from the git-core PPA and thus be of a recent version. If we can find a Debian-style architecture name that is correct for the `cross` target triple, then we install it for that architecture. In principle we might find such a name without the PPA having a build for that architecture, but that is in practice unlikely to occur and, if it does, then either the `git` we do manage to install is new enough, or we will get test failures due to absent features the test suite needs (such as `GIT_CONFIG_{COUNT,KEY,VALUE}` support). When we don't find such a name, we use the host architecture. When we install `git` for the target architecture, its `perl` and `liberror-perl` dependencies, which as declared must be of that architecture as well, may not be installable. We run into this problem in the container for `s390x-unknown-linux-gnu`. To solve it, we install the dependencies except for those, as well as ensuring those are installed for the host architecture, and then install `git` while forcing it install even if those two dependencies are considered unmet. This works because `git` doesn't use `perl` as a library, but rather as an interpreter for some scripts; and `libperl-error` is a library, but it is a Perl module used from Perl scripts, not a shared library object any Git-related binaries have to load. (Currently, direct dependencies of `git` are hard-coded, which, as commented, may be worth changing to decrease the likelihood of breakage in future versions.) In order to test that the procedure really has a chance of working on a variety of architectures (in case `cross` is to be used to test others at some point), this complex procedure for installing `git` is used whether it is being installed for the target or the host architecture. But this doesn't provide much assurance; that the procedure works when it is effectively just installing exactly the same packages as would be installed anyway does not imply that it works with other cross-target installations where it would be installing different packages. More importantly, using this even when it is known not to be needed obscures the cases where it is not needed, and may create the impression that test failures are due to the strange way `git` was installed, even when they are not. Therefore, this modifies the `cross` container customization script so we only take the strange semi-manual dependency installation approach when there is a chance it might actually be needed, i.e., when we are installing `git` for the cross target rather than the host target. --- etc/docker/test-cross-context/customize.sh | 54 +++++++++++++--------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/etc/docker/test-cross-context/customize.sh b/etc/docker/test-cross-context/customize.sh index 31396e3ee2e..a7dd5a4f79b 100755 --- a/etc/docker/test-cross-context/customize.sh +++ b/etc/docker/test-cross-context/customize.sh @@ -76,29 +76,37 @@ gix_test_deps=( pkgconf ) -# Install everything we need except `git` (and what we already have). We can't -# necessarily install `git` this way, because it insists on `perl` and -# `liberror-perl` dependencies of the same architecture as it. These may not be -# possible to install in a mixed environment, where most packages are a -# different architecture, and where `perl` is a dependency of other important -# packages. So we will install everything else first (then manually add `git`). -apt-get install --no-install-recommends -y \ - "${git_deps[@]}" "${gix_test_deps[@]}" file +if test -n "$apt_suffix"; then + # Install everything we need except `git` (and what we already have). We + # can't necessarily install `git` this way, because it insists on `perl` + # and `liberror-perl` dependencies of the same architecture as it. These + # may not be possible to install in a mixed environment, where most + # packages are a different architecture, and where `perl` is a dependency + # of other important packages. So we will install everything else first + # (then manually add `git`). + apt-get install --no-install-recommends -y \ + "${git_deps[@]}" "${gix_test_deps[@]}" file -# Add `git` by manually downloading it and installing it with `dpkg`, forcing -# installation to proceed even if its `perl` and `liberror-perl` dependencies, -# as declared by `git`, are absent. (We have already installed them, but in a -# possibly different architecture. `git` can still use them, because its use is -# to run scripts, rather than to link to a shared library they provide.) It is -# preferred to let `apt-get download` drop privileges to the `_apt` user during -# download, so we download it inside `/tmp`. But we create a subdirectory so it -# is safe to make assumptions about what files globs can expand to, even if -# `/tmp` is mounted to an outside share temp dir on a multi-user system. -mkdir /tmp/dl # Don't use `-p`; if it exists already, we cannot trust it. -chown _apt /tmp/dl # Use owner, as the container may not have an `_apt` group. -(cd /tmp/dl && apt-get download "git$apt_suffix") -dpkg --ignore-depends="perl$apt_suffix,liberror-perl$apt_suffix" \ - -i /tmp/dl/git[-_]*.deb + # Add `git` by manually downloading it and installing it with `dpkg`, + # forcing installation to proceed even if its `perl` and `liberror-perl` + # dependencies, as declared by `git`, are absent. (We have already + # installed them, but in a possibly different architecture. `git` can still + # use them, because its use is to run scripts, rather than to link to a + # shared library they provide.) It is preferred to let `apt-get download` + # drop privileges to the `_apt` user during download, so we download it + # inside `/tmp`. But we create a subdirectory so it is safe to make + # assumptions about what files globs can expand to, even if `/tmp` is + # mounted to an outside share temp dir on a multi-user system. + mkdir /tmp/dl # Don't use `-p`; if it exists already, we cannot trust it. + chown _apt /tmp/dl # Use owner, as the container may have no `_apt` group. + (cd /tmp/dl && apt-get download "git$apt_suffix") + dpkg --ignore-depends="perl$apt_suffix,liberror-perl$apt_suffix" \ + -i /tmp/dl/git[-_]*.deb + rm -r /tmp/dl +else + # Install everything we need, including `git`. + apt-get install --no-install-recommends -y git "${gix_test_deps[@]}" file +fi # Show information about the newly installed `git` (and ensure it can run). git version --build-options @@ -107,7 +115,7 @@ file -- "$git" # Clean up files related to package management that we won't need anymore. apt-get clean -rm -rf /tmp/dl /var/lib/apt/lists/* +rm -rf /var/lib/apt/lists/* # If this image has a runner script `cross` uses for Android, patch the script # to add the ability to suppress its customization of `LD_PRELOAD`. The runner From e88e6355957aae50576b1a8054edc45af4564719 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Wed, 19 Mar 2025 20:00:45 +0000 Subject: [PATCH 065/193] Make it easier to pass arguments to test executable So option arguments like `--test-threads=1` that must come after `--` can be passed through `just` to `cross`, while still being able to customize options like `--features` that go before it. --- justfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/justfile b/justfile index 7fcc4da5b86..138deaadd67 100755 --- a/justfile +++ b/justfile @@ -231,17 +231,17 @@ cross-image target: -f etc/docker/Dockerfile.test-cross etc/docker/test-cross-context # Test another platform with `cross` -cross-test target *cargo-test-args: (cross-image target) +cross-test target options test-options: (cross-image target) CROSS_CONFIG=etc/docker/test-cross.toml NO_PRELOAD_CXX=1 \ cross test --workspace --no-fail-fast --target {{ target }} \ - {{ cargo-test-args }} -- --skip realpath::fuzzed_timeout + {{ options }} -- --skip realpath::fuzzed_timeout {{ test-options }} # Test s390x with `cross` -cross-test-s390x: (cross-test 's390x-unknown-linux-gnu') +cross-test-s390x: (cross-test 's390x-unknown-linux-gnu' '' '') # Test Android with `cross` (max-pure) -cross-test-android: (cross-test 'armv7-linux-androideabi' \ - '--no-default-features' '--features' 'max-pure') +cross-test-android: (cross-test 'armv7-linux-androideabi' + '--no-default-features --features max-pure' '') # Run `cargo diet` on all crates to see that they are still in bounds check-size: From 803d0544dff9ce7a570f16f8146c2d5e522b4c21 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Wed, 19 Mar 2025 20:11:43 +0000 Subject: [PATCH 066/193] Adjust `cross` CI jobs for changed `just` recipe syntax Also, since `--test-threads 1` didn't reveal anything different locally, this uses the nicknamed convenience recipes. --- .github/workflows/ci.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a873c13e7e1..01f40f5187a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -334,7 +334,12 @@ jobs: strategy: matrix: - target: [ armv7-linux-androideabi, s390x-unknown-linux-gnu ] + nickname: [ android, s390x ] + include: + - nickname: android + target: armv7-linux-androideabi + - nickname: s390x + target: s390x-unknown-linux-gnu fail-fast: false steps: @@ -356,7 +361,7 @@ jobs: - name: Test (unit) env: RUST_BACKTRACE: '1' - run: just cross-test ${{ matrix.target }} + run: just cross-test-${{ matrix.nickname }} lint: runs-on: ubuntu-latest From 73dcf57f9cf49bdc9d1745d39b5dd2d93609f3f5 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 7 Apr 2025 04:14:15 +0000 Subject: [PATCH 067/193] Remove `test-cross` CI job definition One or both of these matrix jobs, or related ones, be brought back some day, probably to run only specific tests that have failed in the past and started passing. The files for local testing with `cross` (and associated `justfile` recipes) are kept. --- .github/workflows/ci.yml | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01f40f5187a..f80297f737c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -327,42 +327,6 @@ jobs: - name: Test (nextest) run: cargo nextest run --target $env:TARGET --workspace --no-fail-fast size - # FIXME: *If* this is kept, then remove `fail-fast: false`, run only a subset of the tests unless - # building and running the whole test suite is fast, and add a `Swatinem/rust-cache` step. - test-cross: - runs-on: ubuntu-latest - - strategy: - matrix: - nickname: [ android, s390x ] - include: - - nickname: android - target: armv7-linux-androideabi - - nickname: s390x - target: s390x-unknown-linux-gnu - fail-fast: false - - steps: - - uses: actions/checkout@v4 - - name: Install Rust - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - targets: ${{ matrix.target }} - - uses: extractions/setup-just@v3 - - name: Install cross - uses: taiki-e/install-action@v2 - with: - tool: cross - - name: Configure binfmt_misc for QEMU - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - - name: Build cross image - run: just cross-image ${{ matrix.target }} - - name: Test (unit) - env: - RUST_BACKTRACE: '1' - run: just cross-test-${{ matrix.nickname }} - lint: runs-on: ubuntu-latest @@ -520,7 +484,6 @@ jobs: env: # List all jobs that are intended NOT to block PR auto-merge here. EXPECTED_NONBLOCKING_JOBS: |- - test-cross cargo-deny-advisories wasm tests-pass From d5dd239f11a4b88ca55ebdb8d8232bcfb8eacf0a Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 7 Apr 2025 14:52:25 -0400 Subject: [PATCH 068/193] Add a second "DO NOT USE" feature to `gix-packetline-blocking` This adds a `futures-lite` feature to `gix-packetline-blocking`. The new feature is undocumented except for the warning not to use it. It does nothing, and its purpose is to support an existing internal use of `gix-packetline-blocking` through an alias named `gix-packetline`. This new feature should never be used except to keep `cargo check` commands with `--workspace` that list `gix-packetline/futures-lite` from failing due to the absent feature. Such `cargo check` commands are rare and `cargo check` should not typically be used this way. But RustRover automatically composes and runs such a command. This fixes a RustRover project discovery breakage commented on in #1929. This "ghost feature" may be removed without warning. Nothing should rely on it in production or otherwise in a significant way. It is a bug for any software to break or change behavior if it is removed. This addition is similar to the addition in be4de0d (#1123) of the `async-io` feature of `gix-packetline-blocking`, which likewise shouldn't be used. However, `gix-packetline-blocking/futures-lite` is even less elegant than `gix-packetline-blocking/async-io`, since `gix-packetline` doesn't explicitly delcare a `futures-lite` feature. Instead, we currrently don't use `dep:` for `futures-lite` because it breaks `cargo-auditable` (#1929). --- gix-packetline-blocking/Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gix-packetline-blocking/Cargo.toml b/gix-packetline-blocking/Cargo.toml index 84e1cce0917..b1febf34603 100644 --- a/gix-packetline-blocking/Cargo.toml +++ b/gix-packetline-blocking/Cargo.toml @@ -21,9 +21,12 @@ default = ["blocking-io"] ## If set, all IO will become blocking. The same types will be used preventing side-by-side usage of blocking and non-blocking IO. blocking-io = [] -## DO NOT USE, use instead `gix-packetline` directly. +## DO NOT USE, instead use `gix-packetline` directly. async-io = [] +## DO NOT USE, instead use `gix-packetline` directly (and still don't specify `futures-lite`). +futures-lite = [] + #! ### Other ## Data structures implement `serde::Serialize` and `serde::Deserialize`. serde = ["dep:serde", "bstr/serde"] From 3ca6811418275c4ebede0993b9741e804e81094b Mon Sep 17 00:00:00 2001 From: Fredrik Medley Date: Sun, 6 Apr 2025 22:21:43 +0200 Subject: [PATCH 069/193] Handle trailing slash in ref list prefix filtering Previously, `refs/heads/foo/bar` would be listed when running `repo.references()?.prefixed("refs/heads/b")`. The code identified that the last component was not a directory and started to match it as a filename prefix for all files in all recursive directories, effectively matching `refs/heads/**/b*`. This commit fixes that bug but also allows to use a trailing `/` in the prefix, allowing to filter for `refs/heads/foo/` and not get `refs/heads/foo-bar` as a result. Fixes #1934. --- gix-negotiate/tests/baseline/mod.rs | 2 +- gix-ref/src/namespace.rs | 9 +- gix-ref/src/store/file/loose/iter.rs | 38 +++---- gix-ref/src/store/file/mod.rs | 12 +- gix-ref/src/store/file/overlay_iter.rs | 76 +++++-------- ...make_packed_ref_repository_for_overlay.tar | Bin 64000 -> 70656 bytes .../make_ref_repository.tar | Bin 78848 -> 86528 bytes .../make_packed_ref_repository_for_overlay.sh | 3 + gix-ref/tests/fixtures/make_ref_repository.sh | 5 + gix-ref/tests/refs/file/store/iter.rs | 107 +++++++++++++++--- .../create_or_update/mod.rs | 2 +- gix-ref/tests/refs/file/worktree.rs | 5 +- gix-ref/tests/refs/namespace.rs | 10 +- gix/src/open/repository.rs | 14 +-- gix/src/reference/iter.rs | 28 +++-- gix/tests/gix/repository/reference.rs | 9 +- 16 files changed, 197 insertions(+), 123 deletions(-) diff --git a/gix-negotiate/tests/baseline/mod.rs b/gix-negotiate/tests/baseline/mod.rs index aefbd313f8b..e2736ae7cff 100644 --- a/gix-negotiate/tests/baseline/mod.rs +++ b/gix-negotiate/tests/baseline/mod.rs @@ -71,7 +71,7 @@ fn run() -> crate::Result { // } for tip in lookup_names(&["HEAD"]).into_iter().chain( refs.iter()? - .prefixed("refs/heads".as_ref())? + .prefixed(b"refs/heads".as_bstr().into())? .filter_map(Result::ok) .map(|r| r.target.into_id()), ) { diff --git a/gix-ref/src/namespace.rs b/gix-ref/src/namespace.rs index 1483b1c47e8..cba0b460c73 100644 --- a/gix-ref/src/namespace.rs +++ b/gix-ref/src/namespace.rs @@ -1,4 +1,4 @@ -use std::path::{Path, PathBuf}; +use std::{borrow::Cow, path::Path}; use gix_object::bstr::{BStr, BString, ByteSlice, ByteVec}; @@ -18,10 +18,9 @@ impl Namespace { gix_path::from_byte_slice(&self.0) } /// Append the given `prefix` to this namespace so it becomes usable for prefixed iteration. - pub fn into_namespaced_prefix(mut self, prefix: &Path) -> PathBuf { - let prefix = gix_path::into_bstr(prefix); - self.0.push_str(prefix.as_ref()); - gix_path::to_native_path_on_windows(self.0).into_owned() + pub fn into_namespaced_prefix(mut self, prefix: &BStr) -> Cow<'_, BStr> { + self.0.push_str(prefix); + gix_path::to_unix_separators_on_windows(self.0) } pub(crate) fn into_namespaced_name(mut self, name: &FullNameRef) -> FullName { self.0.push_str(name.as_bstr()); diff --git a/gix-ref/src/store/file/loose/iter.rs b/gix-ref/src/store/file/loose/iter.rs index 0bfbbd91587..5be0bb2cddd 100644 --- a/gix-ref/src/store/file/loose/iter.rs +++ b/gix-ref/src/store/file/loose/iter.rs @@ -1,22 +1,26 @@ -use std::path::{Path, PathBuf}; +use std::{ + borrow::Cow, + path::{Path, PathBuf}, +}; use gix_features::fs::walkdir::DirEntryIter; use gix_object::bstr::ByteSlice; -use crate::{file::iter::LooseThenPacked, store_impl::file, BString, FullName}; +use crate::{file::iter::LooseThenPacked, store_impl::file, BStr, BString, FullName}; /// An iterator over all valid loose reference paths as seen from a particular base directory. pub(in crate::store_impl::file) struct SortedLoosePaths { pub(crate) base: PathBuf, - filename_prefix: Option, + /// A optional prefix to match against if the prefix is not the same as the `file_walk` path. + prefix: Option, file_walk: Option, } impl SortedLoosePaths { - pub fn at(path: &Path, base: PathBuf, filename_prefix: Option, precompose_unicode: bool) -> Self { + pub fn at(path: &Path, base: PathBuf, prefix: Option, precompose_unicode: bool) -> Self { SortedLoosePaths { base, - filename_prefix, + prefix, file_walk: path.is_dir().then(|| { // serial iteration as we expect most refs in packed-refs anyway. gix_features::fs::walkdir_sorted_new( @@ -41,23 +45,9 @@ impl Iterator for SortedLoosePaths { continue; } let full_path = entry.path().into_owned(); - if let Some((prefix, name)) = self - .filename_prefix - .as_deref() - .and_then(|prefix| full_path.file_name().map(|name| (prefix, name))) - { - match gix_path::os_str_into_bstr(name) { - Ok(name) => { - if !name.starts_with(prefix) { - continue; - } - } - Err(_) => continue, // TODO: silently skipping ill-formed UTF-8 on windows - maybe this can be better? - } - } let full_name = full_path .strip_prefix(&self.base) - .expect("prefix-stripping cannot fail as prefix is our root"); + .expect("prefix-stripping cannot fail as base is within our root"); let full_name = match gix_path::try_into_bstr(full_name) { Ok(name) => { let name = gix_path::to_unix_separators_on_windows(name); @@ -65,7 +55,11 @@ impl Iterator for SortedLoosePaths { } Err(_) => continue, // TODO: silently skipping ill-formed UTF-8 on windows here, maybe there are better ways? }; - + if let Some(prefix) = &self.prefix { + if !full_name.starts_with(prefix) { + continue; + } + } if gix_validate::reference::name_partial(full_name.as_bstr()).is_ok() { let name = FullName(full_name); return Some(Ok((full_path, name))); @@ -93,7 +87,7 @@ impl file::Store { /// Return an iterator over all loose references that start with the given `prefix`. /// /// Otherwise it's similar to [`loose_iter()`][file::Store::loose_iter()]. - pub fn loose_iter_prefixed(&self, prefix: &Path) -> std::io::Result> { + pub fn loose_iter_prefixed(&self, prefix: Cow<'_, BStr>) -> std::io::Result> { self.iter_prefixed_packed(prefix, None) } } diff --git a/gix-ref/src/store/file/mod.rs b/gix-ref/src/store/file/mod.rs index 1f8321f4354..3c7d20e8c94 100644 --- a/gix-ref/src/store/file/mod.rs +++ b/gix-ref/src/store/file/mod.rs @@ -1,9 +1,6 @@ -use std::{ - borrow::Cow, - path::{Path, PathBuf}, -}; +use std::path::PathBuf; -use crate::{bstr::BStr, store::WriteReflog, Namespace}; +use crate::{store::WriteReflog, Namespace}; /// A store for reference which uses plain files. /// @@ -92,11 +89,6 @@ pub struct Transaction<'s, 'p> { packed_refs: transaction::PackedRefs<'p>, } -pub(in crate::store_impl::file) fn path_to_name<'a>(path: impl Into>) -> Cow<'a, BStr> { - let path = gix_path::into_bstr(path.into()); - gix_path::to_unix_separators_on_windows(path) -} - /// pub mod loose; mod overlay_iter; diff --git a/gix-ref/src/store/file/overlay_iter.rs b/gix-ref/src/store/file/overlay_iter.rs index 0e39e5af05f..914035bea3d 100644 --- a/gix-ref/src/store/file/overlay_iter.rs +++ b/gix-ref/src/store/file/overlay_iter.rs @@ -7,9 +7,9 @@ use std::{ }; use crate::{ - file::{loose, loose::iter::SortedLoosePaths, path_to_name}, + file::{loose, loose::iter::SortedLoosePaths}, store_impl::{file, packed}, - BString, FullName, Namespace, Reference, + BStr, FullName, Namespace, Reference, }; /// An iterator stepping through sorted input of loose references and packed references, preferring loose refs over otherwise @@ -195,10 +195,9 @@ impl Platform<'_> { self.store.iter_packed(self.packed.as_ref().map(|b| &***b)) } - /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads". - /// - /// Please note that "refs/heads" or "refs\\heads" is equivalent to "refs/heads/" - pub fn prefixed(&self, prefix: &Path) -> std::io::Result> { + /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads/" or + /// "refs/heads/feature-". + pub fn prefixed(&self, prefix: Cow<'_, BStr>) -> std::io::Result> { self.store .iter_prefixed_packed(prefix, self.packed.as_ref().map(|b| &***b)) } @@ -242,22 +241,19 @@ pub(crate) enum IterInfo<'a> { /// The top-level directory as boundary of all references, used to create their short-names after iteration base: &'a Path, /// The original prefix - prefix: Cow<'a, Path>, - /// The remainder of the prefix that wasn't a valid path - remainder: Option, + prefix: Cow<'a, BStr>, /// If `true`, we will convert decomposed into precomposed unicode. precompose_unicode: bool, }, } impl<'a> IterInfo<'a> { - fn prefix(&self) -> Option<&Path> { + fn prefix(&self) -> Option> { match self { IterInfo::Base { .. } => None, - IterInfo::PrefixAndBase { prefix, .. } => Some(*prefix), - IterInfo::ComputedIterationRoot { prefix, .. } | IterInfo::BaseAndIterRoot { prefix, .. } => { - prefix.as_ref().into() - } + IterInfo::PrefixAndBase { prefix, .. } => Some(gix_path::into_bstr(*prefix)), + IterInfo::BaseAndIterRoot { prefix, .. } => Some(gix_path::into_bstr(prefix.clone())), + IterInfo::ComputedIterationRoot { prefix, .. } => Some(prefix.clone()), } } @@ -281,48 +277,37 @@ impl<'a> IterInfo<'a> { IterInfo::ComputedIterationRoot { iter_root, base, - prefix: _, - remainder, + prefix, precompose_unicode, - } => SortedLoosePaths::at(&iter_root, base.into(), remainder, precompose_unicode), + } => SortedLoosePaths::at(&iter_root, base.into(), Some(prefix.into_owned()), precompose_unicode), } .peekable() } - fn from_prefix(base: &'a Path, prefix: Cow<'a, Path>, precompose_unicode: bool) -> std::io::Result { - if prefix.is_absolute() { + fn from_prefix(base: &'a Path, prefix: Cow<'a, BStr>, precompose_unicode: bool) -> std::io::Result { + let prefix_path = gix_path::from_bstring(prefix.as_ref()); + if prefix_path.is_absolute() { return Err(std::io::Error::new( std::io::ErrorKind::InvalidInput, - "prefix must be a relative path, like 'refs/heads'", + "prefix must be a relative path, like 'refs/heads/'", )); } use std::path::Component::*; - if prefix.components().any(|c| matches!(c, CurDir | ParentDir)) { + if prefix_path.components().any(|c| matches!(c, CurDir | ParentDir)) { return Err(std::io::Error::new( std::io::ErrorKind::InvalidInput, "Refusing to handle prefixes with relative path components", )); } - let iter_root = base.join(prefix.as_ref()); - if iter_root.is_dir() { + let iter_root = base.join(&prefix_path); + if prefix.ends_with(b"/") { Ok(IterInfo::BaseAndIterRoot { base, iter_root, - prefix, + prefix: prefix_path.into(), precompose_unicode, }) } else { - let filename_prefix = iter_root - .file_name() - .map(ToOwned::to_owned) - .map(|p| { - gix_path::try_into_bstr(PathBuf::from(p)) - .map(std::borrow::Cow::into_owned) - .map_err(|_| { - std::io::Error::new(std::io::ErrorKind::InvalidInput, "prefix contains ill-formed UTF-8") - }) - }) - .transpose()?; let iter_root = iter_root .parent() .expect("a parent is always there unless empty") @@ -331,7 +316,6 @@ impl<'a> IterInfo<'a> { base, prefix, iter_root, - remainder: filename_prefix, precompose_unicode, }) } @@ -374,30 +358,28 @@ impl file::Store { } } - /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads". - /// - /// Please note that "refs/heads" or "refs\\heads" is equivalent to "refs/heads/" + /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads/" or + /// "refs/heads/feature-". pub fn iter_prefixed_packed<'s, 'p>( &'s self, - prefix: &Path, + prefix: Cow<'_, BStr>, packed: Option<&'p packed::Buffer>, ) -> std::io::Result> { match self.namespace.as_ref() { None => { - let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix.into(), self.precompose_unicode)?; + let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix.clone(), self.precompose_unicode)?; let common_dir_info = self .common_dir() - .map(|base| IterInfo::from_prefix(base, prefix.into(), self.precompose_unicode)) + .map(|base| IterInfo::from_prefix(base, prefix, self.precompose_unicode)) .transpose()?; self.iter_from_info(git_dir_info, common_dir_info, packed) } Some(namespace) => { - let prefix = namespace.to_owned().into_namespaced_prefix(prefix); - let git_dir_info = - IterInfo::from_prefix(self.git_dir(), prefix.clone().into(), self.precompose_unicode)?; + let prefix = namespace.to_owned().into_namespaced_prefix(prefix.as_ref()); + let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix.clone(), self.precompose_unicode)?; let common_dir_info = self .common_dir() - .map(|base| IterInfo::from_prefix(base, prefix.into(), self.precompose_unicode)) + .map(|base| IterInfo::from_prefix(base, prefix, self.precompose_unicode)) .transpose()?; self.iter_from_info(git_dir_info, common_dir_info, packed) } @@ -416,7 +398,7 @@ impl file::Store { iter_packed: match packed { Some(packed) => Some( match git_dir_info.prefix() { - Some(prefix) => packed.iter_prefixed(path_to_name(prefix).into_owned()), + Some(prefix) => packed.iter_prefixed(prefix.into_owned()), None => packed.iter(), } .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))? diff --git a/gix-ref/tests/fixtures/generated-archives/make_packed_ref_repository_for_overlay.tar b/gix-ref/tests/fixtures/generated-archives/make_packed_ref_repository_for_overlay.tar index b6b126990a780393d3cf275759e61eeacbbe64ed..9b1cdb67d27348d13539076cd422ec5f1ae2ea53 100644 GIT binary patch delta 2805 zcmb_eU1%It6wYRMHp!%$G{s7+RxXpJ-G%PY>~1z1sF*g}8k#1$t~4UJPG;`xUNV`P z&QH={bt-5<-;#asRSAgrR5CvJAgC|;sy>N`h)*g-!5^qr&~xw1Zg!K#D!7pB&%O6M z-}%mW&fIIiMz6gcyTQeL?w!MN|LA+aMScF=;h2B)2L1H@?WoTQ1A>33_E&Vo#=3%6 zC8A~4B#pEZg$r9dvCZcF$4aGqsZY$8%3{8dFBJ2A`Mg*b#Zq6sH5OO=NabYYESyjz z2O|lYk|Q@!O45~_VTIppY!Pgy(K1#I3-c3*#v*zH5eKai39+!P%P&4Uf+W+l4AUY2 z#!s|9S{P577GA@;gPbM~Hl_ecwTxAOqZokYv>x>GUT*@Fj*#UiAljJ?q+nHYHRlwK zxK1<;8M?NCVIo5XFiImtL#}B%7M6gCCFvfd zy-u8_;W|h*bX6m=VxQ)gM{pL+s1CLOkBSXk3B*X*t}J8QR$bs{ zA>DA&5R*mJB-;tagkLBkRrC~F3o$(^EXxg;D_Fx0R)YL%Kv^|3%~+>;QEsFGaY5u| z4cqNxZ44?Hpoye6a8H^RUNvZKbp;}XUo1?CfpC(Ak!yoU9vr5EZLqUUO8}P|647mE zniT@E!n0~;!@O}d08fRQPDAFTLG(0)I(T~(qVJw~tTHp3<~>^KDmFDq4(QhwXBQFs z+B7r;TQ)0Cx5EMh07+RkEM`c^VZ(4~U382UJInKJo^{z+!&V(+g}R|s8a>YssYJu4 zg`_C(LlelO@uoWrs1@!MD}}R-EV4}uCS?ADnxwP*kYl-+f1xX0*hu>WRdm}0(R*!+ zB#)UjNV3O+0Nw!GgH1CyF^n?fu|MX(OKYZz*a^Gngcs>wwulbg7K!K z%>VV`c>+y(t z8P+sX;UNhF4`u~Cn@lv#Zm&dVa1}pPj3+_e+b_3-wyH zQsHH#n?Kcn8ma-9D03MJ&niS!X&nIz)T3i2Fi~eD1tWs3U=5ys{7`49XIilxkY5;~ zW7&UlEVcB$_1a=>X1-0Mr(UkU0*T(OT-3RaC7I}Cw{zGtWetOO)NVmeqRP@-jaj3U zRxn8T)@Sux3&lU(y7tO=S=@U$DV2&-?aRqaOI$od;AV5hfBO2H(Vgdp~1GCM~``GHIuWZ__tVxb@&1hVzr%lC=J zefK-DAa*4D{+WpX>JRHI@j`K5vQxXs{*s79OOshY68|Z(_2c!{^{>bL j*Y72f(ZbY24^N5ZLb;rAb#lcYgAG24e-r%ML}&g6EqaEy delta 421 zcmZoz!P4-Bc>^oUV%AkGn_2(;X5X}fi)l0030AJn{JXxfZf2EYSK7?8=qLMT))p?7 z&HVHJGH>Rw`OmzWyM~2hGk@40*3H~W%uw;;bbwKOj?IX?v^v)R$Af^i!gqY%?{ zAs)sOaWizoO^i*=A%;(8Wc<%(YG@3!&Ct|R7idn!X2mP_87C?TPvc;0l`z2!4Rdo7 wh~DjtoQ%ATBF2__rV1L41qC^&3htRDx`w7Enm`xqXWVRXCh&>e`+! z?J9=6Js>XPfi6fzf|sqpGs4m;agl%rUV(QW5Dy3;g!V85yGY|dwv(pq#y}!cE{@On z{_p?(@Be)+{}R9a0rN2v_nDu268^rMDDLn7>sHKXZ*|1|eZTzyzwX_Q`ONt?&hLEt zeyrOjx=a>DRpXaLO|5n5C$Iho%LZKyB6A#Ni zx-x){!46q;2o|v^I#Ly&e;#R4_mjQLm6KXKO?2@Z}|lzPaPc;?#78^=PR} z#MDG7q+gz$p2fjs)zD;O*+F@l9Tpk@NJ^4n1%`wiRt%TcMJGhIvn*TZIVTxQ#F_(H zp>8;x!7sDzimH(bE+uemdmr{_yzvGDYJ~^IN|S6Qi*1vD2?PH@O)^=w-LYK4zS0yg zYNVZkin{HB=v!@zMK3UGnB*1@0(b>%4>slVm`hR89KLi3D(SeEPO1Mp=FqzkRJB7N z(tTkrK^CUyLEmRh?SZ+3c8yf~Z}A9ThVqff@taXExGMDSysK*RAb46)Ubz;UV&plH-GhIAAHFIk2_{^!|+_Bkb&yH`VD78e|{Xu?Kk(UesS^YSK#;F&;2YW7_C3U|{i>IfbdWf}7dy!oI4)P!8Bew)J_ zaJGj+1?-_z_=A2cT#(WhNvyDuc@f%VrxItQG1`ppu|%^8+g=a2O`eBnT1U#Tib|UT zx|&E;19Od_jnv06u`I(H#|k_oVc@~6fM=6Q2Oy2<(YemyBmKhwaS?&e&Se)5}p`}~f#;E>dL`F7hn(-~i9;=4X% zP-30=3C>V^nO2{DBGJ0ub3DG@b2RSvoVf!hsHYNebtE3M-TBqsPs4d>t=f--_~>ZM zNO(4yNTN2lIRyQ*y8ARNs8w-}$rlPu3p%3(Lz-dOwZktRTg6PUvOmWZ04h3W4fMp; zcK4&#{C5vsiPe(7(&JgJ3Tws+`No=qF~66)dC+HHpl7@NaQtIS@R97j8)K_Plx==9 zNLL6jl*kLhNCTlA(t7T0Y>nZNcTmXhIQa>~LL}}6>O(K0jW<$g8LeXeMgnzpZglk` z)Vk5V7u{zzy7mOWA4h*OyXXlCrh;9&)_OLGo6RvJP^Lhq4TMkv`E5P7V>kNIp4PQJ zgUCKGoZnH{v9aNh=mz3Z7m5`|vOb>v5yB@wN~6}KAdC%<2)SH-ly`OYqAyH-i~PyS LFT)RT%=Nzk&2*2Y delta 422 zcmZoz!rJhHWdkeAV%AL@i&@vPY-e>~{LQ@S2p7|GE-prvLso~XdKsfSx^Gk3x-*2Sy`fL5>wux%C<`^vnTi;IV4 zvzQRjbWuJKSL!$OV%A-3+gX(uIe517nlUmmZRay!{Li|bR}aj#VEoQHomGypp2^5? zdmA5P72`Ao#uy#W%=EncqSWNX;#37&g_5GuR4&c}AU{91Aip@ZG%qtbKLsYU+0m|o zahnUH5Yu)cFUEI_{Kf`m24*HEmPRJJK$R8S1!WlDGfw~K%Gf@=m5Wh`&BWZ?1mdUd ujP8uQj3UOCdZr2*js*odsS56yCAx;DCYqZS&)sL-t{}ts07_0&um=G2nSQ_k diff --git a/gix-ref/tests/fixtures/make_packed_ref_repository_for_overlay.sh b/gix-ref/tests/fixtures/make_packed_ref_repository_for_overlay.sh index 03574b865ae..c6e3a57650b 100755 --- a/gix-ref/tests/fixtures/make_packed_ref_repository_for_overlay.sh +++ b/gix-ref/tests/fixtures/make_packed_ref_repository_for_overlay.sh @@ -10,10 +10,13 @@ git branch A git tag -m "tag object" tag-object mkdir -p .git/refs/remotes/origin +mkdir -p .git/refs/heads/sub/dir cp .git/refs/heads/main .git/refs/remotes/origin/ echo "ref: refs/remotes/origin/main" > .git/refs/remotes/origin/HEAD +echo "ref: refs/heads/main" > .git/refs/heads-packed +echo "ref: refs/heads/main" > .git/refs/heads/sub/dir/packed git pack-refs --all --prune diff --git a/gix-ref/tests/fixtures/make_ref_repository.sh b/gix-ref/tests/fixtures/make_ref_repository.sh index 38080cddfca..c3e661cba3a 100755 --- a/gix-ref/tests/fixtures/make_ref_repository.sh +++ b/gix-ref/tests/fixtures/make_ref_repository.sh @@ -22,6 +22,11 @@ echo "ref: refs/tags/multi-link-target2" > .git/refs/heads/multi-link-target1 echo "ref: refs/remotes/origin/multi-link-target3" > .git/refs/tags/multi-link-target2 git rev-parse HEAD > .git/refs/remotes/origin/multi-link-target3 +# Regression test for issue #1934 where prefix refs/m matched refs/heads/main. +mkdir -p .git/refs/heads/sub/dir +echo "ref: refs/remotes/origin/main" > .git/refs/heads-loose +echo "ref: refs/remotes/origin/main" > .git/refs/heads/sub/dir/loose +echo "ref: refs/remotes/origin/main" > .git/refs/remotes/origin/heads echo "ref: refs/loop-b" > .git/refs/loop-a echo "ref: refs/loop-a" > .git/refs/loop-b diff --git a/gix-ref/tests/refs/file/store/iter.rs b/gix-ref/tests/refs/file/store/iter.rs index 211332cddb7..e2e2849e1ca 100644 --- a/gix-ref/tests/refs/file/store/iter.rs +++ b/gix-ref/tests/refs/file/store/iter.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use gix_object::bstr::ByteSlice; use crate::{ @@ -26,7 +28,7 @@ mod with_namespace { let ns_two = gix_ref::namespace::expand("bar")?; let namespaced_refs = store .iter()? - .prefixed(ns_two.to_path())? + .prefixed(ns_two.as_bstr().into())? .map(Result::unwrap) .map(|r: gix_ref::Reference| r.name) .collect::>(); @@ -45,7 +47,7 @@ mod with_namespace { ); assert_eq!( store - .loose_iter_prefixed(ns_two.to_path())? + .loose_iter_prefixed(ns_two.as_bstr().into())? .map(Result::unwrap) .map(|r| r.name.into_inner()) .collect::>(), @@ -90,7 +92,7 @@ mod with_namespace { assert_eq!( store .iter()? - .prefixed(ns_one.to_path())? + .prefixed(ns_one.as_bstr().into())? .map(Result::unwrap) .map(|r: gix_ref::Reference| ( r.name.as_bstr().to_owned(), @@ -262,7 +264,7 @@ fn loose_iter_with_broken_refs() -> crate::Result { let store = store()?; let mut actual: Vec<_> = store.loose_iter()?.collect(); - assert_eq!(actual.len(), 16); + assert_eq!(actual.len(), 19); actual.sort_by_key(Result::is_err); let first_error = actual .iter() @@ -271,7 +273,7 @@ fn loose_iter_with_broken_refs() -> crate::Result { .expect("there is an error"); assert_eq!( - first_error, 15, + first_error, 18, "there is exactly one invalid item, and it didn't abort the iterator most importantly" ); #[cfg(not(windows))] @@ -291,15 +293,18 @@ fn loose_iter_with_broken_refs() -> crate::Result { ref_paths, vec![ "d1", + "heads-loose", "heads/A", "heads/d1", "heads/dt1", "heads/main", "heads/multi-link-target1", + "heads/sub/dir/loose", "loop-a", "loop-b", "multi-link", "remotes/origin/HEAD", + "remotes/origin/heads", "remotes/origin/main", "remotes/origin/multi-link-target3", "tags/dt1", @@ -322,19 +327,20 @@ fn loose_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { #[cfg(windows)] let abs_path = r"c:\hello"; - match store.loose_iter_prefixed(abs_path.as_ref()) { + match store.loose_iter_prefixed(Cow::Borrowed(abs_path.as_ref())) { Ok(_) => unreachable!("absolute paths aren't allowed"), - Err(err) => assert_eq!(err.to_string(), "prefix must be a relative path, like 'refs/heads'"), + Err(err) => assert_eq!(err.to_string(), "prefix must be a relative path, like 'refs/heads/'"), } Ok(()) } #[test] fn loose_iter_with_prefix() -> crate::Result { + // Test 'refs/heads/' with slash. let store = store()?; let actual = store - .loose_iter_prefixed("refs/heads/".as_ref())? + .loose_iter_prefixed(b"refs/heads/".as_bstr().into())? .collect::, _>>() .expect("no broken ref in this subset") .into_iter() @@ -349,6 +355,39 @@ fn loose_iter_with_prefix() -> crate::Result { "refs/heads/dt1", "refs/heads/main", "refs/heads/multi-link-target1", + "refs/heads/sub/dir/loose", + ] + .into_iter() + .map(String::from) + .collect::>(), + "all paths are as expected" + ); + Ok(()) +} + +#[test] +fn loose_iter_with_partial_prefix_dir() -> crate::Result { + // Test 'refs/heads/' without slash. + let store = store()?; + + let actual = store + .loose_iter_prefixed(b"refs/heads".as_bstr().into())? + .collect::, _>>() + .expect("no broken ref in this subset") + .into_iter() + .map(|e| e.name.into_inner()) + .collect::>(); + + assert_eq!( + actual, + vec![ + "refs/heads-loose", + "refs/heads/A", + "refs/heads/d1", + "refs/heads/dt1", + "refs/heads/main", + "refs/heads/multi-link-target1", + "refs/heads/sub/dir/loose", ] .into_iter() .map(String::from) @@ -363,7 +402,7 @@ fn loose_iter_with_partial_prefix() -> crate::Result { let store = store()?; let actual = store - .loose_iter_prefixed("refs/heads/d".as_ref())? + .loose_iter_prefixed(b"refs/heads/d".as_bstr().into())? .collect::, _>>() .expect("no broken ref in this subset") .into_iter() @@ -396,9 +435,14 @@ fn overlay_iter() -> crate::Result { assert_eq!( ref_names, vec![ + ("refs/heads-packed".into(), Symbolic("refs/heads/main".try_into()?),), (b"refs/heads/A".as_bstr().to_owned(), Object(c1)), (b"refs/heads/main".into(), Object(c1)), ("refs/heads/newer-as-loose".into(), Object(c2)), + ( + "refs/heads/sub/dir/packed".into(), + Symbolic("refs/heads/main".try_into()?), + ), ( "refs/remotes/origin/HEAD".into(), Symbolic("refs/remotes/origin/main".try_into()?), @@ -505,21 +549,50 @@ fn overlay_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { #[cfg(windows)] let abs_path = r"c:\hello"; - match store.iter()?.prefixed(abs_path.as_ref()) { + match store.iter()?.prefixed(Cow::Borrowed(abs_path.as_ref())) { Ok(_) => unreachable!("absolute paths aren't allowed"), - Err(err) => assert_eq!(err.to_string(), "prefix must be a relative path, like 'refs/heads'"), + Err(err) => assert_eq!(err.to_string(), "prefix must be a relative path, like 'refs/heads/'"), } Ok(()) } #[test] fn overlay_prefixed_iter() -> crate::Result { + // Test 'refs/heads/' with slash. + use gix_ref::Target::*; + + let store = store_at("make_packed_ref_repository_for_overlay.sh")?; + let ref_names = store + .iter()? + .prefixed(b"refs/heads/".as_bstr().into())? + .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) + .collect::, _>>()?; + let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); + let c2 = hex_to_id("9902e3c3e8f0c569b4ab295ddf473e6de763e1e7"); + assert_eq!( + ref_names, + vec![ + (b"refs/heads/A".as_bstr().to_owned(), Object(c1)), + (b"refs/heads/main".into(), Object(c1)), + ("refs/heads/newer-as-loose".into(), Object(c2)), + ( + b"refs/heads/sub/dir/packed".into(), + Symbolic("refs/heads/main".try_into()?) + ), + ] + ); + Ok(()) +} + +#[test] +fn overlay_partial_prefix_dir_iter() -> crate::Result { + // Test 'refs/heads/' without slash. use gix_ref::Target::*; let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store .iter()? - .prefixed("refs/heads".as_ref())? + .prefixed(b"refs/heads".as_bstr().into())? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); @@ -527,9 +600,17 @@ fn overlay_prefixed_iter() -> crate::Result { assert_eq!( ref_names, vec![ + ( + b"refs/heads-packed".as_bstr().to_owned(), + Symbolic("refs/heads/main".try_into()?) + ), (b"refs/heads/A".as_bstr().to_owned(), Object(c1)), (b"refs/heads/main".into(), Object(c1)), ("refs/heads/newer-as-loose".into(), Object(c2)), + ( + b"refs/heads/sub/dir/packed".into(), + Symbolic("refs/heads/main".try_into()?) + ), ] ); Ok(()) @@ -542,7 +623,7 @@ fn overlay_partial_prefix_iter() -> crate::Result { let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store .iter()? - .prefixed("refs/heads/m".as_ref())? // 'm' is partial + .prefixed(b"refs/heads/m".as_bstr().into())? // 'm' is partial .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); diff --git a/gix-ref/tests/refs/file/transaction/prepare_and_commit/create_or_update/mod.rs b/gix-ref/tests/refs/file/transaction/prepare_and_commit/create_or_update/mod.rs index 1ad9bf62199..3d6680f212d 100644 --- a/gix-ref/tests/refs/file/transaction/prepare_and_commit/create_or_update/mod.rs +++ b/gix-ref/tests/refs/file/transaction/prepare_and_commit/create_or_update/mod.rs @@ -843,7 +843,7 @@ fn packed_refs_creation_with_packed_refs_mode_leave_keeps_original_loose_refs() .commit(committer().to_ref())?; assert_eq!( edits.len(), - 2, + 4, "it claims to have performed all desired operations, even though some don't make it into the pack as 'side-car'" ); diff --git a/gix-ref/tests/refs/file/worktree.rs b/gix-ref/tests/refs/file/worktree.rs index 6606af9cc72..b537286021e 100644 --- a/gix-ref/tests/refs/file/worktree.rs +++ b/gix-ref/tests/refs/file/worktree.rs @@ -191,6 +191,7 @@ mod read_only { mod writable { use gix_lock::acquire::Fail; use gix_ref::{ + bstr::ByteSlice, file::{transaction::PackedRefs, Store}, transaction::{Change, LogChange, PreviousValue, RefEdit}, FullName, FullNameRef, Target, @@ -290,7 +291,7 @@ mod writable { assert_eq!( store .iter()? - .prefixed("refs/stacks/".as_ref())? + .prefixed(b"refs/stacks/".as_bstr().into())? .map(Result::unwrap) .map(|r| (r.name.to_string(), r.target.to_string())) .collect::>(), @@ -571,7 +572,7 @@ mod writable { assert_eq!( store .iter()? - .prefixed("refs/stacks/".as_ref())? + .prefixed(b"refs/stacks/".as_bstr().into())? .map(Result::unwrap) .map(|r| (r.name.to_string(), r.target.to_string())) .collect::>(), diff --git a/gix-ref/tests/refs/namespace.rs b/gix-ref/tests/refs/namespace.rs index baaa4dc95d4..70c81d1c7f7 100644 --- a/gix-ref/tests/refs/namespace.rs +++ b/gix-ref/tests/refs/namespace.rs @@ -1,12 +1,16 @@ -use std::path::Path; - #[test] fn into_namespaced_prefix() { assert_eq!( gix_ref::namespace::expand("foo") .unwrap() .into_namespaced_prefix("prefix".as_ref()), - Path::new("refs").join("namespaces").join("foo").join("prefix") + "refs/namespaces/foo/prefix".as_ref(), + ); + assert_eq!( + gix_ref::namespace::expand("foo") + .unwrap() + .into_namespaced_prefix("prefix/".as_ref()), + "refs/namespaces/foo/prefix/".as_ref(), ); } diff --git a/gix/src/open/repository.rs b/gix/src/open/repository.rs index 3bad04d8263..4b04909a339 100644 --- a/gix/src/open/repository.rs +++ b/gix/src/open/repository.rs @@ -5,6 +5,7 @@ use std::{borrow::Cow, path::PathBuf}; use super::{Error, Options}; use crate::{ + bstr::BString, config, config::{ cache::interpolate_context, @@ -348,14 +349,13 @@ impl ThreadSafeRepository { .and_then(|prefix| { let _span = gix_trace::detail!("find replacement objects"); let platform = refs.iter().ok()?; - let iter = platform.prefixed(&prefix).ok()?; - let prefix = prefix.to_str()?; + let iter = platform.prefixed(prefix.clone().into()).ok()?; let replacements = iter .filter_map(Result::ok) .filter_map(|r: gix_ref::Reference| { let target = r.target.try_id()?.to_owned(); let source = - gix_hash::ObjectId::from_hex(r.name.as_bstr().strip_prefix(prefix.as_bytes())?).ok()?; + gix_hash::ObjectId::from_hex(r.name.as_bstr().strip_prefix(prefix.as_slice())?).ok()?; Some((source, target)) }) .collect::>(); @@ -394,7 +394,7 @@ fn replacement_objects_refs_prefix( config: &gix_config::File<'static>, lenient: bool, mut filter_config_section: fn(&gix_config::file::Metadata) -> bool, -) -> Result, Error> { +) -> Result, Error> { let is_disabled = config::shared::is_replace_refs_enabled(config, lenient, filter_config_section) .map_err(config::Error::ConfigBoolean)? .unwrap_or(true); @@ -403,15 +403,15 @@ fn replacement_objects_refs_prefix( return Ok(None); } - let ref_base = gix_path::from_bstr({ + let ref_base = { let key = "gitoxide.objects.replaceRefBase"; debug_assert_eq!(gitoxide::Objects::REPLACE_REF_BASE.logical_name(), key); config .string_filter(key, &mut filter_config_section) .unwrap_or_else(|| Cow::Borrowed("refs/replace/".into())) - }) + } .into_owned(); - Ok(ref_base.into()) + Ok(Some(ref_base)) } fn check_safe_directories( diff --git a/gix/src/reference/iter.rs b/gix/src/reference/iter.rs index 60ded42fef9..5ba5ccf7c5b 100644 --- a/gix/src/reference/iter.rs +++ b/gix/src/reference/iter.rs @@ -1,8 +1,11 @@ //! #![allow(clippy::empty_docs)] -use std::path::Path; +use std::borrow::Cow; -use gix_ref::file::ReferenceExt; +use gix_ref::{ + bstr::{BStr, ByteSlice}, + file::ReferenceExt, +}; /// A platform to create iterators over references. #[must_use = "Iterators should be obtained from this iterator platform"] @@ -42,11 +45,11 @@ impl Platform<'_> { /// Return an iterator over all references that match the given `prefix`. /// - /// These are of the form `refs/heads` or `refs/remotes/origin`, and must not contain relative paths components like `.` or `..`. + /// These are of the form `refs/heads/` or `refs/remotes/origin`, and must not contain relative paths components like `.` or `..`. // TODO: Create a custom `Path` type that enforces the requirements of git naturally, this type is surprising possibly on windows // and when not using a trailing '/' to signal directories. - pub fn prefixed(&self, prefix: impl AsRef) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed(prefix.as_ref())?)) + pub fn prefixed(&self, prefix: Cow<'_, BStr>) -> Result, init::Error> { + Ok(Iter::new(self.repo, self.platform.prefixed(prefix)?)) } // TODO: tests @@ -54,7 +57,10 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/tags`. pub fn tags(&self) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed("refs/tags/".as_ref())?)) + Ok(Iter::new( + self.repo, + self.platform.prefixed(b"refs/tags/".as_bstr().into())?, + )) } // TODO: tests @@ -62,7 +68,10 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/heads`. pub fn local_branches(&self) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed("refs/heads/".as_ref())?)) + Ok(Iter::new( + self.repo, + self.platform.prefixed(b"refs/heads/".as_bstr().into())?, + )) } // TODO: tests @@ -70,7 +79,10 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/remotes`. pub fn remote_branches(&self) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed("refs/remotes/".as_ref())?)) + Ok(Iter::new( + self.repo, + self.platform.prefixed(b"refs/remotes/".as_bstr().into())?, + )) } } diff --git a/gix/tests/gix/repository/reference.rs b/gix/tests/gix/repository/reference.rs index 94e9e8574d2..ae6f7a80b5a 100644 --- a/gix/tests/gix/repository/reference.rs +++ b/gix/tests/gix/repository/reference.rs @@ -1,5 +1,5 @@ mod set_namespace { - use gix::refs::transaction::PreviousValue; + use gix::{bstr::ByteSlice, refs::transaction::PreviousValue}; use gix_testtools::tempfile; fn easy_repo_rw() -> crate::Result<(gix::Repository, tempfile::TempDir)> { @@ -48,7 +48,7 @@ mod set_namespace { assert_eq!( repo.references()? - .prefixed("refs/tags/")? + .prefixed(b"refs/tags/".as_bstr().into())? .filter_map(Result::ok) .map(|r| r.name().as_bstr().to_owned()) .collect::>(), @@ -81,6 +81,7 @@ mod set_namespace { } mod iter_references { + use gix::bstr::ByteSlice; use crate::util::hex_to_id; @@ -124,7 +125,7 @@ mod iter_references { let repo = repo()?; assert_eq!( repo.references()? - .prefixed("refs/heads/")? + .prefixed(b"refs/heads/".as_bstr().into())? .filter_map(Result::ok) .map(|r| ( r.name().as_bstr().to_string(), @@ -155,7 +156,7 @@ mod iter_references { let repo = repo()?; assert_eq!( repo.references()? - .prefixed("refs/heads/")? + .prefixed(b"refs/heads/".as_bstr().into())? .peeled()? .filter_map(Result::ok) .map(|r| ( From 2d560c7c92197aa0518e1f36d018d4771e56456b Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 7 Apr 2025 16:18:51 -0400 Subject: [PATCH 070/193] Have `gix-filter` depend on `gix-packetline-blocking` unaliased This removes the `gix-packetline-blocking/futures-lite` "ghost feature" added in d5dd239 (#1939), and instead: - Changes `gix-filter` to depends on `gix-packetline-blocking` without aliasing it `gix-packetline`. - Replaces uses of `gix_packetline` with `gix_packetline_blocking` in the code of `gix-filter`. Thus, this replaces the solution in #1939 for the problem discussed in https://github.com/GitoxideLabs/gitoxide/pull/1929#issuecomment-2783852929 with a different solution that avoids carrying a "ghost feature." In contrast, the long-standing `gix-packetline-blocking/async-io` feature added in be4de0d (#1123), though it should not be used, is *not* removed, because: - It is referenced in attributes in `gix-packetline-blocking` code (because `gix-packetline-blocking/src` is copied from `gix-packetline/src` via `etc/copy-packetline.sh`). - For that reason, removing it would cause the `clippy` run in the CI `lint` job to fail, as well as likely making various other reasonable operations fail. --- gix-filter/Cargo.toml | 2 +- gix-filter/src/driver/process/client.rs | 27 +++++++++++++------------ gix-filter/src/driver/process/mod.rs | 15 ++++++++------ gix-filter/src/driver/process/server.rs | 22 ++++++++++---------- gix-packetline-blocking/Cargo.toml | 3 --- 5 files changed, 35 insertions(+), 34 deletions(-) diff --git a/gix-filter/Cargo.toml b/gix-filter/Cargo.toml index e955ab12e07..f7b3de607f6 100644 --- a/gix-filter/Cargo.toml +++ b/gix-filter/Cargo.toml @@ -22,7 +22,7 @@ gix-command = { version = "^0.5.0", path = "../gix-command" } gix-quote = { version = "^0.5.0", path = "../gix-quote" } gix-utils = { version = "^0.2.0", path = "../gix-utils" } gix-path = { version = "^0.10.15", path = "../gix-path" } -gix-packetline = { package = "gix-packetline-blocking", version = "^0.18.3", path = "../gix-packetline-blocking" } +gix-packetline-blocking = { version = "^0.18.3", path = "../gix-packetline-blocking" } gix-attributes = { version = "^0.25.0", path = "../gix-attributes" } encoding_rs = "0.8.32" diff --git a/gix-filter/src/driver/process/client.rs b/gix-filter/src/driver/process/client.rs index 57e59cc3e87..312b0600d4e 100644 --- a/gix-filter/src/driver/process/client.rs +++ b/gix-filter/src/driver/process/client.rs @@ -41,7 +41,7 @@ pub mod invoke { #[error("Failed to read or write to the process")] Io(#[from] std::io::Error), #[error(transparent)] - PacketlineDecode(#[from] gix_packetline::decode::Error), + PacketlineDecode(#[from] gix_packetline_blocking::decode::Error), } impl From for Error { @@ -65,17 +65,18 @@ impl Client { versions: &[usize], desired_capabilities: &[&str], ) -> Result { - let mut out = gix_packetline::Writer::new(process.stdin.take().expect("configured stdin when spawning")); + let mut out = + gix_packetline_blocking::Writer::new(process.stdin.take().expect("configured stdin when spawning")); out.write_all(format!("{welcome_prefix}-client").as_bytes())?; for version in versions { out.write_all(format!("version={version}").as_bytes())?; } - gix_packetline::encode::flush_to_write(out.inner_mut())?; + gix_packetline_blocking::encode::flush_to_write(out.inner_mut())?; out.flush()?; - let mut input = gix_packetline::StreamingPeekableIter::new( + let mut input = gix_packetline_blocking::StreamingPeekableIter::new( process.stdout.take().expect("configured stdout when spawning"), - &[gix_packetline::PacketLineRef::Flush], + &[gix_packetline_blocking::PacketLineRef::Flush], false, /* packet tracing */ ); let mut read = input.as_read(); @@ -125,10 +126,10 @@ impl Client { for capability in desired_capabilities { out.write_all(format!("capability={capability}").as_bytes())?; } - gix_packetline::encode::flush_to_write(out.inner_mut())?; + gix_packetline_blocking::encode::flush_to_write(out.inner_mut())?; out.flush()?; - read.reset_with(&[gix_packetline::PacketLineRef::Flush]); + read.reset_with(&[gix_packetline_blocking::PacketLineRef::Flush]); let mut capabilities = HashSet::new(); loop { buf.clear(); @@ -167,7 +168,7 @@ impl Client { ) -> Result { self.send_command_and_meta(command, meta)?; std::io::copy(content, &mut self.input)?; - gix_packetline::encode::flush_to_write(self.input.inner_mut())?; + gix_packetline_blocking::encode::flush_to_write(self.input.inner_mut())?; self.input.flush()?; Ok(self.read_status()?) } @@ -189,7 +190,7 @@ impl Client { inspect_line(line.as_bstr()); } } - self.out.reset_with(&[gix_packetline::PacketLineRef::Flush]); + self.out.reset_with(&[gix_packetline_blocking::PacketLineRef::Flush]); let status = self.read_status()?; Ok(status) } @@ -197,7 +198,7 @@ impl Client { /// Return a `Read` implementation that reads the server process output until the next flush package, and validates /// the status. If the status indicates failure, the last read will also fail. pub fn as_read(&mut self) -> impl std::io::Read + '_ { - self.out.reset_with(&[gix_packetline::PacketLineRef::Flush]); + self.out.reset_with(&[gix_packetline_blocking::PacketLineRef::Flush]); ReadProcessOutputAndStatus { inner: self.out.as_read(), } @@ -225,7 +226,7 @@ impl Client { buf.push_str(&value); self.input.write_all(&buf)?; } - gix_packetline::encode::flush_to_write(self.input.inner_mut())?; + gix_packetline_blocking::encode::flush_to_write(self.input.inner_mut())?; Ok(()) } } @@ -248,7 +249,7 @@ fn read_status(read: &mut PacketlineReader<'_>) -> std::io::Result 0 && matches!(status, process::Status::Previous) { status = process::Status::Unset; } - read.reset_with(&[gix_packetline::PacketLineRef::Flush]); + read.reset_with(&[gix_packetline_blocking::PacketLineRef::Flush]); Ok(status) } @@ -260,7 +261,7 @@ impl std::io::Read for ReadProcessOutputAndStatus<'_> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { let num_read = self.inner.read(buf)?; if num_read == 0 { - self.inner.reset_with(&[gix_packetline::PacketLineRef::Flush]); + self.inner.reset_with(&[gix_packetline_blocking::PacketLineRef::Flush]); let status = read_status(&mut self.inner)?; if status.is_success() { Ok(0) diff --git a/gix-filter/src/driver/process/mod.rs b/gix-filter/src/driver/process/mod.rs index b4e19c47a83..9377f2f9b10 100644 --- a/gix-filter/src/driver/process/mod.rs +++ b/gix-filter/src/driver/process/mod.rs @@ -12,9 +12,9 @@ pub struct Client { /// The negotiated version of the protocol. version: usize, /// A way to send packet-line encoded information to the process. - input: gix_packetline::Writer, + input: gix_packetline_blocking::Writer, /// A way to read information sent to us by the process. - out: gix_packetline::StreamingPeekableIter, + out: gix_packetline_blocking::StreamingPeekableIter, } /// A handle to facilitate typical server interactions that include the handshake and command-invocations. @@ -24,9 +24,9 @@ pub struct Server { /// The negotiated version of the protocol, it's the highest supported one. version: usize, /// A way to receive information from the client. - input: gix_packetline::StreamingPeekableIter>, + input: gix_packetline_blocking::StreamingPeekableIter>, /// A way to send information to the client. - out: gix_packetline::Writer>, + out: gix_packetline_blocking::Writer>, } /// The return status of an [invoked command][Client::invoke()]. @@ -109,5 +109,8 @@ pub mod client; /// pub mod server; -type PacketlineReader<'a, T = std::process::ChildStdout> = - gix_packetline::read::WithSidebands<'a, T, fn(bool, &[u8]) -> gix_packetline::read::ProgressAction>; +type PacketlineReader<'a, T = std::process::ChildStdout> = gix_packetline_blocking::read::WithSidebands< + 'a, + T, + fn(bool, &[u8]) -> gix_packetline_blocking::read::ProgressAction, +>; diff --git a/gix-filter/src/driver/process/server.rs b/gix-filter/src/driver/process/server.rs index 8afdebc3b63..971b5393bb2 100644 --- a/gix-filter/src/driver/process/server.rs +++ b/gix-filter/src/driver/process/server.rs @@ -26,7 +26,7 @@ pub mod next_request { #[error("{msg} '{actual}'")] Protocol { msg: String, actual: BString }, #[error(transparent)] - PacketlineDecode(#[from] gix_packetline::decode::Error), + PacketlineDecode(#[from] gix_packetline_blocking::decode::Error), } } @@ -63,9 +63,9 @@ impl Server { pick_version: &mut dyn FnMut(&[usize]) -> Option, available_capabilities: &[&str], ) -> Result { - let mut input = gix_packetline::StreamingPeekableIter::new( + let mut input = gix_packetline_blocking::StreamingPeekableIter::new( stdin.lock(), - &[gix_packetline::PacketLineRef::Flush], + &[gix_packetline_blocking::PacketLineRef::Flush], false, /* packet tracing */ ); let mut read = input.as_read(); @@ -104,11 +104,11 @@ impl Server { ); } let version = pick_version(&versions).ok_or(handshake::Error::VersionMismatch { actual: versions })?; - read.reset_with(&[gix_packetline::PacketLineRef::Flush]); - let mut out = gix_packetline::Writer::new(stdout.lock()); + read.reset_with(&[gix_packetline_blocking::PacketLineRef::Flush]); + let mut out = gix_packetline_blocking::Writer::new(stdout.lock()); out.write_all(format!("{welcome_prefix}-server").as_bytes())?; out.write_all(format!("version={version}").as_bytes())?; - gix_packetline::encode::flush_to_write(out.inner_mut())?; + gix_packetline_blocking::encode::flush_to_write(out.inner_mut())?; out.flush()?; let mut capabilities = HashSet::new(); @@ -132,7 +132,7 @@ impl Server { for cap in &capabilities { out.write_all(format!("capability={cap}").as_bytes())?; } - gix_packetline::encode::flush_to_write(out.inner_mut())?; + gix_packetline_blocking::encode::flush_to_write(out.inner_mut())?; out.flush()?; drop(read); @@ -196,7 +196,7 @@ impl Server { } drop(read); - self.input.reset_with(&[gix_packetline::PacketLineRef::Flush]); + self.input.reset_with(&[gix_packetline_blocking::PacketLineRef::Flush]); Ok(Some(Request { parent: self, @@ -233,7 +233,7 @@ mod request { if let Some(message) = status.message() { out.write_all(format!("status={message}").as_bytes())?; } - gix_packetline::encode::flush_to_write(out.inner_mut())?; + gix_packetline_blocking::encode::flush_to_write(out.inner_mut())?; out.flush() } } @@ -248,7 +248,7 @@ mod request { } struct WriteAndFlushOnDrop<'a> { - inner: &'a mut gix_packetline::Writer>, + inner: &'a mut gix_packetline_blocking::Writer>, } impl std::io::Write for WriteAndFlushOnDrop<'_> { @@ -263,7 +263,7 @@ mod request { impl Drop for WriteAndFlushOnDrop<'_> { fn drop(&mut self) { - gix_packetline::encode::flush_to_write(self.inner.inner_mut()).ok(); + gix_packetline_blocking::encode::flush_to_write(self.inner.inner_mut()).ok(); self.inner.flush().ok(); } } diff --git a/gix-packetline-blocking/Cargo.toml b/gix-packetline-blocking/Cargo.toml index b1febf34603..70fa873821b 100644 --- a/gix-packetline-blocking/Cargo.toml +++ b/gix-packetline-blocking/Cargo.toml @@ -24,9 +24,6 @@ blocking-io = [] ## DO NOT USE, instead use `gix-packetline` directly. async-io = [] -## DO NOT USE, instead use `gix-packetline` directly (and still don't specify `futures-lite`). -futures-lite = [] - #! ### Other ## Data structures implement `serde::Serialize` and `serde::Deserialize`. serde = ["dep:serde", "bstr/serde"] From 4554bb9cdabc4cb30bcf85feb06ed6f4c5b3725e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 02:11:24 +0000 Subject: [PATCH 071/193] build(deps): bump tokio in the cargo group across 1 directory Bumps the cargo group with 1 update in the / directory: [tokio](https://github.com/tokio-rs/tokio). Updates `tokio` from 1.44.1 to 1.44.2 - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.44.1...tokio-1.44.2) --- updated-dependencies: - dependency-name: tokio dependency-version: 1.44.2 dependency-type: indirect dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e3cadd7edae..3a54ce74272 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3654,7 +3654,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -5292,9 +5292,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.1" +version = "1.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" dependencies = [ "backtrace", "bytes", From 3501e82467e3b73a87313f3527872d1eea90977e Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Thu, 3 Apr 2025 21:40:48 -0400 Subject: [PATCH 072/193] Use runner-provided Git for Windows now that it's 2.49.0 Because #1849 (https://github.com/git-for-windows/git/issues/5436) caused some incorrect test failures in `test-fixtures-windows`, we have been upgrading Git for Windows on the runner for that job: - We starting doing that in of 4237e5a (#1870). At that time, we upgraded it to the most recent tag, to select the latest release even though it was a release candiate, because Git for Windows 2.49.0 had not yet had a stable release. - Then Git for Windows 2.49.0 got a stable release, and starting in ddef6d3 (#1892) we have upgraded to the release marked "latest" (which in Git for Windows is always the latest stable release). More recently, the Windows Server 2022 runner image (which the `windows-latest` label we use currently selects) has upgraded its Git for Windows installation from 2.48.1 to 2.49.0: https://github.com/actions/runner-images/releases/tag/win22%2F20250330.1 It is therefore no longer necessary for the `test-fixtures-windows` job to upgrade Git for Windows on the runner. This removes the step that did that. (Either version of the step could be brought back from the history if ever needed again.) This closes #1849, per the plan in: https://github.com/GitoxideLabs/gitoxide/issues/1849#issuecomment-2724513361 --- .github/workflows/ci.yml | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f80297f737c..73d7a4b0d16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -193,35 +193,6 @@ jobs: runs-on: windows-latest steps: - - name: Upgrade Git for Windows to latest stable release - # This upgrades Git to work around https://github.com/GitoxideLabs/gitoxide/issues/1849. - # TODO: Remove this step once the runner image has Git 2.49.0 or higher. - env: - GH_TOKEN: ${{ github.token }} - run: | - $workingDir = '~/git-dl' - $repo = 'git-for-windows/git' - $pattern = 'Git-*-64-bit.exe' - $log = 'setup-log.txt' - # Inno Setup args reference: https://jrsoftware.org/ishelp/index.php?topic=setupcmdline - $arguments = @( - '/VERYSILENT', - '/SUPPRESSMSGBOXES', - '/ALLUSERS', - "/LOG=$log", - '/NORESTART', - '/CLOSEAPPLICATIONS', - '/FORCECLOSEAPPLICATIONS' - ) - - mkdir $workingDir | Out-Null - cd $workingDir - gh release download --repo $repo --pattern $pattern - $installer = Get-Item $pattern - Start-Process -FilePath $installer -ArgumentList $arguments -NoNewWindow -Wait - - Get-Content -Path $log -Tail 50 - git version - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 From 94faf5199a32a99348230c2ea4bc8c2b06319360 Mon Sep 17 00:00:00 2001 From: Fredrik Medley Date: Tue, 8 Apr 2025 10:33:19 +0200 Subject: [PATCH 073/193] Rename prefix test branches --- .../make_packed_ref_repository.tar | Bin 69120 -> 73216 bytes ...make_packed_ref_repository_for_overlay.tar | Bin 70656 -> 68608 bytes .../make_ref_repository.tar | Bin 86528 -> 86528 bytes .../fixtures/make_packed_ref_repository.sh | 3 + .../make_packed_ref_repository_for_overlay.sh | 6 +- gix-ref/tests/fixtures/make_ref_repository.sh | 9 +- gix-ref/tests/refs/file/store/iter.rs | 94 ++++++++++-------- .../create_or_update/mod.rs | 4 +- gix-ref/tests/refs/packed/iter.rs | 2 +- 9 files changed, 63 insertions(+), 55 deletions(-) diff --git a/gix-ref/tests/fixtures/generated-archives/make_packed_ref_repository.tar b/gix-ref/tests/fixtures/generated-archives/make_packed_ref_repository.tar index 87d999da6baf14cf49b925aa782da9ab91baec61..4f956f6262c314d0f35d7a8668025b775f0e0bf9 100644 GIT binary patch delta 2746 zcmb_eOK%%h6wWvvH=evoMNnTtR}-tXQOBNfoCG2jkv678EsbQ1TBw9|Gjqqj&17aW zk37_(>4pW%)<8F1P%N=SLLCH~E?|QY3j{1!u<8#$uqjlOLOFNFcI~94AYm!-jPKm< zeCIpgIdd;vOJ2H}{FqOM{O7w<;l$TmGJNX$+k>I-&2TcD`0`h{`r(hkkbicU7>=C3 zKRD(RQzNUG8qzv8Xmj+XlUKeA0A^THUy zw(VH9Ljg>fY<{8b&DaiEC#HwI28kcc0+Q}ns{qF^0LyDW{jMDJC&1{4d0`Tw9os@0 z(XnrMM_9xSY8c2ejV+`$h`Iv6I7W}CXBklyn}E*97?f!6F!C%LSvr6*8f`S>+pgyj z3``ts29Wj!^%|D%A=NTeq|6w$!0*A^3gVTer8BhgwLGho6-xdC&H7{nu5oPQN4>y}|y8%!_8 zjn*M9h`ekNx09?(Km`jl!DgNGrRk7Wi`CZDAVT}bA&eLZhaG}^7eoqRGZSnp+8b#J z;JA*d>3VZfAy8EKsM`5<-lP(PXWN?2LFTkh%^ZY!^y3wX{$R&T<@tr25U^5Lh;3js zre9rJSVGZl!!k7DxKVj}9Tpn^NUEykM23VMwk)63#Uw;?^McUfSyQcb;?zJ^s2j@W z&;=o_Q-d58Gm0prCsDxS&236!Bkc@S zHeDY?@3$?&L1flA$vzJPcpYpHHkGE3m|>(vbnzlo((@gYQU7<$p?4uDbz>j0eQ_>P z7B&u`@AJ0t&|G4>wpIIY@d(<0@{zXVA4FaADfI5LPYvw|cv_ftV1t$$Jw@4$)Q7s7?8dVCFsJies~NBG*FDw8At%O zy5f;l8#a2YwniN!X%9F=?*ukd^Jn8vyqjgwK?o4mG$iTpCq)%tCKNNBWf6(M*)7Bh zxP?r7!M=4dN~up0CvId3L!0bW;!Jyt_TmQuFmqvoP!S+DK^TR#vv0DwdSbC!TUe|_ z-)EL8Cu`M8xh$w!FMp;1GgKWgk+g=yH#Dm2td4*M>aj5so2WaI;t>(85Ch(SLb|)u zH?5*4Ais8mu4VtpvCPst)~id^`BNPlef9Fq6-e}P;PHpADhT_3!$ zKAZ}NKfTL`{KfSCaLnX}TI0*faQyvy6XCE9hoq6$f8W*OlgSqUW2(j9g!9uLKG71M zNwtK7W1&!DXQn6lp_U*gQ&4`LZZ@wcs&G_lHV(>sQJxu?j*mryNv_G?3-&2fJ5EnZ zQRx!=^Bfnx{nrL}8A&&8jgEw)x4A?(_Vax{9Q}!1{dR{RV#f<;DHkH0i6UiWej0M@ zjWiVOo0{1Xsi>5?=d|?s#6--vpc4$UpGdB+vjhqwg#-O71=n9Lzz`^4qi(VF=10T3 z!wbWAxDUpXpKyB;SNEhicW-fOhxW6x#aR2#xLw>RH&~j^hbVsw@*Dp!!6n9vrCFs^ aoPJK8k$jVGhELr6g$vQ$Tk*fk=-A(R^?ES? delta 445 zcmZ9IyDtP$6vp?=+&jB_clL?RQpiw|AoIAphr^K%qoIqN4GLx7oxtnv?V8oSfhHo%{*O?~p@EYg3T^{Haid5>{PPZ6+w3K zAtJ5y)}y@t=0&=}2!{8*M3j4eL=5DK55vQs6a!OYjTP!&P9%;0XwJE7p@c>l7@{~j zxGQceQgJg7$H3S-wdpZIN+J?g#h*oFOePqQx!0>gC0X+!+O#Mkz4yr&`~(3*FFzE6 zPo?hrm0I+6wOZG-|5!J&QO4elK$AZ`J)c=HC&qK8(y1&iESb!ob#-Pgo5`6=^XZAq zWO;(UT`O=DftcXL;_v`rBh^-lp&LfCySd^-1$czQcNEsGwab{qTU&YgyA=?GN~66c fsWkLvv$LksmtJhvlDrY?&aS~x1i1OD+e-H@pIL`P diff --git a/gix-ref/tests/fixtures/generated-archives/make_packed_ref_repository_for_overlay.tar b/gix-ref/tests/fixtures/generated-archives/make_packed_ref_repository_for_overlay.tar index 9b1cdb67d27348d13539076cd422ec5f1ae2ea53..b588e583f6d88e769b00c216e13880cfd4bcc56f 100644 GIT binary patch delta 235 zcmZoz!O}2;WdqlN#at)2*b0hL(=sb2FJuat#KSTC)v85jZC1_p*khQ>w=1`vh+d6~o@Ch4c8CYF>IrRo-!rU4D+ znx4qWsG+0)w53=dRfT?WX_9_QW|4kkPI^8>-EiFrB=RCuK9^Zhl5~pqze6 zX3<1JU$Fck16E@b6C?$EPzCx0iOJciDH8?Vfa<1ZFv^LWG8h_|m>C)v85kKGFc=sZ znwXj!F&IFMzR1tWlAD;Bx7pEZKjTCN-AxC$xOl*>(S;f0htnWqBO^nc2AyfvkTNhc zG(xxC$k5mvrs*p$)8skdKW+Ne#x=R^h2ZAtM=}}tjm#}9%?-_r%*=F4^D-+oJO0_v PxH;g@1_&{E1J5M@QZHk7 diff --git a/gix-ref/tests/fixtures/generated-archives/make_ref_repository.tar b/gix-ref/tests/fixtures/generated-archives/make_ref_repository.tar index 393c27057cd04e0c8da514647b1620696bf4617c..76d6c84863f6ec8402ab5d5db3992642e99bb361 100644 GIT binary patch delta 333 zcmZoz!rHKebpzL(&0J6TSvE_)`KY;_ON#L~Gj~yHTCsiskj$)@oX8q7iHBu!28RKw zk%1Y5DNrC~GviTCMqY>l{j}7?lG38diVDsX6}Z4kpBb{47$T|ULs6MJng5OtSRIQ# zn~90B5k8go;3`dx3=NP}N~4;oUtF4`pORUmpO}-LKT*&gZ2k#-HZwzG0|o<#n=f)Q zi=yh%EiO$1`f;M5D@?tqA<*S8^(@TWS>+i2=<=DFo12(h8krgEmgZ$vY!{Sae9yRD NL5A@Gl$@yG1OVj$Yjywt delta 241 zcmZoz!rHKebpzKO&WzN=lw$qj(xi!kfs=Sxrf0Y?8nT#~F_=zHWKG%3c$}Y+9Vn@v zl36rS&=;s+a>hLaR$~(rBn3QB1^PMp`NfkJ6`Ut3u!2=SF<>Zt(pX2Clg zER*>;ykXMjCdP1SN#@N`4?bvefnB7FFpC$WSf9<<(9jgFnv;1u7Z>Ai=IyL=bhO .git/refs/remotes/origin/HEAD echo "notahexsha" > .git/refs/broken diff --git a/gix-ref/tests/fixtures/make_packed_ref_repository_for_overlay.sh b/gix-ref/tests/fixtures/make_packed_ref_repository_for_overlay.sh index c6e3a57650b..5c231bae009 100755 --- a/gix-ref/tests/fixtures/make_packed_ref_repository_for_overlay.sh +++ b/gix-ref/tests/fixtures/make_packed_ref_repository_for_overlay.sh @@ -10,13 +10,13 @@ git branch A git tag -m "tag object" tag-object mkdir -p .git/refs/remotes/origin -mkdir -p .git/refs/heads/sub/dir +mkdir -p .git/refs/prefix/feature/sub/dir cp .git/refs/heads/main .git/refs/remotes/origin/ +cp .git/refs/heads/main .git/refs/prefix/feature-suffix +cp .git/refs/heads/main .git/refs/prefix/feature/sub/dir/algo echo "ref: refs/remotes/origin/main" > .git/refs/remotes/origin/HEAD -echo "ref: refs/heads/main" > .git/refs/heads-packed -echo "ref: refs/heads/main" > .git/refs/heads/sub/dir/packed git pack-refs --all --prune diff --git a/gix-ref/tests/fixtures/make_ref_repository.sh b/gix-ref/tests/fixtures/make_ref_repository.sh index c3e661cba3a..d89948193fa 100755 --- a/gix-ref/tests/fixtures/make_ref_repository.sh +++ b/gix-ref/tests/fixtures/make_ref_repository.sh @@ -10,9 +10,12 @@ git branch d1 git branch A mkdir -p .git/refs/remotes/origin +mkdir -p .git/refs/prefix/feature/sub/dir cp .git/refs/heads/main .git/refs/remotes/origin/ cp .git/refs/heads/main .git/refs/d1 +cp .git/refs/heads/main .git/refs/prefix/feature-suffix +cp .git/refs/heads/main .git/refs/prefix/feature/sub/dir/algo echo "ref: refs/remotes/origin/main" > .git/refs/remotes/origin/HEAD echo "notahexsha" > .git/refs/broken @@ -22,12 +25,6 @@ echo "ref: refs/tags/multi-link-target2" > .git/refs/heads/multi-link-target1 echo "ref: refs/remotes/origin/multi-link-target3" > .git/refs/tags/multi-link-target2 git rev-parse HEAD > .git/refs/remotes/origin/multi-link-target3 -# Regression test for issue #1934 where prefix refs/m matched refs/heads/main. -mkdir -p .git/refs/heads/sub/dir -echo "ref: refs/remotes/origin/main" > .git/refs/heads-loose -echo "ref: refs/remotes/origin/main" > .git/refs/heads/sub/dir/loose -echo "ref: refs/remotes/origin/main" > .git/refs/remotes/origin/heads - echo "ref: refs/loop-b" > .git/refs/loop-a echo "ref: refs/loop-a" > .git/refs/loop-b diff --git a/gix-ref/tests/refs/file/store/iter.rs b/gix-ref/tests/refs/file/store/iter.rs index e2e2849e1ca..3d25a53b245 100644 --- a/gix-ref/tests/refs/file/store/iter.rs +++ b/gix-ref/tests/refs/file/store/iter.rs @@ -255,7 +255,7 @@ fn no_packed_available_thus_no_iteration_possible() -> crate::Result { #[test] fn packed_file_iter() -> crate::Result { let store = store_with_packed_refs()?; - assert_eq!(store.open_packed_buffer()?.expect("pack available").iter()?.count(), 9); + assert_eq!(store.open_packed_buffer()?.expect("pack available").iter()?.count(), 11); Ok(()) } @@ -264,7 +264,7 @@ fn loose_iter_with_broken_refs() -> crate::Result { let store = store()?; let mut actual: Vec<_> = store.loose_iter()?.collect(); - assert_eq!(actual.len(), 19); + assert_eq!(actual.len(), 18); actual.sort_by_key(Result::is_err); let first_error = actual .iter() @@ -273,7 +273,7 @@ fn loose_iter_with_broken_refs() -> crate::Result { .expect("there is an error"); assert_eq!( - first_error, 18, + first_error, 17, "there is exactly one invalid item, and it didn't abort the iterator most importantly" ); #[cfg(not(windows))] @@ -293,18 +293,17 @@ fn loose_iter_with_broken_refs() -> crate::Result { ref_paths, vec![ "d1", - "heads-loose", "heads/A", "heads/d1", "heads/dt1", "heads/main", "heads/multi-link-target1", - "heads/sub/dir/loose", "loop-a", "loop-b", "multi-link", + "prefix/feature-suffix", + "prefix/feature/sub/dir/algo", "remotes/origin/HEAD", - "remotes/origin/heads", "remotes/origin/main", "remotes/origin/multi-link-target3", "tags/dt1", @@ -355,7 +354,6 @@ fn loose_iter_with_prefix() -> crate::Result { "refs/heads/dt1", "refs/heads/main", "refs/heads/multi-link-target1", - "refs/heads/sub/dir/loose", ] .into_iter() .map(String::from) @@ -381,13 +379,11 @@ fn loose_iter_with_partial_prefix_dir() -> crate::Result { assert_eq!( actual, vec![ - "refs/heads-loose", "refs/heads/A", "refs/heads/d1", "refs/heads/dt1", "refs/heads/main", "refs/heads/multi-link-target1", - "refs/heads/sub/dir/loose", ] .into_iter() .map(String::from) @@ -435,14 +431,11 @@ fn overlay_iter() -> crate::Result { assert_eq!( ref_names, vec![ - ("refs/heads-packed".into(), Symbolic("refs/heads/main".try_into()?),), (b"refs/heads/A".as_bstr().to_owned(), Object(c1)), (b"refs/heads/main".into(), Object(c1)), ("refs/heads/newer-as-loose".into(), Object(c2)), - ( - "refs/heads/sub/dir/packed".into(), - Symbolic("refs/heads/main".try_into()?), - ), + ("refs/prefix/feature-suffix".into(), Object(c1)), + ("refs/prefix/feature/sub/dir/algo".into(), Object(c1)), ( "refs/remotes/origin/HEAD".into(), Symbolic("refs/remotes/origin/main".try_into()?), @@ -558,7 +551,6 @@ fn overlay_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { #[test] fn overlay_prefixed_iter() -> crate::Result { - // Test 'refs/heads/' with slash. use gix_ref::Target::*; let store = store_at("make_packed_ref_repository_for_overlay.sh")?; @@ -575,58 +567,74 @@ fn overlay_prefixed_iter() -> crate::Result { (b"refs/heads/A".as_bstr().to_owned(), Object(c1)), (b"refs/heads/main".into(), Object(c1)), ("refs/heads/newer-as-loose".into(), Object(c2)), - ( - b"refs/heads/sub/dir/packed".into(), - Symbolic("refs/heads/main".try_into()?) - ), ] ); Ok(()) } #[test] -fn overlay_partial_prefix_dir_iter() -> crate::Result { - // Test 'refs/heads/' without slash. +fn overlay_partial_prefix_iter() -> crate::Result { use gix_ref::Target::*; let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store .iter()? - .prefixed(b"refs/heads".as_bstr().into())? + .prefixed(b"refs/heads/m".as_bstr().into())? // 'm' is partial .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); - let c2 = hex_to_id("9902e3c3e8f0c569b4ab295ddf473e6de763e1e7"); - assert_eq!( - ref_names, - vec![ - ( - b"refs/heads-packed".as_bstr().to_owned(), - Symbolic("refs/heads/main".try_into()?) - ), - (b"refs/heads/A".as_bstr().to_owned(), Object(c1)), - (b"refs/heads/main".into(), Object(c1)), - ("refs/heads/newer-as-loose".into(), Object(c2)), - ( - b"refs/heads/sub/dir/packed".into(), - Symbolic("refs/heads/main".try_into()?) - ), - ] - ); + assert_eq!(ref_names, vec![(b"refs/heads/main".as_bstr().to_owned(), Object(c1)),]); Ok(()) } #[test] -fn overlay_partial_prefix_iter() -> crate::Result { +/// The prefix `refs/d` should match `refs/d1` but not `refs/heads/d1`. +fn overlay_partial_prefix_iter_reproduce_1934() -> crate::Result { use gix_ref::Target::*; - let store = store_at("make_packed_ref_repository_for_overlay.sh")?; + let store = store_at("make_ref_repository.sh")?; + let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); + let ref_names = store .iter()? - .prefixed(b"refs/heads/m".as_bstr().into())? // 'm' is partial + .prefixed(b"refs/d".as_bstr().into())? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; + // Should not match `refs/heads/d1`. + assert_eq!(ref_names, vec![("refs/d1".into(), Object(c1)),]); + Ok(()) +} + +#[test] +fn overlay_partial_prefix_iter_when_prefix_is_dir() -> crate::Result { + // Test 'refs/prefix/' with and without trailing slash. + use gix_ref::Target::*; + + let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); - assert_eq!(ref_names, vec![(b"refs/heads/main".as_bstr().to_owned(), Object(c1)),]); + + let ref_names = store + .iter()? + .prefixed(b"refs/prefix/feature".as_bstr().into())? + .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) + .collect::, _>>()?; + assert_eq!( + ref_names, + vec![ + ("refs/prefix/feature-suffix".into(), Object(c1)), + ("refs/prefix/feature/sub/dir/algo".into(), Object(c1)), + ] + ); + + let ref_names = store + .iter()? + .prefixed(b"refs/prefix/feature/".as_bstr().into())? + .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) + .collect::, _>>()?; + assert_eq!( + ref_names, + vec![("refs/prefix/feature/sub/dir/algo".into(), Object(c1)),] + ); + Ok(()) } diff --git a/gix-ref/tests/refs/file/transaction/prepare_and_commit/create_or_update/mod.rs b/gix-ref/tests/refs/file/transaction/prepare_and_commit/create_or_update/mod.rs index 3d6680f212d..0b177ec1354 100644 --- a/gix-ref/tests/refs/file/transaction/prepare_and_commit/create_or_update/mod.rs +++ b/gix-ref/tests/refs/file/transaction/prepare_and_commit/create_or_update/mod.rs @@ -791,7 +791,7 @@ fn packed_refs_creation_with_packed_refs_mode_prune_removes_original_loose_refs( assert_eq!( edits.len(), - 9, + 11, "there are a certain amount of loose refs that are packed" ); @@ -843,7 +843,7 @@ fn packed_refs_creation_with_packed_refs_mode_leave_keeps_original_loose_refs() .commit(committer().to_ref())?; assert_eq!( edits.len(), - 4, + 2, "it claims to have performed all desired operations, even though some don't make it into the pack as 'side-car'" ); diff --git a/gix-ref/tests/refs/packed/iter.rs b/gix-ref/tests/refs/packed/iter.rs index b22c7c7adba..78db809721a 100644 --- a/gix-ref/tests/refs/packed/iter.rs +++ b/gix-ref/tests/refs/packed/iter.rs @@ -18,7 +18,7 @@ fn packed_refs_with_header() -> crate::Result { let dir = gix_testtools::scripted_fixture_read_only_standalone("make_packed_ref_repository.sh")?; let buf = std::fs::read(dir.join(".git").join("packed-refs"))?; let iter = packed::Iter::new(&buf)?; - assert_eq!(iter.count(), 9, "it finds the right amount of items"); + assert_eq!(iter.count(), 11, "it finds the right amount of items"); Ok(()) } From 507d682c08dcda29f044068c13ce87678c1b2a5e Mon Sep 17 00:00:00 2001 From: Fredrik Medley Date: Tue, 8 Apr 2025 11:10:53 +0200 Subject: [PATCH 074/193] Use Into> --- gix-negotiate/tests/baseline/mod.rs | 2 +- gix-ref/src/store/file/loose/iter.rs | 4 ++-- gix-ref/src/store/file/overlay_iter.rs | 11 ++++++----- gix-ref/tests/refs/file/store/iter.rs | 24 ++++++++++++------------ gix-ref/tests/refs/file/worktree.rs | 4 ++-- gix/src/open/repository.rs | 2 +- gix/src/reference/iter.rs | 16 +++++----------- gix/tests/gix/repository/reference.rs | 6 +++--- 8 files changed, 32 insertions(+), 37 deletions(-) diff --git a/gix-negotiate/tests/baseline/mod.rs b/gix-negotiate/tests/baseline/mod.rs index e2736ae7cff..84f71f04801 100644 --- a/gix-negotiate/tests/baseline/mod.rs +++ b/gix-negotiate/tests/baseline/mod.rs @@ -71,7 +71,7 @@ fn run() -> crate::Result { // } for tip in lookup_names(&["HEAD"]).into_iter().chain( refs.iter()? - .prefixed(b"refs/heads".as_bstr().into())? + .prefixed(b"refs/heads".as_bstr())? .filter_map(Result::ok) .map(|r| r.target.into_id()), ) { diff --git a/gix-ref/src/store/file/loose/iter.rs b/gix-ref/src/store/file/loose/iter.rs index 5be0bb2cddd..0ec3a7ddb11 100644 --- a/gix-ref/src/store/file/loose/iter.rs +++ b/gix-ref/src/store/file/loose/iter.rs @@ -87,7 +87,7 @@ impl file::Store { /// Return an iterator over all loose references that start with the given `prefix`. /// /// Otherwise it's similar to [`loose_iter()`][file::Store::loose_iter()]. - pub fn loose_iter_prefixed(&self, prefix: Cow<'_, BStr>) -> std::io::Result> { - self.iter_prefixed_packed(prefix, None) + pub fn loose_iter_prefixed<'a>(&self, prefix: impl Into>) -> std::io::Result> { + self.iter_prefixed_packed(prefix.into(), None) } } diff --git a/gix-ref/src/store/file/overlay_iter.rs b/gix-ref/src/store/file/overlay_iter.rs index 914035bea3d..c9de782d609 100644 --- a/gix-ref/src/store/file/overlay_iter.rs +++ b/gix-ref/src/store/file/overlay_iter.rs @@ -197,9 +197,9 @@ impl Platform<'_> { /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads/" or /// "refs/heads/feature-". - pub fn prefixed(&self, prefix: Cow<'_, BStr>) -> std::io::Result> { + pub fn prefixed<'a>(&self, prefix: impl Into>) -> std::io::Result> { self.store - .iter_prefixed_packed(prefix, self.packed.as_ref().map(|b| &***b)) + .iter_prefixed_packed(prefix.into(), self.packed.as_ref().map(|b| &***b)) } } @@ -284,8 +284,9 @@ impl<'a> IterInfo<'a> { .peekable() } - fn from_prefix(base: &'a Path, prefix: Cow<'a, BStr>, precompose_unicode: bool) -> std::io::Result { - let prefix_path = gix_path::from_bstring(prefix.as_ref()); + fn from_prefix(base: &'a Path, prefix: impl Into>, precompose_unicode: bool) -> std::io::Result { + let prefix = prefix.into(); + let prefix_path = gix_path::from_bstring(prefix.clone().into_owned()); if prefix_path.is_absolute() { return Err(std::io::Error::new( std::io::ErrorKind::InvalidInput, @@ -375,7 +376,7 @@ impl file::Store { self.iter_from_info(git_dir_info, common_dir_info, packed) } Some(namespace) => { - let prefix = namespace.to_owned().into_namespaced_prefix(prefix.as_ref()); + let prefix = namespace.to_owned().into_namespaced_prefix(&prefix); let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix.clone(), self.precompose_unicode)?; let common_dir_info = self .common_dir() diff --git a/gix-ref/tests/refs/file/store/iter.rs b/gix-ref/tests/refs/file/store/iter.rs index 3d25a53b245..2b1e24fd7b7 100644 --- a/gix-ref/tests/refs/file/store/iter.rs +++ b/gix-ref/tests/refs/file/store/iter.rs @@ -28,7 +28,7 @@ mod with_namespace { let ns_two = gix_ref::namespace::expand("bar")?; let namespaced_refs = store .iter()? - .prefixed(ns_two.as_bstr().into())? + .prefixed(ns_two.as_bstr())? .map(Result::unwrap) .map(|r: gix_ref::Reference| r.name) .collect::>(); @@ -47,7 +47,7 @@ mod with_namespace { ); assert_eq!( store - .loose_iter_prefixed(ns_two.as_bstr().into())? + .loose_iter_prefixed(ns_two.as_bstr())? .map(Result::unwrap) .map(|r| r.name.into_inner()) .collect::>(), @@ -61,7 +61,7 @@ mod with_namespace { packed .as_ref() .expect("present") - .iter_prefixed(ns_two.as_bstr().into())? + .iter_prefixed(ns_two.as_bstr().to_owned())? .map(Result::unwrap) .map(|r| r.name.to_owned().into_inner()) .collect::>(), @@ -92,7 +92,7 @@ mod with_namespace { assert_eq!( store .iter()? - .prefixed(ns_one.as_bstr().into())? + .prefixed(ns_one.as_bstr())? .map(Result::unwrap) .map(|r: gix_ref::Reference| ( r.name.as_bstr().to_owned(), @@ -339,7 +339,7 @@ fn loose_iter_with_prefix() -> crate::Result { let store = store()?; let actual = store - .loose_iter_prefixed(b"refs/heads/".as_bstr().into())? + .loose_iter_prefixed(b"refs/heads/".as_bstr())? .collect::, _>>() .expect("no broken ref in this subset") .into_iter() @@ -369,7 +369,7 @@ fn loose_iter_with_partial_prefix_dir() -> crate::Result { let store = store()?; let actual = store - .loose_iter_prefixed(b"refs/heads".as_bstr().into())? + .loose_iter_prefixed(b"refs/heads".as_bstr())? .collect::, _>>() .expect("no broken ref in this subset") .into_iter() @@ -398,7 +398,7 @@ fn loose_iter_with_partial_prefix() -> crate::Result { let store = store()?; let actual = store - .loose_iter_prefixed(b"refs/heads/d".as_bstr().into())? + .loose_iter_prefixed(b"refs/heads/d".as_bstr())? .collect::, _>>() .expect("no broken ref in this subset") .into_iter() @@ -556,7 +556,7 @@ fn overlay_prefixed_iter() -> crate::Result { let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store .iter()? - .prefixed(b"refs/heads/".as_bstr().into())? + .prefixed(b"refs/heads/".as_bstr())? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); @@ -579,7 +579,7 @@ fn overlay_partial_prefix_iter() -> crate::Result { let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store .iter()? - .prefixed(b"refs/heads/m".as_bstr().into())? // 'm' is partial + .prefixed(b"refs/heads/m".as_bstr())? // 'm' is partial .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); @@ -597,7 +597,7 @@ fn overlay_partial_prefix_iter_reproduce_1934() -> crate::Result { let ref_names = store .iter()? - .prefixed(b"refs/d".as_bstr().into())? + .prefixed(b"refs/d".as_bstr())? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; // Should not match `refs/heads/d1`. @@ -615,7 +615,7 @@ fn overlay_partial_prefix_iter_when_prefix_is_dir() -> crate::Result { let ref_names = store .iter()? - .prefixed(b"refs/prefix/feature".as_bstr().into())? + .prefixed(b"refs/prefix/feature".as_bstr())? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; assert_eq!( @@ -628,7 +628,7 @@ fn overlay_partial_prefix_iter_when_prefix_is_dir() -> crate::Result { let ref_names = store .iter()? - .prefixed(b"refs/prefix/feature/".as_bstr().into())? + .prefixed(b"refs/prefix/feature/".as_bstr())? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; assert_eq!( diff --git a/gix-ref/tests/refs/file/worktree.rs b/gix-ref/tests/refs/file/worktree.rs index b537286021e..d59adb906af 100644 --- a/gix-ref/tests/refs/file/worktree.rs +++ b/gix-ref/tests/refs/file/worktree.rs @@ -291,7 +291,7 @@ mod writable { assert_eq!( store .iter()? - .prefixed(b"refs/stacks/".as_bstr().into())? + .prefixed(b"refs/stacks/".as_bstr())? .map(Result::unwrap) .map(|r| (r.name.to_string(), r.target.to_string())) .collect::>(), @@ -572,7 +572,7 @@ mod writable { assert_eq!( store .iter()? - .prefixed(b"refs/stacks/".as_bstr().into())? + .prefixed(b"refs/stacks/".as_bstr())? .map(Result::unwrap) .map(|r| (r.name.to_string(), r.target.to_string())) .collect::>(), diff --git a/gix/src/open/repository.rs b/gix/src/open/repository.rs index 4b04909a339..37094233c82 100644 --- a/gix/src/open/repository.rs +++ b/gix/src/open/repository.rs @@ -349,7 +349,7 @@ impl ThreadSafeRepository { .and_then(|prefix| { let _span = gix_trace::detail!("find replacement objects"); let platform = refs.iter().ok()?; - let iter = platform.prefixed(prefix.clone().into()).ok()?; + let iter = platform.prefixed(&prefix).ok()?; let replacements = iter .filter_map(Result::ok) .filter_map(|r: gix_ref::Reference| { diff --git a/gix/src/reference/iter.rs b/gix/src/reference/iter.rs index 5ba5ccf7c5b..576a81a785a 100644 --- a/gix/src/reference/iter.rs +++ b/gix/src/reference/iter.rs @@ -48,8 +48,8 @@ impl Platform<'_> { /// These are of the form `refs/heads/` or `refs/remotes/origin`, and must not contain relative paths components like `.` or `..`. // TODO: Create a custom `Path` type that enforces the requirements of git naturally, this type is surprising possibly on windows // and when not using a trailing '/' to signal directories. - pub fn prefixed(&self, prefix: Cow<'_, BStr>) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed(prefix)?)) + pub fn prefixed<'a>(&self, prefix: impl Into>) -> Result, init::Error> { + Ok(Iter::new(self.repo, self.platform.prefixed(prefix.into())?)) } // TODO: tests @@ -57,10 +57,7 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/tags`. pub fn tags(&self) -> Result, init::Error> { - Ok(Iter::new( - self.repo, - self.platform.prefixed(b"refs/tags/".as_bstr().into())?, - )) + Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/tags/".as_bstr())?)) } // TODO: tests @@ -68,10 +65,7 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/heads`. pub fn local_branches(&self) -> Result, init::Error> { - Ok(Iter::new( - self.repo, - self.platform.prefixed(b"refs/heads/".as_bstr().into())?, - )) + Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/heads/".as_bstr())?)) } // TODO: tests @@ -81,7 +75,7 @@ impl Platform<'_> { pub fn remote_branches(&self) -> Result, init::Error> { Ok(Iter::new( self.repo, - self.platform.prefixed(b"refs/remotes/".as_bstr().into())?, + self.platform.prefixed(b"refs/remotes/".as_bstr())?, )) } } diff --git a/gix/tests/gix/repository/reference.rs b/gix/tests/gix/repository/reference.rs index ae6f7a80b5a..bd5079aabfc 100644 --- a/gix/tests/gix/repository/reference.rs +++ b/gix/tests/gix/repository/reference.rs @@ -48,7 +48,7 @@ mod set_namespace { assert_eq!( repo.references()? - .prefixed(b"refs/tags/".as_bstr().into())? + .prefixed(b"refs/tags/".as_bstr())? .filter_map(Result::ok) .map(|r| r.name().as_bstr().to_owned()) .collect::>(), @@ -125,7 +125,7 @@ mod iter_references { let repo = repo()?; assert_eq!( repo.references()? - .prefixed(b"refs/heads/".as_bstr().into())? + .prefixed(b"refs/heads/".as_bstr())? .filter_map(Result::ok) .map(|r| ( r.name().as_bstr().to_string(), @@ -156,7 +156,7 @@ mod iter_references { let repo = repo()?; assert_eq!( repo.references()? - .prefixed(b"refs/heads/".as_bstr().into())? + .prefixed(b"refs/heads/".as_bstr())? .peeled()? .filter_map(Result::ok) .map(|r| ( From 3c008378edadf4e7a74aae9f4064d3458560e108 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Wed, 9 Apr 2025 14:08:57 -0400 Subject: [PATCH 075/193] Tell Dependabot not to use conventional commits Dependabot automatically examines existing commits' messages to decide what style to use, if no `commit.prefix` is configured. But gitoxide prefers that conventional commits be used only in limited circumstances: the "purposeful conventional commits" style detailed in `DEVELOPMENT.md`. Commits to bump dependencies should typically not be conventional, so Dependabot should not title its commits with prefixes that can be interpreted as meaningful conventional commits. But the style Dependabot has automatically picked here uses prefixes such as `build(deps): ...`. In practice this does not cause serious problems so far and is unlikely ever to cause serious problems, so it would be fine to use Dependabot even if this behavior couldn't be changed. But there are a few reasons to configure Dependabot not to do this: - Stylistic consistency. - Decrease the likelihood of future undesired behavior if we later expand the use of Dependabot, such as to enable version updates (rather than just security updates) on Rust dependencies, where it would more often affect changelogs due to far more often editing per-crate `Cargo.toml` files than it currently does. - Decrease the likelihood of future undesired behavior if a future version of `cargo-smart-release` treats more conventional commit prefixes specially. - Make commit messages slightly easier to read if one is familiar with the commit message style used in this repository. - Avoid giving newcomers the wrong idea about how and when commit messages in this project are expected to be conventional. Roughly speaking, this configures Dependabot not to use any prefix. There does not appear to be any way to suppress the use of a prefix to restore the exact same behavior as if Dependabot had detected not to use a prefix (in particular, setting `prefix` to `null` produces an error and Dependabot will not use the configuration). So this instead sets an empty string as the prefix. The difference between an empty prefix and no prefix, in terms of how Dependabot currently behaves for this repository, is that the commit message with an empty prefix does not start with a capital letter. But that is not a problem here, because we don't impose a stylistic preference as to whether to capitalize commit message titles; both styles are common, with the uncapitalized style being at least as common as the capitalized style. To ensure this configuration works as intended, it has been tested in a fork (where force-pushing main doesn't cause any disruption). See https://github.com/EliahKagan/gitoxide/pull/16 for details. --- .github/dependabot.yml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index cf081ea3ae5..3dd899d8350 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,12 +1,28 @@ version: 2 updates: - # We only use Dependabot *version* updates for GitHub Actions. Rust dependencies are checked via - # `cargo deny` and manually updated (see https://github.com/GitoxideLabs/gitoxide/issues/144), or - # by Dependabot *security* updates (which don't need the `cargo` ecosystem to be listed here). + # Only GitHub Actions dependencies receive Dependabot *version* updates. Rust dependencies are + # checked via `cargo deny` (https://github.com/GitoxideLabs/gitoxide/issues/144) and updated + # manually or via Dependabot *security* updates (which the restrictions here do not constrain). + - package-ecosystem: cargo + directory: '/' + schedule: + # We include this required key, but it only applies to version updates, which are suppressed. + interval: monthly + # Disable version updates for Rust dependencies. Security updates are still allowed. + open-pull-requests-limit: 0 + commit-message: + # Avoid non-"purposeful" prefix due to Dependabot misdetecting style (see `DEVELOPMENT.md`). + prefix: '' + groups: + cargo: + patterns: ['*'] - package-ecosystem: github-actions directory: '/' schedule: interval: weekly + commit-message: + # Avoid non-"purposeful" prefix due to Dependabot misdetecting style (see `DEVELOPMENT.md`). + prefix: '' groups: github-actions: patterns: ['*'] From c66814fcb5cfcd723963fe01d4a86ef51b0e4f62 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Wed, 9 Apr 2025 23:36:23 -0400 Subject: [PATCH 076/193] Use standard Apache-2.0 license file This uses the standard Apache-2.0 license file, available for download from https://www.apache.org/licenses/LICENSE-2.0.txt, as `LICENSE-APACHE`. The license text itself is unchanged, but this fixes the broken license appendix. The appendix is expressly not part of the licese terms, so probably nothing very bad would happen due to it, but it is better either to have the appendix, or to omit it entirely, than to have only some fragments of it. At the very beginning, gitoxide was licensed under only the MIT license. Early on, all contributors agreed to dual-license gitoxide under the MIT license and the Apache-2.0 license (#8), and an Apache-2.0 license file was added (ea353eb). The standard Apache-2.0 license file ends in an appendix that describes the usual way of explicitly applying it to code, which contains placeholders which are meant to be substituted if the boilerplate code is copied elsewhere, but not in the license file appendix itself. However, in ea353eb, the placeholders were substituted in the appendix in the license file itself, and the more instructional portion of the appendix was removed. This modification to the appendix, which created an unusual license file, may have been done in order to put the copyright notice somewhere where it would be specifically associated with the Apache-2.0 license option. After all, the boilerplate text wasn't (and intentionally continues not to be) used as a header in source code files as the appendix suggests. But this carried two problems: 1. It was potentially confusing with respect to the significance of that text, since it was not present anywhere a copyright notice would be expected, and came after "END OF TERMS AND CONDITIONS". 2. It had the potential to confuse tooling that processed licenses. One specific case of (2) is known, described in 76ae5d6 (#1232) where the license file was changed to remove it. (The MIT license file was also changed to remove the copyright notice, but it is unlikely that the MIT license file contributed to tooling problems, since the copyright line is expected in an MIT license file and is typically present.) That left fragments of the appendix in the Apache-2.0 license file, which no longer even attempts to give any information more specific than that which is present in the licese terms themselves. There are two good ways to fix the problem. One of them is to use the standard version of the Apache-2.0 license file, with the full original appendix with instructions and unsubstituted placeholders intact. That approach is followed here, since adding the missing pieces of the standard appendix makes clear what the current nonstandard fragment is from. (The other approach is to remove the appendix altogether, which is fine to do since it is expressly not part of the license terms, and which seems to be fairly popularly done among Rust projects. We may end up going with that, but for clarity it's not done just yet.) --- LICENSE-APACHE | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 016b1bc2e61..d6456956733 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -176,6 +176,19 @@ END OF TERMS AND CONDITIONS + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at From 519970de35964521114c9e98d10a3b3950607c83 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Thu, 10 Apr 2025 00:42:19 -0400 Subject: [PATCH 077/193] Use the Apache-2.0 license file without the appendix This removes the appendix from the Apache-2.0 license file. The license terms themselves are of course not modified. The license terms end in "END OF TERMS AND CONDITIONS", which is retained, and the appendix that follows it is removed. This follows the practice in most or all of the repositories owned by the Rust organization of using the Apache-2.0 license without the appendix, on the grounds that it is confusing to keep it, as the procedure described in the appendix for indicating that source code is licensed Apache-2.0 is not actually followed in those repositories: individual source code files are not being given Apache-2.0 license headers. Note that this is merely an issue of confusion; the appendix is not part of the terms of the license, and no permission or limitation depends on whether it is included. See https://github.com/rust-lang/rust/pull/67734 for details. Note that the license text itself must of course not be changed. But this does not change it: the appendix, while it was part of the license file, is expressly not part of the terms of the license. --- LICENSE-APACHE | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/LICENSE-APACHE b/LICENSE-APACHE index d6456956733..f433b1a53f5 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -175,28 +175,3 @@ of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. From 1792178cbed5abf4782370bc46207a8c5d113615 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Apr 2025 14:46:41 +0000 Subject: [PATCH 078/193] bump crossbeam-channel from 0.5.14 to 0.5.15 in the cargo group Bumps the cargo group with 1 update: [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam). Updates `crossbeam-channel` from 0.5.14 to 0.5.15 - [Release notes](https://github.com/crossbeam-rs/crossbeam/releases) - [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.14...crossbeam-channel-0.5.15) --- updated-dependencies: - dependency-name: crossbeam-channel dependency-version: 0.5.15 dependency-type: direct:production dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- gitoxide-core/Cargo.toml | 2 +- gix-features/Cargo.toml | 2 +- gix-fs/Cargo.toml | 2 +- gix-odb/tests/Cargo.toml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a54ce74272..31b24c2c3b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -762,9 +762,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] @@ -3654,7 +3654,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] diff --git a/gitoxide-core/Cargo.toml b/gitoxide-core/Cargo.toml index 6a255795d4d..100488eee07 100644 --- a/gitoxide-core/Cargo.toml +++ b/gitoxide-core/Cargo.toml @@ -75,7 +75,7 @@ jwalk = { version = "0.8.0", optional = true } # for 'hours' fs-err = { version = "2.6.0", optional = true } -crossbeam-channel = { version = "0.5.6", optional = true } +crossbeam-channel = { version = "0.5.15", optional = true } smallvec = { version = "1.10.0", optional = true } # for 'query' and 'corpus' diff --git a/gix-features/Cargo.toml b/gix-features/Cargo.toml index e38432028ee..aec82d7e8ea 100644 --- a/gix-features/Cargo.toml +++ b/gix-features/Cargo.toml @@ -110,7 +110,7 @@ gix-path = { version = "^0.10.15", path = "../gix-path", optional = true } gix-utils = { version = "^0.2.0", path = "../gix-utils", optional = true } # 'parallel' feature -crossbeam-channel = { version = "0.5.0", optional = true } +crossbeam-channel = { version = "0.5.15", optional = true } parking_lot = { version = "0.12.0", default-features = false, optional = true } walkdir = { version = "2.3.2", optional = true } # used when parallel is off diff --git a/gix-fs/Cargo.toml b/gix-fs/Cargo.toml index fda6c347bab..8c195ced6ab 100644 --- a/gix-fs/Cargo.toml +++ b/gix-fs/Cargo.toml @@ -30,6 +30,6 @@ serde = { version = "1.0.114", optional = true, default-features = false, featur fastrand = { version = "2.1.0", default-features = false, features = ["std"] } [dev-dependencies] -crossbeam-channel = "0.5.0" +crossbeam-channel = "0.5.15" is_ci = "1.1.1" tempfile = "3.5.0" diff --git a/gix-odb/tests/Cargo.toml b/gix-odb/tests/Cargo.toml index 7c8b8e560ad..770f751a728 100644 --- a/gix-odb/tests/Cargo.toml +++ b/gix-odb/tests/Cargo.toml @@ -31,4 +31,4 @@ gix-actor = { path = "../../gix-actor" } pretty_assertions = "1.0.0" filetime = "0.2.15" maplit = "1.0.2" -crossbeam-channel = "0.5.13" +crossbeam-channel = "0.5.15" From 75b842b13cc4a17acfd3419263aa1520df10fb01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20R=C3=BC=C3=9Fler?= Date: Thu, 10 Apr 2025 16:48:17 +0200 Subject: [PATCH 079/193] Replace BTreeMap by SmallVec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A `SmallVec` provides a better trade-off with respect to performance than a `BTreeMap` because `suspects` in most cases only contains 1 item. The cost of calling `BTreeMap::insert` and `BTreeMap::remove` becomes noticeable in profiling the longer a blame’s history gets and the more hunks a file is split into. --- gix-blame/src/file/function.rs | 4 ++-- gix-blame/src/file/mod.rs | 34 +++++++++++++++++++++------------- gix-blame/src/types.rs | 25 +++++++++++++++++++------ 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/gix-blame/src/file/function.rs b/gix-blame/src/file/function.rs index d9299689c21..08d90b0127d 100644 --- a/gix-blame/src/file/function.rs +++ b/gix-blame/src/file/function.rs @@ -114,7 +114,7 @@ pub fn file( break; } - let is_still_suspect = hunks_to_blame.iter().any(|hunk| hunk.suspects.contains_key(&suspect)); + let is_still_suspect = hunks_to_blame.iter().any(|hunk| hunk.has_suspect(&suspect)); if !is_still_suspect { // There are no `UnblamedHunk`s associated with this `suspect`, so we can continue with // the next one. @@ -189,7 +189,7 @@ pub fn file( .collect(); for hunk in hunks_to_blame.iter() { - if let Some(range_in_suspect) = hunk.suspects.get(&suspect) { + if let Some(range_in_suspect) = hunk.get_range(&suspect) { let range_in_blamed_file = hunk.range_in_blamed_file.clone(); for (blamed_line_number, source_line_number) in range_in_blamed_file.zip(range_in_suspect.clone()) { diff --git a/gix-blame/src/file/mod.rs b/gix-blame/src/file/mod.rs index 668be563533..4783ab30b19 100644 --- a/gix-blame/src/file/mod.rs +++ b/gix-blame/src/file/mod.rs @@ -39,7 +39,7 @@ fn process_change( // 3. `change` *must* be returned if it is not fully included in `hunk`. match (hunk, change) { (Some(hunk), Some(Change::Unchanged(unchanged))) => { - let Some(range_in_suspect) = hunk.suspects.get(&suspect) else { + let Some(range_in_suspect) = hunk.get_range(&suspect) else { // We don’t clone blame to `parent` as `suspect` has nothing to do with this // `hunk`. new_hunks_to_blame.push(hunk); @@ -102,7 +102,7 @@ fn process_change( } } (Some(hunk), Some(Change::AddedOrReplaced(added, number_of_lines_deleted))) => { - let Some(range_in_suspect) = hunk.suspects.get(&suspect).cloned() else { + let Some(range_in_suspect) = hunk.get_range(&suspect).cloned() else { new_hunks_to_blame.push(hunk); return (None, Some(Change::AddedOrReplaced(added, number_of_lines_deleted))); }; @@ -247,7 +247,7 @@ fn process_change( } } (Some(hunk), Some(Change::Deleted(line_number_in_destination, number_of_lines_deleted))) => { - let Some(range_in_suspect) = hunk.suspects.get(&suspect) else { + let Some(range_in_suspect) = hunk.get_range(&suspect) else { new_hunks_to_blame.push(hunk); return ( None, @@ -359,12 +359,16 @@ fn process_changes( impl UnblamedHunk { fn shift_by(mut self, suspect: ObjectId, offset: Offset) -> Self { - self.suspects.entry(suspect).and_modify(|e| *e = e.shift_by(offset)); + if let Some(position) = self.suspects.iter().position(|entry| entry.0 == suspect) { + if let Some((_, ref mut range_in_suspect)) = self.suspects.get_mut(position) { + *range_in_suspect = range_in_suspect.shift_by(offset); + } + } self } fn split_at(self, suspect: ObjectId, line_number_in_destination: u32) -> Either { - match self.suspects.get(&suspect) { + match self.get_range(&suspect) { None => Either::Left(self), Some(range_in_suspect) => { if !range_in_suspect.contains(&line_number_in_destination) { @@ -405,34 +409,38 @@ impl UnblamedHunk { /// This is like [`Self::pass_blame()`], but easier to use in places where the 'passing' is /// done 'inline'. fn passed_blame(mut self, from: ObjectId, to: ObjectId) -> Self { - if let Some(range_in_suspect) = self.suspects.remove(&from) { - self.suspects.insert(to, range_in_suspect); + if let Some(position) = self.suspects.iter().position(|entry| entry.0 == from) { + if let Some((ref mut commit_id, _)) = self.suspects.get_mut(position) { + *commit_id = to; + } } self } /// Transfer all ranges from the commit at `from` to the commit at `to`. fn pass_blame(&mut self, from: ObjectId, to: ObjectId) { - if let Some(range_in_suspect) = self.suspects.remove(&from) { - self.suspects.insert(to, range_in_suspect); + if let Some(position) = self.suspects.iter().position(|entry| entry.0 == from) { + if let Some((ref mut commit_id, _)) = self.suspects.get_mut(position) { + *commit_id = to; + } } } fn clone_blame(&mut self, from: ObjectId, to: ObjectId) { - if let Some(range_in_suspect) = self.suspects.get(&from) { - self.suspects.insert(to, range_in_suspect.clone()); + if let Some(range_in_suspect) = self.get_range(&from) { + self.suspects.push((to, range_in_suspect.clone())); } } fn remove_blame(&mut self, suspect: ObjectId) { - self.suspects.remove(&suspect); + self.suspects.retain(|entry| entry.0 != suspect); } } impl BlameEntry { /// Create an offset from a portion of the *Blamed File*. fn from_unblamed_hunk(unblamed_hunk: &UnblamedHunk, commit_id: ObjectId) -> Option { - let range_in_source_file = unblamed_hunk.suspects.get(&commit_id)?; + let range_in_source_file = unblamed_hunk.get_range(&commit_id)?; Some(Self { start_in_blamed_file: unblamed_hunk.range_in_blamed_file.start, diff --git a/gix-blame/src/types.rs b/gix-blame/src/types.rs index 9f5bc7a528c..f7fdb6608d1 100644 --- a/gix-blame/src/types.rs +++ b/gix-blame/src/types.rs @@ -1,11 +1,9 @@ use crate::file::function::tokens_for_diffing; use gix_hash::ObjectId; use gix_object::bstr::BString; +use smallvec::SmallVec; use std::num::NonZeroU32; -use std::{ - collections::BTreeMap, - ops::{AddAssign, Range, SubAssign}, -}; +use std::ops::{AddAssign, Range, SubAssign}; /// Options to be passed to [`file()`](crate::file()). #[derive(Default, Debug, Clone)] @@ -198,8 +196,23 @@ impl LineRange for Range { pub struct UnblamedHunk { /// The range in the file that is being blamed that this hunk represents. pub range_in_blamed_file: Range, - /// Maps a commit to the range in a source file (i.e. *Blamed File* at a revision) that is equal to `range_in_blamed_file`. - pub suspects: BTreeMap>, + /// Maps a commit to the range in a source file (i.e. *Blamed File* at a revision) that is + /// equal to `range_in_blamed_file`. Since `suspects` rarely contains more than 1 item, it can + /// efficiently be stored as a `SmallVec`. + pub suspects: SmallVec<[(ObjectId, Range); 1]>, +} + +impl UnblamedHunk { + pub(crate) fn has_suspect(&self, suspect: &ObjectId) -> bool { + self.suspects.iter().any(|entry| entry.0 == *suspect) + } + + pub(crate) fn get_range(&self, suspect: &ObjectId) -> Option<&Range> { + self.suspects + .iter() + .find(|entry| entry.0 == *suspect) + .map(|entry| &entry.1) + } } #[derive(Debug)] From db480e740d9271cc0cb47097136fcf302af64837 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Wed, 9 Apr 2025 23:16:57 -0400 Subject: [PATCH 080/193] Enable grouped Dependabot version updates for Rust This enables Dependabot version updates for Rust dependencies, with all such updates grouped into a single PR, on a monthly cadence. When Dependabot version updates for Rust dependencies (i.e. the `cargo` ecosystem) were turned off in 5f2d28e for #144, Dependabot did not yet support grouped version updates. Clustering all the PRs to occur together once per month was possible, and it was considered and decided to be unsuitable, but that is different from a single PR to update multiple dependencies. The comment https://github.com/GitoxideLabs/gitoxide/discussions/143#discussioncomment-1089296 noted: > [...] bundling its updates and making it once a month or even > less often would be the preferred mode of operation. > > Right now I would be hesitant to change the schedule interval in > fear of an onslaught of PRs every month. > > On the other hand, there may be value in seeing each PR as it > contains release notes and changes[...] Using *grouped* Dependabot version updates satisfies each of those points: - The update PR can be set to occur once a month. (This is furthermore independent of the cadence for other ecosystems; it does not require that GitHub Actions version updates be only once a month.) - It is a single PR for all updates in the `cargo` ecosystems, not an onslaught of multiple PRs, so long as it is configured with a single group with which the exhaustive pattern `*` is associated. - The Dependabot pull request description includes any and all of release notes, changelogs, and commits since the release being upgraded from, for *each* of the dependencies being upgraded. Because we already have Dependabot security updates enabled, which are created immediately for any security advisory where Dependabot can upgrade the dependency, it should not be a problem to configure Dependabot version updates on a monthly cadence. This will include updates with breaking changes, so long as they're consistent with explicitly declared MSRV and other constraints. This shouldn't cause a problem, since CI is fairly robust, and will thus detect most breakages. When it is necessary to make changes to adapt to new versions, changes can be committed to the Dependabot feature branch for the PR (or other techniques can be used). To see what the first Dependabot PR after these changes is likely to look like, as well as what kind of commits to its feature branch are likely to fix it up to be ready to merge, see this experiment in a fork: https://github.com/EliahKagan/gitoxide/pull/18 --- .github/dependabot.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3dd899d8350..f3c7773dbfe 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,15 +1,9 @@ version: 2 updates: - # Only GitHub Actions dependencies receive Dependabot *version* updates. Rust dependencies are - # checked via `cargo deny` (https://github.com/GitoxideLabs/gitoxide/issues/144) and updated - # manually or via Dependabot *security* updates (which the restrictions here do not constrain). - package-ecosystem: cargo directory: '/' schedule: - # We include this required key, but it only applies to version updates, which are suppressed. interval: monthly - # Disable version updates for Rust dependencies. Security updates are still allowed. - open-pull-requests-limit: 0 commit-message: # Avoid non-"purposeful" prefix due to Dependabot misdetecting style (see `DEVELOPMENT.md`). prefix: '' From 68e6b2e54613fe788d645ea8c942c71a39c6ede1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Apr 2025 02:10:19 +0000 Subject: [PATCH 081/193] Bump the cargo group with 21 updates Bumps the cargo group with 21 updates: | Package | From | To | | --- | --- | --- | | [clap](https://github.com/clap-rs/clap) | `4.5.32` | `4.5.35` | | [clap_complete](https://github.com/clap-rs/clap) | `4.5.46` | `4.5.47` | | [env_logger](https://github.com/rust-cli/env_logger) | `0.10.2` | `0.11.8` | | [terminal_size](https://github.com/eminence/terminal-size) | `0.3.0` | `0.4.2` | | [once_cell](https://github.com/matklad/once_cell) | `1.21.1` | `1.21.3` | | [bstr](https://github.com/BurntSushi/bstr) | `1.11.3` | `1.12.0` | | [winnow](https://github.com/winnow-rs/winnow) | `0.7.4` | `0.7.6` | | [faster-hex](https://github.com/NervosFoundation/faster-hex) | `0.9.0` | `0.10.0` | | [smallvec](https://github.com/servo/rust-smallvec) | `1.14.0` | `1.15.0` | | [tempfile](https://github.com/Stebalien/tempfile) | `3.19.0` | `3.19.1` | | [bytesize](https://github.com/bytesize-rs/bytesize) | `1.3.2` | `2.0.1` | | [flate2](https://github.com/rust-lang/flate2-rs) | `1.1.0` | `1.1.1` | | [jiff](https://github.com/BurntSushi/jiff) | `0.2.4` | `0.2.6` | | [rustix](https://github.com/bytecodealliance/rustix) | `0.38.44` | `1.0.3` | | [windows-sys](https://github.com/microsoft/windows-rs) | `0.52.0` | `0.59.0` | | [windows](https://github.com/microsoft/windows-rs) | `0.58.0` | `0.61.1` | | [winreg](https://github.com/gentoo90/winreg-rs) | `0.52.0` | `0.55.0` | | [fs-err](https://github.com/andrewhickman/fs-err) | `2.11.0` | `3.1.0` | | [rusqlite](https://github.com/rusqlite/rusqlite) | `0.32.1` | `0.34.0` | | [sysinfo](https://github.com/GuillaumeGomez/sysinfo) | `0.31.4` | `0.34.2` | | [zip](https://github.com/zip-rs/zip2) | `2.4.2` | `2.6.1` | Updates `clap` from 4.5.32 to 4.5.35 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.32...clap_complete-v4.5.35) Updates `clap_complete` from 4.5.46 to 4.5.47 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.46...clap_complete-v4.5.47) Updates `env_logger` from 0.10.2 to 0.11.8 - [Release notes](https://github.com/rust-cli/env_logger/releases) - [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-cli/env_logger/compare/v0.10.2...v0.11.8) Updates `terminal_size` from 0.3.0 to 0.4.2 - [Release notes](https://github.com/eminence/terminal-size/releases) - [Commits](https://github.com/eminence/terminal-size/compare/v0.3.0...v0.4.2) Updates `once_cell` from 1.21.1 to 1.21.3 - [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md) - [Commits](https://github.com/matklad/once_cell/compare/v1.21.1...v1.21.3) Updates `bstr` from 1.11.3 to 1.12.0 - [Commits](https://github.com/BurntSushi/bstr/compare/1.11.3...1.12.0) Updates `winnow` from 0.7.4 to 0.7.6 - [Changelog](https://github.com/winnow-rs/winnow/blob/main/CHANGELOG.md) - [Commits](https://github.com/winnow-rs/winnow/compare/v0.7.4...v0.7.6) Updates `faster-hex` from 0.9.0 to 0.10.0 - [Changelog](https://github.com/nervosnetwork/faster-hex/blob/master/CHANGELOG.md) - [Commits](https://github.com/NervosFoundation/faster-hex/commits) Updates `smallvec` from 1.14.0 to 1.15.0 - [Release notes](https://github.com/servo/rust-smallvec/releases) - [Commits](https://github.com/servo/rust-smallvec/compare/v1.14.0...v1.15.0) Updates `tempfile` from 3.19.0 to 3.19.1 - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.19.0...v3.19.1) Updates `bytesize` from 1.3.2 to 2.0.1 - [Release notes](https://github.com/bytesize-rs/bytesize/releases) - [Changelog](https://github.com/bytesize-rs/bytesize/blob/master/CHANGELOG.md) - [Commits](https://github.com/bytesize-rs/bytesize/compare/v1.3.2...bytesize-v2.0.1) Updates `flate2` from 1.1.0 to 1.1.1 - [Release notes](https://github.com/rust-lang/flate2-rs/releases) - [Commits](https://github.com/rust-lang/flate2-rs/compare/1.1.0...1.1.1) Updates `jiff` from 0.2.4 to 0.2.6 - [Release notes](https://github.com/BurntSushi/jiff/releases) - [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md) - [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.4...jiff-static-0.2.6) Updates `rustix` from 0.38.44 to 1.0.3 - [Release notes](https://github.com/bytecodealliance/rustix/releases) - [Changelog](https://github.com/bytecodealliance/rustix/blob/main/CHANGES.md) - [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.44...v1.0.3) Updates `windows-sys` from 0.52.0 to 0.59.0 - [Release notes](https://github.com/microsoft/windows-rs/releases) - [Commits](https://github.com/microsoft/windows-rs/compare/0.52.0...0.59.0) Updates `windows` from 0.58.0 to 0.61.1 - [Release notes](https://github.com/microsoft/windows-rs/releases) - [Commits](https://github.com/microsoft/windows-rs/commits) Updates `winreg` from 0.52.0 to 0.55.0 - [Release notes](https://github.com/gentoo90/winreg-rs/releases) - [Changelog](https://github.com/gentoo90/winreg-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/gentoo90/winreg-rs/compare/v0.52.0...v0.55.0) Updates `fs-err` from 2.11.0 to 3.1.0 - [Changelog](https://github.com/andrewhickman/fs-err/blob/main/CHANGELOG.md) - [Commits](https://github.com/andrewhickman/fs-err/compare/2.11.0...3.1.0) Updates `rusqlite` from 0.32.1 to 0.34.0 - [Release notes](https://github.com/rusqlite/rusqlite/releases) - [Changelog](https://github.com/rusqlite/rusqlite/blob/master/Changelog.md) - [Commits](https://github.com/rusqlite/rusqlite/compare/v0.32.1...v0.34.0) Updates `sysinfo` from 0.31.4 to 0.34.2 - [Changelog](https://github.com/GuillaumeGomez/sysinfo/blob/master/CHANGELOG.md) - [Commits](https://github.com/GuillaumeGomez/sysinfo/commits) Updates `zip` from 2.4.2 to 2.6.1 - [Release notes](https://github.com/zip-rs/zip2/releases) - [Changelog](https://github.com/zip-rs/zip2/blob/master/CHANGELOG.md) - [Commits](https://github.com/zip-rs/zip2/compare/v2.4.2...v2.6.1) --- updated-dependencies: - dependency-name: clap dependency-version: 4.5.35 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap_complete dependency-version: 4.5.47 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: env_logger dependency-version: 0.11.8 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: terminal_size dependency-version: 0.4.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: once_cell dependency-version: 1.21.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: bstr dependency-version: 1.12.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: winnow dependency-version: 0.7.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: faster-hex dependency-version: 0.10.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: smallvec dependency-version: 1.15.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: tempfile dependency-version: 3.19.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: bytesize dependency-version: 2.0.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: cargo - dependency-name: flate2 dependency-version: 1.1.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: jiff dependency-version: 0.2.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: rustix dependency-version: 1.0.3 dependency-type: direct:production update-type: version-update:semver-major dependency-group: cargo - dependency-name: windows-sys dependency-version: 0.59.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: windows dependency-version: 0.61.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: winreg dependency-version: 0.55.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: fs-err dependency-version: 3.1.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: cargo - dependency-name: rusqlite dependency-version: 0.34.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: sysinfo dependency-version: 0.34.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: zip dependency-version: 2.6.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 301 +++++++++++++++++----------- Cargo.toml | 10 +- gitoxide-core/Cargo.toml | 12 +- gix-actor/Cargo.toml | 4 +- gix-archive/Cargo.toml | 8 +- gix-attributes/Cargo.toml | 4 +- gix-blame/Cargo.toml | 2 +- gix-command/Cargo.toml | 4 +- gix-commitgraph/Cargo.toml | 2 +- gix-config-value/Cargo.toml | 2 +- gix-config/Cargo.toml | 8 +- gix-config/tests/Cargo.toml | 4 +- gix-credentials/Cargo.toml | 4 +- gix-date/Cargo.toml | 6 +- gix-diff/Cargo.toml | 2 +- gix-dir/Cargo.toml | 2 +- gix-discover/Cargo.toml | 4 +- gix-features/Cargo.toml | 8 +- gix-filter/Cargo.toml | 4 +- gix-fs/Cargo.toml | 4 +- gix-glob/Cargo.toml | 2 +- gix-hash/Cargo.toml | 2 +- gix-ignore/Cargo.toml | 2 +- gix-index/Cargo.toml | 6 +- gix-index/tests/Cargo.toml | 2 +- gix-lock/Cargo.toml | 2 +- gix-mailmap/Cargo.toml | 2 +- gix-merge/Cargo.toml | 2 +- gix-negotiate/Cargo.toml | 2 +- gix-object/Cargo.toml | 6 +- gix-odb/Cargo.toml | 2 +- gix-pack/Cargo.toml | 2 +- gix-pack/tests/Cargo.toml | 2 +- gix-packetline-blocking/Cargo.toml | 4 +- gix-packetline/Cargo.toml | 4 +- gix-path/Cargo.toml | 8 +- gix-pathspec/Cargo.toml | 4 +- gix-prompt/Cargo.toml | 2 +- gix-protocol/Cargo.toml | 4 +- gix-quote/Cargo.toml | 2 +- gix-ref/Cargo.toml | 2 +- gix-refspec/Cargo.toml | 4 +- gix-revision/Cargo.toml | 2 +- gix-revwalk/Cargo.toml | 2 +- gix-sec/Cargo.toml | 4 +- gix-shallow/Cargo.toml | 2 +- gix-status/Cargo.toml | 2 +- gix-status/tests/Cargo.toml | 2 +- gix-submodule/Cargo.toml | 2 +- gix-tempfile/Cargo.toml | 4 +- gix-transport/Cargo.toml | 2 +- gix-traverse/Cargo.toml | 2 +- gix-url/Cargo.toml | 2 +- gix-utils/Cargo.toml | 2 +- gix-validate/Cargo.toml | 2 +- gix-worktree-state/Cargo.toml | 2 +- gix-worktree-state/tests/Cargo.toml | 2 +- gix-worktree/Cargo.toml | 2 +- gix-worktree/tests/Cargo.toml | 2 +- gix/Cargo.toml | 4 +- tests/it/Cargo.toml | 4 +- tests/tools/Cargo.toml | 8 +- 62 files changed, 294 insertions(+), 223 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31b24c2c3b7..4ec7eaf2246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -406,9 +406,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.3" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", "regex-automata", @@ -421,6 +421,12 @@ version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.10.1" @@ -429,9 +435,15 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "bytesize" -version = "1.3.2" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" + +[[package]] +name = "bytesize" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2c12f985c78475a6b8d629afd0c360260ef34cfef52efccdcfd31972f81c2e" +checksum = "a3c8f83209414aacf0eeae3cf730b18d6981697fba62f200fcfb92b9f082acba" dependencies = [ "serde", ] @@ -541,9 +553,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.32" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", "clap_derive", @@ -551,9 +563,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.32" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstream", "anstyle", @@ -563,9 +575,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.46" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5c5508ea23c5366f77e53f5a0070e5a84e51687ec3ef9e0464c86dc8d13ce98" +checksum = "c06f5378ea264ad4f82bbc826628b5aad714a75abf6ece087e923010eb937fb6" dependencies = [ "clap", ] @@ -995,16 +1007,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", +] + [[package]] name = "env_logger" -version = "0.10.2" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" dependencies = [ - "humantime", - "is-terminal", + "anstream", + "anstyle", + "env_filter", + "jiff", "log", - "termcolor", ] [[package]] @@ -1079,7 +1101,14 @@ name = "faster-hex" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" + +[[package]] +name = "faster-hex" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7223ae2d2f179b803433d9c830478527e92b8117eab39460edae7f1614d9fb73" dependencies = [ + "heapless", "serde", ] @@ -1103,9 +1132,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "libz-ng-sys", @@ -1152,9 +1181,9 @@ dependencies = [ [[package]] name = "fs-err" -version = "2.11.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +checksum = "1f89bda4c2a21204059a977ed3bfe746677dfd137b83c339e702b0ac91d482aa" dependencies = [ "autocfg", ] @@ -1331,7 +1360,7 @@ dependencies = [ "async-net", "async-trait", "blocking", - "bytesize", + "bytesize 2.0.1", "crossbeam-channel", "document-features", "fs-err", @@ -1462,7 +1491,7 @@ dependencies = [ "pretty_assertions", "serde", "thiserror 2.0.12", - "winnow 0.7.4", + "winnow 0.7.6", ] [[package]] @@ -1641,7 +1670,7 @@ dependencies = [ "smallvec", "thiserror 2.0.12", "unicode-bom", - "winnow 0.7.4", + "winnow 0.7.6", ] [[package]] @@ -1649,7 +1678,7 @@ name = "gix-config-tests" version = "0.0.0" dependencies = [ "bstr", - "bytesize", + "bytesize 2.0.1", "cap", "gix-config", "gix-path 0.10.15", @@ -1840,7 +1869,7 @@ version = "0.41.1" dependencies = [ "bstr", "bytes", - "bytesize", + "bytesize 2.0.1", "crc32fast", "crossbeam-channel", "document-features", @@ -1951,7 +1980,7 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93d7df7366121b5018f947a04d37f034717e113dcf9ccd85c34b58e57a74d5e" dependencies = [ - "faster-hex", + "faster-hex 0.9.0", "thiserror 1.0.69", ] @@ -1960,7 +1989,7 @@ name = "gix-hash" version = "0.17.0" dependencies = [ "document-features", - "faster-hex", + "faster-hex 0.10.0", "gix-features 0.41.1", "gix-testtools", "serde", @@ -2067,7 +2096,7 @@ dependencies = [ "itoa", "libc", "memmap2", - "rustix 0.38.44", + "rustix 1.0.3", "serde", "smallvec", "thiserror 2.0.12", @@ -2228,7 +2257,7 @@ dependencies = [ "smallvec", "termtree", "thiserror 2.0.12", - "winnow 0.7.4", + "winnow 0.7.6", ] [[package]] @@ -2317,7 +2346,7 @@ dependencies = [ "async-std", "bstr", "document-features", - "faster-hex", + "faster-hex 0.10.0", "futures-io", "futures-lite", "gix-hash 0.17.0", @@ -2336,7 +2365,7 @@ version = "0.18.3" dependencies = [ "bstr", "document-features", - "faster-hex", + "faster-hex 0.10.0", "gix-trace 0.1.12", "serde", "thiserror 2.0.12", @@ -2367,7 +2396,7 @@ dependencies = [ "once_cell", "serial_test", "thiserror 2.0.12", - "windows 0.58.0", + "windows 0.61.1", "winreg", ] @@ -2396,7 +2425,7 @@ dependencies = [ "gix-config-value", "gix-testtools", "parking_lot", - "rustix 0.38.44", + "rustix 1.0.3", "serial_test", "thiserror 2.0.12", ] @@ -2429,7 +2458,7 @@ dependencies = [ "maybe-async", "serde", "thiserror 2.0.12", - "winnow 0.7.4", + "winnow 0.7.6", ] [[package]] @@ -2498,7 +2527,7 @@ dependencies = [ "memmap2", "serde", "thiserror 2.0.12", - "winnow 0.7.4", + "winnow 0.7.6", ] [[package]] @@ -2605,7 +2634,7 @@ dependencies = [ "libc", "serde", "tempfile", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2734,7 +2763,7 @@ dependencies = [ "serial_test", "tar", "tempfile", - "winnow 0.7.4", + "winnow 0.7.6", "xz2", ] @@ -3050,6 +3079,15 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -3073,11 +3111,21 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.14.5", + "hashbrown 0.15.2", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", ] [[package]] @@ -3153,12 +3201,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c3b1f728c459d27b12448862017b96ad4767b1ec2ec5e6434e99f1577f085b8" -[[package]] -name = "humantime" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" - [[package]] name = "hyper" version = "1.6.0" @@ -3507,9 +3549,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d699bc6dfc879fb1bf9bdff0d4c56f0884fc6f0d0eb0fba397a6d00cd9a6b85e" +checksum = "1f33145a5cbea837164362c7bd596106eb7c5198f97d1ba6f6ebb3223952e488" dependencies = [ "jiff-static", "jiff-tzdb-platform", @@ -3522,9 +3564,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d16e75759ee0aa64c57a56acbf43916987b20c77373cb7e808979e02b93c9f9" +checksum = "43ce13c40ec6956157a3635d97a1ee2df323b263f09ea14165131289cb0f5c19" dependencies = [ "proc-macro2", "quote", @@ -3533,15 +3575,15 @@ dependencies = [ [[package]] name = "jiff-tzdb" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "962e1dfe9b2d75a84536cf5bf5eaaa4319aa7906c7160134a22883ac316d5f31" +checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" [[package]] name = "jiff-tzdb-platform" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a63c62e404e7b92979d2792352d885a7f8f83fd1d0d31eea582d77b2ceca697e" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" dependencies = [ "jiff-tzdb", ] @@ -3670,9 +3712,9 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.30.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +checksum = "fbb8270bb4060bd76c6e96f20c52d80620f1d82a3470885694e41e0f81ef6fe7" dependencies = [ "cc", "pkg-config", @@ -3691,9 +3733,9 @@ dependencies = [ [[package]] name = "libz-rs-sys" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "902bc563b5d65ad9bba616b490842ef0651066a1a1dc3ce1087113ffcb873c8d" +checksum = "6489ca9bd760fe9642d7644e827b0c9add07df89857b0416ee15c1cc1a3b8c5a" dependencies = [ "zlib-rs", ] @@ -3973,6 +4015,15 @@ dependencies = [ "libc", ] +[[package]] +name = "objc2-core-foundation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daeaf60f25471d26948a1c2f840e3f7d86f4109e3af4e8e4b5cd70c39690d925" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "object" version = "0.36.7" @@ -3984,9 +4035,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" @@ -4272,7 +4323,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ee7ce24c980b976607e2d6ae4aae92827994d23fed71659c3ede3f92528b58b" dependencies = [ "async-io", - "bytesize", + "bytesize 1.3.3", "crosstermion", "futures-core", "futures-lite", @@ -4540,9 +4591,9 @@ dependencies = [ [[package]] name = "rusqlite" -version = "0.32.1" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" +checksum = "37e34486da88d8e051c7c0e23c3f15fd806ea8546260aa2fec247e97242ec143" dependencies = [ "bitflags 2.9.0", "fallible-iterator", @@ -4962,9 +5013,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" dependencies = [ "serde", ] @@ -5085,14 +5136,14 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.31.4" +version = "0.34.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be" +checksum = "a4b93974b3d3aeaa036504b8eefd4c039dced109171c1ae973f1dc63b2c7e4b2" dependencies = [ - "core-foundation-sys", "libc", "memchr", "ntapi", + "objc2-core-foundation", "windows 0.57.0", ] @@ -5136,9 +5187,9 @@ checksum = "1ac9aa371f599d22256307c24a9d748c041e548cbf599f35d890f9d365361790" [[package]] name = "tempfile" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ "fastrand", "getrandom 0.3.2", @@ -5158,12 +5209,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" dependencies = [ - "rustix 0.38.44", - "windows-sys 0.48.0", + "rustix 1.0.3", + "windows-sys 0.59.0", ] [[package]] @@ -5369,7 +5420,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.7.4", + "winnow 0.7.6", ] [[package]] @@ -5818,12 +5869,24 @@ dependencies = [ [[package]] name = "windows" -version = "0.58.0" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", + "windows-collections", + "windows-core 0.61.0", + "windows-future", + "windows-link", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.0", ] [[package]] @@ -5840,15 +5903,25 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.58.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-implement 0.58.0", - "windows-interface 0.58.0", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", + "windows-implement 0.60.0", + "windows-interface 0.59.1", + "windows-link", + "windows-result 0.3.2", + "windows-strings 0.4.0", +] + +[[package]] +name = "windows-future" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32" +dependencies = [ + "windows-core 0.61.0", + "windows-link", ] [[package]] @@ -5864,9 +5937,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.58.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", @@ -5886,9 +5959,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.58.0" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", @@ -5901,6 +5974,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.0", + "windows-link", +] + [[package]] name = "windows-registry" version = "0.4.0" @@ -5921,15 +6004,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-result" version = "0.3.2" @@ -5941,19 +6015,18 @@ dependencies = [ [[package]] name = "windows-strings" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", + "windows-link", ] [[package]] name = "windows-strings" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" dependencies = [ "windows-link", ] @@ -6238,21 +6311,21 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.52.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -6416,26 +6489,24 @@ dependencies = [ [[package]] name = "zip" -version = "2.4.2" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" +checksum = "1dcb24d0152526ae49b9b96c1dcf71850ca1e0b882e4e28ed898a93c41334744" dependencies = [ "arbitrary", "crc32fast", "crossbeam-utils", - "displaydoc", "flate2", "indexmap", "memchr", - "thiserror 2.0.12", "zopfli", ] [[package]] name = "zlib-rs" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b20717f0917c908dc63de2e44e97f1e6b126ca58d0e391cee86d504eb8fbd05" +checksum = "868b928d7949e09af2f6086dfc1e01936064cc7a819253bce650d4e2a2d63ba8" [[package]] name = "zopfli" diff --git a/Cargo.toml b/Cargo.toml index a22f1745259..63ea2709837 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -171,11 +171,11 @@ gitoxide-core = { version = "^0.46.0", path = "gitoxide-core" } gix-features = { version = "^0.41.1", path = "gix-features" } gix = { version = "^0.71.0", path = "gix", default-features = false } -clap = { version = "4.1.1", features = ["derive", "cargo"] } -clap_complete = "4.4.3" +clap = { version = "4.5.35", features = ["derive", "cargo"] } +clap_complete = "4.5.47" prodash = { version = "29.0.1", optional = true } is-terminal = { version = "0.4.0", optional = true } -env_logger = { version = "0.10.0", default-features = false } +env_logger = { version = "0.11.8", default-features = false } crosstermion = { version = "0.14.0", optional = true, default-features = false } futures-lite = { version = "2.1.0", optional = true } @@ -185,12 +185,12 @@ tracing-subscriber = { version = "0.3.17", optional = true } tracing = { version = "0.1.37", optional = true } # for config-tree -terminal_size = "0.3.0" +terminal_size = "0.4.2" # Avoid pre-compiled binaries, see https://github.com/serde-rs/serde/issues/2538 and https://github.com/serde-rs/serde/pull/2590 serde_derive = ">=1.0.185" -once_cell = "1.18.0" +once_cell = "1.21.3" document-features = { version = "0.2.0", optional = true } [profile.dev.package] insta.opt-level = 3 diff --git a/gitoxide-core/Cargo.toml b/gitoxide-core/Cargo.toml index 100488eee07..32fe4238f2d 100644 --- a/gitoxide-core/Cargo.toml +++ b/gitoxide-core/Cargo.toml @@ -58,8 +58,8 @@ gix-fsck = { version = "^0.10.0", path = "../gix-fsck" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } anyhow = "1.0.42" thiserror = "2.0.0" -bytesize = "1.0.1" -tempfile = "3.1.0" +bytesize = "2.0.1" +tempfile = "3.19.1" # for async-client async-trait = { version = "0.1.51", optional = true } @@ -74,16 +74,16 @@ gix-url = { version = "^0.30.0", path = "../gix-url", optional = true } jwalk = { version = "0.8.0", optional = true } # for 'hours' -fs-err = { version = "2.6.0", optional = true } +fs-err = { version = "3.1.0", optional = true } crossbeam-channel = { version = "0.5.15", optional = true } -smallvec = { version = "1.10.0", optional = true } +smallvec = { version = "1.15.0", optional = true } # for 'query' and 'corpus' -rusqlite = { version = "0.32.1", optional = true, features = ["bundled"] } +rusqlite = { version = "0.34.0", optional = true, features = ["bundled"] } # for 'corpus' parking_lot = { version = "0.12.1", optional = true } -sysinfo = { version = "0.31.2", optional = true, default-features = false, features = ["system"] } +sysinfo = { version = "0.34.2", optional = true, default-features = false, features = ["system"] } serde_json = { version = "1.0.65", optional = true } tracing-forest = { version = "0.1.5", features = ["serde"], optional = true } tracing-subscriber = { version = "0.3.17", optional = true } diff --git a/gix-actor/Cargo.toml b/gix-actor/Cargo.toml index 4a5b13fc2cb..56c0b1e388a 100644 --- a/gix-actor/Cargo.toml +++ b/gix-actor/Cargo.toml @@ -23,11 +23,11 @@ gix-date = { version = "^0.9.4", path = "../gix-date" } gix-utils = { version = "^0.2.0", path = "../gix-utils" } thiserror = "2.0.0" -bstr = { version = "1.3.0", default-features = false, features = [ +bstr = { version = "1.12.0", default-features = false, features = [ "std", "unicode", ] } -winnow = { version = "0.7.0", features = ["simd"] } +winnow = { version = "0.7.6", features = ["simd"] } itoa = "1.0.1" serde = { version = "1.0.114", optional = true, default-features = false, features = [ "derive", diff --git a/gix-archive/Cargo.toml b/gix-archive/Cargo.toml index b69f0310835..822dfe8385d 100644 --- a/gix-archive/Cargo.toml +++ b/gix-archive/Cargo.toml @@ -32,14 +32,14 @@ gix-object = { version = "^0.48.0", path = "../gix-object" } gix-path = { version = "^0.10.15", path = "../gix-path", optional = true } gix-date = { version = "^0.9.4", path = "../gix-date" } -flate2 = { version = "1.0.33", optional = true } -zip = { version = "2.3.0", optional = true, default-features = false, features = [ +flate2 = { version = "1.1.1", optional = true } +zip = { version = "2.6.1", optional = true, default-features = false, features = [ "deflate", ] } -jiff = { version = "0.2.0", default-features = false, features = ["std"] } +jiff = { version = "0.2.6", default-features = false, features = ["std"] } thiserror = "2.0.0" -bstr = { version = "1.5.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } tar = { version = "0.4.38", optional = true } diff --git a/gix-attributes/Cargo.toml b/gix-attributes/Cargo.toml index 3cce82c9d0b..f48c561e51c 100644 --- a/gix-attributes/Cargo.toml +++ b/gix-attributes/Cargo.toml @@ -24,8 +24,8 @@ gix-quote = { version = "^0.5.0", path = "../gix-quote" } gix-glob = { version = "^0.19.0", path = "../gix-glob" } gix-trace = { version = "^0.1.12", path = "../gix-trace" } -bstr = { version = "1.3.0", default-features = false, features = ["std", "unicode"] } -smallvec = "1.10.0" +bstr = { version = "1.12.0", default-features = false, features = ["std", "unicode"] } +smallvec = "1.15.0" kstring = "2.0.0" unicode-bom = { version = "2.0.3" } thiserror = "2.0.0" diff --git a/gix-blame/Cargo.toml b/gix-blame/Cargo.toml index 42392624009..604b439f216 100644 --- a/gix-blame/Cargo.toml +++ b/gix-blame/Cargo.toml @@ -24,7 +24,7 @@ gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-worktree = { version = "^0.40.0", path = "../gix-worktree", default-features = false, features = ["attributes"] } gix-traverse = { version = "^0.45.0", path = "../gix-traverse" } -smallvec = "1.10.0" +smallvec = "1.15.0" thiserror = "2.0.0" [dev-dependencies] diff --git a/gix-command/Cargo.toml b/gix-command/Cargo.toml index afb89fb8317..273f11cf13f 100644 --- a/gix-command/Cargo.toml +++ b/gix-command/Cargo.toml @@ -19,9 +19,9 @@ gix-trace = { version = "^0.1.12", path = "../gix-trace" } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-quote = { version = "^0.5.0", path = "../gix-quote" } -bstr = { version = "1.5.0", default-features = false, features = ["std", "unicode"] } +bstr = { version = "1.12.0", default-features = false, features = ["std", "unicode"] } shell-words = "1.0" [dev-dependencies] gix-testtools = { path = "../tests/tools" } -once_cell = "1.17.1" +once_cell = "1.21.3" diff --git a/gix-commitgraph/Cargo.toml b/gix-commitgraph/Cargo.toml index 548d83dc6d2..4c03402bd11 100644 --- a/gix-commitgraph/Cargo.toml +++ b/gix-commitgraph/Cargo.toml @@ -23,7 +23,7 @@ serde = ["dep:serde", "gix-hash/serde", "bstr/serde"] gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-chunk = { version = "^0.4.11", path = "../gix-chunk" } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } memmap2 = "0.9.0" serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } thiserror = "2.0.0" diff --git a/gix-config-value/Cargo.toml b/gix-config-value/Cargo.toml index a864833cdb3..d9cc20755d2 100644 --- a/gix-config-value/Cargo.toml +++ b/gix-config-value/Cargo.toml @@ -22,7 +22,7 @@ serde = ["dep:serde", "bstr/serde"] gix-path = { version = "^0.10.15", path = "../gix-path" } thiserror = "2.0.0" -bstr = { version = "1.0.1", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } bitflags = "2" diff --git a/gix-config/Cargo.toml b/gix-config/Cargo.toml index 07a20a66fa6..5f177ced615 100644 --- a/gix-config/Cargo.toml +++ b/gix-config/Cargo.toml @@ -26,14 +26,14 @@ gix-sec = { version = "^0.10.12", path = "../gix-sec" } gix-ref = { version = "^0.51.0", path = "../gix-ref" } gix-glob = { version = "^0.19.0", path = "../gix-glob" } -winnow = { version = "0.7.0", features = ["simd"] } +winnow = { version = "0.7.6", features = ["simd"] } memchr = "2" thiserror = "2.0.0" unicode-bom = { version = "2.0.3" } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } -smallvec = "1.9.0" -once_cell = "1.14.0" +smallvec = "1.15.0" +once_cell = "1.21.3" document-features = { version = "0.2.0", optional = true } diff --git a/gix-config/tests/Cargo.toml b/gix-config/tests/Cargo.toml index 59a59cb9e89..c07492bd4b3 100644 --- a/gix-config/tests/Cargo.toml +++ b/gix-config/tests/Cargo.toml @@ -27,7 +27,7 @@ gix-ref = { path = "../../gix-ref" } gix-path = { path = "../../gix-path" } gix-sec = { path = "../../gix-sec" } serial_test = { version = "3.1.0", default-features = false } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } -bytesize = "1.3.0" +bytesize = "2.0.1" cap = { version = "0.1.2", features = ["stats"] } diff --git a/gix-credentials/Cargo.toml b/gix-credentials/Cargo.toml index dc43bb99ddc..20f6aefbd72 100644 --- a/gix-credentials/Cargo.toml +++ b/gix-credentials/Cargo.toml @@ -29,7 +29,7 @@ gix-trace = { version = "^0.1.12", path = "../gix-trace" } thiserror = "2.0.0" serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } @@ -38,7 +38,7 @@ document-features = { version = "0.2.1", optional = true } [dev-dependencies] gix-testtools = { path = "../tests/tools" } gix-sec = { path = "../gix-sec" } -once_cell = "1.19.0" +once_cell = "1.21.3" [package.metadata.docs.rs] all-features = true diff --git a/gix-date/Cargo.toml b/gix-date/Cargo.toml index ebf8642903d..22eaa94ff4c 100644 --- a/gix-date/Cargo.toml +++ b/gix-date/Cargo.toml @@ -19,10 +19,10 @@ doctest = false serde = ["dep:serde", "bstr/serde"] [dependencies] -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } itoa = "1.0.1" -jiff = "0.2.0" +jiff = "0.2.6" thiserror = "2.0.0" document-features = { version = "0.2.0", optional = true } @@ -30,7 +30,7 @@ document-features = { version = "0.2.0", optional = true } [dev-dependencies] gix-hash = { path = "../gix-hash" } gix-testtools = { path = "../tests/tools" } -once_cell = "1.12.0" +once_cell = "1.21.3" pretty_assertions = "1.4.1" [package.metadata.docs.rs] diff --git a/gix-diff/Cargo.toml b/gix-diff/Cargo.toml index 7ed05496650..718be7459ba 100644 --- a/gix-diff/Cargo.toml +++ b/gix-diff/Cargo.toml @@ -45,7 +45,7 @@ thiserror = "2.0.0" imara-diff = { version = "0.1.7", optional = true } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } getrandom = { version = "0.2.8", optional = true, default-features = false, features = ["js"] } -bstr = { version = "1.5.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } document-features = { version = "0.2.0", optional = true } diff --git a/gix-dir/Cargo.toml b/gix-dir/Cargo.toml index 80a888965fa..a98e1f4c799 100644 --- a/gix-dir/Cargo.toml +++ b/gix-dir/Cargo.toml @@ -26,7 +26,7 @@ gix-object = { version = "^0.48.0", path = "../gix-object" } gix-ignore = { version = "^0.14.0", path = "../gix-ignore" } gix-utils = { version = "^0.2.0", path = "../gix-utils", features = ["bstr"] } -bstr = { version = "1.5.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } thiserror = "2.0.0" [dev-dependencies] diff --git a/gix-discover/Cargo.toml b/gix-discover/Cargo.toml index 993cf007c3e..c11ba8b5f57 100644 --- a/gix-discover/Cargo.toml +++ b/gix-discover/Cargo.toml @@ -21,7 +21,7 @@ gix-ref = { version = "^0.51.0", path = "../gix-ref" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-fs = { version = "^0.14.0", path = "../gix-fs" } -bstr = { version = "1.3.0", default-features = false, features = ["std", "unicode"] } +bstr = { version = "1.12.0", default-features = false, features = ["std", "unicode"] } thiserror = "2.0.0" [target.'cfg(windows)'.dependencies] @@ -36,4 +36,4 @@ is_ci = "1.1.1" defer = "0.2.1" [target.'cfg(any(unix, windows))'.dev-dependencies] -tempfile = "3.2.0" +tempfile = "3.19.1" diff --git a/gix-features/Cargo.toml b/gix-features/Cargo.toml index aec82d7e8ea..4c94df39d81 100644 --- a/gix-features/Cargo.toml +++ b/gix-features/Cargo.toml @@ -120,16 +120,16 @@ crc32fast = { version = "1.2.1", optional = true } # progress prodash = { version = "29.0.1", optional = true } -bytesize = { version = "1.0.1", optional = true } +bytesize = { version = "2.0.1", optional = true } # pipe bytes = { version = "1.0.0", optional = true } # zlib module -flate2 = { version = "1.1.0", optional = true, default-features = false } +flate2 = { version = "1.1.1", optional = true, default-features = false } thiserror = { version = "2.0.0", optional = true } -once_cell = { version = "1.13.0", optional = true } +once_cell = { version = "1.21.3", optional = true } document-features = { version = "0.2.0", optional = true } @@ -137,7 +137,7 @@ document-features = { version = "0.2.0", optional = true } libc = { version = "0.2.119" } [dev-dependencies] -bstr = { version = "1.3.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } [package.metadata.docs.rs] all-features = true diff --git a/gix-filter/Cargo.toml b/gix-filter/Cargo.toml index f7b3de607f6..4da9dc273e2 100644 --- a/gix-filter/Cargo.toml +++ b/gix-filter/Cargo.toml @@ -26,9 +26,9 @@ gix-packetline-blocking = { version = "^0.18.3", path = "../gix-packetline-block gix-attributes = { version = "^0.25.0", path = "../gix-attributes" } encoding_rs = "0.8.32" -bstr = { version = "1.5.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } thiserror = "2.0.0" -smallvec = "1.10.0" +smallvec = "1.15.0" [dev-dependencies] diff --git a/gix-fs/Cargo.toml b/gix-fs/Cargo.toml index 8c195ced6ab..94226708d7a 100644 --- a/gix-fs/Cargo.toml +++ b/gix-fs/Cargo.toml @@ -19,7 +19,7 @@ doctest = false serde = ["dep:serde"] [dependencies] -bstr = "1.5.0" +bstr = "1.12.0" gix-path = { version = "^0.10.15", path = "../gix-path" } gix-features = { version = "^0.41.1", path = "../gix-features", features = ["fs-read-dir"] } gix-utils = { version = "^0.2.0", path = "../gix-utils" } @@ -32,4 +32,4 @@ fastrand = { version = "2.1.0", default-features = false, features = ["std"] } [dev-dependencies] crossbeam-channel = "0.5.15" is_ci = "1.1.1" -tempfile = "3.5.0" +tempfile = "3.19.1" diff --git a/gix-glob/Cargo.toml b/gix-glob/Cargo.toml index 94009462e12..5a9156c7407 100644 --- a/gix-glob/Cargo.toml +++ b/gix-glob/Cargo.toml @@ -21,7 +21,7 @@ serde = ["dep:serde", "bstr/serde", "bitflags/serde"] [dependencies] gix-path = { version = "^0.10.15", path = "../gix-path" } gix-features = { version = "^0.41.1", path = "../gix-features" } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } bitflags = "2" serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } diff --git a/gix-hash/Cargo.toml b/gix-hash/Cargo.toml index 89e06071865..d193c664852 100644 --- a/gix-hash/Cargo.toml +++ b/gix-hash/Cargo.toml @@ -23,7 +23,7 @@ serde = ["dep:serde"] gix-features = { version = "^0.41.1", path = "../gix-features", features = ["progress"] } thiserror = "2.0.0" -faster-hex = { version = "0.9.0" } +faster-hex = { version = "0.10.0" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } sha1-checked = { version = "0.10.0", default-features = false } diff --git a/gix-ignore/Cargo.toml b/gix-ignore/Cargo.toml index 88f737efd2e..41a1de8b7eb 100644 --- a/gix-ignore/Cargo.toml +++ b/gix-ignore/Cargo.toml @@ -23,7 +23,7 @@ gix-glob = { version = "^0.19.0", path = "../gix-glob" } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-trace = { version = "^0.1.12", path = "../gix-trace" } -bstr = { version = "1.3.0", default-features = false, features = ["std", "unicode"] } +bstr = { version = "1.12.0", default-features = false, features = ["std", "unicode"] } unicode-bom = { version = "2.0.3" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } diff --git a/gix-index/Cargo.toml b/gix-index/Cargo.toml index e860d4d4dcf..fbe2be3f1b6 100644 --- a/gix-index/Cargo.toml +++ b/gix-index/Cargo.toml @@ -39,19 +39,19 @@ fnv = "1.0.7" thiserror = "2.0.0" memmap2 = "0.9.0" filetime = "0.2.15" -bstr = { version = "1.3.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } serde = { version = "1.0.114", optional = true, default-features = false, features = [ "derive", ] } -smallvec = "1.7.0" +smallvec = "1.15.0" itoa = "1.0.3" bitflags = "2" document-features = { version = "0.2.0", optional = true } [target.'cfg(not(windows))'.dependencies] -rustix = { version = "0.38.20", default-features = false, features = [ +rustix = { version = "1.0.3", default-features = false, features = [ "std", "fs", ] } diff --git a/gix-index/tests/Cargo.toml b/gix-index/tests/Cargo.toml index 85356da7dd2..519ecd41df4 100644 --- a/gix-index/tests/Cargo.toml +++ b/gix-index/tests/Cargo.toml @@ -26,4 +26,4 @@ gix-odb = { path = "../../gix-odb" } gix-object = { path = "../../gix-object" } gix-hash = { path = "../../gix-hash" } filetime = "0.2.15" -bstr = { version = "1.3.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } diff --git a/gix-lock/Cargo.toml b/gix-lock/Cargo.toml index 9f389f44f34..c31fdd7f06a 100644 --- a/gix-lock/Cargo.toml +++ b/gix-lock/Cargo.toml @@ -21,4 +21,4 @@ gix-tempfile = { version = "^17.0.0", default-features = false, path = "../gix-t thiserror = "2.0.0" [dev-dependencies] -tempfile = "3.2.0" +tempfile = "3.19.1" diff --git a/gix-mailmap/Cargo.toml b/gix-mailmap/Cargo.toml index 7bf17adaacd..0725d516495 100644 --- a/gix-mailmap/Cargo.toml +++ b/gix-mailmap/Cargo.toml @@ -21,7 +21,7 @@ serde = ["dep:serde", "bstr/serde", "gix-actor/serde"] [dependencies] gix-actor = { version = "^0.34.0", path = "../gix-actor" } gix-date = { version = "^0.9.4", path = "../gix-date" } -bstr = { version = "1.3.0", default-features = false, features = ["std", "unicode"] } +bstr = { version = "1.12.0", default-features = false, features = ["std", "unicode"] } thiserror = "2.0.0" serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } diff --git a/gix-merge/Cargo.toml b/gix-merge/Cargo.toml index 82cff992af2..4ec991faaa4 100644 --- a/gix-merge/Cargo.toml +++ b/gix-merge/Cargo.toml @@ -36,7 +36,7 @@ gix-index = { version = "^0.39.0", path = "../gix-index" } thiserror = "2.0.0" imara-diff = { version = "0.1.7" } -bstr = { version = "1.5.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } document-features = { version = "0.2.0", optional = true } diff --git a/gix-negotiate/Cargo.toml b/gix-negotiate/Cargo.toml index 1b44731bbc1..4eac876da89 100644 --- a/gix-negotiate/Cargo.toml +++ b/gix-negotiate/Cargo.toml @@ -22,7 +22,7 @@ gix-date = { version = "^0.9.4", path = "../gix-date" } gix-commitgraph = { version = "^0.27.0", path = "../gix-commitgraph" } gix-revwalk = { version = "^0.19.0", path = "../gix-revwalk" } thiserror = "2.0.0" -smallvec = "1.10.0" +smallvec = "1.15.0" bitflags = "2" [dev-dependencies] diff --git a/gix-object/Cargo.toml b/gix-object/Cargo.toml index cdb28c16028..f8b68d5e45f 100644 --- a/gix-object/Cargo.toml +++ b/gix-object/Cargo.toml @@ -54,12 +54,12 @@ gix-utils = { version = "^0.2.0", path = "../gix-utils" } itoa = "1.0.1" thiserror = "2.0.0" -bstr = { version = "1.3.0", default-features = false, features = [ +bstr = { version = "1.12.0", default-features = false, features = [ "std", "unicode", ] } -winnow = { version = "0.7.0", features = ["simd"] } -smallvec = { version = "1.4.0", features = ["write"] } +winnow = { version = "0.7.6", features = ["simd"] } +smallvec = { version = "1.15.0", features = ["write"] } serde = { version = "1.0.114", optional = true, default-features = false, features = [ "derive", ] } diff --git a/gix-odb/Cargo.toml b/gix-odb/Cargo.toml index 69e82121e83..5fb72b6f61b 100644 --- a/gix-odb/Cargo.toml +++ b/gix-odb/Cargo.toml @@ -31,7 +31,7 @@ gix-pack = { version = "^0.58.0", path = "../gix-pack", default-features = false gix-fs = { version = "^0.14.0", path = "../gix-fs" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } -tempfile = "3.10.0" +tempfile = "3.19.1" thiserror = "2.0.0" parking_lot = { version = "0.12.0" } arc-swap = "1.5.0" diff --git a/gix-pack/Cargo.toml b/gix-pack/Cargo.toml index 9a1a80e64f0..c3573c3e492 100644 --- a/gix-pack/Cargo.toml +++ b/gix-pack/Cargo.toml @@ -46,7 +46,7 @@ gix-traverse = { version = "^0.45.0", path = "../gix-traverse", optional = true gix-diff = { version = "^0.51.0", path = "../gix-diff", default-features = false, optional = true } memmap2 = "0.9.0" -smallvec = "1.3.0" +smallvec = "1.15.0" parking_lot = { version = "0.12.0", default-features = false, optional = true } thiserror = "2.0.0" diff --git a/gix-pack/tests/Cargo.toml b/gix-pack/tests/Cargo.toml index ef9920cdfcd..1738aa50500 100644 --- a/gix-pack/tests/Cargo.toml +++ b/gix-pack/tests/Cargo.toml @@ -23,7 +23,7 @@ gix-pack = { path = "..", features = ["generate", "streaming-input"] } gix-features = { path = "../../gix-features" } gix-testtools = { path = "../../tests/tools" } gix-odb = { path = "../../gix-odb" } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } maplit = "1.0.2" gix-object = { path = "../../gix-object" } gix-traverse = { path = "../../gix-traverse" } diff --git a/gix-packetline-blocking/Cargo.toml b/gix-packetline-blocking/Cargo.toml index 70fa873821b..ac0477aa3e8 100644 --- a/gix-packetline-blocking/Cargo.toml +++ b/gix-packetline-blocking/Cargo.toml @@ -33,8 +33,8 @@ gix-trace = { version = "^0.1.12", path = "../gix-trace" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["std", "derive"] } thiserror = "2.0.0" -faster-hex = { version = "0.9.0" } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +faster-hex = { version = "0.10.0" } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } document-features = { version = "0.2.0", optional = true } diff --git a/gix-packetline/Cargo.toml b/gix-packetline/Cargo.toml index 35929a31b99..f684dd388b6 100644 --- a/gix-packetline/Cargo.toml +++ b/gix-packetline/Cargo.toml @@ -46,8 +46,8 @@ gix-trace = { version = "^0.1.12", path = "../gix-trace" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["std", "derive"] } thiserror = "2.0.0" -faster-hex = { version = "0.9.0" } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +faster-hex = { version = "0.10.0" } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } # async support futures-io = { version = "0.3.16", optional = true } futures-lite = { version = "2.1.0", optional = true } diff --git a/gix-path/Cargo.toml b/gix-path/Cargo.toml index 5cdf8c74b8d..ee4be88d33f 100644 --- a/gix-path/Cargo.toml +++ b/gix-path/Cargo.toml @@ -16,9 +16,9 @@ doctest = false [dependencies] gix-trace = { version = "^0.1.12", path = "../gix-trace" } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } thiserror = "2.0.0" -once_cell = "1.17.1" +once_cell = "1.21.3" [target.'cfg(not(target_family = "wasm"))'.dependencies] home = "0.5.5" @@ -29,5 +29,5 @@ serial_test = { version = "3.1.0", default-features = false } [target.'cfg(windows)'.dev-dependencies] known-folders = "1.1.0" -windows = { version = "0.58.0", features = ["Win32_System_Threading"] } -winreg = "0.52.0" +windows = { version = "0.61.1", features = ["Win32_System_Threading"] } +winreg = "0.55.0" diff --git a/gix-pathspec/Cargo.toml b/gix-pathspec/Cargo.toml index 07021be519b..01c4b49fab9 100644 --- a/gix-pathspec/Cargo.toml +++ b/gix-pathspec/Cargo.toml @@ -20,11 +20,11 @@ gix-path = { version = "^0.10.15", path = "../gix-path" } gix-attributes = { version = "^0.25.0", path = "../gix-attributes" } gix-config-value = { version = "^0.14.12", path = "../gix-config-value" } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } bitflags = "2" thiserror = "2.0.0" [dev-dependencies] gix-testtools = { path = "../tests/tools" } -once_cell = "1.12.0" +once_cell = "1.21.3" serial_test = "3.1.1" diff --git a/gix-prompt/Cargo.toml b/gix-prompt/Cargo.toml index a131e69adf8..b19be03bd46 100644 --- a/gix-prompt/Cargo.toml +++ b/gix-prompt/Cargo.toml @@ -21,7 +21,7 @@ gix-config-value = { version = "^0.14.12", path = "../gix-config-value" } thiserror = "2.0.0" [target.'cfg(unix)'.dependencies] -rustix = { version = "0.38.4", features = ["termios"] } +rustix = { version = "1.0.3", features = ["termios"] } parking_lot = "0.12.1" [dev-dependencies] diff --git a/gix-protocol/Cargo.toml b/gix-protocol/Cargo.toml index b820147a0e0..5d52c67636a 100644 --- a/gix-protocol/Cargo.toml +++ b/gix-protocol/Cargo.toml @@ -90,11 +90,11 @@ thiserror = "2.0.0" serde = { version = "1.0.114", optional = true, default-features = false, features = [ "derive", ] } -bstr = { version = "1.3.0", default-features = false, features = [ +bstr = { version = "1.12.0", default-features = false, features = [ "std", "unicode", ] } -winnow = { version = "0.7.0", features = ["simd"] } +winnow = { version = "0.7.6", features = ["simd"] } # for async-client async-trait = { version = "0.1.51", optional = true } diff --git a/gix-quote/Cargo.toml b/gix-quote/Cargo.toml index a472598f167..cdccfd3ca34 100644 --- a/gix-quote/Cargo.toml +++ b/gix-quote/Cargo.toml @@ -17,5 +17,5 @@ doctest = false [dependencies] gix-utils = { version = "^0.2.0", path = "../gix-utils" } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } thiserror = "2.0.0" diff --git a/gix-ref/Cargo.toml b/gix-ref/Cargo.toml index e76a8e2a480..c368479a399 100644 --- a/gix-ref/Cargo.toml +++ b/gix-ref/Cargo.toml @@ -33,7 +33,7 @@ gix-lock = { version = "^17.0.0", path = "../gix-lock" } gix-tempfile = { version = "^17.0.0", default-features = false, path = "../gix-tempfile" } thiserror = "2.0.0" -winnow = { version = "0.7.0", features = ["simd"] } +winnow = { version = "0.7.6", features = ["simd"] } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } # packed refs diff --git a/gix-refspec/Cargo.toml b/gix-refspec/Cargo.toml index 4dd4c75178a..b308faa9e00 100644 --- a/gix-refspec/Cargo.toml +++ b/gix-refspec/Cargo.toml @@ -19,9 +19,9 @@ gix-revision = { version = "^0.33.0", path = "../gix-revision", default-features gix-validate = { version = "^0.9.4", path = "../gix-validate" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } thiserror = "2.0.0" -smallvec = "1.9.0" +smallvec = "1.15.0" [dev-dependencies] gix-testtools = { path = "../tests/tools" } diff --git a/gix-revision/Cargo.toml b/gix-revision/Cargo.toml index 8265d2c77e8..93913299b8d 100644 --- a/gix-revision/Cargo.toml +++ b/gix-revision/Cargo.toml @@ -35,7 +35,7 @@ gix-revwalk = { version = "^0.19.0", path = "../gix-revwalk" } gix-commitgraph = { version = "^0.27.0", path = "../gix-commitgraph" } gix-trace = { version = "^0.1.12", path = "../gix-trace", optional = true } -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } bitflags = { version = "2", optional = true } thiserror = "2.0.0" serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } diff --git a/gix-revwalk/Cargo.toml b/gix-revwalk/Cargo.toml index d6692eb150d..5168935ccbd 100644 --- a/gix-revwalk/Cargo.toml +++ b/gix-revwalk/Cargo.toml @@ -22,7 +22,7 @@ gix-hashtable = { version = "^0.8.0", path = "../gix-hashtable" } gix-commitgraph = { version = "^0.27.0", path = "../gix-commitgraph" } thiserror = "2.0.0" -smallvec = "1.10.0" +smallvec = "1.15.0" [dev-dependencies] gix-testtools = { path = "../tests/tools" } diff --git a/gix-sec/Cargo.toml b/gix-sec/Cargo.toml index f0b5b28affd..684a4653ca6 100644 --- a/gix-sec/Cargo.toml +++ b/gix-sec/Cargo.toml @@ -32,7 +32,7 @@ libc = "0.2.123" [target.'cfg(windows)'.dependencies] gix-path = { version = "^0.10.15", path = "../gix-path" } -windows-sys = { version = "0.52.0", features = [ +windows-sys = { version = "0.59.0", features = [ "Win32_Foundation", "Win32_Security_Authorization", "Win32_Storage_FileSystem", @@ -41,7 +41,7 @@ windows-sys = { version = "0.52.0", features = [ ] } [dev-dependencies] -tempfile = "3.3.0" +tempfile = "3.19.1" [package.metadata.docs.rs] all-features = true diff --git a/gix-shallow/Cargo.toml b/gix-shallow/Cargo.toml index b0a040b048c..d348e1e8dde 100644 --- a/gix-shallow/Cargo.toml +++ b/gix-shallow/Cargo.toml @@ -24,5 +24,5 @@ gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-lock = { version = "^17.0.0", path = "../gix-lock" } thiserror = "2.0.0" -bstr = { version = "1.5.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } serde = { version = "1.0.114", optional = true, default-features = false, features = ["std", "derive"] } diff --git a/gix-status/Cargo.toml b/gix-status/Cargo.toml index 1d61ae95d09..d22d4006d06 100644 --- a/gix-status/Cargo.toml +++ b/gix-status/Cargo.toml @@ -35,7 +35,7 @@ gix-diff = { version = "^0.51.0", path = "../gix-diff", default-features = false thiserror = "2.0.0" filetime = "0.2.15" -bstr = { version = "1.3.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } document-features = { version = "0.2.0", optional = true } diff --git a/gix-status/tests/Cargo.toml b/gix-status/tests/Cargo.toml index 86142741025..c7e06202f6c 100644 --- a/gix-status/tests/Cargo.toml +++ b/gix-status/tests/Cargo.toml @@ -34,5 +34,5 @@ gix-features = { path = "../../gix-features", features = ["parallel"] } gix-pathspec = { path = "../../gix-pathspec" } gix-worktree = { path = "../../gix-worktree" } filetime = "0.2.15" -bstr = { version = "1.3.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } pretty_assertions = "1.4.0" diff --git a/gix-submodule/Cargo.toml b/gix-submodule/Cargo.toml index 3653977c44d..d11304e345d 100644 --- a/gix-submodule/Cargo.toml +++ b/gix-submodule/Cargo.toml @@ -21,7 +21,7 @@ gix-config = { version = "^0.44.0", path = "../gix-config" } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-url = { version = "^0.30.0", path = "../gix-url" } -bstr = { version = "1.5.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } thiserror = "2.0.0" [dev-dependencies] diff --git a/gix-tempfile/Cargo.toml b/gix-tempfile/Cargo.toml index 40dc1da5d67..25a4c7940c5 100644 --- a/gix-tempfile/Cargo.toml +++ b/gix-tempfile/Cargo.toml @@ -34,8 +34,8 @@ test = true gix-fs = { version = "^0.14.0", path = "../gix-fs" } parking_lot = "0.12.1" dashmap = { version = "6.0.1", optional = true } -once_cell = { version = "1.8.0", default-features = false, features = ["race", "std"] } -tempfile = "3.10.0" +once_cell = { version = "1.21.3", default-features = false, features = ["race", "std"] } +tempfile = "3.19.1" signal-hook = { version = "0.3.9", default-features = false, optional = true } signal-hook-registry = { version = "1.4.0", optional = true } diff --git a/gix-transport/Cargo.toml b/gix-transport/Cargo.toml index 0851ea0fffe..7a21d63734f 100644 --- a/gix-transport/Cargo.toml +++ b/gix-transport/Cargo.toml @@ -93,7 +93,7 @@ serde = { version = "1.0.114", optional = true, default-features = false, featur "std", "derive", ] } -bstr = { version = "1.3.0", default-features = false, features = [ +bstr = { version = "1.12.0", default-features = false, features = [ "std", "unicode", ] } diff --git a/gix-traverse/Cargo.toml b/gix-traverse/Cargo.toml index df7efa2f045..fbdca6f9a25 100644 --- a/gix-traverse/Cargo.toml +++ b/gix-traverse/Cargo.toml @@ -22,6 +22,6 @@ gix-date = { version = "^0.9.4", path = "../gix-date" } gix-hashtable = { version = "^0.8.0", path = "../gix-hashtable" } gix-revwalk = { version = "^0.19.0", path = "../gix-revwalk" } gix-commitgraph = { version = "^0.27.0", path = "../gix-commitgraph" } -smallvec = "1.10.0" +smallvec = "1.15.0" thiserror = "2.0.0" bitflags = "2" diff --git a/gix-url/Cargo.toml b/gix-url/Cargo.toml index 6bb03e9690b..5abf17feea6 100644 --- a/gix-url/Cargo.toml +++ b/gix-url/Cargo.toml @@ -25,7 +25,7 @@ gix-path = { version = "^0.10.15", path = "../gix-path" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["std", "derive"] } thiserror = "2.0.0" url = "2.5.2" -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } percent-encoding = "2.3.1" document-features = { version = "0.2.0", optional = true } diff --git a/gix-utils/Cargo.toml b/gix-utils/Cargo.toml index b58722a0d51..a6acefe3931 100644 --- a/gix-utils/Cargo.toml +++ b/gix-utils/Cargo.toml @@ -19,5 +19,5 @@ bstr = ["dep:bstr"] [dependencies] fastrand = "2.0.0" -bstr = { version = "1.5.0", default-features = false, features = ["std"], optional = true } +bstr = { version = "1.12.0", default-features = false, features = ["std"], optional = true } unicode-normalization = { version = "0.1.19", default-features = false } diff --git a/gix-validate/Cargo.toml b/gix-validate/Cargo.toml index 6d70ded8903..1128fdfcf8b 100644 --- a/gix-validate/Cargo.toml +++ b/gix-validate/Cargo.toml @@ -17,7 +17,7 @@ test = true [dependencies] thiserror = "2.0.0" -bstr = { version = "1.3.0", default-features = false, features = ["std"] } +bstr = { version = "1.12.0", default-features = false, features = ["std"] } [dev-dependencies] gix-testtools = { path = "../tests/tools" } diff --git a/gix-worktree-state/Cargo.toml b/gix-worktree-state/Cargo.toml index ca8acedae47..154f3afef9d 100644 --- a/gix-worktree-state/Cargo.toml +++ b/gix-worktree-state/Cargo.toml @@ -28,4 +28,4 @@ gix-filter = { version = "^0.18.0", path = "../gix-filter" } io-close = "0.3.7" thiserror = "2.0.0" -bstr = { version = "1.3.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } diff --git a/gix-worktree-state/tests/Cargo.toml b/gix-worktree-state/tests/Cargo.toml index cbf979e2b20..7f41c26467b 100644 --- a/gix-worktree-state/tests/Cargo.toml +++ b/gix-worktree-state/tests/Cargo.toml @@ -30,6 +30,6 @@ gix-features = { path = "../../gix-features" } gix-testtools = { path = "../../tests/tools" } gix-odb = { path = "../../gix-odb" } symlink = "0.1.0" -once_cell = "1.18.0" +once_cell = "1.21.3" walkdir = "2.3.2" diff --git a/gix-worktree/Cargo.toml b/gix-worktree/Cargo.toml index 9e9ae3a62f9..dbdeb333d28 100644 --- a/gix-worktree/Cargo.toml +++ b/gix-worktree/Cargo.toml @@ -35,7 +35,7 @@ gix-ignore = { version = "^0.14.0", path = "../gix-ignore" } gix-features = { version = "^0.41.1", path = "../gix-features" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } -bstr = { version = "1.3.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } document-features = { version = "0.2.0", optional = true } diff --git a/gix-worktree/tests/Cargo.toml b/gix-worktree/tests/Cargo.toml index 7ff00c91c49..2028cc98d8c 100644 --- a/gix-worktree/tests/Cargo.toml +++ b/gix-worktree/tests/Cargo.toml @@ -31,7 +31,7 @@ gix-ignore = { path = "../../gix-ignore" } gix-features = { path = "../../gix-features" } gix-discover = { path = "../../gix-discover" } -bstr = { version = "1.3.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } gix-testtools = { path = "../../tests/tools" } gix-odb = { path = "../../gix-odb" } diff --git a/gix/Cargo.toml b/gix/Cargo.toml index ee8a57b048e..f85a161ade7 100644 --- a/gix/Cargo.toml +++ b/gix/Cargo.toml @@ -377,13 +377,13 @@ gix-transport = { version = "^0.46.0", path = "../gix-transport", optional = tru # Just to get the progress-tree feature prodash = { version = "29.0.1", optional = true, features = ["progress-tree"] } -once_cell = "1.14.0" +once_cell = "1.21.3" signal-hook = { version = "0.3.9", default-features = false, optional = true } thiserror = "2.0.0" serde = { version = "1.0.114", optional = true, default-features = false, features = [ "derive", ] } -smallvec = "1.9.0" +smallvec = "1.15.0" async-std = { version = "1.12.0", optional = true } ## For use in rev-parse, which provides searching commits by running a regex on their message. diff --git a/tests/it/Cargo.toml b/tests/it/Cargo.toml index 892e3b748ba..42c86a18836 100644 --- a/tests/it/Cargo.toml +++ b/tests/it/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0.86" -clap = { version = "4.5.16", features = ["derive"] } +clap = { version = "4.5.35", features = ["derive"] } gix = { version = "^0.71.0", path = "../../gix", default-features = false, features = ["attributes", "revision"] } -once_cell = "1.20.2" +once_cell = "1.21.3" regex = { version = "1.11.1", default-features = false, features = ["std"] } diff --git a/tests/tools/Cargo.toml b/tests/tools/Cargo.toml index 43435b11b23..0938eedf57d 100644 --- a/tests/tools/Cargo.toml +++ b/tests/tools/Cargo.toml @@ -31,12 +31,12 @@ gix-worktree = "0.34.0" gix-fs = "0.11" gix-tempfile = { version = "^14.0.0", default-features = false, features = ["signals"] } -winnow = { version = "0.7.0", features = ["simd"] } +winnow = { version = "0.7.6", features = ["simd"] } fastrand = "2.0.0" -bstr = { version = "1.5.0", default-features = false } +bstr = { version = "1.12.0", default-features = false } crc = "3.0.0" -once_cell = "1.8.0" -tempfile = "3.2.0" +once_cell = "1.21.3" +tempfile = "3.19.1" fs_extra = "1.2.0" parking_lot = { version = "0.12.0" } is_ci = "1.1.1" From 8e5e68f8562d2f9f37672dd95d60c9dae52a312e Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Thu, 10 Apr 2025 12:30:54 -0400 Subject: [PATCH 082/193] Adapt `gix-sec` to changes in `windows-sys` Bumping the `windows-sys` dependency of `gix-sec` from 0.52.0 to 0.59.9 broke a Windows API function call that passed a literal `0` for a null handle, because the interface became a bit more strongly typed. This changes the argument to `std::ptr::null_mut()`. --- gix-sec/src/identity.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gix-sec/src/identity.rs b/gix-sec/src/identity.rs index 9fcdc2cb84d..06cecae2924 100644 --- a/gix-sec/src/identity.rs +++ b/gix-sec/src/identity.rs @@ -200,7 +200,7 @@ mod impl_ { } let mut is_member = 0; - if CheckTokenMembership(0, token_owner, &mut is_member) == 0 { + if CheckTokenMembership(std::ptr::null_mut(), token_owner, &mut is_member) == 0 { error!("Couldn't check if user is an administrator"); } From 417917f3cb488eee155cdcc75f88dcd7b42d3c95 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Thu, 10 Apr 2025 12:53:38 -0400 Subject: [PATCH 083/193] Adapt `gitoxide-core` to changes in `sysinfo` Bumping the `sysinfo` dependency of `gitoxide-core` from 0.31.2 to 0.34.2 broke `RefreshKind::new()` and `CpuRefreshKind::new()` calls because `sysinfo` 0.33.0 renamed those `new()` to `nothing()`: https://github.com/GuillaumeGomez/sysinfo/blob/master/CHANGELOG.md#0330 This renames the calls accordingly. --- gitoxide-core/src/corpus/db.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gitoxide-core/src/corpus/db.rs b/gitoxide-core/src/corpus/db.rs index f1ee3f6ec3e..6b9640f7bcd 100644 --- a/gitoxide-core/src/corpus/db.rs +++ b/gitoxide-core/src/corpus/db.rs @@ -118,7 +118,7 @@ pub fn create(path: impl AsRef) -> anyhow::Result) -> anyhow::Result anyhow::Result { - let sys = - sysinfo::System::new_with_specifics(RefreshKind::new().with_cpu(CpuRefreshKind::new().with_frequency())); + let sys = sysinfo::System::new_with_specifics( + RefreshKind::nothing().with_cpu(CpuRefreshKind::nothing().with_frequency()), + ); let cpu = &sys.cpus()[0]; let vendor = Some(cpu.vendor_id().to_owned()); let host = sysinfo::System::host_name(); From 2fc48a11df504e135546f6c23c7d696c04c5006a Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Thu, 10 Apr 2025 13:26:20 -0400 Subject: [PATCH 084/193] Adapt `gix-path` tests to changes in `windows` Bumping the `windows` dev-dependency of `gix-path` from 0.58.0 to 0.61.1 broke the use of `windows::Win32::Foundation::BOOL`, since `BOOL` is now `windows::core::BOOL` (and also available through the `windows_core` crate). It is not immediately obvious from the changelog at what point the change occurred. (A seemingly related change is described for the newer version https://github.com/microsoft/windows-rs/pull/3441. See https://github.com/microsoft/windows-rs/pull/3441 for context.) This imports `BOOL` from `windows::core` to adjust. --- gix-path/src/env/git/tests.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gix-path/src/env/git/tests.rs b/gix-path/src/env/git/tests.rs index 0964be27d41..99f3377fd3a 100644 --- a/gix-path/src/env/git/tests.rs +++ b/gix-path/src/env/git/tests.rs @@ -7,8 +7,7 @@ mod locations { use std::path::{Path, PathBuf}; use known_folders::{get_known_folder_path, KnownFolder}; - use windows::core::Result as WindowsResult; - use windows::Win32::Foundation::BOOL; + use windows::core::{Result as WindowsResult, BOOL}; use windows::Win32::System::Threading::{GetCurrentProcess, IsWow64Process}; use winreg::enums::{HKEY_LOCAL_MACHINE, KEY_QUERY_VALUE}; use winreg::RegKey; From 77a3a1b85521ec87495a73151dd422e2cde49f99 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Thu, 10 Apr 2025 17:37:09 -0400 Subject: [PATCH 085/193] fix: Use less ambiguous "kB" for SI kilobyte `gix free pack verify --statistics` formerly used "KB" for kilobytes (i.e., SI decimal kilobytes, units of 1000 bytes). This was somewhat ambiguous because it is occasionally also used for kibibytes (i.e., IEC binary kibibytes, units of 1024 bytes). Kilobytes and kibibytes can be more precisely distinguished by using kB for kilobytes (since "k" is the SI prefix for "kilo") and KiB for kibibytes (since decimal kilobytes are never written KiB). This adapts `gitoxide-core` to changes in `bytesize` and, in so doing, allows the SI unit symbol "kB" to be used. Fixes #1947 --- gitoxide-core/src/pack/verify.rs | 8 ++++---- .../pack/verify/index-with-statistics-success | 8 ++++---- .../multi-index/index-with-statistics-success | 16 ++++++++-------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/gitoxide-core/src/pack/verify.rs b/gitoxide-core/src/pack/verify.rs index 0e6a5d3bdfd..837475aab63 100644 --- a/gitoxide-core/src/pack/verify.rs +++ b/gitoxide-core/src/pack/verify.rs @@ -236,10 +236,10 @@ fn print_statistics(out: &mut impl io::Write, stats: &index::traverse::Statistic #[rustfmt::skip] writeln!( out, "\t{: Date: Fri, 11 Apr 2025 23:19:05 +0200 Subject: [PATCH 086/193] refactor: replace `futures_lite::ready!` with `std::task::ready!` --- gix-packetline-blocking/src/encode/async_io.rs | 3 +-- gix-packetline-blocking/src/read/sidebands/async_io.rs | 3 +-- gix-packetline-blocking/src/write/async_io.rs | 4 ++-- gix-packetline/src/encode/async_io.rs | 3 +-- gix-packetline/src/read/sidebands/async_io.rs | 3 +-- gix-packetline/src/write/async_io.rs | 4 ++-- 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/gix-packetline-blocking/src/encode/async_io.rs b/gix-packetline-blocking/src/encode/async_io.rs index 27566ada140..6532b84c9fa 100644 --- a/gix-packetline-blocking/src/encode/async_io.rs +++ b/gix-packetline-blocking/src/encode/async_io.rs @@ -3,7 +3,7 @@ use std::{ io, pin::Pin, - task::{Context, Poll}, + task::{ready, Context, Poll}, }; use futures_io::AsyncWrite; @@ -56,7 +56,6 @@ fn into_io_err(err: Error) -> io::Error { impl AsyncWrite for LineWriter<'_, W> { fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, data: &[u8]) -> Poll> { - use futures_lite::ready; let mut this = self.project(); loop { match &mut this.state { diff --git a/gix-packetline-blocking/src/read/sidebands/async_io.rs b/gix-packetline-blocking/src/read/sidebands/async_io.rs index 6ffe200590d..43224dd15fe 100644 --- a/gix-packetline-blocking/src/read/sidebands/async_io.rs +++ b/gix-packetline-blocking/src/read/sidebands/async_io.rs @@ -3,11 +3,10 @@ use std::{ future::Future, pin::Pin, - task::{Context, Poll}, + task::{ready, Context, Poll}, }; use futures_io::{AsyncBufRead, AsyncRead}; -use futures_lite::ready; use crate::{decode, read::ProgressAction, BandRef, PacketLineRef, StreamingPeekableIter, TextRef, U16_HEX_BYTES}; diff --git a/gix-packetline-blocking/src/write/async_io.rs b/gix-packetline-blocking/src/write/async_io.rs index a77dbe274a7..a5813e1ede8 100644 --- a/gix-packetline-blocking/src/write/async_io.rs +++ b/gix-packetline-blocking/src/write/async_io.rs @@ -3,7 +3,7 @@ use std::{ io, pin::Pin, - task::{Context, Poll}, + task::{ready, Context, Poll}, }; use futures_io::AsyncWrite; @@ -75,7 +75,7 @@ impl AsyncWrite for Writer { State::WriteData(written) => { while *written != buf.len() { let data = &buf[*written..*written + (buf.len() - *written).min(MAX_DATA_LEN)]; - let n = futures_lite::ready!(this.inner.as_mut().poll_write(cx, data))?; + let n = ready!(this.inner.as_mut().poll_write(cx, data))?; if n == 0 { return Poll::Ready(Err(io::ErrorKind::WriteZero.into())); } diff --git a/gix-packetline/src/encode/async_io.rs b/gix-packetline/src/encode/async_io.rs index 983644c1d9f..9add6f27a41 100644 --- a/gix-packetline/src/encode/async_io.rs +++ b/gix-packetline/src/encode/async_io.rs @@ -1,7 +1,7 @@ use std::{ io, pin::Pin, - task::{Context, Poll}, + task::{ready, Context, Poll}, }; use futures_io::AsyncWrite; @@ -54,7 +54,6 @@ fn into_io_err(err: Error) -> io::Error { impl AsyncWrite for LineWriter<'_, W> { fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, data: &[u8]) -> Poll> { - use futures_lite::ready; let mut this = self.project(); loop { match &mut this.state { diff --git a/gix-packetline/src/read/sidebands/async_io.rs b/gix-packetline/src/read/sidebands/async_io.rs index 1a04a381254..92e61114214 100644 --- a/gix-packetline/src/read/sidebands/async_io.rs +++ b/gix-packetline/src/read/sidebands/async_io.rs @@ -1,11 +1,10 @@ use std::{ future::Future, pin::Pin, - task::{Context, Poll}, + task::{ready, Context, Poll}, }; use futures_io::{AsyncBufRead, AsyncRead}; -use futures_lite::ready; use crate::{decode, read::ProgressAction, BandRef, PacketLineRef, StreamingPeekableIter, TextRef, U16_HEX_BYTES}; diff --git a/gix-packetline/src/write/async_io.rs b/gix-packetline/src/write/async_io.rs index 707d2b7b576..4775fc06df4 100644 --- a/gix-packetline/src/write/async_io.rs +++ b/gix-packetline/src/write/async_io.rs @@ -1,7 +1,7 @@ use std::{ io, pin::Pin, - task::{Context, Poll}, + task::{ready, Context, Poll}, }; use futures_io::AsyncWrite; @@ -73,7 +73,7 @@ impl AsyncWrite for Writer { State::WriteData(written) => { while *written != buf.len() { let data = &buf[*written..*written + (buf.len() - *written).min(MAX_DATA_LEN)]; - let n = futures_lite::ready!(this.inner.as_mut().poll_write(cx, data))?; + let n = ready!(this.inner.as_mut().poll_write(cx, data))?; if n == 0 { return Poll::Ready(Err(io::ErrorKind::WriteZero.into())); } From 9f1fbc741e1b6c718c7787f2858e07f3bd5473e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 13 Apr 2025 10:05:28 +0000 Subject: [PATCH 087/193] Bump the cargo group with 3 updates Bumps the cargo group with 3 updates: [clap](https://github.com/clap-rs/clap), [prodash](https://github.com/Byron/prodash) and [rustix](https://github.com/bytecodealliance/rustix). Updates `clap` from 4.5.35 to 4.5.36 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.35...clap_complete-v4.5.36) Updates `prodash` from 29.0.1 to 29.0.2 - [Release notes](https://github.com/Byron/prodash/releases) - [Changelog](https://github.com/Byron/prodash/blob/main/CHANGELOG.md) - [Commits](https://github.com/Byron/prodash/compare/v29.0.1...v29.0.2) Updates `rustix` from 1.0.3 to 1.0.5 - [Release notes](https://github.com/bytecodealliance/rustix/releases) - [Changelog](https://github.com/bytecodealliance/rustix/blob/main/CHANGES.md) - [Commits](https://github.com/bytecodealliance/rustix/compare/v1.0.3...v1.0.5) --- updated-dependencies: - dependency-name: clap dependency-version: 4.5.36 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: prodash dependency-version: 29.0.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: rustix dependency-version: 1.0.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 46 ++++++++++++++++++----------------------- Cargo.toml | 4 ++-- gix-features/Cargo.toml | 2 +- gix-index/Cargo.toml | 2 +- gix-prompt/Cargo.toml | 2 +- gix/Cargo.toml | 2 +- tests/it/Cargo.toml | 2 +- 7 files changed, 27 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4ec7eaf2246..ea022114ebb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,12 +433,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -[[package]] -name = "bytesize" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" - [[package]] name = "bytesize" version = "2.0.1" @@ -553,9 +547,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.35" +version = "4.5.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" dependencies = [ "clap_builder", "clap_derive", @@ -563,9 +557,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.35" +version = "4.5.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" dependencies = [ "anstream", "anstyle", @@ -1343,7 +1337,7 @@ dependencies = [ "gix-features 0.41.1", "is-terminal", "once_cell", - "prodash 29.0.1", + "prodash 29.0.2", "serde_derive", "terminal_size", "tracing", @@ -1360,7 +1354,7 @@ dependencies = [ "async-net", "async-trait", "blocking", - "bytesize 2.0.1", + "bytesize", "crossbeam-channel", "document-features", "fs-err", @@ -1452,7 +1446,7 @@ dependencies = [ "once_cell", "parking_lot", "pretty_assertions", - "prodash 29.0.1", + "prodash 29.0.2", "regex", "serde", "serial_test", @@ -1678,7 +1672,7 @@ name = "gix-config-tests" version = "0.0.0" dependencies = [ "bstr", - "bytesize 2.0.1", + "bytesize", "cap", "gix-config", "gix-path 0.10.15", @@ -1869,7 +1863,7 @@ version = "0.41.1" dependencies = [ "bstr", "bytes", - "bytesize 2.0.1", + "bytesize", "crc32fast", "crossbeam-channel", "document-features", @@ -1880,7 +1874,7 @@ dependencies = [ "libc", "once_cell", "parking_lot", - "prodash 29.0.1", + "prodash 29.0.2", "thiserror 2.0.12", "walkdir", ] @@ -2096,7 +2090,7 @@ dependencies = [ "itoa", "libc", "memmap2", - "rustix 1.0.3", + "rustix 1.0.5", "serde", "smallvec", "thiserror 2.0.12", @@ -2425,7 +2419,7 @@ dependencies = [ "gix-config-value", "gix-testtools", "parking_lot", - "rustix 1.0.3", + "rustix 1.0.5", "serial_test", "thiserror 2.0.12", ] @@ -4318,12 +4312,12 @@ checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" [[package]] name = "prodash" -version = "29.0.1" +version = "29.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee7ce24c980b976607e2d6ae4aae92827994d23fed71659c3ede3f92528b58b" +checksum = "f04bb108f648884c23b98a0e940ebc2c93c0c3b89f04dbaf7eb8256ce617d1bc" dependencies = [ "async-io", - "bytesize 1.3.3", + "bytesize", "crosstermion", "futures-core", "futures-lite", @@ -4636,9 +4630,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ "bitflags 2.9.0", "errno", @@ -5194,7 +5188,7 @@ dependencies = [ "fastrand", "getrandom 0.3.2", "once_cell", - "rustix 1.0.3", + "rustix 1.0.5", "windows-sys 0.59.0", ] @@ -5213,7 +5207,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" dependencies = [ - "rustix 1.0.3", + "rustix 1.0.5", "windows-sys 0.59.0", ] @@ -6356,7 +6350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" dependencies = [ "libc", - "rustix 1.0.3", + "rustix 1.0.5", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 63ea2709837..a51765d4cb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -171,9 +171,9 @@ gitoxide-core = { version = "^0.46.0", path = "gitoxide-core" } gix-features = { version = "^0.41.1", path = "gix-features" } gix = { version = "^0.71.0", path = "gix", default-features = false } -clap = { version = "4.5.35", features = ["derive", "cargo"] } +clap = { version = "4.5.36", features = ["derive", "cargo"] } clap_complete = "4.5.47" -prodash = { version = "29.0.1", optional = true } +prodash = { version = "29.0.2", optional = true } is-terminal = { version = "0.4.0", optional = true } env_logger = { version = "0.11.8", default-features = false } crosstermion = { version = "0.14.0", optional = true, default-features = false } diff --git a/gix-features/Cargo.toml b/gix-features/Cargo.toml index 4c94df39d81..09c919b715f 100644 --- a/gix-features/Cargo.toml +++ b/gix-features/Cargo.toml @@ -119,7 +119,7 @@ walkdir = { version = "2.3.2", optional = true } # used when parallel is off crc32fast = { version = "1.2.1", optional = true } # progress -prodash = { version = "29.0.1", optional = true } +prodash = { version = "29.0.2", optional = true } bytesize = { version = "2.0.1", optional = true } # pipe diff --git a/gix-index/Cargo.toml b/gix-index/Cargo.toml index fbe2be3f1b6..ddea59ca3be 100644 --- a/gix-index/Cargo.toml +++ b/gix-index/Cargo.toml @@ -51,7 +51,7 @@ bitflags = "2" document-features = { version = "0.2.0", optional = true } [target.'cfg(not(windows))'.dependencies] -rustix = { version = "1.0.3", default-features = false, features = [ +rustix = { version = "1.0.5", default-features = false, features = [ "std", "fs", ] } diff --git a/gix-prompt/Cargo.toml b/gix-prompt/Cargo.toml index b19be03bd46..e248625787b 100644 --- a/gix-prompt/Cargo.toml +++ b/gix-prompt/Cargo.toml @@ -21,7 +21,7 @@ gix-config-value = { version = "^0.14.12", path = "../gix-config-value" } thiserror = "2.0.0" [target.'cfg(unix)'.dependencies] -rustix = { version = "1.0.3", features = ["termios"] } +rustix = { version = "1.0.5", features = ["termios"] } parking_lot = "0.12.1" [dev-dependencies] diff --git a/gix/Cargo.toml b/gix/Cargo.toml index f85a161ade7..4b1045bdd27 100644 --- a/gix/Cargo.toml +++ b/gix/Cargo.toml @@ -376,7 +376,7 @@ gix-protocol = { version = "^0.49.0", path = "../gix-protocol" } gix-transport = { version = "^0.46.0", path = "../gix-transport", optional = true } # Just to get the progress-tree feature -prodash = { version = "29.0.1", optional = true, features = ["progress-tree"] } +prodash = { version = "29.0.2", optional = true, features = ["progress-tree"] } once_cell = "1.21.3" signal-hook = { version = "0.3.9", default-features = false, optional = true } thiserror = "2.0.0" diff --git a/tests/it/Cargo.toml b/tests/it/Cargo.toml index 42c86a18836..41c9d4c5aa7 100644 --- a/tests/it/Cargo.toml +++ b/tests/it/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0.86" -clap = { version = "4.5.35", features = ["derive"] } +clap = { version = "4.5.36", features = ["derive"] } gix = { version = "^0.71.0", path = "../../gix", default-features = false, features = ["attributes", "revision"] } once_cell = "1.21.3" regex = { version = "1.11.1", default-features = false, features = ["std"] } From 57c9014d4f17f00ceb7fd2e3ca6b80f081af3356 Mon Sep 17 00:00:00 2001 From: Fredrik Medley Date: Sun, 13 Apr 2025 16:09:50 +0200 Subject: [PATCH 088/193] Fix ci failures --- gix-ref/src/store/file/loose/iter.rs | 5 ++++- gix-ref/src/store/file/overlay_iter.rs | 6 +++++- gix/src/open/repository.rs | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gix-ref/src/store/file/loose/iter.rs b/gix-ref/src/store/file/loose/iter.rs index 0ec3a7ddb11..99ebc2d7f4d 100644 --- a/gix-ref/src/store/file/loose/iter.rs +++ b/gix-ref/src/store/file/loose/iter.rs @@ -87,7 +87,10 @@ impl file::Store { /// Return an iterator over all loose references that start with the given `prefix`. /// /// Otherwise it's similar to [`loose_iter()`][file::Store::loose_iter()]. - pub fn loose_iter_prefixed<'a>(&self, prefix: impl Into>) -> std::io::Result> { + pub fn loose_iter_prefixed<'a>( + &self, + prefix: impl Into>, + ) -> std::io::Result> { self.iter_prefixed_packed(prefix.into(), None) } } diff --git a/gix-ref/src/store/file/overlay_iter.rs b/gix-ref/src/store/file/overlay_iter.rs index c9de782d609..0920b7bff95 100644 --- a/gix-ref/src/store/file/overlay_iter.rs +++ b/gix-ref/src/store/file/overlay_iter.rs @@ -284,7 +284,11 @@ impl<'a> IterInfo<'a> { .peekable() } - fn from_prefix(base: &'a Path, prefix: impl Into>, precompose_unicode: bool) -> std::io::Result { + fn from_prefix( + base: &'a Path, + prefix: impl Into>, + precompose_unicode: bool, + ) -> std::io::Result { let prefix = prefix.into(); let prefix_path = gix_path::from_bstring(prefix.clone().into_owned()); if prefix_path.is_absolute() { diff --git a/gix/src/open/repository.rs b/gix/src/open/repository.rs index 37094233c82..ac61097e5a3 100644 --- a/gix/src/open/repository.rs +++ b/gix/src/open/repository.rs @@ -349,7 +349,7 @@ impl ThreadSafeRepository { .and_then(|prefix| { let _span = gix_trace::detail!("find replacement objects"); let platform = refs.iter().ok()?; - let iter = platform.prefixed(&prefix).ok()?; + let iter = platform.prefixed(prefix.clone()).ok()?; let replacements = iter .filter_map(Result::ok) .filter_map(|r: gix_ref::Reference| { From f5385595987e0be84fb56827682df013bf54e09c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 13 Apr 2025 16:26:56 +0200 Subject: [PATCH 089/193] fix!: prefixed ref iteration now properly deals with slashes. Previously, `refs/heads/foo/bar` would be listed when running `repo.references()?.prefixed("refs/heads/b")`. The code identified that the last component was not a directory and started to match it as a filename prefix for all files in all recursive directories, effectively matching `refs/heads/**/b*`. This commit fixes that bug but also allows to use a trailing `/` in the prefix, allowing to filter for `refs/heads/foo/` and not get `refs/heads/foo-bar` as a result. --- gix-ref/src/namespace.rs | 11 ++++--- gix-ref/src/store/file/loose/iter.rs | 31 +++++++++---------- gix-ref/src/store/file/overlay_iter.rs | 40 ++++++++++++++++-------- gix-ref/tests/refs/file/store/iter.rs | 43 ++++++++++++-------------- gix-ref/tests/refs/file/worktree.rs | 5 ++- gix-ref/tests/refs/namespace.rs | 8 ++--- 6 files changed, 74 insertions(+), 64 deletions(-) diff --git a/gix-ref/src/namespace.rs b/gix-ref/src/namespace.rs index cba0b460c73..0570ff27434 100644 --- a/gix-ref/src/namespace.rs +++ b/gix-ref/src/namespace.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, path::Path}; +use std::path::Path; use gix_object::bstr::{BStr, BString, ByteSlice, ByteVec}; @@ -18,9 +18,12 @@ impl Namespace { gix_path::from_byte_slice(&self.0) } /// Append the given `prefix` to this namespace so it becomes usable for prefixed iteration. - pub fn into_namespaced_prefix(mut self, prefix: &BStr) -> Cow<'_, BStr> { - self.0.push_str(prefix); - gix_path::to_unix_separators_on_windows(self.0) + /// + /// The prefix is a relative path with slash-separated path components. + // TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it. + pub fn into_namespaced_prefix<'a>(mut self, prefix: impl Into<&'a BStr>) -> BString { + self.0.push_str(prefix.into()); + gix_path::to_unix_separators_on_windows(self.0).into_owned() } pub(crate) fn into_namespaced_name(mut self, name: &FullNameRef) -> FullName { self.0.push_str(name.as_bstr()); diff --git a/gix-ref/src/store/file/loose/iter.rs b/gix-ref/src/store/file/loose/iter.rs index 99ebc2d7f4d..2982e4a22e3 100644 --- a/gix-ref/src/store/file/loose/iter.rs +++ b/gix-ref/src/store/file/loose/iter.rs @@ -1,7 +1,4 @@ -use std::{ - borrow::Cow, - path::{Path, PathBuf}, -}; +use std::path::{Path, PathBuf}; use gix_features::fs::walkdir::DirEntryIter; use gix_object::bstr::ByteSlice; @@ -11,7 +8,7 @@ use crate::{file::iter::LooseThenPacked, store_impl::file, BStr, BString, FullNa /// An iterator over all valid loose reference paths as seen from a particular base directory. pub(in crate::store_impl::file) struct SortedLoosePaths { pub(crate) base: PathBuf, - /// A optional prefix to match against if the prefix is not the same as the `file_walk` path. + /// An prefix like `refs/heads/foo/` or `refs/heads/prefix` that a returned reference must match against.. prefix: Option, file_walk: Option, } @@ -48,12 +45,10 @@ impl Iterator for SortedLoosePaths { let full_name = full_path .strip_prefix(&self.base) .expect("prefix-stripping cannot fail as base is within our root"); - let full_name = match gix_path::try_into_bstr(full_name) { - Ok(name) => { - let name = gix_path::to_unix_separators_on_windows(name); - name.into_owned() - } - Err(_) => continue, // TODO: silently skipping ill-formed UTF-8 on windows here, maybe there are better ways? + let Ok(full_name) = gix_path::try_into_bstr(full_name) + .map(|name| gix_path::to_unix_separators_on_windows(name).into_owned()) + else { + continue; }; if let Some(prefix) = &self.prefix { if !full_name.starts_with(prefix) { @@ -86,11 +81,15 @@ impl file::Store { /// Return an iterator over all loose references that start with the given `prefix`. /// - /// Otherwise it's similar to [`loose_iter()`][file::Store::loose_iter()]. - pub fn loose_iter_prefixed<'a>( - &self, - prefix: impl Into>, - ) -> std::io::Result> { + /// Otherwise, it's similar to [`loose_iter()`](file::Store::loose_iter()). + /// + /// Note that if a prefix isn't using a trailing `/`, like in `refs/heads/foo`, it will effectively + /// start the traversal in the parent directory, e.g. `refs/heads/` and list everything inside that + /// starts with `foo`, like `refs/heads/foo` and `refs/heads/foobar`. + /// + /// Prefixes are relative paths with slash-separated components. + // TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it. + pub fn loose_iter_prefixed<'a>(&self, prefix: impl Into<&'a BStr>) -> std::io::Result> { self.iter_prefixed_packed(prefix.into(), None) } } diff --git a/gix-ref/src/store/file/overlay_iter.rs b/gix-ref/src/store/file/overlay_iter.rs index 0920b7bff95..e69c9cfed15 100644 --- a/gix-ref/src/store/file/overlay_iter.rs +++ b/gix-ref/src/store/file/overlay_iter.rs @@ -195,9 +195,16 @@ impl Platform<'_> { self.store.iter_packed(self.packed.as_ref().map(|b| &***b)) } - /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads/" or + /// As [`iter(…)`](file::Store::iter()), but filters by `prefix`, i.e. "refs/heads/" or /// "refs/heads/feature-". - pub fn prefixed<'a>(&self, prefix: impl Into>) -> std::io::Result> { + /// + /// Note that if a prefix isn't using a trailing `/`, like in `refs/heads/foo`, it will effectively + /// start the traversal in the parent directory, e.g. `refs/heads/` and list everything inside that + /// starts with `foo`, like `refs/heads/foo` and `refs/heads/foobar`. + /// + /// Prefixes are relative paths with slash-separated components. + // TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it. + pub fn prefixed<'a>(&self, prefix: impl Into<&'a BStr>) -> std::io::Result> { self.store .iter_prefixed_packed(prefix.into(), self.packed.as_ref().map(|b| &***b)) } @@ -227,7 +234,7 @@ pub(crate) enum IterInfo<'a> { BaseAndIterRoot { base: &'a Path, iter_root: PathBuf, - prefix: Cow<'a, Path>, + prefix: PathBuf, precompose_unicode: bool, }, PrefixAndBase { @@ -238,9 +245,9 @@ pub(crate) enum IterInfo<'a> { ComputedIterationRoot { /// The root to iterate over iter_root: PathBuf, - /// The top-level directory as boundary of all references, used to create their short-names after iteration + /// The top-level directory as boundary of all references, used to create their short-names after iteration. base: &'a Path, - /// The original prefix + /// The original prefix. prefix: Cow<'a, BStr>, /// If `true`, we will convert decomposed into precomposed unicode. precompose_unicode: bool, @@ -290,7 +297,7 @@ impl<'a> IterInfo<'a> { precompose_unicode: bool, ) -> std::io::Result { let prefix = prefix.into(); - let prefix_path = gix_path::from_bstring(prefix.clone().into_owned()); + let prefix_path = gix_path::from_bstr(prefix.as_ref()); if prefix_path.is_absolute() { return Err(std::io::Error::new( std::io::ErrorKind::InvalidInput, @@ -309,7 +316,7 @@ impl<'a> IterInfo<'a> { Ok(IterInfo::BaseAndIterRoot { base, iter_root, - prefix: prefix_path.into(), + prefix: prefix_path.into_owned(), precompose_unicode, }) } else { @@ -363,16 +370,23 @@ impl file::Store { } } - /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads/" or - /// "refs/heads/feature-". - pub fn iter_prefixed_packed<'s, 'p>( + /// As [`iter(…)`](file::Store::iter()), but filters by `prefix`, i.e. `refs/heads/` or + /// `refs/heads/feature-`. + /// Note that if a prefix isn't using a trailing `/`, like in `refs/heads/foo`, it will effectively + /// start the traversal in the parent directory, e.g. `refs/heads/` and list everything inside that + /// starts with `foo`, like `refs/heads/foo` and `refs/heads/foobar`. + /// + /// Prefixes are relative paths with slash-separated components. + // TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it. + pub fn iter_prefixed_packed<'a, 's, 'p>( &'s self, - prefix: Cow<'_, BStr>, + prefix: impl Into<&'a BStr>, packed: Option<&'p packed::Buffer>, ) -> std::io::Result> { + let prefix = prefix.into(); match self.namespace.as_ref() { None => { - let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix.clone(), self.precompose_unicode)?; + let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix, self.precompose_unicode)?; let common_dir_info = self .common_dir() .map(|base| IterInfo::from_prefix(base, prefix, self.precompose_unicode)) @@ -380,7 +394,7 @@ impl file::Store { self.iter_from_info(git_dir_info, common_dir_info, packed) } Some(namespace) => { - let prefix = namespace.to_owned().into_namespaced_prefix(&prefix); + let prefix = namespace.to_owned().into_namespaced_prefix(prefix); let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix.clone(), self.precompose_unicode)?; let common_dir_info = self .common_dir() diff --git a/gix-ref/tests/refs/file/store/iter.rs b/gix-ref/tests/refs/file/store/iter.rs index 2b1e24fd7b7..fb0a6ddb3b3 100644 --- a/gix-ref/tests/refs/file/store/iter.rs +++ b/gix-ref/tests/refs/file/store/iter.rs @@ -1,5 +1,3 @@ -use std::borrow::Cow; - use gix_object::bstr::ByteSlice; use crate::{ @@ -326,7 +324,7 @@ fn loose_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { #[cfg(windows)] let abs_path = r"c:\hello"; - match store.loose_iter_prefixed(Cow::Borrowed(abs_path.as_ref())) { + match store.loose_iter_prefixed(abs_path) { Ok(_) => unreachable!("absolute paths aren't allowed"), Err(err) => assert_eq!(err.to_string(), "prefix must be a relative path, like 'refs/heads/'"), } @@ -335,11 +333,9 @@ fn loose_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { #[test] fn loose_iter_with_prefix() -> crate::Result { - // Test 'refs/heads/' with slash. - let store = store()?; - - let actual = store - .loose_iter_prefixed(b"refs/heads/".as_bstr())? + let prefix_with_slash = b"refs/heads/"; + let actual = store()? + .loose_iter_prefixed(prefix_with_slash)? .collect::, _>>() .expect("no broken ref in this subset") .into_iter() @@ -365,11 +361,9 @@ fn loose_iter_with_prefix() -> crate::Result { #[test] fn loose_iter_with_partial_prefix_dir() -> crate::Result { - // Test 'refs/heads/' without slash. - let store = store()?; - - let actual = store - .loose_iter_prefixed(b"refs/heads".as_bstr())? + let prefix_without_slash = b"refs/heads"; + let actual = store()? + .loose_iter_prefixed(prefix_without_slash)? .collect::, _>>() .expect("no broken ref in this subset") .into_iter() @@ -395,9 +389,7 @@ fn loose_iter_with_partial_prefix_dir() -> crate::Result { #[test] fn loose_iter_with_partial_prefix() -> crate::Result { - let store = store()?; - - let actual = store + let actual = store()? .loose_iter_prefixed(b"refs/heads/d".as_bstr())? .collect::, _>>() .expect("no broken ref in this subset") @@ -542,7 +534,7 @@ fn overlay_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { #[cfg(windows)] let abs_path = r"c:\hello"; - match store.iter()?.prefixed(Cow::Borrowed(abs_path.as_ref())) { + match store.iter()?.prefixed(abs_path) { Ok(_) => unreachable!("absolute paths aren't allowed"), Err(err) => assert_eq!(err.to_string(), "prefix must be a relative path, like 'refs/heads/'"), } @@ -556,7 +548,7 @@ fn overlay_prefixed_iter() -> crate::Result { let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store .iter()? - .prefixed(b"refs/heads/".as_bstr())? + .prefixed(b"refs/heads/")? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); @@ -579,7 +571,7 @@ fn overlay_partial_prefix_iter() -> crate::Result { let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store .iter()? - .prefixed(b"refs/heads/m".as_bstr())? // 'm' is partial + .prefixed(b"refs/heads/m")? // 'm' is partial .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); @@ -597,11 +589,14 @@ fn overlay_partial_prefix_iter_reproduce_1934() -> crate::Result { let ref_names = store .iter()? - .prefixed(b"refs/d".as_bstr())? + .prefixed(b"refs/d")? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; - // Should not match `refs/heads/d1`. - assert_eq!(ref_names, vec![("refs/d1".into(), Object(c1)),]); + assert_eq!( + ref_names, + vec![("refs/d1".into(), Object(c1))], + "Should not match `refs/heads/d1`" + ); Ok(()) } @@ -615,7 +610,7 @@ fn overlay_partial_prefix_iter_when_prefix_is_dir() -> crate::Result { let ref_names = store .iter()? - .prefixed(b"refs/prefix/feature".as_bstr())? + .prefixed(b"refs/prefix/feature")? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; assert_eq!( @@ -628,7 +623,7 @@ fn overlay_partial_prefix_iter_when_prefix_is_dir() -> crate::Result { let ref_names = store .iter()? - .prefixed(b"refs/prefix/feature/".as_bstr())? + .prefixed(b"refs/prefix/feature/")? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; assert_eq!( diff --git a/gix-ref/tests/refs/file/worktree.rs b/gix-ref/tests/refs/file/worktree.rs index d59adb906af..6bc4d73f515 100644 --- a/gix-ref/tests/refs/file/worktree.rs +++ b/gix-ref/tests/refs/file/worktree.rs @@ -191,7 +191,6 @@ mod read_only { mod writable { use gix_lock::acquire::Fail; use gix_ref::{ - bstr::ByteSlice, file::{transaction::PackedRefs, Store}, transaction::{Change, LogChange, PreviousValue, RefEdit}, FullName, FullNameRef, Target, @@ -291,7 +290,7 @@ mod writable { assert_eq!( store .iter()? - .prefixed(b"refs/stacks/".as_bstr())? + .prefixed(b"refs/stacks/")? .map(Result::unwrap) .map(|r| (r.name.to_string(), r.target.to_string())) .collect::>(), @@ -572,7 +571,7 @@ mod writable { assert_eq!( store .iter()? - .prefixed(b"refs/stacks/".as_bstr())? + .prefixed(b"refs/stacks/")? .map(Result::unwrap) .map(|r| (r.name.to_string(), r.target.to_string())) .collect::>(), diff --git a/gix-ref/tests/refs/namespace.rs b/gix-ref/tests/refs/namespace.rs index 70c81d1c7f7..58cf96e3092 100644 --- a/gix-ref/tests/refs/namespace.rs +++ b/gix-ref/tests/refs/namespace.rs @@ -3,14 +3,14 @@ fn into_namespaced_prefix() { assert_eq!( gix_ref::namespace::expand("foo") .unwrap() - .into_namespaced_prefix("prefix".as_ref()), - "refs/namespaces/foo/prefix".as_ref(), + .into_namespaced_prefix("prefix"), + "refs/namespaces/foo/prefix", ); assert_eq!( gix_ref::namespace::expand("foo") .unwrap() - .into_namespaced_prefix("prefix/".as_ref()), - "refs/namespaces/foo/prefix/".as_ref(), + .into_namespaced_prefix("prefix/"), + "refs/namespaces/foo/prefix/", ); } From 52142b472918844f5d4f752aa343ee9e4f9f7c30 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 13 Apr 2025 17:37:06 +0200 Subject: [PATCH 090/193] adapt to changes in `gix-ref`. --- gix-negotiate/tests/baseline/mod.rs | 2 +- gix/src/open/repository.rs | 11 ++++++----- gix/src/reference/iter.rs | 18 ++++++------------ 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/gix-negotiate/tests/baseline/mod.rs b/gix-negotiate/tests/baseline/mod.rs index 84f71f04801..76c18b74cea 100644 --- a/gix-negotiate/tests/baseline/mod.rs +++ b/gix-negotiate/tests/baseline/mod.rs @@ -71,7 +71,7 @@ fn run() -> crate::Result { // } for tip in lookup_names(&["HEAD"]).into_iter().chain( refs.iter()? - .prefixed(b"refs/heads".as_bstr())? + .prefixed(b"refs/heads")? .filter_map(Result::ok) .map(|r| r.target.into_id()), ) { diff --git a/gix/src/open/repository.rs b/gix/src/open/repository.rs index ac61097e5a3..7cadf579028 100644 --- a/gix/src/open/repository.rs +++ b/gix/src/open/repository.rs @@ -1,10 +1,7 @@ #![allow(clippy::result_large_err)] -use gix_features::threading::OwnShared; -use std::ffi::OsStr; -use std::{borrow::Cow, path::PathBuf}; - use super::{Error, Options}; use crate::{ + bstr, bstr::BString, config, config::{ @@ -14,6 +11,9 @@ use crate::{ open::Permissions, ThreadSafeRepository, }; +use gix_features::threading::OwnShared; +use std::ffi::OsStr; +use std::{borrow::Cow, path::PathBuf}; #[derive(Default, Clone)] pub(crate) struct EnvironmentOverrides { @@ -347,9 +347,10 @@ impl ThreadSafeRepository { refs.namespace.clone_from(&config.refs_namespace); let replacements = replacement_objects_refs_prefix(&config.resolved, lenient_config, filter_config_section)? .and_then(|prefix| { + use bstr::ByteSlice; let _span = gix_trace::detail!("find replacement objects"); let platform = refs.iter().ok()?; - let iter = platform.prefixed(prefix.clone()).ok()?; + let iter = platform.prefixed(prefix.as_bstr()).ok()?; let replacements = iter .filter_map(Result::ok) .filter_map(|r: gix_ref::Reference| { diff --git a/gix/src/reference/iter.rs b/gix/src/reference/iter.rs index 576a81a785a..6c975d95bc3 100644 --- a/gix/src/reference/iter.rs +++ b/gix/src/reference/iter.rs @@ -2,10 +2,7 @@ #![allow(clippy::empty_docs)] use std::borrow::Cow; -use gix_ref::{ - bstr::{BStr, ByteSlice}, - file::ReferenceExt, -}; +use gix_ref::{bstr::BStr, file::ReferenceExt}; /// A platform to create iterators over references. #[must_use = "Iterators should be obtained from this iterator platform"] @@ -49,7 +46,7 @@ impl Platform<'_> { // TODO: Create a custom `Path` type that enforces the requirements of git naturally, this type is surprising possibly on windows // and when not using a trailing '/' to signal directories. pub fn prefixed<'a>(&self, prefix: impl Into>) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed(prefix.into())?)) + Ok(Iter::new(self.repo, self.platform.prefixed(prefix.into().as_ref())?)) } // TODO: tests @@ -57,7 +54,7 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/tags`. pub fn tags(&self) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/tags/".as_bstr())?)) + Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/tags/")?)) } // TODO: tests @@ -65,7 +62,7 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/heads`. pub fn local_branches(&self) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/heads/".as_bstr())?)) + Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/heads/")?)) } // TODO: tests @@ -73,10 +70,7 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/remotes`. pub fn remote_branches(&self) -> Result, init::Error> { - Ok(Iter::new( - self.repo, - self.platform.prefixed(b"refs/remotes/".as_bstr())?, - )) + Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/remotes/")?)) } } @@ -123,7 +117,7 @@ impl<'r> Iterator for Iter<'r> { /// pub mod init { - /// The error returned by [`Platform::all()`][super::Platform::all()] or [`Platform::prefixed()`][super::Platform::prefixed()]. + /// The error returned by [`Platform::all()`](super::Platform::all()) or [`Platform::prefixed()`](super::Platform::prefixed()). #[derive(Debug, thiserror::Error)] #[allow(missing_docs)] pub enum Error { From 9fa72c1f0fc274cd145c287b834121b1a3cef6ce Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 14 Apr 2025 17:47:00 -0400 Subject: [PATCH 091/193] Remove old unused cargo-deny `license.clarify` entry 3cfd7fa (#1927) removed `LicenseRef-ring` from the `cargo deny` license allowlist, because we no longer used any `ring` version old enough to involve the old custom license. But the associated entry in the `license.clarify` array that definded `LicenseRef-ring` was not removed, even though it's not needed either given that the license it clarifies is no longer referenced. This cleans that up. --- deny.toml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/deny.toml b/deny.toml index 26587fb91b6..eb328f3d68b 100644 --- a/deny.toml +++ b/deny.toml @@ -50,12 +50,3 @@ deny = [ # end range due to https://github.com/serde-rs/serde/pull/2590 { name = "serde_derive", version = ">1.0.171, <1.0.185" }, ] - - -[[licenses.clarify]] -name = "ring" -expression = "LicenseRef-ring" -license-files = [ - { path = "LICENSE", hash = 0xbd0eed23 }, -] - From 788290717da8ec396635aec386af99e1917bf3a0 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 14 Apr 2025 18:21:51 -0400 Subject: [PATCH 092/193] feat!: `gix-features` uses and republishes `bytesize` version 2 `gix-features` republishes `bytesize`, which has been bumped from major version 1 to major version 2. Because the interface of `bytesize` is effectively part of that of `gix-features` due to the explicit republication of the `bytesize` module in full (with no documented extra limitations related to interface stability), this is effectively a breaking change in `gix-features` as well, though many callers may not be substantially affected. Major changes that may affect some callers that use `bytesize` through `gix-features` include the removal of the top-level `bytesize::to_string()` function, the change in default behavior from displaying decimal SI units to displaying binary IEC units (though all or most gitoxide-related creates, in adapting to the changes, have thus far opted to continue using decimal SI units), and the small but UI-facing change that decimal SI kilobytes (units of 1000 bytes) are given with the symbol "kB" rather than the more ambiguous (and arguably less accurate) symbol "KB". In addition to republishing `bytesize`, `gix-features` also republishes `prodash`. Futhermore, some uses of `bytesize` are transitively through `prodash`, which itself has recently received an update to use `bytesize` major version 2. (Since `prodash` does not republish `bytesize`, that is not considered to be a breaking change in `prodash` itself.) To get the benefits of the newer version of `bytesize` while avoiding new inconsistencies, and also to avoid depending on multiple versions of `bytesize`, the `prodash` dependency version has also been upgraded. For more information, see: - https://github.com/GitoxideLabs/gitoxide/discussions/1952 - https://github.com/bytesize-rs/bytesize/releases/tag/bytesize-v2.0.0 - https://github.com/GitoxideLabs/gitoxide/pull/1949 - https://github.com/Byron/prodash/pull/33 - https://github.com/GitoxideLabs/gitoxide/pull/1953 --- gix-features/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gix-features/Cargo.toml b/gix-features/Cargo.toml index 09c919b715f..c2e75d6f6fd 100644 --- a/gix-features/Cargo.toml +++ b/gix-features/Cargo.toml @@ -4,7 +4,7 @@ lints.workspace = true name = "gix-features" description = "A crate to integrate various capabilities using compile-time feature flags" repository = "https://github.com/GitoxideLabs/gitoxide" -version = "0.41.1" +version = "0.42.0" authors = ["Sebastian Thiel "] license = "MIT OR Apache-2.0" edition = "2021" From 63155368cc5074328314f1b3f565e5813df725cf Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 14 Apr 2025 18:46:04 -0400 Subject: [PATCH 093/193] Adapt `Cargo.toml` files in workspace to `gix-features` bump This does not increment their package versions, which can be done when they are actually being released. It only bumps the versions of `gix-features` they specify as dependencies, to allow them to build again after the "out of band" version bump done in the preceding commit. For context, see the preceding commit as well as: https://github.com/GitoxideLabs/gitoxide/discussions/1952 --- Cargo.lock | 54 +++++++++++++++++----------------- Cargo.toml | 2 +- gix-config/Cargo.toml | 2 +- gix-fs/Cargo.toml | 2 +- gix-glob/Cargo.toml | 2 +- gix-hash/Cargo.toml | 2 +- gix-index/Cargo.toml | 2 +- gix-object/Cargo.toml | 2 +- gix-odb/Cargo.toml | 2 +- gix-pack/Cargo.toml | 2 +- gix-protocol/Cargo.toml | 2 +- gix-ref/Cargo.toml | 2 +- gix-status/Cargo.toml | 2 +- gix-transport/Cargo.toml | 2 +- gix-url/Cargo.toml | 2 +- gix-worktree-state/Cargo.toml | 2 +- gix-worktree-stream/Cargo.toml | 2 +- gix-worktree/Cargo.toml | 2 +- gix/Cargo.toml | 2 +- 19 files changed, 45 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea022114ebb..74337864f53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1334,7 +1334,7 @@ dependencies = [ "futures-lite", "gitoxide-core", "gix", - "gix-features 0.41.1", + "gix-features 0.42.0", "is-terminal", "once_cell", "prodash 29.0.2", @@ -1403,7 +1403,7 @@ dependencies = [ "gix-diff", "gix-dir", "gix-discover 0.39.0", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-filter", "gix-fs 0.14.0", "gix-glob 0.19.0", @@ -1653,7 +1653,7 @@ dependencies = [ "criterion", "document-features", "gix-config-value", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-glob 0.19.0", "gix-path 0.10.15", "gix-ref 0.51.0", @@ -1859,7 +1859,7 @@ dependencies = [ [[package]] name = "gix-features" -version = "0.41.1" +version = "0.42.0" dependencies = [ "bstr", "bytes", @@ -1923,7 +1923,7 @@ dependencies = [ "bstr", "crossbeam-channel", "fastrand", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-path 0.10.15", "gix-utils 0.2.0", "is_ci", @@ -1962,7 +1962,7 @@ dependencies = [ "bitflags 2.9.0", "bstr", "document-features", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-path 0.10.15", "gix-testtools", "serde", @@ -1984,7 +1984,7 @@ version = "0.17.0" dependencies = [ "document-features", "faster-hex 0.10.0", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-testtools", "serde", "sha1-checked", @@ -2077,7 +2077,7 @@ dependencies = [ "filetime", "fnv", "gix-bitmap 0.2.14", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-fs 0.14.0", "gix-hash 0.17.0", "gix-lock 17.0.0", @@ -2102,7 +2102,7 @@ version = "0.0.0" dependencies = [ "bstr", "filetime", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-hash 0.17.0", "gix-index 0.39.0", "gix-object 0.48.0", @@ -2237,7 +2237,7 @@ dependencies = [ "document-features", "gix-actor 0.34.0", "gix-date 0.9.4", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-hash 0.17.0", "gix-hashtable 0.8.0", "gix-odb", @@ -2261,7 +2261,7 @@ dependencies = [ "arc-swap", "document-features", "gix-date 0.9.4", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-fs 0.14.0", "gix-hash 0.17.0", "gix-hashtable 0.8.0", @@ -2283,7 +2283,7 @@ dependencies = [ "filetime", "gix-actor 0.34.0", "gix-date 0.9.4", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-hash 0.17.0", "gix-object 0.48.0", "gix-odb", @@ -2301,7 +2301,7 @@ dependencies = [ "document-features", "gix-chunk 0.4.11", "gix-diff", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-hash 0.17.0", "gix-hashtable 0.8.0", "gix-object 0.48.0", @@ -2322,7 +2322,7 @@ name = "gix-pack-tests" version = "0.0.0" dependencies = [ "bstr", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-hash 0.17.0", "gix-object 0.48.0", "gix-odb", @@ -2436,7 +2436,7 @@ dependencies = [ "futures-lite", "gix-credentials", "gix-date 0.9.4", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-hash 0.17.0", "gix-lock 17.0.0", "gix-negotiate", @@ -2508,7 +2508,7 @@ dependencies = [ "document-features", "gix-actor 0.34.0", "gix-date 0.9.4", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-fs 0.14.0", "gix-hash 0.17.0", "gix-lock 17.0.0", @@ -2531,7 +2531,7 @@ dependencies = [ "gix-actor 0.34.0", "gix-date 0.9.4", "gix-discover 0.39.0", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-fs 0.14.0", "gix-hash 0.17.0", "gix-lock 17.0.0", @@ -2655,7 +2655,7 @@ dependencies = [ "filetime", "gix-diff", "gix-dir", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-filter", "gix-fs 0.14.0", "gix-hash 0.17.0", @@ -2676,7 +2676,7 @@ dependencies = [ "filetime", "gix-diff", "gix-dir", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-filter", "gix-fs 0.14.0", "gix-hash 0.17.0", @@ -2697,7 +2697,7 @@ version = "0.18.0" dependencies = [ "bstr", "gix-config", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-path 0.10.15", "gix-pathspec", "gix-refspec", @@ -2794,7 +2794,7 @@ dependencies = [ "futures-lite", "gix-command", "gix-credentials", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-hash 0.17.0", "gix-pack", "gix-packetline", @@ -2864,7 +2864,7 @@ dependencies = [ "assert_matches", "bstr", "document-features", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-path 0.10.15", "gix-testtools", "percent-encoding", @@ -2937,7 +2937,7 @@ dependencies = [ "bstr", "document-features", "gix-attributes 0.25.0", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-fs 0.14.0", "gix-glob 0.19.0", "gix-hash 0.17.0", @@ -2954,7 +2954,7 @@ name = "gix-worktree-state" version = "0.18.0" dependencies = [ "bstr", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-filter", "gix-fs 0.14.0", "gix-glob 0.19.0", @@ -2972,7 +2972,7 @@ name = "gix-worktree-state-tests" version = "0.0.0" dependencies = [ "gix-discover 0.39.0", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-filter", "gix-fs 0.14.0", "gix-hash 0.17.0", @@ -2991,7 +2991,7 @@ name = "gix-worktree-stream" version = "0.20.0" dependencies = [ "gix-attributes 0.25.0", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-filter", "gix-fs 0.14.0", "gix-hash 0.17.0", @@ -3012,7 +3012,7 @@ dependencies = [ "bstr", "gix-attributes 0.25.0", "gix-discover 0.39.0", - "gix-features 0.41.1", + "gix-features 0.42.0", "gix-fs 0.14.0", "gix-glob 0.19.0", "gix-hash 0.17.0", diff --git a/Cargo.toml b/Cargo.toml index a51765d4cb9..7cd5df3a944 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,7 +168,7 @@ gitoxide-core-async-client = ["gitoxide-core/async-client", "futures-lite"] anyhow = "1.0.42" gitoxide-core = { version = "^0.46.0", path = "gitoxide-core" } -gix-features = { version = "^0.41.1", path = "gix-features" } +gix-features = { version = "^0.42.0", path = "gix-features" } gix = { version = "^0.71.0", path = "gix", default-features = false } clap = { version = "4.5.36", features = ["derive", "cargo"] } diff --git a/gix-config/Cargo.toml b/gix-config/Cargo.toml index 5f177ced615..2c28c355f21 100644 --- a/gix-config/Cargo.toml +++ b/gix-config/Cargo.toml @@ -19,7 +19,7 @@ autotests = false serde = ["dep:serde", "bstr/serde", "gix-sec/serde", "gix-ref/serde", "gix-glob/serde", "gix-config-value/serde"] [dependencies] -gix-features = { version = "^0.41.1", path = "../gix-features" } +gix-features = { version = "^0.42.0", path = "../gix-features" } gix-config-value = { version = "^0.14.12", path = "../gix-config-value" } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-sec = { version = "^0.10.12", path = "../gix-sec" } diff --git a/gix-fs/Cargo.toml b/gix-fs/Cargo.toml index 94226708d7a..d308adfe82e 100644 --- a/gix-fs/Cargo.toml +++ b/gix-fs/Cargo.toml @@ -21,7 +21,7 @@ serde = ["dep:serde"] [dependencies] bstr = "1.12.0" gix-path = { version = "^0.10.15", path = "../gix-path" } -gix-features = { version = "^0.41.1", path = "../gix-features", features = ["fs-read-dir"] } +gix-features = { version = "^0.42.0", path = "../gix-features", features = ["fs-read-dir"] } gix-utils = { version = "^0.2.0", path = "../gix-utils" } thiserror = "2.0.0" serde = { version = "1.0.114", optional = true, default-features = false, features = ["std", "derive"] } diff --git a/gix-glob/Cargo.toml b/gix-glob/Cargo.toml index 5a9156c7407..03b75a78b0d 100644 --- a/gix-glob/Cargo.toml +++ b/gix-glob/Cargo.toml @@ -20,7 +20,7 @@ serde = ["dep:serde", "bstr/serde", "bitflags/serde"] [dependencies] gix-path = { version = "^0.10.15", path = "../gix-path" } -gix-features = { version = "^0.41.1", path = "../gix-features" } +gix-features = { version = "^0.42.0", path = "../gix-features" } bstr = { version = "1.12.0", default-features = false, features = ["std"] } bitflags = "2" serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } diff --git a/gix-hash/Cargo.toml b/gix-hash/Cargo.toml index d193c664852..5f8e71e6eb3 100644 --- a/gix-hash/Cargo.toml +++ b/gix-hash/Cargo.toml @@ -20,7 +20,7 @@ test = false serde = ["dep:serde"] [dependencies] -gix-features = { version = "^0.41.1", path = "../gix-features", features = ["progress"] } +gix-features = { version = "^0.42.0", path = "../gix-features", features = ["progress"] } thiserror = "2.0.0" faster-hex = { version = "0.10.0" } diff --git a/gix-index/Cargo.toml b/gix-index/Cargo.toml index ddea59ca3be..62cabd34ed7 100644 --- a/gix-index/Cargo.toml +++ b/gix-index/Cargo.toml @@ -22,7 +22,7 @@ test = true serde = ["dep:serde", "smallvec/serde", "gix-hash/serde"] [dependencies] -gix-features = { version = "^0.41.1", path = "../gix-features", features = [ +gix-features = { version = "^0.42.0", path = "../gix-features", features = [ "progress", ] } gix-hash = { version = "^0.17.0", path = "../gix-hash" } diff --git a/gix-object/Cargo.toml b/gix-object/Cargo.toml index f8b68d5e45f..e8df5b9a7f9 100644 --- a/gix-object/Cargo.toml +++ b/gix-object/Cargo.toml @@ -41,7 +41,7 @@ serde = [ verbose-object-parsing-errors = ["winnow/std"] [dependencies] -gix-features = { version = "^0.41.1", path = "../gix-features", features = [ +gix-features = { version = "^0.42.0", path = "../gix-features", features = [ "progress", ] } gix-hash = { version = "^0.17.0", path = "../gix-hash" } diff --git a/gix-odb/Cargo.toml b/gix-odb/Cargo.toml index 5fb72b6f61b..8c0ee48e7d2 100644 --- a/gix-odb/Cargo.toml +++ b/gix-odb/Cargo.toml @@ -20,7 +20,7 @@ doctest = false serde = ["dep:serde", "gix-hash/serde", "gix-object/serde", "gix-pack/serde"] [dependencies] -gix-features = { version = "^0.41.1", path = "../gix-features", features = ["walkdir", "zlib", "crc32"] } +gix-features = { version = "^0.42.0", path = "../gix-features", features = ["walkdir", "zlib", "crc32"] } gix-hashtable = { version = "^0.8.0", path = "../gix-hashtable" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-date = { version = "^0.9.4", path = "../gix-date" } diff --git a/gix-pack/Cargo.toml b/gix-pack/Cargo.toml index c3573c3e492..9bcc76a3ca6 100644 --- a/gix-pack/Cargo.toml +++ b/gix-pack/Cargo.toml @@ -34,7 +34,7 @@ serde = ["dep:serde", "gix-object/serde"] wasm = ["gix-diff?/wasm"] [dependencies] -gix-features = { version = "^0.41.1", path = "../gix-features", features = ["crc32", "progress", "zlib"] } +gix-features = { version = "^0.42.0", path = "../gix-features", features = ["crc32", "progress", "zlib"] } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-chunk = { version = "^0.4.11", path = "../gix-chunk" } diff --git a/gix-protocol/Cargo.toml b/gix-protocol/Cargo.toml index 5d52c67636a..cb4ca0d18da 100644 --- a/gix-protocol/Cargo.toml +++ b/gix-protocol/Cargo.toml @@ -68,7 +68,7 @@ path = "tests/async-protocol.rs" required-features = ["async-client"] [dependencies] -gix-features = { version = "^0.41.1", path = "../gix-features", features = [ +gix-features = { version = "^0.42.0", path = "../gix-features", features = [ "progress", ] } gix-transport = { version = "^0.46.0", path = "../gix-transport" } diff --git a/gix-ref/Cargo.toml b/gix-ref/Cargo.toml index c368479a399..90a2f7346b8 100644 --- a/gix-ref/Cargo.toml +++ b/gix-ref/Cargo.toml @@ -21,7 +21,7 @@ test = true serde = ["dep:serde", "gix-hash/serde", "gix-actor/serde", "gix-object/serde"] [dependencies] -gix-features = { version = "^0.41.1", path = "../gix-features", features = ["walkdir"] } +gix-features = { version = "^0.42.0", path = "../gix-features", features = ["walkdir"] } gix-fs = { version = "^0.14.0", path = "../gix-fs" } gix-path = { version = "^0.10.15", path = "../gix-path" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } diff --git a/gix-status/Cargo.toml b/gix-status/Cargo.toml index d22d4006d06..5102d316aa1 100644 --- a/gix-status/Cargo.toml +++ b/gix-status/Cargo.toml @@ -25,7 +25,7 @@ gix-fs = { version = "^0.14.0", path = "../gix-fs" } gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-object = { version = "^0.48.0", path = "../gix-object" } gix-path = { version = "^0.10.15", path = "../gix-path" } -gix-features = { version = "^0.41.1", path = "../gix-features", features = ["progress"] } +gix-features = { version = "^0.42.0", path = "../gix-features", features = ["progress"] } gix-filter = { version = "^0.18.0", path = "../gix-filter" } gix-worktree = { version = "^0.40.0", path = "../gix-worktree", default-features = false, features = ["attributes"] } gix-pathspec = { version = "^0.10.0", path = "../gix-pathspec" } diff --git a/gix-transport/Cargo.toml b/gix-transport/Cargo.toml index 7a21d63734f..77d297c7894 100644 --- a/gix-transport/Cargo.toml +++ b/gix-transport/Cargo.toml @@ -82,7 +82,7 @@ required-features = ["async-client"] [dependencies] gix-command = { version = "^0.5.0", path = "../gix-command" } -gix-features = { version = "^0.41.1", path = "../gix-features" } +gix-features = { version = "^0.42.0", path = "../gix-features" } gix-url = { version = "^0.30.0", path = "../gix-url" } gix-sec = { version = "^0.10.12", path = "../gix-sec" } gix-packetline = { version = "^0.18.4", path = "../gix-packetline" } diff --git a/gix-url/Cargo.toml b/gix-url/Cargo.toml index 5abf17feea6..8a546ee9c74 100644 --- a/gix-url/Cargo.toml +++ b/gix-url/Cargo.toml @@ -19,7 +19,7 @@ doctest = false serde = ["dep:serde", "bstr/serde"] [dependencies] -gix-features = { version = "^0.41.1", path = "../gix-features" } +gix-features = { version = "^0.42.0", path = "../gix-features" } gix-path = { version = "^0.10.15", path = "../gix-path" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["std", "derive"] } diff --git a/gix-worktree-state/Cargo.toml b/gix-worktree-state/Cargo.toml index 154f3afef9d..43f24bc551d 100644 --- a/gix-worktree-state/Cargo.toml +++ b/gix-worktree-state/Cargo.toml @@ -23,7 +23,7 @@ gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-object = { version = "^0.48.0", path = "../gix-object" } gix-glob = { version = "^0.19.0", path = "../gix-glob" } gix-path = { version = "^0.10.15", path = "../gix-path" } -gix-features = { version = "^0.41.1", path = "../gix-features" } +gix-features = { version = "^0.42.0", path = "../gix-features" } gix-filter = { version = "^0.18.0", path = "../gix-filter" } io-close = "0.3.7" diff --git a/gix-worktree-stream/Cargo.toml b/gix-worktree-stream/Cargo.toml index a1e2992b6f4..dedb1625415 100644 --- a/gix-worktree-stream/Cargo.toml +++ b/gix-worktree-stream/Cargo.toml @@ -15,7 +15,7 @@ include = ["src/**/*", "LICENSE-*"] doctest = false [dependencies] -gix-features = { version = "^0.41.1", path = "../gix-features", features = ["progress", "io-pipe"] } +gix-features = { version = "^0.42.0", path = "../gix-features", features = ["progress", "io-pipe"] } gix-hash = { version = "^0.17.0", path = "../gix-hash" } gix-object = { version = "^0.48.0", path = "../gix-object" } gix-attributes = { version = "^0.25.0", path = "../gix-attributes" } diff --git a/gix-worktree/Cargo.toml b/gix-worktree/Cargo.toml index dbdeb333d28..9524b64b61e 100644 --- a/gix-worktree/Cargo.toml +++ b/gix-worktree/Cargo.toml @@ -32,7 +32,7 @@ gix-path = { version = "^0.10.15", path = "../gix-path" } gix-attributes = { version = "^0.25.0", path = "../gix-attributes", optional = true } gix-validate = { version = "^0.9.4", path = "../gix-validate", optional = true } gix-ignore = { version = "^0.14.0", path = "../gix-ignore" } -gix-features = { version = "^0.41.1", path = "../gix-features" } +gix-features = { version = "^0.42.0", path = "../gix-features" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } bstr = { version = "1.12.0", default-features = false } diff --git a/gix/Cargo.toml b/gix/Cargo.toml index 4b1045bdd27..d78595756f0 100644 --- a/gix/Cargo.toml +++ b/gix/Cargo.toml @@ -344,7 +344,7 @@ gix-traverse = { version = "^0.45.0", path = "../gix-traverse" } gix-diff = { version = "^0.51.0", path = "../gix-diff", default-features = false } gix-merge = { version = "^0.4.0", path = "../gix-merge", default-features = false, optional = true } gix-mailmap = { version = "^0.26.0", path = "../gix-mailmap", optional = true } -gix-features = { version = "^0.41.1", path = "../gix-features", features = [ +gix-features = { version = "^0.42.0", path = "../gix-features", features = [ "progress", "once_cell", ] } From a74a8615c350e16f1ec55121754b1c9204713488 Mon Sep 17 00:00:00 2001 From: DianaNites <5275194+DianaNites@users.noreply.github.com> Date: Tue, 15 Apr 2025 13:04:06 +0200 Subject: [PATCH 094/193] Add reftable test --- gix-discover/tests/discover/is_git/mod.rs | 8 ++++++++ .../generated-archives/make_reftable_repo.tar | Bin 0 -> 52224 bytes .../tests/fixtures/make_reftable_repo.sh | 13 +++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 gix-discover/tests/fixtures/generated-archives/make_reftable_repo.tar create mode 100755 gix-discover/tests/fixtures/make_reftable_repo.sh diff --git a/gix-discover/tests/discover/is_git/mod.rs b/gix-discover/tests/discover/is_git/mod.rs index 09f8576a409..a7cdd4ce86d 100644 --- a/gix-discover/tests/discover/is_git/mod.rs +++ b/gix-discover/tests/discover/is_git/mod.rs @@ -130,3 +130,11 @@ fn split_worktree_using_configuration() -> crate::Result { } Ok(()) } + +#[test] +fn reftable() -> crate::Result { + let repo = gix_testtools::scripted_fixture_read_only("make_reftable_repo.sh")?.join("reftable-clone"); + let kind = gix_discover::is_git(&repo)?; + assert_eq!(kind, gix_discover::repository::Kind::WorkTree { linked_git_dir: None }); + Ok(()) +} diff --git a/gix-discover/tests/fixtures/generated-archives/make_reftable_repo.tar b/gix-discover/tests/fixtures/generated-archives/make_reftable_repo.tar new file mode 100644 index 0000000000000000000000000000000000000000..b57fe223574aa22c0bfa6dd8924a4ab9dad73626 GIT binary patch literal 52224 zcmeHQ4RjR69p4Z@30k1#Rjk@BAQC<Yemu&Hd;5`Wxx0;bdvLU+ zXj`h%M^S2Rp*(7lCt|Un0kJ#;pVsmrK?RhyQp-aq)>kdBPZ534cJ`7Zxw*@2ve|(^ z=H5&0W_I?!Gr!;d|NEcWnfaG76!s4bKe8xN&Nuv^-|0NS3KC#BmgCdMWu6l$5qr(x z1(FF{iPLnKFO_auo5pon;Q0{{*9}_X0Y5J8CZmVzf4v@wSS4;Ck>i&t0*L;X)tR>M zO?C9YllGsJc!Ah|-za$d< z_n+-tiG}%RSino1$ntDh32I>_#7c%NN+C%$LV8G5_>dq-f|4sXE63r#p#KN^dfEOT z2PCJzm?Z^MqKEr`siG-+c2Awos=FpP?cRN&7j@lhy$550nuzUw2o%zP4){}FFZN$# zW#a$&1Ajp&h52VR9vXdxlfrU{RfM1z)FfFJ1x05?jTJOQ)dh`J3toXr_wx(de+i)W zpJPRd*nbyX{WzQ|8Z)Y@dL}D{S%GDFFs*d=uCYdNXZ=%q_P%uVRMiXrRt|i4qUoOT zuQm0jPE~!03>El+diRl0NdNf@Y5xIB?EiVVO$zhR1VgIEt6^3#pzW7bKBNTsprY`) zC>WZ|DM9!rxZNgh{yztAG{pbsSja!||MA}dsUrPnQ%ZV)f#tJL4E{_1{hudCvJc($ z&&qM7L+UOcG=6*Wo)c(bGjQdv%s$5I|^!b0V-#t?P!SY`|R2kR4vh?Q%rY=0#_t#Amcf9+| z@w3lQdFFWE`))egXVAXju|Ea3Zxw_4x9yxL_1^mN`YFe@fAWRk-|UhOHIo!-2Z4h6 zFST=0C$qiTfAapXlQ4TKUYLI-r0HBJ9Og8jNdhl~gJCYD=7lNwDhq^lc z%K{m-{~Un53S$2~QQE1KGV?#~rKo-zi%xdxTvGVrM*U#e8X?tN#a3 z{||^jfO3@ ztY&(JGfa3j1!%Tp=z*;(ZrJk3nng?Ml2u1$_x}67>MN389b^3VVfuHc7S-Q&oSFHb zF*Wfow^u=uj}?LZ`tQ$s-%Q0l^#6EKBK^M%emK9|FBN`pnVd*-{(&&V4)0P1xv{Z&}P;6U|#}agDGS+ehM?{o1 z4SK$nq~|Fy=(<{TGLiOBqoc;blSh}$vXt4*j~@^>6}hGI=|9Z#b$Hg3{U_`H5vK4Y z+vA_9*A>mDyTHx41hNeb4Ro1m|&(h z=&>1AGOp?jbV#j~sX0GV0nJRP7OV~fCEE$cFjICit|yo}J*LOu<+Oli1!9&RaE3OS zs4_>d&D{9#M}x%(p`a{sfCGVK%uF$5usyo1*28*?aWH9q8Zx8Dr4!9nPB6_?W=5CH z3dfZgEIll$G&iB8Q4{FqA|?HzdOU+^MwnCf!dul03~lv4lh^)T)43xa{69e;^S?U> zvd7XHuJiHFuqlVSmJbMIC53<@Xk1V;*fJ=i;ME-g1=fE;6-WI)4$dng>wgM@>eIpL z6}Q$DQ3Es5idug3j#JcnYWU=eo6CC*fc&;KTGV_bqZmBgG=AfTML&6U#g7(0d3@@j z(GQNkxzGLAAa>FbRx~7iE^@>%g@cDW|EYYUDC$~@;;CMBRB>hMuj;N(8j`khdO*>R zt2a`w?rW5;d1uQD*R6W{@aEI&{+E1qZs4|k$Icu+ym#5MgTtl;Umv=87}!FOoH?L$ zzg>T#>WO#yetc}@nQb*=7HwL6=G%SFzIpWE>hOX|#l^*E?_Ygp{lR0)!VCWQ!-Lz7 zoY}wnSk2i__AWcKc<~IoFForOP{-5 ztdK|4%FK>(Ssc+=K2ZiYirY)YXRimNF8gEYu0!&3o8Tr$oWLCnG`+t5%|q{p>l=DM zQ~J&uldEqZ)%U|)d#@Svo)MiqwyLS=vK4E8Q~TKRRm;~dz4rZu4>lgE;2u>!|Hdy~ z+OzAmmtTJ6<&&!(=ttfDHO6d@ybPP|e6P>sSN-_zw==)VcaKB>s$-k|ADjLEOdgXy zk|>Lqi7ssl=3@U@R^-v~Un%{(I3JAk@cm!1p6LZ2@fY4#Js-D2PrF7&*W3Dk&V$-d z99;E3XZ<(ed6-Au|M_Lkvl|GAw0pCHR*{;Fmo2Q2V*d!bqS?^nPFq}5*RKa4s<>_37djwHgrKLH<*in`kWoc$l+ zj$m;AH}d`$0TM$p|Nf68{sRW6yQRo1{r4;21JY7&_Fp3QAHfkv65-#UfDcGT-RysE z{0C_NIr9D=fe}lR#DBm7>qR3pOaJ`}_<*$DgZ<}tp4fi`Ml8uJ{{0I0fYj6z|FADg z#{Uo?F(kA2_bcE7Qcn;31DTBfBPilYBK-Rk@Byi+oBx*^|G}Z3%>PDU#FEV4|0nSu zuz=kSg=Xo$UjZMGc6ze^fV}@hV8oI{`1dE^15#5r`=1;C0os4E|1W|fo+OF?fCtx$ zMQXPG`xNj2X}mZ4Pu~9_Fk(p}{QDE|0ja5*{m+g60D}vW{XY>D@gy_zKkg;*AMgO& z&84RGf6~dKnhit@^u>KV8BUSn7Nhhsh2@xS3lTyRf#^8Vj99i#^14<9d zNb7%_03SG-?xz2auA}N&FWSk)D-K>%ZRtUl0i0^gmDh7r=@ldHy3f z;z;Jif4O|Yz;yf<_}vo!#q>S?%db9OGv#lm+4V!FJpd+fi~B68KRq2s3Kchaj*4+dDoGg(3Un_$6er4-_OPn*Goj^DLPY`qBKl74A*8k#Ty;ZWq zO-DYo&dZV!l5|Ot4WNd2UQ`tT-9rmZbo}?*5<9Cm``3d?mUaVQBm> Xr|U;%gtr40$tDO81PB6`5CZ=PU710v literal 0 HcmV?d00001 diff --git a/gix-discover/tests/fixtures/make_reftable_repo.sh b/gix-discover/tests/fixtures/make_reftable_repo.sh new file mode 100755 index 00000000000..11eac3a2f77 --- /dev/null +++ b/gix-discover/tests/fixtures/make_reftable_repo.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -eu -o pipefail + +git init -q + +git checkout -b main +touch this +git add this +git commit -q -m c1 +echo hello >> this +git commit -q -am c2 + +git clone --ref-format=reftable . reftable-clone From a4801fe1817da8fb3da7744d5897718abc28d308 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 14 Apr 2025 21:32:05 +0200 Subject: [PATCH 095/193] fix: assure valid path components are never plain `.` or `..`. --- gix-validate/src/path.rs | 5 +++++ gix-validate/tests/path/mod.rs | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/gix-validate/src/path.rs b/gix-validate/src/path.rs index 51997b9be1e..e924b5b452e 100644 --- a/gix-validate/src/path.rs +++ b/gix-validate/src/path.rs @@ -20,6 +20,8 @@ pub mod component { DotGitDir, #[error("The .gitmodules file must not be a symlink")] SymlinkedGitModules, + #[error("Relative components '.' and '..' are disallowed")] + Relative, } /// Further specify what to check for in [`component()`](super::component()) @@ -78,6 +80,9 @@ pub fn component( if input.is_empty() { return Err(component::Error::Empty); } + if input == ".." || input == "." { + return Err(component::Error::Relative); + } if protect_windows { if input.find_byteset(br"/\").is_some() { return Err(component::Error::PathSeparator); diff --git a/gix-validate/tests/path/mod.rs b/gix-validate/tests/path/mod.rs index 1330ff4a9c7..4c53601a932 100644 --- a/gix-validate/tests/path/mod.rs +++ b/gix-validate/tests/path/mod.rs @@ -253,6 +253,10 @@ mod component { mktest!(con_with_extension, b"CON.abc", Error::WindowsReservedName); mktest!(con_with_middle, b"CON.tar.xz", Error::WindowsReservedName); mktest!(con_mixed_with_middle, b"coN.tar.xz ", Error::WindowsReservedName); + mktest!(dot_dot, b"..", Error::Relative); + mktest!(dot_dot_no_opts, b"..", Error::Relative, NO_OPTS); + mktest!(single_dot, b".", Error::Relative); + mktest!(single_dot_no_opts, b".", Error::Relative, NO_OPTS); mktest!( conout_mixed_with_extension, b"ConOut$ .xyz", From 692caeba599110d61da66cbbff545f2bc16748d5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 15 Apr 2025 21:22:51 +0200 Subject: [PATCH 096/193] fix!: don't panic, instead provide an error when fixture script fails. This makes introspection easier, even though we still have to print to script output to stderr in order to make it legible. --- tests/tools/src/lib.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/tools/src/lib.rs b/tests/tools/src/lib.rs index a9c2938a56f..882231c6f48 100644 --- a/tests/tools/src/lib.rs +++ b/tests/tools/src/lib.rs @@ -583,13 +583,10 @@ fn scripted_fixture_read_only_with_args_inner( }; if !output.status.success() { write_failure_marker(&failure_marker); + eprintln!("stdout: {}", output.stdout.as_bstr()); + eprintln!("stderr: {}", output.stderr.as_bstr()); + return Err(format!("fixture script of {cmd:?} failed").into()); } - assert!( - output.status.success(), - "fixture script of {cmd:?} failed: stdout: {}\nstderr: {}", - output.stdout.as_bstr(), - output.stderr.as_bstr() - ); create_archive_if_we_should( &script_result_directory, &archive_file_path, From 8624586f4d9df726afe1c6939b952e4241865571 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 15 Apr 2025 11:03:45 +0200 Subject: [PATCH 097/193] fix: make `is_executable()` more permissive by taking the group and 'other' permissions into account. --- gix-fs/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gix-fs/src/lib.rs b/gix-fs/src/lib.rs index 9f77d8e8614..b04ba80eced 100644 --- a/gix-fs/src/lib.rs +++ b/gix-fs/src/lib.rs @@ -77,10 +77,10 @@ pub struct Stack { } #[cfg(unix)] -/// Returns whether a a file has the executable permission set. +/// Returns whether a file has the executable permission set. pub fn is_executable(metadata: &std::fs::Metadata) -> bool { use std::os::unix::fs::MetadataExt; - (metadata.mode() & 0o100) != 0 + (metadata.mode() & 0o111) != 0 } /// Classifiers for IO-errors. From 59c8a965081303ff6f86607af7b1f66e79f04c93 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 2 Feb 2025 09:32:19 +0100 Subject: [PATCH 098/193] fix: repositories using ref-tables will be recognised. --- gix-discover/src/is.rs | 30 ++++++++++++------- .../discover/{is_git/mod.rs => is_git.rs} | 11 +++++-- .../tests/discover/{parse/mod.rs => parse.rs} | 0 .../tests/discover/{path/mod.rs => path.rs} | 0 4 files changed, 28 insertions(+), 13 deletions(-) rename gix-discover/tests/discover/{is_git/mod.rs => is_git.rs} (91%) rename gix-discover/tests/discover/{parse/mod.rs => parse.rs} (100%) rename gix-discover/tests/discover/{path/mod.rs => path.rs} (100%) diff --git a/gix-discover/src/is.rs b/gix-discover/src/is.rs index 6817a5fe8af..5c88db3a1f5 100644 --- a/gix-discover/src/is.rs +++ b/gix-discover/src/is.rs @@ -1,6 +1,5 @@ -use std::{borrow::Cow, ffi::OsStr, path::Path}; - use crate::{DOT_GIT_DIR, MODULES}; +use std::{borrow::Cow, ffi::OsStr, path::Path}; /// Returns true if the given `git_dir` seems to be a bare repository. /// @@ -67,21 +66,30 @@ pub(crate) fn git_with_metadata( { // Fast-path: avoid doing the complete search if HEAD is already not there. - // TODO(reftable): use a ref-store to lookup HEAD if ref-tables should be supported, or detect ref-tables beforehand. - // Actually ref-tables still keep a specially marked `HEAD` around, so nothing might be needed here - // Even though our head-check later would fail without supporting it. if !dot_git.join("HEAD").exists() { return Err(crate::is_git::Error::MissingHead); } // We expect to be able to parse any ref-hash, so we shouldn't have to know the repos hash here. - // With ref-table, the has is probably stored as part of the ref-db itself, so we can handle it from there. + // With ref-table, the hash is probably stored as part of the ref-db itself, so we can handle it from there. // In other words, it's important not to fail on detached heads here because we guessed the hash kind wrongly. let refs = gix_ref::file::Store::at(dot_git.as_ref().into(), Default::default()); - let head = refs.find_loose("HEAD")?; - if head.name.as_bstr() != "HEAD" { - return Err(crate::is_git::Error::MisplacedHead { - name: head.name.into_inner(), - }); + match refs.find_loose("HEAD") { + Ok(head) => { + if head.name.as_bstr() != "HEAD" { + return Err(crate::is_git::Error::MisplacedHead { + name: head.name.into_inner(), + }); + } + } + Err(gix_ref::file::find::existing::Error::Find(gix_ref::file::find::Error::ReferenceCreation { + source: _, + relative_path, + })) if relative_path == Path::new("HEAD") => { + // It's fine as long as the reference is found is `HEAD`. + } + Err(err) => { + return Err(err.into()); + } } } diff --git a/gix-discover/tests/discover/is_git/mod.rs b/gix-discover/tests/discover/is_git.rs similarity index 91% rename from gix-discover/tests/discover/is_git/mod.rs rename to gix-discover/tests/discover/is_git.rs index a7cdd4ce86d..f7e0644c774 100644 --- a/gix-discover/tests/discover/is_git/mod.rs +++ b/gix-discover/tests/discover/is_git.rs @@ -133,8 +133,15 @@ fn split_worktree_using_configuration() -> crate::Result { #[test] fn reftable() -> crate::Result { - let repo = gix_testtools::scripted_fixture_read_only("make_reftable_repo.sh")?.join("reftable-clone"); - let kind = gix_discover::is_git(&repo)?; + let repo_path = match gix_testtools::scripted_fixture_read_only("make_reftable_repo.sh") { + Ok(root) => root.join("reftable-clone/.git"), + Err(_) if *gix_testtools::GIT_VERSION < (2, 44, 0) => { + eprintln!("Fixture script failure ignored as it looks like Git isn't recent enough."); + return Ok(()); + } + Err(err) => panic!("{err}"), + }; + let kind = gix_discover::is_git(&repo_path)?; assert_eq!(kind, gix_discover::repository::Kind::WorkTree { linked_git_dir: None }); Ok(()) } diff --git a/gix-discover/tests/discover/parse/mod.rs b/gix-discover/tests/discover/parse.rs similarity index 100% rename from gix-discover/tests/discover/parse/mod.rs rename to gix-discover/tests/discover/parse.rs diff --git a/gix-discover/tests/discover/path/mod.rs b/gix-discover/tests/discover/path.rs similarity index 100% rename from gix-discover/tests/discover/path/mod.rs rename to gix-discover/tests/discover/path.rs From 3c16e534a5db85a73f9dfbc6b4846ff6f89d57b2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 15 Apr 2025 13:28:18 +0200 Subject: [PATCH 099/193] show that ref-tables aren't currently supported. --- .../generated-archives/make_reftable_repo.tar | Bin 0 -> 52224 bytes gix/tests/fixtures/make_reftable_repo.sh | 13 +++++++++ gix/tests/gix/repository/open.rs | 27 ++++++++++++++++++ gix/tests/gix/util.rs | 4 ++- 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 gix/tests/fixtures/generated-archives/make_reftable_repo.tar create mode 100755 gix/tests/fixtures/make_reftable_repo.sh diff --git a/gix/tests/fixtures/generated-archives/make_reftable_repo.tar b/gix/tests/fixtures/generated-archives/make_reftable_repo.tar new file mode 100644 index 0000000000000000000000000000000000000000..b57fe223574aa22c0bfa6dd8924a4ab9dad73626 GIT binary patch literal 52224 zcmeHQ4RjR69p4Z@30k1#Rjk@BAQC<Yemu&Hd;5`Wxx0;bdvLU+ zXj`h%M^S2Rp*(7lCt|Un0kJ#;pVsmrK?RhyQp-aq)>kdBPZ534cJ`7Zxw*@2ve|(^ z=H5&0W_I?!Gr!;d|NEcWnfaG76!s4bKe8xN&Nuv^-|0NS3KC#BmgCdMWu6l$5qr(x z1(FF{iPLnKFO_auo5pon;Q0{{*9}_X0Y5J8CZmVzf4v@wSS4;Ck>i&t0*L;X)tR>M zO?C9YllGsJc!Ah|-za$d< z_n+-tiG}%RSino1$ntDh32I>_#7c%NN+C%$LV8G5_>dq-f|4sXE63r#p#KN^dfEOT z2PCJzm?Z^MqKEr`siG-+c2Awos=FpP?cRN&7j@lhy$550nuzUw2o%zP4){}FFZN$# zW#a$&1Ajp&h52VR9vXdxlfrU{RfM1z)FfFJ1x05?jTJOQ)dh`J3toXr_wx(de+i)W zpJPRd*nbyX{WzQ|8Z)Y@dL}D{S%GDFFs*d=uCYdNXZ=%q_P%uVRMiXrRt|i4qUoOT zuQm0jPE~!03>El+diRl0NdNf@Y5xIB?EiVVO$zhR1VgIEt6^3#pzW7bKBNTsprY`) zC>WZ|DM9!rxZNgh{yztAG{pbsSja!||MA}dsUrPnQ%ZV)f#tJL4E{_1{hudCvJc($ z&&qM7L+UOcG=6*Wo)c(bGjQdv%s$5I|^!b0V-#t?P!SY`|R2kR4vh?Q%rY=0#_t#Amcf9+| z@w3lQdFFWE`))egXVAXju|Ea3Zxw_4x9yxL_1^mN`YFe@fAWRk-|UhOHIo!-2Z4h6 zFST=0C$qiTfAapXlQ4TKUYLI-r0HBJ9Og8jNdhl~gJCYD=7lNwDhq^lc z%K{m-{~Un53S$2~QQE1KGV?#~rKo-zi%xdxTvGVrM*U#e8X?tN#a3 z{||^jfO3@ ztY&(JGfa3j1!%Tp=z*;(ZrJk3nng?Ml2u1$_x}67>MN389b^3VVfuHc7S-Q&oSFHb zF*Wfow^u=uj}?LZ`tQ$s-%Q0l^#6EKBK^M%emK9|FBN`pnVd*-{(&&V4)0P1xv{Z&}P;6U|#}agDGS+ehM?{o1 z4SK$nq~|Fy=(<{TGLiOBqoc;blSh}$vXt4*j~@^>6}hGI=|9Z#b$Hg3{U_`H5vK4Y z+vA_9*A>mDyTHx41hNeb4Ro1m|&(h z=&>1AGOp?jbV#j~sX0GV0nJRP7OV~fCEE$cFjICit|yo}J*LOu<+Oli1!9&RaE3OS zs4_>d&D{9#M}x%(p`a{sfCGVK%uF$5usyo1*28*?aWH9q8Zx8Dr4!9nPB6_?W=5CH z3dfZgEIll$G&iB8Q4{FqA|?HzdOU+^MwnCf!dul03~lv4lh^)T)43xa{69e;^S?U> zvd7XHuJiHFuqlVSmJbMIC53<@Xk1V;*fJ=i;ME-g1=fE;6-WI)4$dng>wgM@>eIpL z6}Q$DQ3Es5idug3j#JcnYWU=eo6CC*fc&;KTGV_bqZmBgG=AfTML&6U#g7(0d3@@j z(GQNkxzGLAAa>FbRx~7iE^@>%g@cDW|EYYUDC$~@;;CMBRB>hMuj;N(8j`khdO*>R zt2a`w?rW5;d1uQD*R6W{@aEI&{+E1qZs4|k$Icu+ym#5MgTtl;Umv=87}!FOoH?L$ zzg>T#>WO#yetc}@nQb*=7HwL6=G%SFzIpWE>hOX|#l^*E?_Ygp{lR0)!VCWQ!-Lz7 zoY}wnSk2i__AWcKc<~IoFForOP{-5 ztdK|4%FK>(Ssc+=K2ZiYirY)YXRimNF8gEYu0!&3o8Tr$oWLCnG`+t5%|q{p>l=DM zQ~J&uldEqZ)%U|)d#@Svo)MiqwyLS=vK4E8Q~TKRRm;~dz4rZu4>lgE;2u>!|Hdy~ z+OzAmmtTJ6<&&!(=ttfDHO6d@ybPP|e6P>sSN-_zw==)VcaKB>s$-k|ADjLEOdgXy zk|>Lqi7ssl=3@U@R^-v~Un%{(I3JAk@cm!1p6LZ2@fY4#Js-D2PrF7&*W3Dk&V$-d z99;E3XZ<(ed6-Au|M_Lkvl|GAw0pCHR*{;Fmo2Q2V*d!bqS?^nPFq}5*RKa4s<>_37djwHgrKLH<*in`kWoc$l+ zj$m;AH}d`$0TM$p|Nf68{sRW6yQRo1{r4;21JY7&_Fp3QAHfkv65-#UfDcGT-RysE z{0C_NIr9D=fe}lR#DBm7>qR3pOaJ`}_<*$DgZ<}tp4fi`Ml8uJ{{0I0fYj6z|FADg z#{Uo?F(kA2_bcE7Qcn;31DTBfBPilYBK-Rk@Byi+oBx*^|G}Z3%>PDU#FEV4|0nSu zuz=kSg=Xo$UjZMGc6ze^fV}@hV8oI{`1dE^15#5r`=1;C0os4E|1W|fo+OF?fCtx$ zMQXPG`xNj2X}mZ4Pu~9_Fk(p}{QDE|0ja5*{m+g60D}vW{XY>D@gy_zKkg;*AMgO& z&84RGf6~dKnhit@^u>KV8BUSn7Nhhsh2@xS3lTyRf#^8Vj99i#^14<9d zNb7%_03SG-?xz2auA}N&FWSk)D-K>%ZRtUl0i0^gmDh7r=@ldHy3f z;z;Jif4O|Yz;yf<_}vo!#q>S?%db9OGv#lm+4V!FJpd+fi~B68KRq2s3Kchaj*4+dDoGg(3Un_$6er4-_OPn*Goj^DLPY`qBKl74A*8k#Ty;ZWq zO-DYo&dZV!l5|Ot4WNd2UQ`tT-9rmZbo}?*5<9Cm``3d?mUaVQBm> Xr|U;%gtr40$tDO81PB6`5CZ=PU710v literal 0 HcmV?d00001 diff --git a/gix/tests/fixtures/make_reftable_repo.sh b/gix/tests/fixtures/make_reftable_repo.sh new file mode 100755 index 00000000000..11eac3a2f77 --- /dev/null +++ b/gix/tests/fixtures/make_reftable_repo.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -eu -o pipefail + +git init -q + +git checkout -b main +touch this +git add this +git commit -q -m c1 +echo hello >> this +git commit -q -am c2 + +git clone --ref-format=reftable . reftable-clone diff --git a/gix/tests/gix/repository/open.rs b/gix/tests/gix/repository/open.rs index f24edc68914..d60227414da 100644 --- a/gix/tests/gix/repository/open.rs +++ b/gix/tests/gix/repository/open.rs @@ -55,6 +55,33 @@ fn on_root_with_decomposed_unicode() -> crate::Result { Ok(()) } +#[test] +fn non_bare_reftable() -> crate::Result { + let repo = match named_subrepo_opts( + "make_reftable_repo.sh", + "reftable-clone", + gix::open::Options::isolated(), + ) { + Ok(r) => r, + Err(_) if *gix_testtools::GIT_VERSION < (2, 44, 0) => { + eprintln!("Fixture script failure ignored as it looks like Git isn't recent enough."); + return Ok(()); + } + Err(err) => panic!("{err}"), + }; + assert!( + repo.head_id().is_err(), + "Trying to do anything with head will fail as we don't support reftables yet" + ); + assert!(!repo.is_bare()); + assert_ne!( + repo.workdir(), + None, + "Otherwise it can be used, but it's hard to do without refs" + ); + Ok(()) +} + #[test] fn bare_repo_with_index() -> crate::Result { let repo = named_subrepo_opts( diff --git a/gix/tests/gix/util.rs b/gix/tests/gix/util.rs index 493abd9d36b..eab545ea34a 100644 --- a/gix/tests/gix/util.rs +++ b/gix/tests/gix/util.rs @@ -38,7 +38,9 @@ pub fn named_subrepo_opts( name: &str, opts: open::Options, ) -> std::result::Result { - let repo_path = gix_testtools::scripted_fixture_read_only(fixture).unwrap().join(name); + let repo_path = gix_testtools::scripted_fixture_read_only(fixture) + .map_err(|err| gix::open::Error::Io(std::io::Error::other(err)))? + .join(name); Ok(ThreadSafeRepository::open_opts(repo_path, opts)?.to_thread_local()) } From 5fd0ab90e3fbdc7c82b390520e007e258d7d0ce8 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 19 Apr 2025 16:32:19 +0200 Subject: [PATCH 100/193] various minor changes --- gix-odb/src/store_impls/dynamic/init.rs | 8 ++++---- gix-odb/src/store_impls/dynamic/types.rs | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/gix-odb/src/store_impls/dynamic/init.rs b/gix-odb/src/store_impls/dynamic/init.rs index 2031e48c837..be6a1ea9475 100644 --- a/gix-odb/src/store_impls/dynamic/init.rs +++ b/gix-odb/src/store_impls/dynamic/init.rs @@ -32,20 +32,20 @@ impl Default for Options { } } -/// Configures the amount of slots in the index slotmap, which is fixed throughout the existence of the store. +/// Configures the number of slots in the index slotmap, which is fixed throughout the existence of the store. #[derive(Copy, Clone, Debug)] pub enum Slots { - /// The amount of slots to use, that is the total amount of indices we can hold at a time. + /// The number of slots to use, that is the total number of indices we can hold at a time. /// Using this has the advantage of avoiding an initial directory listing of the repository, and is recommended /// on the server side where the repository setup is controlled. /// /// Note that this won't affect their packs, as each index can have one or more packs associated with it. Given(u16), - /// Compute the amount of slots needed, as probably best used on the client side where a variety of repositories is encountered. + /// Compute the number of slots needed, as probably best used on the client side where a variety of repositories is encountered. AsNeededByDiskState { /// 1.0 means no safety, 1.1 means 10% more slots than needed multiplier: f32, - /// The minimum amount of slots to assume + /// The minimum number of slots to assume minimum: usize, }, } diff --git a/gix-odb/src/store_impls/dynamic/types.rs b/gix-odb/src/store_impls/dynamic/types.rs index ff91761b5a8..7627001559b 100644 --- a/gix-odb/src/store_impls/dynamic/types.rs +++ b/gix-odb/src/store_impls/dynamic/types.rs @@ -84,10 +84,11 @@ impl PackId { /// An index that changes only if the packs directory changes and its contents is re-read. #[derive(Default)] pub struct SlotMapIndex { - /// The index into the slot map at which we expect an index or pack file. Neither of these might be loaded yet. + /// The index into the slot map at which we expect an index or pack file. Neither of these might be already loaded. pub(crate) slot_indices: Vec, - /// A list of loose object databases as resolved by their alternates file in the `object_directory`. The first entry is this objects - /// directory loose file database. All other entries are the loose stores of alternates. + /// A list of loose object databases as resolved by their alternates file in the `object_directory`. + /// The first entry is this repository's directory for the loose file database. + /// All other entries are the loose stores of alternates. /// It's in an Arc to be shared to Handles, but not to be shared across SlotMapIndices. pub(crate) loose_dbs: Arc>, From 5396b2b6318d2066b07b23a58286d71344d804d3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 22 Feb 2025 14:36:17 +0100 Subject: [PATCH 101/193] add test to assure dynamic allocation of slots works (#1788) --- gix/tests/gix/remote/fetch.rs | 65 ++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/gix/tests/gix/remote/fetch.rs b/gix/tests/gix/remote/fetch.rs index 98c15b43685..7d5893f2758 100644 --- a/gix/tests/gix/remote/fetch.rs +++ b/gix/tests/gix/remote/fetch.rs @@ -102,6 +102,39 @@ mod blocking_and_async_io { )?; Ok(()) } + fn check_fetch_output( + repo: &gix::Repository, + out: gix::remote::fetch::Outcome, + expected_count: usize, + ) -> gix_testtools::Result { + for local_tracking_branch_name in out.ref_map.mappings.into_iter().filter_map(|m| m.local) { + let r = repo.find_reference(&local_tracking_branch_name)?; + r.id() + .object() + .expect("object should be present after fetching, triggering pack refreshes works"); + repo.head_ref()?.unwrap().set_target_id(r.id(), "post fetch")?; + } + check_odb_accessability(repo, expected_count)?; + Ok(()) + } + fn check_odb_accessability(repo: &gix::Repository, expected_count: usize) -> gix_testtools::Result { + let mut count_unique = 0; + // TODO: somehow there is a lot of duplication when receiving objects. + let mut seen = gix_hashtable::HashSet::default(); + for id in repo.objects.iter()? { + let id = id?; + if !seen.insert(id) { + continue; + } + let _obj = repo.find_object(id)?; + count_unique += 1; + } + assert_eq!( + count_unique, expected_count, + "Each round we receive exactly one commit, effectively" + ); + Ok(()) + } for max_packs in 1..=3 { let remote_dir = tempfile::tempdir()?; let mut remote_repo = gix::init_bare(remote_dir.path())?; @@ -128,25 +161,33 @@ mod blocking_and_async_io { Fetch, ) .expect("remote is configured after clone")?; - for _round_to_create_pack in 1..12 { + let minimum_slots = 5; + let slots = Slots::AsNeededByDiskState { + multiplier: 1.1, + minimum: minimum_slots, + }; + let one_more_than_minimum = minimum_slots + 1; + for round_to_create_pack in 1..one_more_than_minimum { + let expected_object_count = round_to_create_pack + 1 + 1 /* first commit + tree */; create_empty_commit(&remote_repo)?; match remote .connect(Fetch)? .prepare_fetch(gix::progress::Discard, Default::default())? .receive(gix::progress::Discard, &IS_INTERRUPTED) { - Ok(out) => { - for local_tracking_branch_name in out.ref_map.mappings.into_iter().filter_map(|m| m.local) { - let r = local_repo.find_reference(&local_tracking_branch_name)?; - r.id() - .object() - .expect("object should be present after fetching, triggering pack refreshes works"); - local_repo.head_ref()?.unwrap().set_target_id(r.id(), "post fetch")?; - } + Ok(out) => check_fetch_output(&local_repo, out, expected_object_count)?, + Err(err) => { + assert!(err + .to_string() + .starts_with("The slotmap turned out to be too small with ")); + // But opening a new repo will always be able to read all objects + // as it dynamically sizes the otherwise static slotmap. + let local_repo = gix::open_opts( + local_repo.path(), + gix::open::Options::isolated().object_store_slots(slots), + )?; + check_odb_accessability(&local_repo, expected_object_count)?; } - Err(err) => assert!(err - .to_string() - .starts_with("The slotmap turned out to be too small with ")), } } } From 9f8a468cfb8730fcb0f88cbf62e559cb369fdb42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20R=C3=BC=C3=9Fler?= Date: Sun, 20 Apr 2025 09:09:02 +0200 Subject: [PATCH 102/193] feat: 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` --- Cargo.lock | 1 + gix-path/Cargo.toml | 1 + gix-path/src/lib.rs | 5 +- gix-path/src/relative_path.rs | 314 ++++++++++++++++++++++++++++++++++ 4 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 gix-path/src/relative_path.rs diff --git a/Cargo.lock b/Cargo.lock index 74337864f53..f95b890b2a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2385,6 +2385,7 @@ dependencies = [ "bstr", "gix-testtools", "gix-trace 0.1.12", + "gix-validate 0.9.4", "home", "known-folders", "once_cell", diff --git a/gix-path/Cargo.toml b/gix-path/Cargo.toml index ee4be88d33f..805e9720cf4 100644 --- a/gix-path/Cargo.toml +++ b/gix-path/Cargo.toml @@ -16,6 +16,7 @@ doctest = false [dependencies] gix-trace = { version = "^0.1.12", path = "../gix-trace" } +gix-validate = { version = "^0.9.4", path = "../gix-validate" } bstr = { version = "1.12.0", default-features = false, features = ["std"] } thiserror = "2.0.0" once_cell = "1.21.3" diff --git a/gix-path/src/lib.rs b/gix-path/src/lib.rs index a83b8bde7a8..3ad116ac006 100644 --- a/gix-path/src/lib.rs +++ b/gix-path/src/lib.rs @@ -47,7 +47,7 @@ //! ever get into a code-path which does panic though. //!
#![deny(missing_docs, rust_2018_idioms)] -#![cfg_attr(not(test), forbid(unsafe_code))] +#![cfg_attr(not(test), deny(unsafe_code))] /// A dummy type to represent path specs and help finding all spots that take path specs once it is implemented. mod convert; @@ -62,3 +62,6 @@ pub use realpath::function::{realpath, realpath_opts}; /// Information about the environment in terms of locations of resources. pub mod env; + +/// +pub mod relative_path; diff --git a/gix-path/src/relative_path.rs b/gix-path/src/relative_path.rs new file mode 100644 index 00000000000..6682d647136 --- /dev/null +++ b/gix-path/src/relative_path.rs @@ -0,0 +1,314 @@ +use bstr::BStr; +use bstr::BString; +use bstr::ByteSlice; +use gix_validate::path::component::Options; +use std::borrow::Cow; + +use crate::os_str_into_bstr; +use crate::try_from_bstr; +use crate::try_from_byte_slice; + +/// A wrapper for `BStr`. It is used to enforce the following constraints: +/// +/// - The path separator always is `/`, independent of the platform. +/// - Only normal components are allowed. +/// - It is always represented as a bunch of bytes. +#[derive()] +pub struct RelativePath { + inner: BStr, +} + +impl RelativePath { + fn new_unchecked(value: &BStr) -> Result<&RelativePath, Error> { + // SAFETY: `RelativePath` is transparent and equivalent to a `&BStr` if provided as reference. + #[allow(unsafe_code)] + unsafe { + std::mem::transmute(value) + } + } + + /// TODO + /// Needs docs. + pub fn ends_with(&self, needle: &[u8]) -> bool { + self.inner.ends_with(needle) + } +} + +/// The error used in [`RelativePath`]. +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum Error { + #[error("A RelativePath is not allowed to be absolute")] + IsAbsolute, + #[error(transparent)] + ContainsInvalidComponent(#[from] gix_validate::path::component::Error), + #[error(transparent)] + IllegalUtf8(#[from] crate::Utf8Error), +} + +impl<'a> TryFrom<&'a str> for &'a RelativePath { + type Error = Error; + + fn try_from(value: &'a str) -> Result { + use std::path::Path; + + let path: &std::path::Path = Path::new(value); + + if path.is_absolute() { + return Err(Error::IsAbsolute); + } + + let options: Options = Default::default(); + + for component in path.components() { + let component = os_str_into_bstr(component.as_os_str())?; + + gix_validate::path::component(component, None, options)?; + } + + RelativePath::new_unchecked(BStr::new(value.as_bytes())) + } +} + +impl<'a> TryFrom<&'a BStr> for &'a RelativePath { + type Error = Error; + + fn try_from(value: &'a BStr) -> Result { + let path: &std::path::Path = &try_from_bstr(value)?; + + if path.is_absolute() { + return Err(Error::IsAbsolute); + } + + let options: Options = Default::default(); + + for component in path.components() { + let component = os_str_into_bstr(component.as_os_str())?; + + gix_validate::path::component(component, None, options)?; + } + + RelativePath::new_unchecked(value) + } +} + +impl<'a, const N: usize> TryFrom<&'a [u8; N]> for &'a RelativePath { + type Error = Error; + + #[inline] + fn try_from(value: &'a [u8; N]) -> Result { + let path: &std::path::Path = try_from_byte_slice(value)?; + + if path.is_absolute() { + return Err(Error::IsAbsolute); + } + + let options: Options = Default::default(); + + for component in path.components() { + let component = os_str_into_bstr(component.as_os_str())?; + + gix_validate::path::component(component, None, options)?; + } + + RelativePath::new_unchecked(value.into()) + } +} + +impl<'a> TryFrom<&'a BString> for &'a RelativePath { + type Error = Error; + + fn try_from(value: &'a BString) -> Result { + let path: &std::path::Path = &try_from_bstr(value.as_bstr())?; + + if path.is_absolute() { + return Err(Error::IsAbsolute); + } + + let options: Options = Default::default(); + + for component in path.components() { + let component = os_str_into_bstr(component.as_os_str())?; + + gix_validate::path::component(component, None, options)?; + } + + RelativePath::new_unchecked(value.as_bstr()) + } +} + +/// This is required by a trait bound on [`from_str`](crate::from_bstr). +impl<'a> From<&'a RelativePath> for Cow<'a, BStr> { + #[inline] + fn from(value: &'a RelativePath) -> Cow<'a, BStr> { + Cow::Borrowed(&value.inner) + } +} + +impl AsRef<[u8]> for RelativePath { + #[inline] + fn as_ref(&self) -> &[u8] { + self.inner.as_bytes() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[cfg(not(windows))] + #[test] + fn absolute_paths_return_err() { + let path_str: &str = "/refs/heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8; 11] = b"/refs/heads"; + let path_bstring: BString = "/refs/heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::IsAbsolute) + )); + } + + #[cfg(windows)] + #[test] + fn absolute_paths_return_err() { + let path_str: &str = r"c:\refs\heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8; 13] = b"c:\\refs\\heads"; + let path_bstring: BString = r"c:\refs\heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::IsAbsolute) + )); + } + + #[cfg(not(windows))] + #[test] + fn dots_in_paths_return_err() { + let path_str: &str = "./heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8; 7] = b"./heads"; + let path_bstring: BString = "./heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::ContainsInvalidComponent(_)) + )); + } + + #[cfg(windows)] + #[test] + fn dots_in_paths_return_err() { + let path_str: &str = r".\heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8; 7] = b".\\heads"; + let path_bstring: BString = r".\heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::ContainsInvalidComponent(_)) + )); + } + + #[cfg(not(windows))] + #[test] + fn double_dots_in_paths_return_err() { + let path_str: &str = "../heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8; 8] = b"../heads"; + let path_bstring: BString = "../heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::ContainsInvalidComponent(_)) + )); + } + + #[cfg(windows)] + #[test] + fn double_dots_in_paths_return_err() { + let path_str: &str = r"..\heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8; 8] = b"..\\heads"; + let path_bstring: BString = r"..\heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::ContainsInvalidComponent(_)) + )); + } +} From 8ece02aeda4b3044dd68dd8a6c20ea4ee4ed1bda Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 20 Apr 2025 16:13:48 +0100 Subject: [PATCH 103/193] Fix documentation of zlib-rs feature: no longer conflicts with other zlibs --- gix-features/Cargo.toml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gix-features/Cargo.toml b/gix-features/Cargo.toml index c2e75d6f6fd..d17b62f2876 100644 --- a/gix-features/Cargo.toml +++ b/gix-features/Cargo.toml @@ -63,8 +63,10 @@ crc32 = ["dep:crc32fast"] zlib = ["dep:flate2", "flate2?/rust_backend", "dep:thiserror"] ## Use the C-based zlib-ng backend, which can compress and decompress significantly faster. zlib-ng = ["zlib", "flate2?/zlib-ng"] -## Use the high-performance rust-based zlib backend en par with zlib-ng. -## Note that this will cause duplicate symbol errors if the application also depends on `zlib`, without remediation. +## Use the high-performance rust-based zlib backend on par with zlib-ng. +## As of zlib-rs 0.5.0 (used by flate2 1.1.1), this no longer exports C symbols +## by default, so it doesn't conflict with any other zlib library that might be +## loaded into the same address space. zlib-rs = ["zlib", "flate2?/zlib-rs"] ## Use zlib-ng via its zlib-compat API. Useful if you already need zlib for C ## code elsewhere in your dependencies. Otherwise, use zlib-ng. From 108a8ca9cbc808499cc943208e2bca638362a743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20R=C3=BC=C3=9Fler?= Date: Sun, 20 Apr 2025 22:01:03 +0200 Subject: [PATCH 104/193] feat!: Use `&RelativePath` in `*::prefixed()` methods. That way there now is a type to capture requirements. Co-authored-by: Sebastian Thiel --- gix-ref/src/namespace.rs | 6 +-- gix-ref/src/store/file/loose/iter.rs | 8 ++-- gix-ref/src/store/file/overlay_iter.rs | 41 ++++++-------------- gix-ref/tests/refs/file/store/iter.rs | 52 ++++++-------------------- gix-ref/tests/refs/file/worktree.rs | 4 +- gix-ref/tests/refs/namespace.rs | 4 +- 6 files changed, 34 insertions(+), 81 deletions(-) diff --git a/gix-ref/src/namespace.rs b/gix-ref/src/namespace.rs index 0570ff27434..632b8546e66 100644 --- a/gix-ref/src/namespace.rs +++ b/gix-ref/src/namespace.rs @@ -1,6 +1,7 @@ use std::path::Path; use gix_object::bstr::{BStr, BString, ByteSlice, ByteVec}; +use gix_path::relative_path::RelativePath; use crate::{FullName, FullNameRef, Namespace, PartialNameRef}; @@ -20,9 +21,8 @@ impl Namespace { /// Append the given `prefix` to this namespace so it becomes usable for prefixed iteration. /// /// The prefix is a relative path with slash-separated path components. - // TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it. - pub fn into_namespaced_prefix<'a>(mut self, prefix: impl Into<&'a BStr>) -> BString { - self.0.push_str(prefix.into()); + pub fn into_namespaced_prefix(mut self, prefix: &RelativePath) -> BString { + self.0.push_str(prefix); gix_path::to_unix_separators_on_windows(self.0).into_owned() } pub(crate) fn into_namespaced_name(mut self, name: &FullNameRef) -> FullName { diff --git a/gix-ref/src/store/file/loose/iter.rs b/gix-ref/src/store/file/loose/iter.rs index 2982e4a22e3..bf5206cbb97 100644 --- a/gix-ref/src/store/file/loose/iter.rs +++ b/gix-ref/src/store/file/loose/iter.rs @@ -2,8 +2,9 @@ use std::path::{Path, PathBuf}; use gix_features::fs::walkdir::DirEntryIter; use gix_object::bstr::ByteSlice; +use gix_path::relative_path::RelativePath; -use crate::{file::iter::LooseThenPacked, store_impl::file, BStr, BString, FullName}; +use crate::{file::iter::LooseThenPacked, store_impl::file, BString, FullName}; /// An iterator over all valid loose reference paths as seen from a particular base directory. pub(in crate::store_impl::file) struct SortedLoosePaths { @@ -88,8 +89,7 @@ impl file::Store { /// starts with `foo`, like `refs/heads/foo` and `refs/heads/foobar`. /// /// Prefixes are relative paths with slash-separated components. - // TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it. - pub fn loose_iter_prefixed<'a>(&self, prefix: impl Into<&'a BStr>) -> std::io::Result> { - self.iter_prefixed_packed(prefix.into(), None) + pub fn loose_iter_prefixed(&self, prefix: &RelativePath) -> std::io::Result> { + self.iter_prefixed_packed(prefix, None) } } diff --git a/gix-ref/src/store/file/overlay_iter.rs b/gix-ref/src/store/file/overlay_iter.rs index e69c9cfed15..daec5dc47f6 100644 --- a/gix-ref/src/store/file/overlay_iter.rs +++ b/gix-ref/src/store/file/overlay_iter.rs @@ -12,6 +12,9 @@ use crate::{ BStr, FullName, Namespace, Reference, }; +use gix_object::bstr::ByteSlice; +use gix_path::relative_path::RelativePath; + /// An iterator stepping through sorted input of loose references and packed references, preferring loose refs over otherwise /// equivalent packed references. /// @@ -203,10 +206,9 @@ impl Platform<'_> { /// starts with `foo`, like `refs/heads/foo` and `refs/heads/foobar`. /// /// Prefixes are relative paths with slash-separated components. - // TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it. - pub fn prefixed<'a>(&self, prefix: impl Into<&'a BStr>) -> std::io::Result> { + pub fn prefixed(&self, prefix: &RelativePath) -> std::io::Result> { self.store - .iter_prefixed_packed(prefix.into(), self.packed.as_ref().map(|b| &***b)) + .iter_prefixed_packed(prefix, self.packed.as_ref().map(|b| &***b)) } } @@ -291,26 +293,8 @@ impl<'a> IterInfo<'a> { .peekable() } - fn from_prefix( - base: &'a Path, - prefix: impl Into>, - precompose_unicode: bool, - ) -> std::io::Result { - let prefix = prefix.into(); - let prefix_path = gix_path::from_bstr(prefix.as_ref()); - if prefix_path.is_absolute() { - return Err(std::io::Error::new( - std::io::ErrorKind::InvalidInput, - "prefix must be a relative path, like 'refs/heads/'", - )); - } - use std::path::Component::*; - if prefix_path.components().any(|c| matches!(c, CurDir | ParentDir)) { - return Err(std::io::Error::new( - std::io::ErrorKind::InvalidInput, - "Refusing to handle prefixes with relative path components", - )); - } + fn from_prefix(base: &'a Path, prefix: &'a RelativePath, precompose_unicode: bool) -> std::io::Result { + let prefix_path = gix_path::from_bstr(prefix); let iter_root = base.join(&prefix_path); if prefix.ends_with(b"/") { Ok(IterInfo::BaseAndIterRoot { @@ -326,7 +310,7 @@ impl<'a> IterInfo<'a> { .to_owned(); Ok(IterInfo::ComputedIterationRoot { base, - prefix, + prefix: prefix.into(), iter_root, precompose_unicode, }) @@ -377,13 +361,11 @@ impl file::Store { /// starts with `foo`, like `refs/heads/foo` and `refs/heads/foobar`. /// /// Prefixes are relative paths with slash-separated components. - // TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it. - pub fn iter_prefixed_packed<'a, 's, 'p>( + pub fn iter_prefixed_packed<'s, 'p>( &'s self, - prefix: impl Into<&'a BStr>, + prefix: &RelativePath, packed: Option<&'p packed::Buffer>, ) -> std::io::Result> { - let prefix = prefix.into(); match self.namespace.as_ref() { None => { let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix, self.precompose_unicode)?; @@ -395,7 +377,8 @@ impl file::Store { } Some(namespace) => { let prefix = namespace.to_owned().into_namespaced_prefix(prefix); - let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix.clone(), self.precompose_unicode)?; + let prefix = prefix.as_bstr().try_into().map_err(std::io::Error::other)?; + let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix, self.precompose_unicode)?; let common_dir_info = self .common_dir() .map(|base| IterInfo::from_prefix(base, prefix, self.precompose_unicode)) diff --git a/gix-ref/tests/refs/file/store/iter.rs b/gix-ref/tests/refs/file/store/iter.rs index fb0a6ddb3b3..527fd03c1cb 100644 --- a/gix-ref/tests/refs/file/store/iter.rs +++ b/gix-ref/tests/refs/file/store/iter.rs @@ -26,7 +26,7 @@ mod with_namespace { let ns_two = gix_ref::namespace::expand("bar")?; let namespaced_refs = store .iter()? - .prefixed(ns_two.as_bstr())? + .prefixed(ns_two.as_bstr().try_into().unwrap())? .map(Result::unwrap) .map(|r: gix_ref::Reference| r.name) .collect::>(); @@ -45,7 +45,7 @@ mod with_namespace { ); assert_eq!( store - .loose_iter_prefixed(ns_two.as_bstr())? + .loose_iter_prefixed(ns_two.as_bstr().try_into().unwrap())? .map(Result::unwrap) .map(|r| r.name.into_inner()) .collect::>(), @@ -90,7 +90,7 @@ mod with_namespace { assert_eq!( store .iter()? - .prefixed(ns_one.as_bstr())? + .prefixed(ns_one.as_bstr().try_into().unwrap())? .map(Result::unwrap) .map(|r: gix_ref::Reference| ( r.name.as_bstr().to_owned(), @@ -316,26 +316,11 @@ fn loose_iter_with_broken_refs() -> crate::Result { Ok(()) } -#[test] -fn loose_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { - let store = store()?; - #[cfg(not(windows))] - let abs_path = "/hello"; - #[cfg(windows)] - let abs_path = r"c:\hello"; - - match store.loose_iter_prefixed(abs_path) { - Ok(_) => unreachable!("absolute paths aren't allowed"), - Err(err) => assert_eq!(err.to_string(), "prefix must be a relative path, like 'refs/heads/'"), - } - Ok(()) -} - #[test] fn loose_iter_with_prefix() -> crate::Result { let prefix_with_slash = b"refs/heads/"; let actual = store()? - .loose_iter_prefixed(prefix_with_slash)? + .loose_iter_prefixed(prefix_with_slash.try_into().unwrap())? .collect::, _>>() .expect("no broken ref in this subset") .into_iter() @@ -363,7 +348,7 @@ fn loose_iter_with_prefix() -> crate::Result { fn loose_iter_with_partial_prefix_dir() -> crate::Result { let prefix_without_slash = b"refs/heads"; let actual = store()? - .loose_iter_prefixed(prefix_without_slash)? + .loose_iter_prefixed(prefix_without_slash.try_into().unwrap())? .collect::, _>>() .expect("no broken ref in this subset") .into_iter() @@ -390,7 +375,7 @@ fn loose_iter_with_partial_prefix_dir() -> crate::Result { #[test] fn loose_iter_with_partial_prefix() -> crate::Result { let actual = store()? - .loose_iter_prefixed(b"refs/heads/d".as_bstr())? + .loose_iter_prefixed(b"refs/heads/d".as_bstr().try_into().unwrap())? .collect::, _>>() .expect("no broken ref in this subset") .into_iter() @@ -526,21 +511,6 @@ fn overlay_iter_reproduce_1928() -> crate::Result { Ok(()) } -#[test] -fn overlay_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { - let store = store_with_packed_refs()?; - #[cfg(not(windows))] - let abs_path = "/hello"; - #[cfg(windows)] - let abs_path = r"c:\hello"; - - match store.iter()?.prefixed(abs_path) { - Ok(_) => unreachable!("absolute paths aren't allowed"), - Err(err) => assert_eq!(err.to_string(), "prefix must be a relative path, like 'refs/heads/'"), - } - Ok(()) -} - #[test] fn overlay_prefixed_iter() -> crate::Result { use gix_ref::Target::*; @@ -548,7 +518,7 @@ fn overlay_prefixed_iter() -> crate::Result { let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store .iter()? - .prefixed(b"refs/heads/")? + .prefixed(b"refs/heads/".try_into().unwrap())? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); @@ -571,7 +541,7 @@ fn overlay_partial_prefix_iter() -> crate::Result { let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store .iter()? - .prefixed(b"refs/heads/m")? // 'm' is partial + .prefixed(b"refs/heads/m".try_into().unwrap())? // 'm' is partial .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); @@ -589,7 +559,7 @@ fn overlay_partial_prefix_iter_reproduce_1934() -> crate::Result { let ref_names = store .iter()? - .prefixed(b"refs/d")? + .prefixed(b"refs/d".try_into().unwrap())? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; assert_eq!( @@ -610,7 +580,7 @@ fn overlay_partial_prefix_iter_when_prefix_is_dir() -> crate::Result { let ref_names = store .iter()? - .prefixed(b"refs/prefix/feature")? + .prefixed(b"refs/prefix/feature".try_into().unwrap())? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; assert_eq!( @@ -623,7 +593,7 @@ fn overlay_partial_prefix_iter_when_prefix_is_dir() -> crate::Result { let ref_names = store .iter()? - .prefixed(b"refs/prefix/feature/")? + .prefixed(b"refs/prefix/feature/".try_into().unwrap())? .map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target))) .collect::, _>>()?; assert_eq!( diff --git a/gix-ref/tests/refs/file/worktree.rs b/gix-ref/tests/refs/file/worktree.rs index 6bc4d73f515..de8cc54f777 100644 --- a/gix-ref/tests/refs/file/worktree.rs +++ b/gix-ref/tests/refs/file/worktree.rs @@ -290,7 +290,7 @@ mod writable { assert_eq!( store .iter()? - .prefixed(b"refs/stacks/")? + .prefixed(b"refs/stacks/".try_into().unwrap())? .map(Result::unwrap) .map(|r| (r.name.to_string(), r.target.to_string())) .collect::>(), @@ -571,7 +571,7 @@ mod writable { assert_eq!( store .iter()? - .prefixed(b"refs/stacks/")? + .prefixed(b"refs/stacks/".try_into().unwrap())? .map(Result::unwrap) .map(|r| (r.name.to_string(), r.target.to_string())) .collect::>(), diff --git a/gix-ref/tests/refs/namespace.rs b/gix-ref/tests/refs/namespace.rs index 58cf96e3092..3f0a6e180e0 100644 --- a/gix-ref/tests/refs/namespace.rs +++ b/gix-ref/tests/refs/namespace.rs @@ -3,13 +3,13 @@ fn into_namespaced_prefix() { assert_eq!( gix_ref::namespace::expand("foo") .unwrap() - .into_namespaced_prefix("prefix"), + .into_namespaced_prefix("prefix".try_into().unwrap()), "refs/namespaces/foo/prefix", ); assert_eq!( gix_ref::namespace::expand("foo") .unwrap() - .into_namespaced_prefix("prefix/"), + .into_namespaced_prefix("prefix/".try_into().unwrap()), "refs/namespaces/foo/prefix/", ); } From a6d7d701517f7eafe1e2ed15d564114aa5c1d07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20R=C3=BC=C3=9Fler?= Date: Sun, 20 Apr 2025 22:09:00 +0200 Subject: [PATCH 105/193] feat!: use `RelativePath` for prefixed ref iteration. Its type captures the requirements better. Co-authored-by: Sebastian Thiel --- gix/src/open/mod.rs | 2 ++ gix/src/open/repository.rs | 45 ++++++++++++++++++++++---------------- gix/src/reference/iter.rs | 25 +++++++++++++++------ 3 files changed, 46 insertions(+), 26 deletions(-) diff --git a/gix/src/open/mod.rs b/gix/src/open/mod.rs index efb95e153cb..ac22c42ae8f 100644 --- a/gix/src/open/mod.rs +++ b/gix/src/open/mod.rs @@ -56,6 +56,8 @@ pub enum Error { UnsafeGitDir { path: PathBuf }, #[error(transparent)] EnvironmentAccessDenied(#[from] gix_sec::permission::Error), + #[error(transparent)] + PrefixNotRelative(#[from] gix_path::relative_path::Error), } mod options; diff --git a/gix/src/open/repository.rs b/gix/src/open/repository.rs index 7cadf579028..0bc308b0c35 100644 --- a/gix/src/open/repository.rs +++ b/gix/src/open/repository.rs @@ -1,7 +1,6 @@ #![allow(clippy::result_large_err)] use super::{Error, Options}; use crate::{ - bstr, bstr::BString, config, config::{ @@ -12,6 +11,8 @@ use crate::{ ThreadSafeRepository, }; use gix_features::threading::OwnShared; +use gix_object::bstr::ByteSlice; +use gix_path::relative_path::RelativePath; use std::ffi::OsStr; use std::{borrow::Cow, path::PathBuf}; @@ -345,24 +346,30 @@ impl ThreadSafeRepository { refs.write_reflog = config::cache::util::reflog_or_default(config.reflog, worktree_dir.is_some()); refs.namespace.clone_from(&config.refs_namespace); - let replacements = replacement_objects_refs_prefix(&config.resolved, lenient_config, filter_config_section)? - .and_then(|prefix| { - use bstr::ByteSlice; - let _span = gix_trace::detail!("find replacement objects"); - let platform = refs.iter().ok()?; - let iter = platform.prefixed(prefix.as_bstr()).ok()?; - let replacements = iter - .filter_map(Result::ok) - .filter_map(|r: gix_ref::Reference| { - let target = r.target.try_id()?.to_owned(); - let source = - gix_hash::ObjectId::from_hex(r.name.as_bstr().strip_prefix(prefix.as_slice())?).ok()?; - Some((source, target)) - }) - .collect::>(); - Some(replacements) - }) - .unwrap_or_default(); + let prefix = replacement_objects_refs_prefix(&config.resolved, lenient_config, filter_config_section)?; + let replacements = match prefix { + Some(prefix) => { + let prefix: &RelativePath = prefix.as_bstr().try_into()?; + + Some(prefix).and_then(|prefix| { + let _span = gix_trace::detail!("find replacement objects"); + let platform = refs.iter().ok()?; + let iter = platform.prefixed(prefix).ok()?; + let replacements = iter + .filter_map(Result::ok) + .filter_map(|r: gix_ref::Reference| { + let target = r.target.try_id()?.to_owned(); + let source = + gix_hash::ObjectId::from_hex(r.name.as_bstr().strip_prefix(prefix.as_ref())?).ok()?; + Some((source, target)) + }) + .collect::>(); + Some(replacements) + }) + } + None => None, + }; + let replacements = replacements.unwrap_or_default(); Ok(ThreadSafeRepository { objects: OwnShared::new(gix_odb::Store::at_opts( diff --git a/gix/src/reference/iter.rs b/gix/src/reference/iter.rs index 6c975d95bc3..e4cd88738fc 100644 --- a/gix/src/reference/iter.rs +++ b/gix/src/reference/iter.rs @@ -1,8 +1,8 @@ //! #![allow(clippy::empty_docs)] -use std::borrow::Cow; -use gix_ref::{bstr::BStr, file::ReferenceExt}; +use gix_path::relative_path::RelativePath; +use gix_ref::file::ReferenceExt; /// A platform to create iterators over references. #[must_use = "Iterators should be obtained from this iterator platform"] @@ -45,8 +45,11 @@ impl Platform<'_> { /// These are of the form `refs/heads/` or `refs/remotes/origin`, and must not contain relative paths components like `.` or `..`. // TODO: Create a custom `Path` type that enforces the requirements of git naturally, this type is surprising possibly on windows // and when not using a trailing '/' to signal directories. - pub fn prefixed<'a>(&self, prefix: impl Into>) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed(prefix.into().as_ref())?)) + pub fn prefixed<'a>( + &self, + prefix: impl TryInto<&'a RelativePath, Error = gix_path::relative_path::Error>, + ) -> Result, init::Error> { + Ok(Iter::new(self.repo, self.platform.prefixed(prefix.try_into()?)?)) } // TODO: tests @@ -54,7 +57,7 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/tags`. pub fn tags(&self) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/tags/")?)) + Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/tags/".try_into()?)?)) } // TODO: tests @@ -62,7 +65,10 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/heads`. pub fn local_branches(&self) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/heads/")?)) + Ok(Iter::new( + self.repo, + self.platform.prefixed(b"refs/heads/".try_into()?)?, + )) } // TODO: tests @@ -70,7 +76,10 @@ impl Platform<'_> { /// /// They are all prefixed with `refs/remotes`. pub fn remote_branches(&self) -> Result, init::Error> { - Ok(Iter::new(self.repo, self.platform.prefixed(b"refs/remotes/")?)) + Ok(Iter::new( + self.repo, + self.platform.prefixed(b"refs/remotes/".try_into()?)?, + )) } } @@ -123,6 +132,8 @@ pub mod init { pub enum Error { #[error(transparent)] Io(#[from] std::io::Error), + #[error(transparent)] + RelativePath(#[from] gix_path::relative_path::Error), } } From 697c27f078d3000f7fa84105bf14a2765fded031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20R=C3=BC=C3=9Fler?= Date: Sun, 20 Apr 2025 09:55:08 +0200 Subject: [PATCH 106/193] Adapt to changes in `gix-path` --- gix-negotiate/tests/baseline/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gix-negotiate/tests/baseline/mod.rs b/gix-negotiate/tests/baseline/mod.rs index 76c18b74cea..4c4df125516 100644 --- a/gix-negotiate/tests/baseline/mod.rs +++ b/gix-negotiate/tests/baseline/mod.rs @@ -71,7 +71,7 @@ fn run() -> crate::Result { // } for tip in lookup_names(&["HEAD"]).into_iter().chain( refs.iter()? - .prefixed(b"refs/heads")? + .prefixed(b"refs/heads".try_into().unwrap())? .filter_map(Result::ok) .map(|r| r.target.into_id()), ) { From 294902e0dbc350a33a0e54164eed626720c1a1d7 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 20 Apr 2025 09:56:50 +0200 Subject: [PATCH 107/193] refactor * move `RelativePath` up to crate level. * deduplicate try-from * move tests into integration test - make them platform independent * do not support initialization from an array (use slice instead) --- gix-path/src/lib.rs | 1 + gix-path/src/relative_path.rs | 299 ++++--------------------- gix-path/tests/path/main.rs | 1 + gix-path/tests/path/relative_path.rs | 160 +++++++++++++ gix-ref/src/namespace.rs | 2 +- gix-ref/src/store/file/loose/iter.rs | 2 +- gix-ref/src/store/file/overlay_iter.rs | 8 +- gix/src/open/repository.rs | 2 +- gix/src/reference/iter.rs | 4 +- gix/tests/gix/repository/reference.rs | 10 +- 10 files changed, 223 insertions(+), 266 deletions(-) create mode 100644 gix-path/tests/path/relative_path.rs diff --git a/gix-path/src/lib.rs b/gix-path/src/lib.rs index 3ad116ac006..5157e78fec1 100644 --- a/gix-path/src/lib.rs +++ b/gix-path/src/lib.rs @@ -65,3 +65,4 @@ pub mod env; /// pub mod relative_path; +pub use relative_path::types::RelativePath; diff --git a/gix-path/src/relative_path.rs b/gix-path/src/relative_path.rs index 6682d647136..2ee5ec222e3 100644 --- a/gix-path/src/relative_path.rs +++ b/gix-path/src/relative_path.rs @@ -2,21 +2,32 @@ use bstr::BStr; use bstr::BString; use bstr::ByteSlice; use gix_validate::path::component::Options; -use std::borrow::Cow; +use std::path::Path; use crate::os_str_into_bstr; use crate::try_from_bstr; use crate::try_from_byte_slice; -/// A wrapper for `BStr`. It is used to enforce the following constraints: -/// -/// - The path separator always is `/`, independent of the platform. -/// - Only normal components are allowed. -/// - It is always represented as a bunch of bytes. -#[derive()] -pub struct RelativePath { - inner: BStr, +pub(super) mod types { + use bstr::{BStr, ByteSlice}; + /// A wrapper for `BStr`. It is used to enforce the following constraints: + /// + /// - The path separator always is `/`, independent of the platform. + /// - Only normal components are allowed. + /// - It is always represented as a bunch of bytes. + #[derive()] + pub struct RelativePath { + inner: BStr, + } + + impl AsRef<[u8]> for RelativePath { + #[inline] + fn as_ref(&self) -> &[u8] { + self.inner.as_bytes() + } + } } +use types::RelativePath; impl RelativePath { fn new_unchecked(value: &BStr) -> Result<&RelativePath, Error> { @@ -26,12 +37,6 @@ impl RelativePath { std::mem::transmute(value) } } - - /// TODO - /// Needs docs. - pub fn ends_with(&self, needle: &[u8]) -> bool { - self.inner.ends_with(needle) - } } /// The error used in [`RelativePath`]. @@ -46,27 +51,26 @@ pub enum Error { IllegalUtf8(#[from] crate::Utf8Error), } -impl<'a> TryFrom<&'a str> for &'a RelativePath { - type Error = Error; - - fn try_from(value: &'a str) -> Result { - use std::path::Path; +fn relative_path_from_value_and_path<'a>(path_bstr: &'a BStr, path: &Path) -> Result<&'a RelativePath, Error> { + if path.is_absolute() { + return Err(Error::IsAbsolute); + } - let path: &std::path::Path = Path::new(value); + let options = Options::default(); - if path.is_absolute() { - return Err(Error::IsAbsolute); - } - - let options: Options = Default::default(); + for component in path.components() { + let component = os_str_into_bstr(component.as_os_str())?; + gix_validate::path::component(component, None, options)?; + } - for component in path.components() { - let component = os_str_into_bstr(component.as_os_str())?; + RelativePath::new_unchecked(BStr::new(path_bstr.as_bytes())) +} - gix_validate::path::component(component, None, options)?; - } +impl<'a> TryFrom<&'a str> for &'a RelativePath { + type Error = Error; - RelativePath::new_unchecked(BStr::new(value.as_bytes())) + fn try_from(value: &'a str) -> Result { + relative_path_from_value_and_path(value.into(), Path::new(value)) } } @@ -74,21 +78,18 @@ impl<'a> TryFrom<&'a BStr> for &'a RelativePath { type Error = Error; fn try_from(value: &'a BStr) -> Result { - let path: &std::path::Path = &try_from_bstr(value)?; - - if path.is_absolute() { - return Err(Error::IsAbsolute); - } - - let options: Options = Default::default(); - - for component in path.components() { - let component = os_str_into_bstr(component.as_os_str())?; + let path = try_from_bstr(value)?; + relative_path_from_value_and_path(value, &path) + } +} - gix_validate::path::component(component, None, options)?; - } +impl<'a> TryFrom<&'a [u8]> for &'a RelativePath { + type Error = Error; - RelativePath::new_unchecked(value) + #[inline] + fn try_from(value: &'a [u8]) -> Result { + let path = try_from_byte_slice(value)?; + relative_path_from_value_and_path(value.as_bstr(), path) } } @@ -97,21 +98,8 @@ impl<'a, const N: usize> TryFrom<&'a [u8; N]> for &'a RelativePath { #[inline] fn try_from(value: &'a [u8; N]) -> Result { - let path: &std::path::Path = try_from_byte_slice(value)?; - - if path.is_absolute() { - return Err(Error::IsAbsolute); - } - - let options: Options = Default::default(); - - for component in path.components() { - let component = os_str_into_bstr(component.as_os_str())?; - - gix_validate::path::component(component, None, options)?; - } - - RelativePath::new_unchecked(value.into()) + let path = try_from_byte_slice(value.as_bstr())?; + relative_path_from_value_and_path(value.as_bstr(), path) } } @@ -119,196 +107,7 @@ impl<'a> TryFrom<&'a BString> for &'a RelativePath { type Error = Error; fn try_from(value: &'a BString) -> Result { - let path: &std::path::Path = &try_from_bstr(value.as_bstr())?; - - if path.is_absolute() { - return Err(Error::IsAbsolute); - } - - let options: Options = Default::default(); - - for component in path.components() { - let component = os_str_into_bstr(component.as_os_str())?; - - gix_validate::path::component(component, None, options)?; - } - - RelativePath::new_unchecked(value.as_bstr()) - } -} - -/// This is required by a trait bound on [`from_str`](crate::from_bstr). -impl<'a> From<&'a RelativePath> for Cow<'a, BStr> { - #[inline] - fn from(value: &'a RelativePath) -> Cow<'a, BStr> { - Cow::Borrowed(&value.inner) - } -} - -impl AsRef<[u8]> for RelativePath { - #[inline] - fn as_ref(&self) -> &[u8] { - self.inner.as_bytes() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[cfg(not(windows))] - #[test] - fn absolute_paths_return_err() { - let path_str: &str = "/refs/heads"; - let path_bstr: &BStr = path_str.into(); - let path_u8: &[u8; 11] = b"/refs/heads"; - let path_bstring: BString = "/refs/heads".into(); - - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_str), - Err(Error::IsAbsolute) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_bstr), - Err(Error::IsAbsolute) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_u8), - Err(Error::IsAbsolute) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(&path_bstring), - Err(Error::IsAbsolute) - )); - } - - #[cfg(windows)] - #[test] - fn absolute_paths_return_err() { - let path_str: &str = r"c:\refs\heads"; - let path_bstr: &BStr = path_str.into(); - let path_u8: &[u8; 13] = b"c:\\refs\\heads"; - let path_bstring: BString = r"c:\refs\heads".into(); - - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_str), - Err(Error::IsAbsolute) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_bstr), - Err(Error::IsAbsolute) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_u8), - Err(Error::IsAbsolute) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(&path_bstring), - Err(Error::IsAbsolute) - )); - } - - #[cfg(not(windows))] - #[test] - fn dots_in_paths_return_err() { - let path_str: &str = "./heads"; - let path_bstr: &BStr = path_str.into(); - let path_u8: &[u8; 7] = b"./heads"; - let path_bstring: BString = "./heads".into(); - - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_str), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_bstr), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_u8), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(&path_bstring), - Err(Error::ContainsInvalidComponent(_)) - )); - } - - #[cfg(windows)] - #[test] - fn dots_in_paths_return_err() { - let path_str: &str = r".\heads"; - let path_bstr: &BStr = path_str.into(); - let path_u8: &[u8; 7] = b".\\heads"; - let path_bstring: BString = r".\heads".into(); - - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_str), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_bstr), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_u8), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(&path_bstring), - Err(Error::ContainsInvalidComponent(_)) - )); - } - - #[cfg(not(windows))] - #[test] - fn double_dots_in_paths_return_err() { - let path_str: &str = "../heads"; - let path_bstr: &BStr = path_str.into(); - let path_u8: &[u8; 8] = b"../heads"; - let path_bstring: BString = "../heads".into(); - - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_str), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_bstr), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_u8), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(&path_bstring), - Err(Error::ContainsInvalidComponent(_)) - )); - } - - #[cfg(windows)] - #[test] - fn double_dots_in_paths_return_err() { - let path_str: &str = r"..\heads"; - let path_bstr: &BStr = path_str.into(); - let path_u8: &[u8; 8] = b"..\\heads"; - let path_bstring: BString = r"..\heads".into(); - - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_str), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_bstr), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(path_u8), - Err(Error::ContainsInvalidComponent(_)) - )); - assert!(matches!( - TryInto::<&RelativePath>::try_into(&path_bstring), - Err(Error::ContainsInvalidComponent(_)) - )); + let path = try_from_bstr(value.as_bstr())?; + relative_path_from_value_and_path(value.as_bstr(), &path) } } diff --git a/gix-path/tests/path/main.rs b/gix-path/tests/path/main.rs index dae33bb7746..4b2f26262b4 100644 --- a/gix-path/tests/path/main.rs +++ b/gix-path/tests/path/main.rs @@ -2,6 +2,7 @@ pub type Result = std::result::Result>; mod convert; mod realpath; +mod relative_path; mod home_dir { #[test] fn returns_existing_directory() { diff --git a/gix-path/tests/path/relative_path.rs b/gix-path/tests/path/relative_path.rs new file mode 100644 index 00000000000..c8d880b3d71 --- /dev/null +++ b/gix-path/tests/path/relative_path.rs @@ -0,0 +1,160 @@ +use bstr::{BStr, BString}; +use gix_path::relative_path::Error; +use gix_path::RelativePath; + +#[cfg(not(windows))] +#[test] +fn absolute_paths_return_err() { + let path_str: &str = "/refs/heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8a: &[u8; 11] = b"/refs/heads"; + let path_u8: &[u8] = &b"/refs/heads"[..]; + let path_bstring: BString = "/refs/heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8a), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::IsAbsolute) + )); +} + +#[cfg(windows)] +#[test] +fn absolute_paths_with_backslashes_return_err() { + let path_str: &str = r"c:\refs\heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8] = &b"c:\\refs\\heads"[..]; + let path_bstring: BString = r"c:\refs\heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::IsAbsolute) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::IsAbsolute) + )); +} + +#[test] +fn dots_in_paths_return_err() { + let path_str: &str = "./heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8] = &b"./heads"[..]; + let path_bstring: BString = "./heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::ContainsInvalidComponent(_)) + )); +} + +#[test] +fn dots_in_paths_with_backslashes_return_err() { + let path_str: &str = r".\heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8] = &b".\\heads"[..]; + let path_bstring: BString = r".\heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::ContainsInvalidComponent(_)) + )); +} + +#[test] +fn double_dots_in_paths_return_err() { + let path_str: &str = "../heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8] = &b"../heads"[..]; + let path_bstring: BString = "../heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::ContainsInvalidComponent(_)) + )); +} + +#[test] +fn double_dots_in_paths_with_backslashes_return_err() { + let path_str: &str = r"..\heads"; + let path_bstr: &BStr = path_str.into(); + let path_u8: &[u8] = &b"..\\heads"[..]; + let path_bstring: BString = r"..\heads".into(); + + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_str), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_bstr), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(path_u8), + Err(Error::ContainsInvalidComponent(_)) + )); + assert!(matches!( + TryInto::<&RelativePath>::try_into(&path_bstring), + Err(Error::ContainsInvalidComponent(_)) + )); +} diff --git a/gix-ref/src/namespace.rs b/gix-ref/src/namespace.rs index 632b8546e66..912fe190ddc 100644 --- a/gix-ref/src/namespace.rs +++ b/gix-ref/src/namespace.rs @@ -1,7 +1,7 @@ use std::path::Path; use gix_object::bstr::{BStr, BString, ByteSlice, ByteVec}; -use gix_path::relative_path::RelativePath; +use gix_path::RelativePath; use crate::{FullName, FullNameRef, Namespace, PartialNameRef}; diff --git a/gix-ref/src/store/file/loose/iter.rs b/gix-ref/src/store/file/loose/iter.rs index bf5206cbb97..31d91a4b094 100644 --- a/gix-ref/src/store/file/loose/iter.rs +++ b/gix-ref/src/store/file/loose/iter.rs @@ -2,7 +2,7 @@ use std::path::{Path, PathBuf}; use gix_features::fs::walkdir::DirEntryIter; use gix_object::bstr::ByteSlice; -use gix_path::relative_path::RelativePath; +use gix_path::RelativePath; use crate::{file::iter::LooseThenPacked, store_impl::file, BString, FullName}; diff --git a/gix-ref/src/store/file/overlay_iter.rs b/gix-ref/src/store/file/overlay_iter.rs index daec5dc47f6..bd5ca365201 100644 --- a/gix-ref/src/store/file/overlay_iter.rs +++ b/gix-ref/src/store/file/overlay_iter.rs @@ -13,7 +13,7 @@ use crate::{ }; use gix_object::bstr::ByteSlice; -use gix_path::relative_path::RelativePath; +use gix_path::RelativePath; /// An iterator stepping through sorted input of loose references and packed references, preferring loose refs over otherwise /// equivalent packed references. @@ -294,9 +294,9 @@ impl<'a> IterInfo<'a> { } fn from_prefix(base: &'a Path, prefix: &'a RelativePath, precompose_unicode: bool) -> std::io::Result { - let prefix_path = gix_path::from_bstr(prefix); + let prefix_path = gix_path::from_bstr(prefix.as_ref().as_bstr()); let iter_root = base.join(&prefix_path); - if prefix.ends_with(b"/") { + if prefix.as_ref().ends_with(b"/") { Ok(IterInfo::BaseAndIterRoot { base, iter_root, @@ -310,7 +310,7 @@ impl<'a> IterInfo<'a> { .to_owned(); Ok(IterInfo::ComputedIterationRoot { base, - prefix: prefix.into(), + prefix: prefix.as_ref().as_bstr().into(), iter_root, precompose_unicode, }) diff --git a/gix/src/open/repository.rs b/gix/src/open/repository.rs index 0bc308b0c35..bb3e15e26ee 100644 --- a/gix/src/open/repository.rs +++ b/gix/src/open/repository.rs @@ -12,7 +12,7 @@ use crate::{ }; use gix_features::threading::OwnShared; use gix_object::bstr::ByteSlice; -use gix_path::relative_path::RelativePath; +use gix_path::RelativePath; use std::ffi::OsStr; use std::{borrow::Cow, path::PathBuf}; diff --git a/gix/src/reference/iter.rs b/gix/src/reference/iter.rs index e4cd88738fc..a18ecbeda91 100644 --- a/gix/src/reference/iter.rs +++ b/gix/src/reference/iter.rs @@ -1,7 +1,7 @@ //! #![allow(clippy::empty_docs)] -use gix_path::relative_path::RelativePath; +use gix_path::RelativePath; use gix_ref::file::ReferenceExt; /// A platform to create iterators over references. @@ -43,8 +43,6 @@ impl Platform<'_> { /// Return an iterator over all references that match the given `prefix`. /// /// These are of the form `refs/heads/` or `refs/remotes/origin`, and must not contain relative paths components like `.` or `..`. - // TODO: Create a custom `Path` type that enforces the requirements of git naturally, this type is surprising possibly on windows - // and when not using a trailing '/' to signal directories. pub fn prefixed<'a>( &self, prefix: impl TryInto<&'a RelativePath, Error = gix_path::relative_path::Error>, diff --git a/gix/tests/gix/repository/reference.rs b/gix/tests/gix/repository/reference.rs index bd5079aabfc..b69ac5445c7 100644 --- a/gix/tests/gix/repository/reference.rs +++ b/gix/tests/gix/repository/reference.rs @@ -1,5 +1,5 @@ mod set_namespace { - use gix::{bstr::ByteSlice, refs::transaction::PreviousValue}; + use gix::refs::transaction::PreviousValue; use gix_testtools::tempfile; fn easy_repo_rw() -> crate::Result<(gix::Repository, tempfile::TempDir)> { @@ -48,7 +48,7 @@ mod set_namespace { assert_eq!( repo.references()? - .prefixed(b"refs/tags/".as_bstr())? + .prefixed("refs/tags/")? .filter_map(Result::ok) .map(|r| r.name().as_bstr().to_owned()) .collect::>(), @@ -81,8 +81,6 @@ mod set_namespace { } mod iter_references { - use gix::bstr::ByteSlice; - use crate::util::hex_to_id; fn repo() -> crate::Result { @@ -125,7 +123,7 @@ mod iter_references { let repo = repo()?; assert_eq!( repo.references()? - .prefixed(b"refs/heads/".as_bstr())? + .prefixed("refs/heads/")? .filter_map(Result::ok) .map(|r| ( r.name().as_bstr().to_string(), @@ -156,7 +154,7 @@ mod iter_references { let repo = repo()?; assert_eq!( repo.references()? - .prefixed(b"refs/heads/".as_bstr())? + .prefixed(b"refs/heads/")? .peeled()? .filter_map(Result::ok) .map(|r| ( From d139fa469cef4d2a2c351ba4c7f34a090a03c233 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 20 Apr 2025 21:26:43 +0200 Subject: [PATCH 108/193] fix: `ToNormalPathComponent` now also validates the component if it's not a `Path`. Previously it was possible for strings or BString/BStr to contain non-normal components, now there is much more validation. --- gix-fs/src/stack.rs | 27 ++++++++++++++++++++------- gix-fs/tests/fs/stack.rs | 13 +++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/gix-fs/src/stack.rs b/gix-fs/src/stack.rs index 2c4d1c0e3a1..2486543d441 100644 --- a/gix-fs/src/stack.rs +++ b/gix-fs/src/stack.rs @@ -50,30 +50,43 @@ fn component_to_os_str<'a>( impl ToNormalPathComponents for &BStr { fn to_normal_path_components(&self) -> impl Iterator> { - self.split(|b| *b == b'/').filter_map(bytes_component_to_os_str) + self.split(|b| *b == b'/') + .filter_map(|c| bytes_component_to_os_str(c, self)) } } impl ToNormalPathComponents for &str { fn to_normal_path_components(&self) -> impl Iterator> { - self.split('/').filter_map(|c| bytes_component_to_os_str(c.as_bytes())) + self.split('/') + .filter_map(|c| bytes_component_to_os_str(c.as_bytes(), (*self).into())) } } impl ToNormalPathComponents for &BString { fn to_normal_path_components(&self) -> impl Iterator> { - self.split(|b| *b == b'/').filter_map(bytes_component_to_os_str) + self.split(|b| *b == b'/') + .filter_map(|c| bytes_component_to_os_str(c, self.as_bstr())) } } -fn bytes_component_to_os_str(component: &[u8]) -> Option> { +fn bytes_component_to_os_str<'a>( + component: &'a [u8], + path: &BStr, +) -> Option> { if component.is_empty() { return None; } - gix_path::try_from_byte_slice(component.as_bstr()) + let component = match gix_path::try_from_byte_slice(component.as_bstr()) .map_err(|_| to_normal_path_components::Error::IllegalUtf8) - .map(Path::as_os_str) - .into() + { + Ok(c) => c, + Err(err) => return Some(Err(err)), + }; + let component = component.components().next()?; + Some(component_to_os_str( + component, + gix_path::try_from_byte_slice(path.as_ref()).ok()?, + )) } /// Access diff --git a/gix-fs/tests/fs/stack.rs b/gix-fs/tests/fs/stack.rs index f3ba1d70751..0c5519b19fa 100644 --- a/gix-fs/tests/fs/stack.rs +++ b/gix-fs/tests/fs/stack.rs @@ -246,6 +246,19 @@ fn absolute_paths_are_invalid() -> crate::Result { r#"Input path "/" contains relative or absolute components"#, "a leading slash is always considered absolute" ); + s.make_relative_path_current("/", &mut r)?; + assert_eq!( + s.current(), + s.root(), + "as string this is a no-op as it's just split by /" + ); + + let err = s.make_relative_path_current("../breakout", &mut r).unwrap_err(); + assert_eq!( + err.to_string(), + r#"Input path "../breakout" contains relative or absolute components"#, + "otherwise breakout attempts are detected" + ); s.make_relative_path_current(p("a/"), &mut r)?; assert_eq!( s.current(), From 96164c5936032b4edb973828178cc55793dd57cc Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 21 Apr 2025 02:53:12 +0100 Subject: [PATCH 109/193] Switch to zlib-rs by default and drop other zlib backends As of zlib-rs 0.5.0 (depended on by flate2 1.1.1), zlib-rs no longer exports C symbols by default, so it doesn't conflict with any other zlib that might be loaded into the address space. This removed the primary issue that made zlib selection a challenge that needed to be exposed to users: users may already have some other particular preference on zlib implementations, or want to use a system library, or want to ensure C dependencies use a particular zlib. Since zlib-rs 0.5.0 no longer conflicts with other zlib implementations, gix can make this choice independently and not create issues for the user. Given that, use zlib-rs by default, for performance out of the box with no C compiler requirement, and deprecate all the feature flags for other variations. A future major version bump can drop all of these features. This also means that (for instance) max-performance becomes the same as max-performance-safe, so such features are deprecated as well. Depend on flate2 with `default-features = false`, which brings us closer to eliminating the `miniz_oxide` dependency, which will improve build time for everyone. Currently, the `gix-archive` dependency on `zip` still activates the `zip/deflate` feature which enables `flate2/rust_backend`; this can be fixed to use `deflate-flate2` as soon as https://github.com/zip-rs/zip2/pull/340 is fixed upstream. Fixes: https://github.com/GitoxideLabs/gitoxide/issues/1961 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 3 --- Cargo.lock | 25 ++------------------ Cargo.toml | 40 ++++++++++---------------------- README.md | 4 ++-- etc/docker/Dockerfile.alpine | 6 ++--- gix-archive/Cargo.toml | 9 ++++---- gix-features/Cargo.toml | 43 +++++++++++++++-------------------- gix/Cargo.toml | 32 ++++++++++---------------- justfile | 4 ---- tests/journey/gix.sh | 9 +------- 11 files changed, 55 insertions(+), 124 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73d7a4b0d16..38daebcd927 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,7 @@ jobs: continue-on-error: true - name: Check for unrecognized *-sys dependencies run: | - ! grep -qP '(? Date: Mon, 21 Apr 2025 08:46:52 +0200 Subject: [PATCH 110/193] Allow `testing::TestUrlExtension` in release builds for consistency (#1962) The module is still hidden from the documentation, and those who discover it anyway will be informed that it's not for general use. --- gix-url/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gix-url/src/lib.rs b/gix-url/src/lib.rs index caf9ef6a473..bbde5a08295 100644 --- a/gix-url/src/lib.rs +++ b/gix-url/src/lib.rs @@ -370,11 +370,10 @@ impl Url { } /// This module contains extensions to the [Url] struct which are only intended to be used -/// for testing code. Do not use this module in production! For all intends and purposes the APIs of +/// for testing code. Do not use this module in production! For all intents and purposes, the APIs of /// all functions and types exposed by this module are considered unstable and are allowed to break /// even in patch releases! #[doc(hidden)] -#[cfg(debug_assertions)] pub mod testing { use bstr::BString; From c33d154cb5ff03dfd4ea0950404ec45b70c27e79 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 21 Apr 2025 10:44:33 +0200 Subject: [PATCH 111/193] refactor tests --- gix-sec/tests/{identity/mod.rs => sec/identity.rs} | 0 gix-sec/tests/{sec.rs => sec/main.rs} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename gix-sec/tests/{identity/mod.rs => sec/identity.rs} (100%) rename gix-sec/tests/{sec.rs => sec/main.rs} (100%) diff --git a/gix-sec/tests/identity/mod.rs b/gix-sec/tests/sec/identity.rs similarity index 100% rename from gix-sec/tests/identity/mod.rs rename to gix-sec/tests/sec/identity.rs diff --git a/gix-sec/tests/sec.rs b/gix-sec/tests/sec/main.rs similarity index 100% rename from gix-sec/tests/sec.rs rename to gix-sec/tests/sec/main.rs From aa91f9ae4c589efb5b047c1f0d9be7fe49f55ab0 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 21 Apr 2025 14:19:15 +0200 Subject: [PATCH 112/193] feat: add `File::section_ids()` iterator and `file::SectionMut::set_trust()` #(1912) That way it's easier to make changes to sections in a mutable instance of Git configuration. --- gix-config/src/file/access/read_only.rs | 5 +++++ gix-config/src/file/mutable/section.rs | 14 +++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gix-config/src/file/access/read_only.rs b/gix-config/src/file/access/read_only.rs index e433bd4d0ae..308b26766d2 100644 --- a/gix-config/src/file/access/read_only.rs +++ b/gix-config/src/file/access/read_only.rs @@ -410,6 +410,11 @@ impl<'event> File<'event> { self.section_order.iter().map(move |id| (&self.sections[id], *id)) } + /// Return an iterator over all section ids, in order of occurrence in the file itself. + pub fn section_ids(&mut self) -> impl Iterator + '_ { + self.section_order.iter().copied() + } + /// Return an iterator over all sections along with non-section events that are placed right after them, /// in order of occurrence in the file itself. /// diff --git a/gix-config/src/file/mutable/section.rs b/gix-config/src/file/mutable/section.rs index 447c8648d67..d41f2f6e8f5 100644 --- a/gix-config/src/file/mutable/section.rs +++ b/gix-config/src/file/mutable/section.rs @@ -3,9 +3,6 @@ use std::{ ops::{Deref, Range}, }; -use bstr::{BStr, BString, ByteSlice, ByteVec}; -use smallvec::SmallVec; - use crate::{ file::{ self, @@ -16,6 +13,9 @@ use crate::{ parse::{section::ValueName, Event}, value::{normalize, normalize_bstr, normalize_bstring}, }; +use bstr::{BStr, BString, ByteSlice, ByteVec}; +use gix_sec::Trust; +use smallvec::SmallVec; /// A opaque type that represents a mutable reference to a section. #[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] @@ -142,6 +142,14 @@ impl<'event> SectionMut<'_, 'event> { } } + /// Set the trust level in the meta-data of this section to `trust`. + pub fn set_trust(&mut self, trust: Trust) -> &mut Self { + let mut meta = (*self.section.meta).clone(); + meta.trust = trust; + self.section.meta = meta.into(); + self + } + /// Removes the latest value by key and returns it, if it exists. pub fn remove(&mut self, value_name: &str) -> Option> { let key = ValueName::from_str_unchecked(value_name); From 24d235d7a6bdb01c5c1cff79b5be14f1d5afa11a Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 21 Apr 2025 14:21:08 +0200 Subject: [PATCH 113/193] fix: `safe.directory` now applies to configuration as well (#1912) This means that repo-local configuration that is considered safe, ideally with `safe.directory=safe/dir/*` notation, will be usable for sensitive operations. --- gix/src/open/repository.rs | 94 ++++++++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 23 deletions(-) diff --git a/gix/src/open/repository.rs b/gix/src/open/repository.rs index bb3e15e26ee..55a2db1a111 100644 --- a/gix/src/open/repository.rs +++ b/gix/src/open/repository.rs @@ -233,7 +233,7 @@ impl ThreadSafeRepository { let home = gix_path::env::home_dir().and_then(|home| env.home.check_opt(home)); let mut filter_config_section = filter_config_section.unwrap_or(config::section::is_trusted); - let config = config::Cache::from_stage_one( + let mut config = config::Cache::from_stage_one( repo_config, common_dir_ref, head.as_ref().and_then(|head| head.target.try_name()), @@ -248,14 +248,54 @@ impl ThreadSafeRepository { cli_config_overrides, )?; - if bail_if_untrusted && git_dir_trust != gix_sec::Trust::Full { - check_safe_directories( - &git_dir, - git_install_dir.as_deref(), - current_dir, - home.as_deref(), - &config, - )?; + // TODO: Testing - it's hard to get non-ownership reliably and without root. + // For now tested manually with https://github.com/GitoxideLabs/gitoxide/issues/1912 + if git_dir_trust != gix_sec::Trust::Full { + let safe_dirs: Vec = config + .resolved + .strings_filter(Safe::DIRECTORY, &mut Safe::directory_filter) + .unwrap_or_default() + .into_iter() + .map(Cow::into_owned) + .collect(); + if bail_if_untrusted { + check_safe_directories( + &git_dir, + git_install_dir.as_deref(), + current_dir, + home.as_deref(), + &safe_dirs, + )?; + } + let Ok(mut resolved) = gix_features::threading::OwnShared::try_unwrap(config.resolved) else { + unreachable!("Shared ownership was just established, with one reference") + }; + let section_ids: Vec<_> = resolved.section_ids().collect(); + for id in section_ids { + let Some(mut section) = resolved.section_mut_by_id(id) else { + continue; + }; + let section_trusted_by_default = Safe::directory_filter(section.meta()); + if section_trusted_by_default || section.meta().trust == gix_sec::Trust::Full { + continue; + } + let Some(meta_path) = section.meta().path.as_deref() else { + continue; + }; + let config_file_is_safe = check_safe_directories( + meta_path, + git_install_dir.as_deref(), + current_dir, + home.as_deref(), + &safe_dirs, + ) + .is_ok(); + + if config_file_is_safe { + section.set_trust(gix_sec::Trust::Full); + } + } + config.resolved = resolved.into(); } // core.worktree might be used to overwrite the worktree directory @@ -423,23 +463,20 @@ fn replacement_objects_refs_prefix( } fn check_safe_directories( - git_dir: &std::path::Path, + path_to_test: &std::path::Path, git_install_dir: Option<&std::path::Path>, current_dir: &std::path::Path, home: Option<&std::path::Path>, - config: &config::Cache, + safe_dirs: &[BString], ) -> Result<(), Error> { let mut is_safe = false; - let git_dir = match gix_path::realpath_opts(git_dir, current_dir, gix_path::realpath::MAX_SYMLINKS) { + let path_to_test = match gix_path::realpath_opts(path_to_test, current_dir, gix_path::realpath::MAX_SYMLINKS) { Ok(p) => p, - Err(_) => git_dir.to_owned(), + Err(_) => path_to_test.to_owned(), }; - for safe_dir in config - .resolved - .strings_filter(Safe::DIRECTORY, &mut Safe::directory_filter) - .unwrap_or_default() - { - if safe_dir.as_ref() == "*" { + for safe_dir in safe_dirs { + let safe_dir = safe_dir.as_bstr(); + if safe_dir == "*" { is_safe = true; continue; } @@ -448,21 +485,32 @@ fn check_safe_directories( continue; } if !is_safe { - let safe_dir = match gix_config::Path::from(std::borrow::Cow::Borrowed(safe_dir.as_ref())) + let safe_dir = match gix_config::Path::from(Cow::Borrowed(safe_dir)) .interpolate(interpolate_context(git_install_dir, home)) { Ok(path) => path, Err(_) => gix_path::from_bstr(safe_dir), }; - if safe_dir == git_dir { - is_safe = true; + if !safe_dir.is_absolute() { + gix_trace::warn!( + "safe.directory '{safe_dir}' not absolute", + safe_dir = safe_dir.display() + ); continue; } + if safe_dir.ends_with("*") { + let safe_dir = safe_dir.parent().expect("* is last component"); + if path_to_test.strip_prefix(safe_dir).is_ok() { + is_safe = true; + } + } else if safe_dir == path_to_test { + is_safe = true; + } } } if is_safe { Ok(()) } else { - Err(Error::UnsafeGitDir { path: git_dir }) + Err(Error::UnsafeGitDir { path: path_to_test }) } } From ca165174e3502aa75e74ef90728d192f517f4406 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 21 Apr 2025 20:53:50 +0200 Subject: [PATCH 114/193] fix: correctly handle safe.directory for worktrees (#1912) --- gix/src/open/repository.rs | 135 ++++++++++++++++++++------------- gix/src/repository/location.rs | 1 + 2 files changed, 83 insertions(+), 53 deletions(-) diff --git a/gix/src/open/repository.rs b/gix/src/open/repository.rs index 55a2db1a111..422f2f4f3e3 100644 --- a/gix/src/open/repository.rs +++ b/gix/src/open/repository.rs @@ -13,6 +13,8 @@ use crate::{ use gix_features::threading::OwnShared; use gix_object::bstr::ByteSlice; use gix_path::RelativePath; +use std::collections::btree_map::Entry; +use std::collections::BTreeMap; use std::ffi::OsStr; use std::{borrow::Cow, path::PathBuf}; @@ -157,7 +159,7 @@ impl ThreadSafeRepository { ) -> Result { let _span = gix_trace::detail!("open_from_paths()"); let Options { - git_dir_trust, + ref mut git_dir_trust, object_store_slots, filter_config_section, lossy_config, @@ -174,7 +176,7 @@ impl ThreadSafeRepository { ref cli_config_overrides, ref mut current_dir, } = options; - let git_dir_trust = git_dir_trust.expect("trust must be determined by now"); + let git_dir_trust = git_dir_trust.as_mut().expect("trust must be determined by now"); let mut common_dir = gix_discover::path::from_plain_file(git_dir.join("commondir").as_ref()) .transpose()? @@ -182,7 +184,7 @@ impl ThreadSafeRepository { let repo_config = config::cache::StageOne::new( common_dir.as_deref().unwrap_or(&git_dir), git_dir.as_ref(), - git_dir_trust, + *git_dir_trust, lossy_config, lenient_config, )?; @@ -248,56 +250,6 @@ impl ThreadSafeRepository { cli_config_overrides, )?; - // TODO: Testing - it's hard to get non-ownership reliably and without root. - // For now tested manually with https://github.com/GitoxideLabs/gitoxide/issues/1912 - if git_dir_trust != gix_sec::Trust::Full { - let safe_dirs: Vec = config - .resolved - .strings_filter(Safe::DIRECTORY, &mut Safe::directory_filter) - .unwrap_or_default() - .into_iter() - .map(Cow::into_owned) - .collect(); - if bail_if_untrusted { - check_safe_directories( - &git_dir, - git_install_dir.as_deref(), - current_dir, - home.as_deref(), - &safe_dirs, - )?; - } - let Ok(mut resolved) = gix_features::threading::OwnShared::try_unwrap(config.resolved) else { - unreachable!("Shared ownership was just established, with one reference") - }; - let section_ids: Vec<_> = resolved.section_ids().collect(); - for id in section_ids { - let Some(mut section) = resolved.section_mut_by_id(id) else { - continue; - }; - let section_trusted_by_default = Safe::directory_filter(section.meta()); - if section_trusted_by_default || section.meta().trust == gix_sec::Trust::Full { - continue; - } - let Some(meta_path) = section.meta().path.as_deref() else { - continue; - }; - let config_file_is_safe = check_safe_directories( - meta_path, - git_install_dir.as_deref(), - current_dir, - home.as_deref(), - &safe_dirs, - ) - .is_ok(); - - if config_file_is_safe { - section.set_trust(gix_sec::Trust::Full); - } - } - config.resolved = resolved.into(); - } - // core.worktree might be used to overwrite the worktree directory if !config.is_bare { let mut key_source = None; @@ -384,6 +336,83 @@ impl ThreadSafeRepository { } } + // TODO: Testing - it's hard to get non-ownership reliably and without root. + // For now tested manually with https://github.com/GitoxideLabs/gitoxide/issues/1912 + if *git_dir_trust != gix_sec::Trust::Full + || worktree_dir + .as_deref() + .is_some_and(|wd| !gix_sec::identity::is_path_owned_by_current_user(wd).unwrap_or(false)) + { + let safe_dirs: Vec = config + .resolved + .strings_filter(Safe::DIRECTORY, &mut Safe::directory_filter) + .unwrap_or_default() + .into_iter() + .map(Cow::into_owned) + .collect(); + let test_dir = worktree_dir.as_deref().unwrap_or(git_dir.as_path()); + let res = check_safe_directories( + test_dir, + git_install_dir.as_deref(), + current_dir, + home.as_deref(), + &safe_dirs, + ); + if res.is_ok() { + *git_dir_trust = gix_sec::Trust::Full; + } else if bail_if_untrusted { + res?; + } else { + // This is how the worktree-trust can reduce the git-dir trust. + *git_dir_trust = gix_sec::Trust::Reduced; + } + + let Ok(mut resolved) = gix_features::threading::OwnShared::try_unwrap(config.resolved) else { + unreachable!("Shared ownership was just established, with one reference") + }; + let section_ids: Vec<_> = resolved.section_ids().collect(); + let mut is_valid_by_path = BTreeMap::new(); + for id in section_ids { + let Some(mut section) = resolved.section_mut_by_id(id) else { + continue; + }; + let section_trusted_by_default = Safe::directory_filter(section.meta()); + if section_trusted_by_default || section.meta().trust == gix_sec::Trust::Full { + continue; + } + let Some(meta_path) = section.meta().path.as_deref() else { + continue; + }; + match is_valid_by_path.entry(meta_path.to_owned()) { + Entry::Occupied(entry) => { + if *entry.get() { + section.set_trust(gix_sec::Trust::Full); + } else { + continue; + } + } + Entry::Vacant(entry) => { + let config_file_is_safe = (meta_path.strip_prefix(test_dir).is_ok() + && *git_dir_trust == gix_sec::Trust::Full) + || check_safe_directories( + meta_path, + git_install_dir.as_deref(), + current_dir, + home.as_deref(), + &safe_dirs, + ) + .is_ok(); + + entry.insert(config_file_is_safe); + if config_file_is_safe { + section.set_trust(gix_sec::Trust::Full); + } + } + } + } + config.resolved = resolved.into(); + } + refs.write_reflog = config::cache::util::reflog_or_default(config.reflog, worktree_dir.is_some()); refs.namespace.clone_from(&config.refs_namespace); let prefix = replacement_objects_refs_prefix(&config.resolved, lenient_config, filter_config_section)?; diff --git a/gix/src/repository/location.rs b/gix/src/repository/location.rs index 95cda2e4fc9..204e61e6612 100644 --- a/gix/src/repository/location.rs +++ b/gix/src/repository/location.rs @@ -12,6 +12,7 @@ impl crate::Repository { } /// The trust we place in the git-dir, with lower amounts of trust causing access to configuration to be limited. + /// Note that if the git-dir is trusted but the worktree is not, the result is that the git-dir is also less trusted. pub fn git_dir_trust(&self) -> gix_sec::Trust { self.options.git_dir_trust.expect("definitely set by now") } From 67fe07aa4e1dae4509f6a920d98e31cc577bc52d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 21 Apr 2025 17:16:57 +0200 Subject: [PATCH 115/193] The monthly report for April 2025 --- etc/reports/25-04.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 etc/reports/25-04.md diff --git a/etc/reports/25-04.md b/etc/reports/25-04.md new file mode 100644 index 00000000000..f28675465c4 --- /dev/null +++ b/etc/reports/25-04.md @@ -0,0 +1,47 @@ +While the previous month was full of bug reports, this month is full of fixes (fortunately). And there is more…. + +## SHA1 with collision detection + +Let's face it, `gitoxide` had it coming. Using the fastest possible SHA1 implementation was great while not too many people were using it, but with `jj` using it for Git interactions the requirements changed. + +It was quite a lot of [contributed work](https://github.com/GitoxideLabs/gitoxide/pull/1915), but now we are finally en-par with Git, which seems to also use a slow SHA1 implementation with collision detection. Unfortunately, this also removes a major performance advantage as it reduces the SHA1 hashing speed by a factor of roughly 3x, a slowdown most noticeable when cloning repositories. In numbers, on my machine I could previously get ~24.5GB/s hashing speed on, and now it's down to 8.5GB/s. + +On the bright side, this will definitely increase the motivation of supporting SHA256 sooner, which should hash with up to 2.1GB per core on my machine, nearly twice as fast as SHA1 prior to collision detection. + +Finally, let me share the [security advisory](https://github.com/GitoxideLabs/gitoxide/security/advisories/GHSA-2frx-2596-x5r6) that motivated the fix, which should help the downstream to upgrade to the latest release. + +## `zlib-rs` as the one and only + +With [zlib-rs](https://github.com/trifectatechfoundation/zlib-rs) we now have a pure-Rust implementation of `zlib-ng`, which for `gitoxide` turned out to be 1% faster than `zlib-ng`, the previously fastest C implementation. That number is an even greater achievement when realizing this is 1% of 3x longer time compared to the SHA1 implementation without collision detection. + +Thanks to [Josh Triplett](https://github.com/joshtriplett/) we could now deprecate all zlib-related configuration flags as a pure Rust implementation will never clash with C symbol exports. In a future step, the deprecated Cargo features will be removed for a great reduction in configuration complexity. + +## Improved `safe.directory` handling + +As `gitoxide` had the luxury of implementing Git from the ground up it could prepare for certain 'concepts' while Git had to tack them on. With that in mind, `safe.directory` wasn't all that important, to the point where it wasn't used where it should have been. + +For one, Git now supports `*` as wildcard-suffixes, allowing to set a directory prefix as safe, and with [this fix](https://github.com/GitoxideLabs/gitoxide/issues/1912) `gitoxide` will do the same. This will also affect Git configuration, which previously wasn't trusted as `safe.directory` didn't affect it. + +Additionally, and unfortunately only with manual testing, I now believe that the fixed implementation is similar to what Git does. + +## Welcome to the Family + +In an effort to unify the maintenance setup of various related projects, as driven by [Eliah Kagan](https://github.com/EliahKagan), we brought `prodash`, `cargo-smart-release` and `learning-Rust-with-Gitoxide` into the GitoxideLabs organization. +From here they will get more timely security updates and patches, and maybe even some improvements here and there. + +## Community + +### An even faster "Blame" with caching + +Even though it's not quite done, yet, I thought it was worth highlighting that Fractional has been working on [adding caching support](https://github.com/GitoxideLabs/gitoxide/pull/1852) for `gix blame`, with examples showing a 80x speedup! +When merged, `gitoxide` will be able to support a new generation of investigative tooling that quickly tells users where lines have been changed, and more. + +### Gix in Cargo + +Thanks to the generous support of [the Rustweek organisers](https://rustweek.org/unconf-intro/) Christoph Rüßler and me will have the opportunity to join the Critical Infrastructure group of the [Unconference](https://rustweek.org/unconf/). There, I hope to get in touch with users of Gitoxide, and of course, the Cargo team to finally meet in person :). And of course, I'd love to finish the [STF application](https://github.com/GitoxideLabs/gitoxide/issues/1406) to get a grant supporting `gitoxide` development, which ideally will be beneficial for `zlib-rs` as well. +With a grant, feature development could be sped up, and I could work on `gitoxide` more as well. + +Cheers +Sebastian + +PS: The latest timesheets can be found [here (2025)](https://github.com/Byron/byron/blob/main/timesheets/2025.csv). \ No newline at end of file From b77d156596249cbbe136e30d82d46b5a9dffb982 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Fri, 25 Apr 2025 00:50:56 -0400 Subject: [PATCH 116/193] Always let Dependabot propose `Cargo.lock` updates This fixes a bug in the `dependabot.yml` configuration since #1948, where we intend Dependabot to include the effect of `cargo update`, but this does not happen because `dependency-type: all` was not explicitly allowed. This does not make an analogous change to the Dependabot configuration for GitHub Actions, because `all` and `direct` currently have the same effect for them (and it is not obvious how it would work if that ever changes, or which we would prefer). For details on why this is needed for Dependabot to update most locked dependencies in `Cargo.lock` aside from the case where the update is done as part of updating a `Cargo.toml` dependency, see: - https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/controlling-dependencies-updated#allowing-specific-dependencies-to-be-updated - https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#dependency-type-allow --- .github/dependabot.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f3c7773dbfe..9946b189a3f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,9 +7,12 @@ updates: commit-message: # Avoid non-"purposeful" prefix due to Dependabot misdetecting style (see `DEVELOPMENT.md`). prefix: '' + allow: + - dependency-type: all groups: cargo: patterns: ['*'] + - package-ecosystem: github-actions directory: '/' schedule: From 06bf1e1552de65ce692911bdc4c501d487bbc3d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Apr 2025 15:01:30 +0000 Subject: [PATCH 117/193] Bump the cargo group with 40 updates Bumps the cargo group with 40 updates: | Package | From | To | | --- | --- | --- | | [anyhow](https://github.com/dtolnay/anyhow) | `1.0.97` | `1.0.98` | | [clap](https://github.com/clap-rs/clap) | `4.5.36` | `4.5.37` | | [winnow](https://github.com/winnow-rs/winnow) | `0.7.6` | `0.7.7` | | [libc](https://github.com/rust-lang/libc) | `0.2.171` | `0.2.172` | | [jiff](https://github.com/BurntSushi/jiff) | `0.2.6` | `0.2.10` | | [proc-macro2](https://github.com/dtolnay/proc-macro2) | `1.0.94` | `1.0.95` | | [signal-hook-registry](https://github.com/vorner/signal-hook) | `1.4.2` | `1.4.5` | | [rusqlite](https://github.com/rusqlite/rusqlite) | `0.34.0` | `0.35.0` | | [layout-rs](https://github.com/nadavrot/layout) | `0.1.2` | `0.1.3` | | [aws-lc-rs](https://github.com/aws/aws-lc-rs) | `1.12.6` | `1.13.0` | | [aws-lc-sys](https://github.com/aws/aws-lc-rs) | `0.27.1` | `0.28.2` | | [cc](https://github.com/rust-lang/cc-rs) | `1.2.16` | `1.2.20` | | [clap_builder](https://github.com/clap-rs/clap) | `4.5.36` | `4.5.37` | | [errno](https://github.com/lambda-fairy/rust-errno) | `0.3.10` | `0.3.11` | | [event-listener-strategy](https://github.com/smol-rs/event-listener-strategy) | `0.5.3` | `0.5.4` | | [h2](https://github.com/hyperium/h2) | `0.4.8` | `0.4.9` | | [half](https://github.com/VoidStarKat/half-rs) | `2.5.0` | `2.6.0` | | [hyper-util](https://github.com/hyperium/hyper-util) | `0.1.10` | `0.1.11` | | [icu_locid_transform_data](https://github.com/unicode-org/icu4x) | `1.5.0` | `1.5.1` | | [icu_normalizer_data](https://github.com/unicode-org/icu4x) | `1.5.0` | `1.5.1` | | [icu_properties_data](https://github.com/unicode-org/icu4x) | `1.5.0` | `1.5.1` | | [indexmap](https://github.com/indexmap-rs/indexmap) | `2.8.0` | `2.9.0` | | [jiff-static](https://github.com/BurntSushi/jiff) | `0.2.6` | `0.2.10` | | [jobserver](https://github.com/rust-lang/jobserver-rs) | `0.1.32` | `0.1.33` | | [libsqlite3-sys](https://github.com/rusqlite/rusqlite) | `0.32.0` | `0.33.0` | | [log](https://github.com/rust-lang/log) | `0.4.26` | `0.4.27` | | [miniz_oxide](https://github.com/Frommi/miniz_oxide) | `0.8.5` | `0.8.8` | | [objc2-core-foundation](https://github.com/madsmtm/objc2) | `0.3.0` | `0.3.1` | | [prettyplease](https://github.com/dtolnay/prettyplease) | `0.2.31` | `0.2.32` | | [quinn-proto](https://github.com/quinn-rs/quinn) | `0.11.10` | `0.11.11` | | [quinn-udp](https://github.com/quinn-rs/quinn) | `0.5.10` | `0.5.11` | | [rand](https://github.com/rust-random/rand) | `0.9.0` | `0.9.1` | | redox_syscall | `0.5.10` | `0.5.11` | | [rustls](https://github.com/rustls/rustls) | `0.23.25` | `0.23.26` | | [scc](https://github.com/wvwwvwwv/scalable-concurrent-containers) | `2.3.3` | `2.3.4` | | [socket2](https://github.com/rust-lang/socket2) | `0.5.8` | `0.5.9` | | [time](https://github.com/time-rs/time) | `0.3.40` | `0.3.41` | | [time-macros](https://github.com/time-rs/time) | `0.2.21` | `0.2.22` | | [tokio-util](https://github.com/tokio-rs/tokio) | `0.7.14` | `0.7.15` | | [value-bag](https://github.com/sval-rs/value-bag) | `1.10.0` | `1.11.1` | Updates `anyhow` from 1.0.97 to 1.0.98 - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.97...1.0.98) Updates `clap` from 4.5.36 to 4.5.37 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.36...clap_complete-v4.5.37) Updates `winnow` from 0.7.6 to 0.7.7 - [Changelog](https://github.com/winnow-rs/winnow/blob/main/CHANGELOG.md) - [Commits](https://github.com/winnow-rs/winnow/compare/v0.7.6...v0.7.7) Updates `libc` from 0.2.171 to 0.2.172 - [Release notes](https://github.com/rust-lang/libc/releases) - [Changelog](https://github.com/rust-lang/libc/blob/0.2.172/CHANGELOG.md) - [Commits](https://github.com/rust-lang/libc/compare/0.2.171...0.2.172) Updates `jiff` from 0.2.6 to 0.2.10 - [Release notes](https://github.com/BurntSushi/jiff/releases) - [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md) - [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.6...jiff-static-0.2.10) Updates `proc-macro2` from 1.0.94 to 1.0.95 - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.94...1.0.95) Updates `signal-hook-registry` from 1.4.2 to 1.4.5 - [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md) - [Commits](https://github.com/vorner/signal-hook/compare/registry-v1.4.2...registry-v1.4.5) Updates `rusqlite` from 0.34.0 to 0.35.0 - [Release notes](https://github.com/rusqlite/rusqlite/releases) - [Changelog](https://github.com/rusqlite/rusqlite/blob/master/Changelog.md) - [Commits](https://github.com/rusqlite/rusqlite/compare/v0.34.0...v0.35.0) Updates `layout-rs` from 0.1.2 to 0.1.3 - [Commits](https://github.com/nadavrot/layout/commits) Updates `aws-lc-rs` from 1.12.6 to 1.13.0 - [Release notes](https://github.com/aws/aws-lc-rs/releases) - [Commits](https://github.com/aws/aws-lc-rs/compare/v1.12.6...v1.13.0) Updates `aws-lc-sys` from 0.27.1 to 0.28.2 - [Release notes](https://github.com/aws/aws-lc-rs/releases) - [Commits](https://github.com/aws/aws-lc-rs/compare/aws-lc-sys/v0.27.1...aws-lc-sys/v0.28.2) Updates `cc` from 1.2.16 to 1.2.20 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.16...cc-v1.2.20) Updates `clap_builder` from 4.5.36 to 4.5.37 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.5.36...v4.5.37) Updates `errno` from 0.3.10 to 0.3.11 - [Release notes](https://github.com/lambda-fairy/rust-errno/releases) - [Changelog](https://github.com/lambda-fairy/rust-errno/blob/main/CHANGELOG.md) - [Commits](https://github.com/lambda-fairy/rust-errno/compare/v0.3.10...v0.3.11) Updates `event-listener-strategy` from 0.5.3 to 0.5.4 - [Release notes](https://github.com/smol-rs/event-listener-strategy/releases) - [Changelog](https://github.com/smol-rs/event-listener-strategy/blob/main/CHANGELOG.md) - [Commits](https://github.com/smol-rs/event-listener-strategy/compare/v0.5.3...v0.5.4) Updates `h2` from 0.4.8 to 0.4.9 - [Release notes](https://github.com/hyperium/h2/releases) - [Changelog](https://github.com/hyperium/h2/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/h2/compare/v0.4.8...v0.4.9) Updates `half` from 2.5.0 to 2.6.0 - [Release notes](https://github.com/VoidStarKat/half-rs/releases) - [Changelog](https://github.com/VoidStarKat/half-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/VoidStarKat/half-rs/compare/v2.5.0...v2.6.0) Updates `hyper-util` from 0.1.10 to 0.1.11 - [Release notes](https://github.com/hyperium/hyper-util/releases) - [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.10...v0.1.11) Updates `icu_locid_transform_data` from 1.5.0 to 1.5.1 - [Release notes](https://github.com/unicode-org/icu4x/releases) - [Changelog](https://github.com/unicode-org/icu4x/blob/main/CHANGELOG.md) - [Commits](https://github.com/unicode-org/icu4x/compare/icu@1.5.0...ind/icu_capi@1.5.1) Updates `icu_normalizer_data` from 1.5.0 to 1.5.1 - [Release notes](https://github.com/unicode-org/icu4x/releases) - [Changelog](https://github.com/unicode-org/icu4x/blob/main/CHANGELOG.md) - [Commits](https://github.com/unicode-org/icu4x/compare/icu@1.5.0...ind/icu_capi@1.5.1) Updates `icu_properties_data` from 1.5.0 to 1.5.1 - [Release notes](https://github.com/unicode-org/icu4x/releases) - [Changelog](https://github.com/unicode-org/icu4x/blob/main/CHANGELOG.md) - [Commits](https://github.com/unicode-org/icu4x/compare/icu@1.5.0...ind/icu_capi@1.5.1) Updates `indexmap` from 2.8.0 to 2.9.0 - [Changelog](https://github.com/indexmap-rs/indexmap/blob/main/RELEASES.md) - [Commits](https://github.com/indexmap-rs/indexmap/compare/2.8.0...2.9.0) Updates `jiff-static` from 0.2.6 to 0.2.10 - [Release notes](https://github.com/BurntSushi/jiff/releases) - [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md) - [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.6...jiff-static-0.2.10) Updates `jobserver` from 0.1.32 to 0.1.33 - [Commits](https://github.com/rust-lang/jobserver-rs/compare/0.1.32...0.1.33) Updates `libsqlite3-sys` from 0.32.0 to 0.33.0 - [Release notes](https://github.com/rusqlite/rusqlite/releases) - [Changelog](https://github.com/rusqlite/rusqlite/blob/master/Changelog.md) - [Commits](https://github.com/rusqlite/rusqlite/compare/v0.32.0...v0.33.0) Updates `log` from 0.4.26 to 0.4.27 - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.26...0.4.27) Updates `miniz_oxide` from 0.8.5 to 0.8.8 - [Changelog](https://github.com/Frommi/miniz_oxide/blob/master/CHANGELOG.md) - [Commits](https://github.com/Frommi/miniz_oxide/compare/0.8.5...0.8.8) Updates `objc2-core-foundation` from 0.3.0 to 0.3.1 - [Commits](https://github.com/madsmtm/objc2/compare/block2-0.3.0...objc-sys-0.3.1) Updates `prettyplease` from 0.2.31 to 0.2.32 - [Release notes](https://github.com/dtolnay/prettyplease/releases) - [Commits](https://github.com/dtolnay/prettyplease/compare/0.2.31...0.2.32) Updates `quinn-proto` from 0.11.10 to 0.11.11 - [Release notes](https://github.com/quinn-rs/quinn/releases) - [Commits](https://github.com/quinn-rs/quinn/compare/quinn-proto-0.11.10...quinn-proto-0.11.11) Updates `quinn-udp` from 0.5.10 to 0.5.11 - [Release notes](https://github.com/quinn-rs/quinn/releases) - [Commits](https://github.com/quinn-rs/quinn/compare/quinn-udp-0.5.10...quinn-udp-0.5.11) Updates `rand` from 0.9.0 to 0.9.1 - [Release notes](https://github.com/rust-random/rand/releases) - [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-random/rand/compare/0.9.0...rand_core-0.9.1) Updates `redox_syscall` from 0.5.10 to 0.5.11 Updates `rustls` from 0.23.25 to 0.23.26 - [Release notes](https://github.com/rustls/rustls/releases) - [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustls/rustls/compare/v/0.23.25...v/0.23.26) Updates `scc` from 2.3.3 to 2.3.4 - [Changelog](https://github.com/wvwwvwwv/scalable-concurrent-containers/blob/main/CHANGELOG.md) - [Commits](https://github.com/wvwwvwwv/scalable-concurrent-containers/commits) Updates `socket2` from 0.5.8 to 0.5.9 - [Release notes](https://github.com/rust-lang/socket2/releases) - [Changelog](https://github.com/rust-lang/socket2/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/socket2/commits) Updates `time` from 0.3.40 to 0.3.41 - [Release notes](https://github.com/time-rs/time/releases) - [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md) - [Commits](https://github.com/time-rs/time/compare/v0.3.40...v0.3.41) Updates `time-macros` from 0.2.21 to 0.2.22 - [Release notes](https://github.com/time-rs/time/releases) - [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md) - [Commits](https://github.com/time-rs/time/compare/v0.2.21...v0.2.22) Updates `tokio-util` from 0.7.14 to 0.7.15 - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-util-0.7.14...tokio-util-0.7.15) Updates `value-bag` from 1.10.0 to 1.11.1 - [Release notes](https://github.com/sval-rs/value-bag/releases) - [Commits](https://github.com/sval-rs/value-bag/compare/v1.10.0...v1.11.1) --- updated-dependencies: - dependency-name: anyhow dependency-version: 1.0.98 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap dependency-version: 4.5.37 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: winnow dependency-version: 0.7.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: libc dependency-version: 0.2.172 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: jiff dependency-version: 0.2.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: proc-macro2 dependency-version: 1.0.95 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: signal-hook-registry dependency-version: 1.4.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: rusqlite dependency-version: 0.35.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: layout-rs dependency-version: 0.1.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: aws-lc-rs dependency-version: 1.13.0 dependency-type: indirect update-type: version-update:semver-minor dependency-group: cargo - dependency-name: aws-lc-sys dependency-version: 0.28.2 dependency-type: indirect update-type: version-update:semver-minor dependency-group: cargo - dependency-name: cc dependency-version: 1.2.20 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap_builder dependency-version: 4.5.37 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: errno dependency-version: 0.3.11 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: event-listener-strategy dependency-version: 0.5.4 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: h2 dependency-version: 0.4.9 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: half dependency-version: 2.6.0 dependency-type: indirect update-type: version-update:semver-minor dependency-group: cargo - dependency-name: hyper-util dependency-version: 0.1.11 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: icu_locid_transform_data dependency-version: 1.5.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: icu_normalizer_data dependency-version: 1.5.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: icu_properties_data dependency-version: 1.5.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: indexmap dependency-version: 2.9.0 dependency-type: indirect update-type: version-update:semver-minor dependency-group: cargo - dependency-name: jiff-static dependency-version: 0.2.10 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: jobserver dependency-version: 0.1.33 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: libsqlite3-sys dependency-version: 0.33.0 dependency-type: indirect update-type: version-update:semver-minor dependency-group: cargo - dependency-name: log dependency-version: 0.4.27 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: miniz_oxide dependency-version: 0.8.8 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: objc2-core-foundation dependency-version: 0.3.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: prettyplease dependency-version: 0.2.32 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: quinn-proto dependency-version: 0.11.11 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: quinn-udp dependency-version: 0.5.11 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: rand dependency-version: 0.9.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: redox_syscall dependency-version: 0.5.11 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: rustls dependency-version: 0.23.26 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: scc dependency-version: 2.3.4 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: socket2 dependency-version: 0.5.9 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: time dependency-version: 0.3.41 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: time-macros dependency-version: 0.2.22 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: tokio-util dependency-version: 0.7.15 dependency-type: indirect update-type: version-update:semver-patch dependency-group: cargo - dependency-name: value-bag dependency-version: 1.11.1 dependency-type: indirect update-type: version-update:semver-minor dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 183 ++++++++++++++++++++------------------- Cargo.toml | 4 +- gitoxide-core/Cargo.toml | 6 +- gix-actor/Cargo.toml | 2 +- gix-archive/Cargo.toml | 2 +- gix-config/Cargo.toml | 2 +- gix-date/Cargo.toml | 2 +- gix-features/Cargo.toml | 2 +- gix-index/Cargo.toml | 2 +- gix-object/Cargo.toml | 2 +- gix-protocol/Cargo.toml | 2 +- gix-ref/Cargo.toml | 2 +- gix-sec/Cargo.toml | 2 +- gix-tempfile/Cargo.toml | 4 +- tests/it/Cargo.toml | 4 +- tests/tools/Cargo.toml | 2 +- 16 files changed, 112 insertions(+), 111 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c1304f77e1..811a8c2cb35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "arbitrary" @@ -302,9 +302,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-lc-rs" -version = "1.12.6" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabb68eb3a7aa08b46fddfd59a3d55c978243557a90ab804769f7e20e67d2b01" +checksum = "19b756939cb2f8dc900aa6dcd505e6e2428e9cae7ff7b028c49e3946efa70878" dependencies = [ "aws-lc-sys", "zeroize", @@ -312,9 +312,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.27.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77926887776171ced7d662120a75998e444d3750c951abfe07f90da130514b1f" +checksum = "bfa9b6986f250236c27e5a204062434a773a13243d2ffc2955f37bdba4c5c6a1" dependencies = [ "bindgen", "cc", @@ -353,7 +353,7 @@ dependencies = [ "bitflags 2.9.0", "cexpr", "clang-sys", - "itertools 0.12.1", + "itertools 0.10.5", "lazy_static", "lazycell", "log", @@ -471,9 +471,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.16" +version = "1.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" dependencies = [ "jobserver", "libc", @@ -547,9 +547,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" dependencies = [ "clap_builder", "clap_derive", @@ -557,9 +557,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" dependencies = [ "anstream", "anstyle", @@ -1031,9 +1031,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", "windows-sys 0.59.0", @@ -1058,9 +1058,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener 5.4.0", "pin-project-lite", @@ -1483,7 +1483,7 @@ dependencies = [ "pretty_assertions", "serde", "thiserror 2.0.12", - "winnow 0.7.6", + "winnow 0.7.7", ] [[package]] @@ -1662,7 +1662,7 @@ dependencies = [ "smallvec", "thiserror 2.0.12", "unicode-bom", - "winnow 0.7.6", + "winnow 0.7.7", ] [[package]] @@ -2249,7 +2249,7 @@ dependencies = [ "smallvec", "termtree", "thiserror 2.0.12", - "winnow 0.7.6", + "winnow 0.7.7", ] [[package]] @@ -2451,7 +2451,7 @@ dependencies = [ "maybe-async", "serde", "thiserror 2.0.12", - "winnow 0.7.6", + "winnow 0.7.7", ] [[package]] @@ -2520,7 +2520,7 @@ dependencies = [ "memmap2", "serde", "thiserror 2.0.12", - "winnow 0.7.6", + "winnow 0.7.7", ] [[package]] @@ -2756,7 +2756,7 @@ dependencies = [ "serial_test", "tar", "tempfile", - "winnow 0.7.6", + "winnow 0.7.7", "xz2", ] @@ -3045,9 +3045,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" dependencies = [ "atomic-waker", "bytes", @@ -3064,9 +3064,9 @@ dependencies = [ [[package]] name = "half" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", @@ -3250,9 +3250,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" dependencies = [ "bytes", "futures-channel", @@ -3260,6 +3260,7 @@ dependencies = [ "http", "http-body", "hyper", + "libc", "pin-project-lite", "socket2", "tokio", @@ -3308,9 +3309,9 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] name = "icu_normalizer" @@ -3332,9 +3333,9 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] name = "icu_properties" @@ -3353,9 +3354,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] name = "icu_provider" @@ -3417,9 +3418,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -3542,9 +3543,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.6" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f33145a5cbea837164362c7bd596106eb7c5198f97d1ba6f6ebb3223952e488" +checksum = "5a064218214dc6a10fbae5ec5fa888d80c45d611aba169222fc272072bf7aef6" dependencies = [ "jiff-static", "jiff-tzdb-platform", @@ -3557,9 +3558,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.6" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ce13c40ec6956157a3635d97a1ee2df323b263f09ea14165131289cb0f5c19" +checksum = "199b7932d97e325aff3a7030e141eafe7f2c6268e1d1b24859b753a627f45254" dependencies = [ "proc-macro2", "quote", @@ -3603,10 +3604,11 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ + "getrandom 0.3.2", "libc", ] @@ -3660,9 +3662,9 @@ dependencies = [ [[package]] name = "layout-rs" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84deb28a3a6c839ca42a7341664f32281416d69e2f29deb85aec5cc0243fdea8" +checksum = "5b8b38bc67665e362eb770c6b6ae88b48d040d94a0a10c4904c37bc79d263b95" [[package]] name = "lazy_static" @@ -3678,9 +3680,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libloading" @@ -3689,7 +3691,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -3705,9 +3707,9 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb8270bb4060bd76c6e96f20c52d80620f1d82a3470885694e41e0f81ef6fe7" +checksum = "947e6816f7825b2b45027c2c32e7085da9934defa535de4a6a46b10a4d5257fa" dependencies = [ "cc", "pkg-config", @@ -3777,9 +3779,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" dependencies = [ "value-bag", ] @@ -3859,9 +3861,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", ] @@ -3993,9 +3995,9 @@ dependencies = [ [[package]] name = "objc2-core-foundation" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daeaf60f25471d26948a1c2f840e3f7d86f4109e3af4e8e4b5cd70c39690d925" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ "bitflags 2.9.0", ] @@ -4269,9 +4271,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" +checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" dependencies = [ "proc-macro2", "syn 2.0.100", @@ -4279,9 +4281,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -4346,9 +4348,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" +checksum = "bcbafbbdbb0f638fe3f35f3c56739f77a8a1d070cb25603226c83339b391472b" dependencies = [ "bytes", "getrandom 0.3.2", @@ -4366,9 +4368,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944" +checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" dependencies = [ "cfg_aliases", "libc", @@ -4395,13 +4397,12 @@ checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" [[package]] name = "rand" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha", "rand_core", - "zerocopy 0.8.23", ] [[package]] @@ -4465,9 +4466,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ "bitflags 2.9.0", ] @@ -4567,9 +4568,9 @@ dependencies = [ [[package]] name = "rusqlite" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e34486da88d8e051c7c0e23c3f15fd806ea8546260aa2fec247e97242ec143" +checksum = "a22715a5d6deef63c637207afbe68d0c72c3f8d0022d7cf9714c442d6157606b" dependencies = [ "bitflags 2.9.0", "fallible-iterator", @@ -4625,9 +4626,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.25" +version = "0.23.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" +checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" dependencies = [ "aws-lc-rs", "once_cell", @@ -4758,9 +4759,9 @@ dependencies = [ [[package]] name = "scc" -version = "2.3.3" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea091f6cac2595aa38993f04f4ee692ed43757035c36e67c180b6828356385b1" +checksum = "22b2d775fb28f245817589471dd49c5edf64237f4a19d10ce9a92ff4651a27f4" dependencies = [ "sdd", ] @@ -4959,9 +4960,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ "libc", ] @@ -4998,9 +4999,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", @@ -5251,9 +5252,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.40" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -5274,9 +5275,9 @@ checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -5354,9 +5355,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" dependencies = [ "bytes", "futures-core", @@ -5396,7 +5397,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.7.6", + "winnow 0.7.7", ] [[package]] @@ -5631,9 +5632,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "value-bag" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" +checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5" [[package]] name = "vcpkg" @@ -5815,7 +5816,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -6287,9 +6288,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +checksum = "6cb8234a863ea0e8cd7284fcdd4f145233eb00fee02bbdd9861aec44e6477bc5" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 2ff494ab6f6..e868f2b8306 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -149,13 +149,13 @@ http-client-reqwest = ["gix/blocking-http-transport-reqwest-rust-tls"] gitoxide-core-async-client = ["gitoxide-core/async-client", "futures-lite"] [dependencies] -anyhow = "1.0.42" +anyhow = "1.0.98" gitoxide-core = { version = "^0.46.0", path = "gitoxide-core" } gix-features = { version = "^0.42.0", path = "gix-features" } gix = { version = "^0.71.0", path = "gix", default-features = false } -clap = { version = "4.5.36", features = ["derive", "cargo"] } +clap = { version = "4.5.37", features = ["derive", "cargo"] } clap_complete = "4.5.47" prodash = { version = "29.0.2", optional = true } is-terminal = { version = "0.4.0", optional = true } diff --git a/gitoxide-core/Cargo.toml b/gitoxide-core/Cargo.toml index 32fe4238f2d..b460003ed42 100644 --- a/gitoxide-core/Cargo.toml +++ b/gitoxide-core/Cargo.toml @@ -56,7 +56,7 @@ gix-archive-for-configuration-only = { package = "gix-archive", version = "^0.20 gix-status = { version = "^0.18.0", path = "../gix-status" } gix-fsck = { version = "^0.10.0", path = "../gix-fsck" } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } -anyhow = "1.0.42" +anyhow = "1.0.98" thiserror = "2.0.0" bytesize = "2.0.1" tempfile = "3.19.1" @@ -79,7 +79,7 @@ crossbeam-channel = { version = "0.5.15", optional = true } smallvec = { version = "1.15.0", optional = true } # for 'query' and 'corpus' -rusqlite = { version = "0.34.0", optional = true, features = ["bundled"] } +rusqlite = { version = "0.35.0", optional = true, features = ["bundled"] } # for 'corpus' parking_lot = { version = "0.12.1", optional = true } @@ -90,7 +90,7 @@ tracing-subscriber = { version = "0.3.17", optional = true } tracing = { version = "0.1.37", optional = true } # for svg graph output -layout-rs = "0.1.1" +layout-rs = "0.1.3" open = "5.0.0" document-features = { version = "0.2.0", optional = true } diff --git a/gix-actor/Cargo.toml b/gix-actor/Cargo.toml index 56c0b1e388a..cb41d4561e1 100644 --- a/gix-actor/Cargo.toml +++ b/gix-actor/Cargo.toml @@ -27,7 +27,7 @@ bstr = { version = "1.12.0", default-features = false, features = [ "std", "unicode", ] } -winnow = { version = "0.7.6", features = ["simd"] } +winnow = { version = "0.7.7", features = ["simd"] } itoa = "1.0.1" serde = { version = "1.0.114", optional = true, default-features = false, features = [ "derive", diff --git a/gix-archive/Cargo.toml b/gix-archive/Cargo.toml index 85f19157cab..436493e0240 100644 --- a/gix-archive/Cargo.toml +++ b/gix-archive/Cargo.toml @@ -35,7 +35,7 @@ gix-date = { version = "^0.9.4", path = "../gix-date" } flate2 = { version = "1.1.1", optional = true, default-features = false, features = ["zlib-rs"] } zip = { version = "2.6.1", optional = true, default-features = false, features = ["deflate"] } -jiff = { version = "0.2.6", default-features = false, features = ["std"] } +jiff = { version = "0.2.10", default-features = false, features = ["std"] } thiserror = "2.0.0" bstr = { version = "1.12.0", default-features = false } diff --git a/gix-config/Cargo.toml b/gix-config/Cargo.toml index 2c28c355f21..f0e3e0f05b5 100644 --- a/gix-config/Cargo.toml +++ b/gix-config/Cargo.toml @@ -26,7 +26,7 @@ gix-sec = { version = "^0.10.12", path = "../gix-sec" } gix-ref = { version = "^0.51.0", path = "../gix-ref" } gix-glob = { version = "^0.19.0", path = "../gix-glob" } -winnow = { version = "0.7.6", features = ["simd"] } +winnow = { version = "0.7.7", features = ["simd"] } memchr = "2" thiserror = "2.0.0" unicode-bom = { version = "2.0.3" } diff --git a/gix-date/Cargo.toml b/gix-date/Cargo.toml index 22eaa94ff4c..1c6acca213b 100644 --- a/gix-date/Cargo.toml +++ b/gix-date/Cargo.toml @@ -22,7 +22,7 @@ serde = ["dep:serde", "bstr/serde"] bstr = { version = "1.12.0", default-features = false, features = ["std"] } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } itoa = "1.0.1" -jiff = "0.2.6" +jiff = "0.2.10" thiserror = "2.0.0" document-features = { version = "0.2.0", optional = true } diff --git a/gix-features/Cargo.toml b/gix-features/Cargo.toml index 0ef19601ccf..0414b241f57 100644 --- a/gix-features/Cargo.toml +++ b/gix-features/Cargo.toml @@ -129,7 +129,7 @@ once_cell = { version = "1.21.3", optional = true } document-features = { version = "0.2.0", optional = true } [target.'cfg(unix)'.dependencies] -libc = { version = "0.2.119" } +libc = { version = "0.2.172" } [dev-dependencies] bstr = { version = "1.12.0", default-features = false } diff --git a/gix-index/Cargo.toml b/gix-index/Cargo.toml index 62cabd34ed7..b8664f0e17b 100644 --- a/gix-index/Cargo.toml +++ b/gix-index/Cargo.toml @@ -55,7 +55,7 @@ rustix = { version = "1.0.5", default-features = false, features = [ "std", "fs", ] } -libc = { version = "0.2.149" } +libc = { version = "0.2.172" } [dev-dependencies] gix-testtools = { path = "../tests/tools" } diff --git a/gix-object/Cargo.toml b/gix-object/Cargo.toml index e8df5b9a7f9..205e4a7e8c8 100644 --- a/gix-object/Cargo.toml +++ b/gix-object/Cargo.toml @@ -58,7 +58,7 @@ bstr = { version = "1.12.0", default-features = false, features = [ "std", "unicode", ] } -winnow = { version = "0.7.6", features = ["simd"] } +winnow = { version = "0.7.7", features = ["simd"] } smallvec = { version = "1.15.0", features = ["write"] } serde = { version = "1.0.114", optional = true, default-features = false, features = [ "derive", diff --git a/gix-protocol/Cargo.toml b/gix-protocol/Cargo.toml index cb4ca0d18da..43f901ef86a 100644 --- a/gix-protocol/Cargo.toml +++ b/gix-protocol/Cargo.toml @@ -94,7 +94,7 @@ bstr = { version = "1.12.0", default-features = false, features = [ "std", "unicode", ] } -winnow = { version = "0.7.6", features = ["simd"] } +winnow = { version = "0.7.7", features = ["simd"] } # for async-client async-trait = { version = "0.1.51", optional = true } diff --git a/gix-ref/Cargo.toml b/gix-ref/Cargo.toml index 90a2f7346b8..9a73592a6d8 100644 --- a/gix-ref/Cargo.toml +++ b/gix-ref/Cargo.toml @@ -33,7 +33,7 @@ gix-lock = { version = "^17.0.0", path = "../gix-lock" } gix-tempfile = { version = "^17.0.0", default-features = false, path = "../gix-tempfile" } thiserror = "2.0.0" -winnow = { version = "0.7.6", features = ["simd"] } +winnow = { version = "0.7.7", features = ["simd"] } serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] } # packed refs diff --git a/gix-sec/Cargo.toml b/gix-sec/Cargo.toml index 684a4653ca6..f2a11c1d845 100644 --- a/gix-sec/Cargo.toml +++ b/gix-sec/Cargo.toml @@ -28,7 +28,7 @@ bitflags = "2" document-features = { version = "0.2.1", optional = true } [target.'cfg(not(windows))'.dependencies] -libc = "0.2.123" +libc = "0.2.172" [target.'cfg(windows)'.dependencies] gix-path = { version = "^0.10.15", path = "../gix-path" } diff --git a/gix-tempfile/Cargo.toml b/gix-tempfile/Cargo.toml index 25a4c7940c5..2bd82e255ef 100644 --- a/gix-tempfile/Cargo.toml +++ b/gix-tempfile/Cargo.toml @@ -38,7 +38,7 @@ once_cell = { version = "1.21.3", default-features = false, features = ["race", tempfile = "3.19.1" signal-hook = { version = "0.3.9", default-features = false, optional = true } -signal-hook-registry = { version = "1.4.0", optional = true } +signal-hook-registry = { version = "1.4.5", optional = true } document-features = { version = "0.2.0", optional = true } @@ -51,7 +51,7 @@ signals = ["dep:signal-hook", "dep:signal-hook-registry"] hp-hashmap = ["dep:dashmap"] [target.'cfg(not(windows))'.dependencies] -libc = { version = "0.2.98", default-features = false } +libc = { version = "0.2.172", default-features = false } [package.metadata.docs.rs] all-features = true diff --git a/tests/it/Cargo.toml b/tests/it/Cargo.toml index 41c9d4c5aa7..1a0eda57ec6 100644 --- a/tests/it/Cargo.toml +++ b/tests/it/Cargo.toml @@ -15,8 +15,8 @@ name = "it" path = "src/main.rs" [dependencies] -anyhow = "1.0.86" -clap = { version = "4.5.36", features = ["derive"] } +anyhow = "1.0.98" +clap = { version = "4.5.37", features = ["derive"] } gix = { version = "^0.71.0", path = "../../gix", default-features = false, features = ["attributes", "revision"] } once_cell = "1.21.3" regex = { version = "1.11.1", default-features = false, features = ["std"] } diff --git a/tests/tools/Cargo.toml b/tests/tools/Cargo.toml index 0938eedf57d..4397c9dd12d 100644 --- a/tests/tools/Cargo.toml +++ b/tests/tools/Cargo.toml @@ -31,7 +31,7 @@ gix-worktree = "0.34.0" gix-fs = "0.11" gix-tempfile = { version = "^14.0.0", default-features = false, features = ["signals"] } -winnow = { version = "0.7.6", features = ["simd"] } +winnow = { version = "0.7.7", features = ["simd"] } fastrand = "2.0.0" bstr = { version = "1.12.0", default-features = false } crc = "3.0.0" From 37367d708e0aea72bf3cef00808ab0069be0a606 Mon Sep 17 00:00:00 2001 From: Pierre Chevalier Date: Sun, 6 Apr 2025 13:08:31 +0100 Subject: [PATCH 118/193] feat: Expose parsing for Time `gix_date::Time` can be parsed in two ways: * From raw bytes (in the data format Git adheres too) * From the date format used in gix config Add utility constructors for these two cases. When parsing from raw bytes, also support a format like `` since this is a situation that happens in the wild and that Git can handle. --- gix-date/src/lib.rs | 17 +++++++++++++++++ gix-date/src/parse.rs | 11 ++++++++--- gix-date/tests/time/parse.rs | 19 +++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/gix-date/src/lib.rs b/gix-date/src/lib.rs index 20893a7cab8..9c5f8faee3b 100644 --- a/gix-date/src/lib.rs +++ b/gix-date/src/lib.rs @@ -15,7 +15,11 @@ pub mod time; /// pub mod parse; +use bstr::{BStr, ByteSlice}; pub use parse::function::parse; +use parse::function::parse_raw; +use parse::Error; +use std::time::SystemTime; /// A timestamp with timezone. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] @@ -29,6 +33,19 @@ pub struct Time { pub sign: time::Sign, } +impl Time { + /// Parse date in config format into a Time + pub fn from_config(i: &BStr) -> Result { + let s = i.as_bstr().to_str().expect("Input must be ascii"); + parse(s, Some(SystemTime::now())) + } + /// Parse raw bytes into a Time + pub fn from_bytes(i: &BStr) -> Result { + let s = i.as_bstr().to_str().expect("Input must be ascii"); + parse_raw(s).ok_or(Error::InvalidDateString { input: s.into() }) + } +} + /// The amount of seconds since unix epoch. /// /// Note that negative dates represent times before the unix epoch. diff --git a/gix-date/src/parse.rs b/gix-date/src/parse.rs index afd3470ac60..622804ac0d1 100644 --- a/gix-date/src/parse.rs +++ b/gix-date/src/parse.rs @@ -60,11 +60,11 @@ pub(crate) mod function { }) } - fn parse_raw(input: &str) -> Option