summaryrefslogtreecommitdiffstats
path: root/vendor/gix-features-0.35.0
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-features-0.35.0')
-rw-r--r--vendor/gix-features-0.35.0/.cargo-checksum.json1
-rw-r--r--vendor/gix-features-0.35.0/CHANGELOG.md1563
-rw-r--r--vendor/gix-features-0.35.0/Cargo.toml184
-rw-r--r--vendor/gix-features-0.35.0/LICENSE-APACHE191
-rw-r--r--vendor/gix-features-0.35.0/LICENSE-MIT21
-rw-r--r--vendor/gix-features-0.35.0/src/cache.rs76
-rw-r--r--vendor/gix-features-0.35.0/src/decode.rs38
-rw-r--r--vendor/gix-features-0.35.0/src/fs.rs118
-rw-r--r--vendor/gix-features-0.35.0/src/hash.rs190
-rw-r--r--vendor/gix-features-0.35.0/src/interrupt.rs161
-rw-r--r--vendor/gix-features-0.35.0/src/io.rs94
-rw-r--r--vendor/gix-features-0.35.0/src/lib.rs66
-rw-r--r--vendor/gix-features-0.35.0/src/parallel/eager_iter.rs124
-rw-r--r--vendor/gix-features-0.35.0/src/parallel/in_order.rs83
-rw-r--r--vendor/gix-features-0.35.0/src/parallel/in_parallel.rs301
-rw-r--r--vendor/gix-features-0.35.0/src/parallel/mod.rs178
-rw-r--r--vendor/gix-features-0.35.0/src/parallel/reduce.rs279
-rw-r--r--vendor/gix-features-0.35.0/src/parallel/serial.rs174
-rw-r--r--vendor/gix-features-0.35.0/src/progress.rs150
-rw-r--r--vendor/gix-features-0.35.0/src/threading.rs110
-rw-r--r--vendor/gix-features-0.35.0/src/zlib/mod.rs52
-rw-r--r--vendor/gix-features-0.35.0/src/zlib/stream/deflate/mod.rs113
-rw-r--r--vendor/gix-features-0.35.0/src/zlib/stream/deflate/tests.rs101
-rw-r--r--vendor/gix-features-0.35.0/src/zlib/stream/inflate.rs40
-rw-r--r--vendor/gix-features-0.35.0/src/zlib/stream/mod.rs4
-rw-r--r--vendor/gix-features-0.35.0/tests/features.rs1
-rw-r--r--vendor/gix-features-0.35.0/tests/hash.rs13
-rw-r--r--vendor/gix-features-0.35.0/tests/parallel/in_order_iter.rs54
-rw-r--r--vendor/gix-features-0.35.0/tests/parallel/mod.rs125
-rw-r--r--vendor/gix-features-0.35.0/tests/parallel_shared.rs1
-rw-r--r--vendor/gix-features-0.35.0/tests/parallel_shared_threaded.rs1
-rw-r--r--vendor/gix-features-0.35.0/tests/parallel_threaded.rs122
-rw-r--r--vendor/gix-features-0.35.0/tests/pipe.rs117
-rw-r--r--vendor/gix-features-0.35.0/tests/trace/mod.rs15
34 files changed, 4861 insertions, 0 deletions
diff --git a/vendor/gix-features-0.35.0/.cargo-checksum.json b/vendor/gix-features-0.35.0/.cargo-checksum.json
new file mode 100644
index 000000000..086fdc237
--- /dev/null
+++ b/vendor/gix-features-0.35.0/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"ad033e719adbd1f2d77a83005e05e205ab72271ad0119d49743f6defee9da073","Cargo.toml":"3c40a4a3227333b290498f1d2b3ed975165704007f95f2dbdeefe75638a7761e","LICENSE-APACHE":"cb4780590812826851ba250f90bed0ed19506ec98f6865a0e2e20bbf62391ff9","LICENSE-MIT":"49df47913ab2beafe8dc45607877ae64198bf0eee64aaad3e82ed9e4d27424e8","src/cache.rs":"0f66cbbe9f5808b21ee255e157a88e2cf7717427214a08b5b9b4f65e4153a617","src/decode.rs":"bf614320c6b69556da40d8412c73fb6a8648c80b7d75b9b2525eb62ac6c8d802","src/fs.rs":"cdcd94974e87e64e98d227876c57e4c198f7920538621b726c0d02466cbed691","src/hash.rs":"62a6c705a9dc7c03214f55bb0f9b2607dbecac5eed81b4883bc5d9970afdb072","src/interrupt.rs":"e2cc5cf58d596ffff9d6b91952a659e4cb7211cb62423b520737abe98a8c25de","src/io.rs":"031f3a9aefb8eff48b98d5794d9c5f277781a4e1ad6ba22f43d79f5ce5b70e14","src/lib.rs":"3b1c85dc37cfc3f1240b5bfe6ba1b0ad70361e3c4f992c1c06badf295bf2056a","src/parallel/eager_iter.rs":"6ab493e6d868c3ac64f4038934a6a71d0d0cbd6e52c4addeec54887aaeab9e8c","src/parallel/in_order.rs":"a1c8c2f6ee4a91d6103f3fc6f27525e309cccc49ffc661d1403dbcdc57d120ad","src/parallel/in_parallel.rs":"4a24250843a3eb0fabe272eeec53bfd5d2c838cdff9e66fb6827fd0c85b81e78","src/parallel/mod.rs":"87abd8147a53ec8d02defd9044e8e12c18fb018446a7cb98ec90cf2fb47133ed","src/parallel/reduce.rs":"3ed124c86af1860dbb07f01ad0249714955327c687bda7ee024cf3a3baf94186","src/parallel/serial.rs":"ee4ff7d6546dc8304e60df9b564d8540b173c093dc9cc78f0ef6caa902fafdd7","src/progress.rs":"1710618bece767f07c05da99a54d27d55a817e69f58a7fdb3b9caafd89f25252","src/threading.rs":"60ff581054d27a0d6ba3df1c14919966274c8f2853981886e3f75812e601fdc3","src/zlib/mod.rs":"720eebfa556bff56a9d90042d4c922f0be0259a9ff921b4f7edf1be0c09ae660","src/zlib/stream/deflate/mod.rs":"c712255c72fa74e2d79af27ad90905d3389e5f760c3f396d936f82906e7c1e14","src/zlib/stream/deflate/tests.rs":"c82d29bf27d1ba54cca4447a750bbaac94547a7ed4eb6e9a311600b8da9a63b8","src/zlib/stream/inflate.rs":"8bad4115c592310cf9f0053f635c8882a0d39e582119ac12dd321ac43d84d1a0","src/zlib/stream/mod.rs":"0af2967eb75a07308c789a4187490cc7c36693b7f7d8a4f7705f3b4b90568f6f","tests/features.rs":"573ade257c38b53430be7e724705e68f7cbca258413c11cd0eec64981c44d97f","tests/hash.rs":"d03f99e2ed1f00066e14212e7e65ee3ae076df42935d38c47d5a563b69367e8c","tests/parallel/in_order_iter.rs":"acd746c25929406748de5080b7ae5dcb2516269f037944d7aa84802520b885b4","tests/parallel/mod.rs":"798b36204033558adb16f44d494e893ea593ef92d09418f8b84ac7cb4cf278af","tests/parallel_shared.rs":"5d8dabaa42fce087e2ec57843cfe69f2be1ca2fa3518030b5a31aeaa706675e0","tests/parallel_shared_threaded.rs":"5d8dabaa42fce087e2ec57843cfe69f2be1ca2fa3518030b5a31aeaa706675e0","tests/parallel_threaded.rs":"02cfb39c7e81bca7e92a851c731e993cad13eff87ec1f8a228d74761ec964f7a","tests/pipe.rs":"ea9e429327dd86002c001f8fc069ac798bd7952ddf3f3b0dd24e3fa69d73c08b","tests/trace/mod.rs":"9896e8394068e99e460607d75291912f511479b223a4722389c26d23eb512d3c"},"package":"9b9ff423ae4983f762659040d13dd7a5defbd54b6a04ac3cc7347741cec828cd"} \ No newline at end of file
diff --git a/vendor/gix-features-0.35.0/CHANGELOG.md b/vendor/gix-features-0.35.0/CHANGELOG.md
new file mode 100644
index 000000000..fa3adcfee
--- /dev/null
+++ b/vendor/gix-features-0.35.0/CHANGELOG.md
@@ -0,0 +1,1563 @@
+# Changelog
+
+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.35.0 (2023-09-24)
+
+### New Features
+
+ - <csr-id-51971969d2cf13587d4bfbd4cb047f2377b8bc0f/> Add `threading::make_mut()` to allow obtaining a mutable reference to shared data.
+ This is particularly useful when handling an index file, which may be shared across clones of
+ a repository.
+
+### Bug Fixes
+
+ - <csr-id-7a8f79357ce99c4b86e22be166b54f7376c71469/> cargo-auditable build error
+ Use `prodash` instead of `dep:prodash` in gix-features and `tracing`
+ instead of `dep:tracing` in gitoxide-core.
+
+ The `dep:mydep` syntax removes the implicit `mydep` feature for optional
+ dependencies, this triggers a bug in cargo that affects
+ `cargo-auditable`. See https://github.com/rust-lang/cargo/issues/12336
+
+ This affects some Linux distributions like NixOS which use
+ `cargo-auditable` by default. Related issues:
+
+ - https://github.com/NixOS/nixpkgs/issues/253911
+- https://github.com/rust-secure-code/cargo-auditable/issues/124
+
+### Bug Fixes (BREAKING)
+
+ - <csr-id-70c7c29266bc4396c968c7aa311c9721929a7cab/> parallel utilities that create thread-state now use `FnOnce`.
+ This way, all unnecessary cloning is avoided.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 8 commits contributed to the release over the course of 15 calendar days.
+ - 16 days passed between releases.
+ - 3 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Prepare changelogs prior to release ([`8a60d5b`](https://github.com/Byron/gitoxide/commit/8a60d5b80877c213c3b646d3061e8a33e0e433ec))
+ - Merge branch 'reset' ([`54a8495`](https://github.com/Byron/gitoxide/commit/54a849545140f7f1c0c7564c418071c0a76a34e7))
+ - Add `threading::make_mut()` to allow obtaining a mutable reference to shared data. ([`5197196`](https://github.com/Byron/gitoxide/commit/51971969d2cf13587d4bfbd4cb047f2377b8bc0f))
+ - Parallel utilities that create thread-state now use `FnOnce`. ([`70c7c29`](https://github.com/Byron/gitoxide/commit/70c7c29266bc4396c968c7aa311c9721929a7cab))
+ - Merge pull request #1024 from Byron/nix-adjustments ([`14e0763`](https://github.com/Byron/gitoxide/commit/14e0763cbf368bda476046a0fd28be230d67b1bd))
+ - Cargo-auditable build error ([`7a8f793`](https://github.com/Byron/gitoxide/commit/7a8f79357ce99c4b86e22be166b54f7376c71469))
+ - Merge branch 'optimize/progress-use' ([`1f2ffb6`](https://github.com/Byron/gitoxide/commit/1f2ffb6d86ef073caf43a2f7a77fe712a1aa495e))
+ - Use trait object for `progress` in `PrepareFetch::fetch_only` ([`70989b3`](https://github.com/Byron/gitoxide/commit/70989b3965077ae00ec6cf344f31627a804a8225))
+</details>
+
+## 0.34.0 (2023-09-08)
+
+<csr-id-ed327f6163f54756e58c20f86a563a97efb256ca/>
+
+### Chore (BREAKING)
+
+ - <csr-id-ed327f6163f54756e58c20f86a563a97efb256ca/> update to the latest `prodash`
+ It makes proper usage of `Progress` types easier and allows them to be used
+ as `dyn` traits as well.
+
+### New Features (BREAKING)
+
+ - <csr-id-24dd870919ba444aa8099c63a78ea120d47ec28e/> use `prodash::Count` to indicate that nothing more than counting is performed, in place of `prodash::Progress`
+
+### Bug Fixes (BREAKING)
+
+ - <csr-id-072ee32f693a31161cd6a843da6582d13efbb20b/> use `dyn` trait where possible.
+ This reduces compile time due to avoiding duplication.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 7 commits contributed to the release over the course of 17 calendar days.
+ - 17 days passed between releases.
+ - 3 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-date v0.8.0, gix-hash v0.13.0, gix-features v0.34.0, gix-actor v0.26.0, gix-object v0.36.0, gix-path v0.10.0, gix-glob v0.12.0, gix-attributes v0.18.0, gix-packetline-blocking v0.16.6, gix-filter v0.4.0, gix-fs v0.6.0, gix-commitgraph v0.20.0, gix-hashtable v0.4.0, gix-revwalk v0.7.0, gix-traverse v0.32.0, gix-worktree-stream v0.4.0, gix-archive v0.4.0, gix-config-value v0.14.0, gix-tempfile v9.0.0, gix-lock v9.0.0, gix-ref v0.36.0, gix-sec v0.10.0, gix-config v0.29.0, gix-prompt v0.7.0, gix-url v0.23.0, gix-credentials v0.19.0, gix-diff v0.35.0, gix-discover v0.24.0, gix-ignore v0.7.0, gix-index v0.24.0, gix-macros v0.1.0, gix-mailmap v0.18.0, gix-negotiate v0.7.0, gix-pack v0.42.0, gix-odb v0.52.0, gix-pathspec v0.2.0, gix-packetline v0.16.6, gix-transport v0.36.0, gix-protocol v0.39.0, gix-revision v0.21.0, gix-refspec v0.17.0, gix-submodule v0.3.0, gix-worktree v0.25.0, gix-worktree-state v0.2.0, gix v0.53.0, safety bump 39 crates ([`8bd0456`](https://github.com/Byron/gitoxide/commit/8bd045676bb2cdc02624ab93e73ff8518064ca38))
+ - Prepare changelogs for release ([`375db06`](https://github.com/Byron/gitoxide/commit/375db06a8442378c3f7a922fae38e2a6694d9d04))
+ - Merge branch `dyn`ification ([`f658fcc`](https://github.com/Byron/gitoxide/commit/f658fcc52dc2200ae34ca53dc10be97fb9012057))
+ - Use `dyn` trait where possible. ([`072ee32`](https://github.com/Byron/gitoxide/commit/072ee32f693a31161cd6a843da6582d13efbb20b))
+ - Use `prodash::Count` to indicate that nothing more than counting is performed, in place of `prodash::Progress` ([`24dd870`](https://github.com/Byron/gitoxide/commit/24dd870919ba444aa8099c63a78ea120d47ec28e))
+ - Update to the latest `prodash` ([`ed327f6`](https://github.com/Byron/gitoxide/commit/ed327f6163f54756e58c20f86a563a97efb256ca))
+ - Merge branch 'gix-submodule' ([`363ee77`](https://github.com/Byron/gitoxide/commit/363ee77400805f473c9ad66eadad9214e7ab66f4))
+</details>
+
+## 0.33.0 (2023-08-22)
+
+A maintenance release without user-facing changes.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 2 commits contributed to the release.
+ - 30 days passed between releases.
+ - 0 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-date v0.7.3, gix-hash v0.12.0, gix-features v0.33.0, gix-actor v0.25.0, gix-object v0.35.0, gix-path v0.9.0, gix-glob v0.11.0, gix-quote v0.4.7, gix-attributes v0.17.0, gix-command v0.2.9, gix-packetline-blocking v0.16.5, gix-filter v0.3.0, gix-fs v0.5.0, gix-commitgraph v0.19.0, gix-hashtable v0.3.0, gix-revwalk v0.6.0, gix-traverse v0.31.0, gix-worktree-stream v0.3.0, gix-archive v0.3.0, gix-config-value v0.13.0, gix-tempfile v8.0.0, gix-lock v8.0.0, gix-ref v0.35.0, gix-sec v0.9.0, gix-config v0.28.0, gix-prompt v0.6.0, gix-url v0.22.0, gix-credentials v0.18.0, gix-diff v0.34.0, gix-discover v0.23.0, gix-ignore v0.6.0, gix-bitmap v0.2.7, gix-index v0.22.0, gix-mailmap v0.17.0, gix-negotiate v0.6.0, gix-pack v0.41.0, gix-odb v0.51.0, gix-pathspec v0.1.0, gix-packetline v0.16.5, gix-transport v0.35.0, gix-protocol v0.38.0, gix-revision v0.20.0, gix-refspec v0.16.0, gix-submodule v0.2.0, gix-worktree v0.24.0, gix-worktree-state v0.1.0, gix v0.52.0, gitoxide-core v0.31.0, gitoxide v0.29.0, safety bump 41 crates ([`30b2761`](https://github.com/Byron/gitoxide/commit/30b27615047692d3ced1b2d9c2ac15a80f79fbee))
+ - Update changelogs prior to release ([`f23ea88`](https://github.com/Byron/gitoxide/commit/f23ea8828f2d9ba7559973daca388c9591bcc5fc))
+</details>
+
+## 0.32.1 (2023-07-22)
+
+### New Features
+
+ - <csr-id-717950977fa758812bc4dd5713f96995bddc491a/> add `interrupt::Write` to auto-fail writes on interrupt.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 7 commits contributed to the release over the course of 1 calendar day.
+ - 3 days passed between releases.
+ - 1 commit was understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-features v0.32.1, gix-actor v0.24.1, gix-validate v0.7.7, gix-object v0.33.1, gix-path v0.8.4, gix-glob v0.10.1, gix-quote v0.4.6, gix-attributes v0.16.0, gix-command v0.2.8, gix-packetline-blocking v0.16.4, gix-filter v0.2.0, gix-fs v0.4.1, gix-chunk v0.4.4, gix-commitgraph v0.18.1, gix-hashtable v0.2.4, gix-revwalk v0.4.1, gix-traverse v0.30.1, gix-worktree-stream v0.2.0, gix-archive v0.2.0, gix-config-value v0.12.5, gix-tempfile v7.0.1, gix-utils v0.1.5, gix-lock v7.0.2, gix-ref v0.33.1, gix-sec v0.8.4, gix-prompt v0.5.4, gix-url v0.21.1, gix-credentials v0.17.1, gix-diff v0.33.1, gix-discover v0.22.1, gix-ignore v0.5.1, gix-bitmap v0.2.6, gix-index v0.21.1, gix-mailmap v0.16.1, gix-negotiate v0.5.1, gix-pack v0.40.1, gix-odb v0.50.1, gix-packetline v0.16.4, gix-transport v0.34.1, gix-protocol v0.36.1, gix-revision v0.18.1, gix-refspec v0.14.1, gix-worktree v0.23.0, gix v0.50.0, safety bump 5 crates ([`16295b5`](https://github.com/Byron/gitoxide/commit/16295b58e2581d2e8b8b762816f52baabe871c75))
+ - Prepare more changelogs ([`c4cc5f2`](https://github.com/Byron/gitoxide/commit/c4cc5f261d29f712a101033a18293a97a9d4ae85))
+ - Release gix-date v0.7.1, gix-hash v0.11.4, gix-trace v0.1.3, gix-features v0.32.0, gix-actor v0.24.0, gix-validate v0.7.7, gix-object v0.33.0, gix-path v0.8.4, gix-glob v0.10.0, gix-quote v0.4.6, gix-attributes v0.15.0, gix-command v0.2.7, gix-packetline-blocking v0.16.3, gix-filter v0.1.0, gix-fs v0.4.0, gix-chunk v0.4.4, gix-commitgraph v0.18.0, gix-hashtable v0.2.4, gix-revwalk v0.4.0, gix-traverse v0.30.0, gix-worktree-stream v0.2.0, gix-archive v0.2.0, gix-config-value v0.12.4, gix-tempfile v7.0.1, gix-utils v0.1.5, gix-lock v7.0.2, gix-ref v0.33.0, gix-sec v0.8.4, gix-prompt v0.5.3, gix-url v0.21.0, gix-credentials v0.17.0, gix-diff v0.33.0, gix-discover v0.22.0, gix-ignore v0.5.0, gix-bitmap v0.2.6, gix-index v0.21.0, gix-mailmap v0.16.0, gix-negotiate v0.5.0, gix-pack v0.40.0, gix-odb v0.50.0, gix-packetline v0.16.4, gix-transport v0.34.0, gix-protocol v0.36.0, gix-revision v0.18.0, gix-refspec v0.14.0, gix-worktree v0.22.0, gix v0.49.1 ([`5cb3589`](https://github.com/Byron/gitoxide/commit/5cb3589b74fc5376e02cbfe151e71344e1c417fe))
+ - Update changelogs prior to release ([`2fc66b5`](https://github.com/Byron/gitoxide/commit/2fc66b55097ed494b72d1af939ba5561f71fde97))
+ - Merge branch 'gix-archive' ([`1dda48b`](https://github.com/Byron/gitoxide/commit/1dda48ba2fccb93ebac00fe3460e923af43c86ce))
+ - Add `interrupt::Write` to auto-fail writes on interrupt. ([`7179509`](https://github.com/Byron/gitoxide/commit/717950977fa758812bc4dd5713f96995bddc491a))
+ - Update license field following SPDX 2.1 license expression standard ([`9064ea3`](https://github.com/Byron/gitoxide/commit/9064ea31fae4dc59a56bdd3a06c0ddc990ee689e))
+</details>
+
+## 0.32.0 (2023-07-19)
+
+### New Features
+
+ - <csr-id-2a76929ece48c3b0fbdba7e08ae5d7e647db4d36/> add `in_parallel_with_finalize` to support a usecase for `gix-worktree`
+ - <csr-id-717950977fa758812bc4dd5713f96995bddc491a/> add `interrupt::Write` to auto-fail writes on interrupt.
+
+### Changed (BREAKING)
+
+ - <csr-id-032cea3d6cfde80fdfc7bfe8722e2514d2bcb5cf/> remove `zlib::stream::inflate::ReadBoxed`.
+ It was a special-case type that was only used in one spot, and thus
+ not really that interesting to have in a shared place.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 7 commits contributed to the release over the course of 10 calendar days.
+ - 19 days passed between releases.
+ - 2 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-features v0.32.0, gix-actor v0.24.0, gix-glob v0.10.0, gix-attributes v0.15.0, gix-commitgraph v0.18.0, gix-config-value v0.12.4, gix-fs v0.4.0, gix-object v0.33.0, gix-ref v0.33.0, gix-config v0.26.0, gix-command v0.2.7, gix-url v0.21.0, gix-credentials v0.17.0, gix-diff v0.33.0, gix-discover v0.22.0, gix-filter v0.1.0, gix-ignore v0.5.0, gix-revwalk v0.4.0, gix-traverse v0.30.0, gix-index v0.21.0, gix-mailmap v0.16.0, gix-negotiate v0.5.0, gix-pack v0.40.0, gix-odb v0.50.0, gix-transport v0.34.0, gix-protocol v0.36.0, gix-revision v0.18.0, gix-refspec v0.14.0, gix-worktree v0.22.0, gix v0.49.0 ([`68ae3ff`](https://github.com/Byron/gitoxide/commit/68ae3ff9d642ec56f088a6a682a073dc16f4e8ca))
+ - Adjust package versions (by cargo-smart-release) ([`c70e54f`](https://github.com/Byron/gitoxide/commit/c70e54f163c312c87753a506eeaad462e8579bfb))
+ - Prepare changelogs prior to release ([`e4dded0`](https://github.com/Byron/gitoxide/commit/e4dded05138562f9737a7dcfb60570c55769486d))
+ - Merge branch 'refactor-pack-streaming' ([`8a46a7e`](https://github.com/Byron/gitoxide/commit/8a46a7ef3efc22241b67f3447223b2505e205442))
+ - Remove `zlib::stream::inflate::ReadBoxed`. ([`032cea3`](https://github.com/Byron/gitoxide/commit/032cea3d6cfde80fdfc7bfe8722e2514d2bcb5cf))
+ - Merge branch 'integrate-filtering' ([`b19a56d`](https://github.com/Byron/gitoxide/commit/b19a56dcfa9bea86332a84aa4e8fad445e7d1724))
+ - Add `in_parallel_with_finalize` to support a usecase for `gix-worktree` ([`2a76929`](https://github.com/Byron/gitoxide/commit/2a76929ece48c3b0fbdba7e08ae5d7e647db4d36))
+</details>
+
+## 0.31.1 (2023-06-29)
+
+A maintenance release without user-facing changes.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 3 commits contributed to the release.
+ - 6 days passed between releases.
+ - 0 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-features v0.31.1, gix-path v0.8.3, gix v0.48.0 ([`9ca3464`](https://github.com/Byron/gitoxide/commit/9ca346462806671fbc49643a87cea25ab0da3be8))
+ - Prepare changelogs once more ([`4bf355a`](https://github.com/Byron/gitoxide/commit/4bf355a8c6a7dbcdb49105af3208d56a0ed8628d))
+ - Adjust `gix-trace` to the latest version. ([`353df4b`](https://github.com/Byron/gitoxide/commit/353df4bf59c7aa98da48bcdcc299f947d9449f55))
+</details>
+
+## 0.31.0 (2023-06-22)
+
+<csr-id-bcad5c22049d56a25ef69d6c7a3344e78f9a1d4d/>
+
+### Chore
+
+ - <csr-id-bcad5c22049d56a25ef69d6c7a3344e78f9a1d4d/> Add `clippy::redundant-closure-for-method-calls` lint
+
+### New Features
+
+ - <csr-id-093efafa7c39aa03bfef4894779cca6e3716f471/> add `tracing` feature toggle to provide minimal tracing API
+ This API is based on `tracing-core`, not on tracing, and provides a limited
+ API that is always available, while being a no-op if `tracing` isn't enabled.
+
+ That way, plumbing crates can add instrumentation at will.
+
+### Bug Fixes (BREAKING)
+
+ - <csr-id-bc69804d5f6cba56349b5b15a2f6d1741849a5eb/> `new_thread_state()` functions are now `FnOnce` across the board.
+ This properly communicates that they will only be called once per thread,
+ while providing more options to the implementor.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 8 commits contributed to the release over the course of 10 calendar days.
+ - 15 days passed between releases.
+ - 3 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-date v0.6.0, gix-hash v0.11.3, gix-trace v0.1.1, gix-features v0.31.0, gix-actor v0.22.0, gix-path v0.8.2, gix-glob v0.9.0, gix-quote v0.4.5, gix-attributes v0.14.0, gix-chunk v0.4.3, gix-commitgraph v0.17.0, gix-config-value v0.12.2, gix-fs v0.3.0, gix-tempfile v7.0.0, gix-utils v0.1.3, gix-lock v7.0.0, gix-validate v0.7.6, gix-object v0.31.0, gix-ref v0.31.0, gix-sec v0.8.2, gix-config v0.24.0, gix-command v0.2.6, gix-prompt v0.5.2, gix-url v0.20.0, gix-credentials v0.16.0, gix-diff v0.31.0, gix-discover v0.20.0, gix-hashtable v0.2.2, gix-ignore v0.4.0, gix-bitmap v0.2.5, gix-revwalk v0.2.0, gix-traverse v0.28.0, gix-index v0.19.0, gix-mailmap v0.14.0, gix-negotiate v0.3.0, gix-pack v0.38.0, gix-odb v0.48.0, gix-packetline v0.16.3, gix-transport v0.33.0, gix-protocol v0.34.0, gix-revision v0.16.0, gix-refspec v0.12.0, gix-worktree v0.20.0, gix v0.47.0, gitoxide-core v0.29.0, gitoxide v0.27.0, safety bump 30 crates ([`ea9f942`](https://github.com/Byron/gitoxide/commit/ea9f9424e777f10da0e33bb9ffbbefd01c4c5a74))
+ - Prepare changelogs prior to release ([`18b0a37`](https://github.com/Byron/gitoxide/commit/18b0a371941aa2d4d62512437d5daa351ba99ffd))
+ - Merge branch 'corpus' ([`aa16c8c`](https://github.com/Byron/gitoxide/commit/aa16c8ce91452a3e3063cf1cf0240b6014c4743f))
+ - Change MSRV to 1.65 ([`4f635fc`](https://github.com/Byron/gitoxide/commit/4f635fc4429350bae2582d25de86429969d28f30))
+ - Add `tracing` feature toggle to provide minimal tracing API ([`093efaf`](https://github.com/Byron/gitoxide/commit/093efafa7c39aa03bfef4894779cca6e3716f471))
+ - `new_thread_state()` functions are now `FnOnce` across the board. ([`bc69804`](https://github.com/Byron/gitoxide/commit/bc69804d5f6cba56349b5b15a2f6d1741849a5eb))
+ - Merge branch 'help-874-redundant-closures' ([`fe59956`](https://github.com/Byron/gitoxide/commit/fe59956ad667303a923d7cfd9ffd72283df41d78))
+ - Add `clippy::redundant-closure-for-method-calls` lint ([`bcad5c2`](https://github.com/Byron/gitoxide/commit/bcad5c22049d56a25ef69d6c7a3344e78f9a1d4d))
+</details>
+
+## 0.30.0 (2023-06-06)
+
+### New Features
+
+ - <csr-id-d81b7e3036371d0a2a22f02a92df3c2b2950ff22/> add `zlib::Inflate::reset()`.
+ That way, each instance can be reused.
+ - <csr-id-add5ea8b83d00972b560536da82f9914ef6080d3/> make `prodash::RawProgress` available.
+ It's an object-safe version of the `Progress` trait.
+
+### New Features (BREAKING)
+
+ - <csr-id-0fa04bcbdf3102c5435e64cfef894a1bfc8d6e7b/> make current thread-count accessible in slice-workers.
+ Threads started for working on an entry in a slice can now see the amount
+ of threads left for use (and manipulate that variable) which effectively
+ allows them to implement their own parallelization on top of the current one.
+
+ This is useful if there is there is very imbalanced work within the slice itself.
+
+ While at it, we also make consumer functions mutable as they exsit per thread.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 20 commits contributed to the release over the course of 22 calendar days.
+ - 48 days passed between releases.
+ - 3 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 1 unique issue was worked on: [#851](https://github.com/Byron/gitoxide/issues/851)
+
+### Thanks Clippy
+
+<csr-read-only-do-not-edit/>
+
+[Clippy](https://github.com/rust-lang/rust-clippy) helped 1 time to make code idiomatic.
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **[#851](https://github.com/Byron/gitoxide/issues/851)**
+ - Make current thread-count accessible in slice-workers. ([`0fa04bc`](https://github.com/Byron/gitoxide/commit/0fa04bcbdf3102c5435e64cfef894a1bfc8d6e7b))
+ * **Uncategorized**
+ - Release gix-date v0.5.1, gix-hash v0.11.2, gix-features v0.30.0, gix-actor v0.21.0, gix-path v0.8.1, gix-glob v0.8.0, gix-quote v0.4.4, gix-attributes v0.13.0, gix-chunk v0.4.2, gix-commitgraph v0.16.0, gix-config-value v0.12.1, gix-fs v0.2.0, gix-tempfile v6.0.0, gix-utils v0.1.2, gix-lock v6.0.0, gix-validate v0.7.5, gix-object v0.30.0, gix-ref v0.30.0, gix-sec v0.8.1, gix-config v0.23.0, gix-command v0.2.5, gix-prompt v0.5.1, gix-url v0.19.0, gix-credentials v0.15.0, gix-diff v0.30.0, gix-discover v0.19.0, gix-hashtable v0.2.1, gix-ignore v0.3.0, gix-bitmap v0.2.4, gix-traverse v0.26.0, gix-index v0.17.0, gix-mailmap v0.13.0, gix-revision v0.15.0, gix-negotiate v0.2.0, gix-pack v0.36.0, gix-odb v0.46.0, gix-packetline v0.16.2, gix-transport v0.32.0, gix-protocol v0.33.0, gix-refspec v0.11.0, gix-worktree v0.18.0, gix v0.45.0, safety bump 29 crates ([`9a9fa96`](https://github.com/Byron/gitoxide/commit/9a9fa96fa8a722bddc5c3b2270b0edf8f6615141))
+ - Prepare changelogs prior to release ([`8f15cec`](https://github.com/Byron/gitoxide/commit/8f15cec1ec7d5a9d56bb158f155011ef2bb3539b))
+ - Merge branch 'integrate-gix-negotiate' ([`ae845de`](https://github.com/Byron/gitoxide/commit/ae845dea6cee6523c88a23d7a14293589cf8092f))
+ - Thanks clippy ([`9525ac8`](https://github.com/Byron/gitoxide/commit/9525ac822aa902f5325f17e7b08ffb60b683e0e7))
+ - Merge branch 'fix-alloc' ([`d9d9bc0`](https://github.com/Byron/gitoxide/commit/d9d9bc01b34ac75b28a5f1b75f40123aa6d83c60))
+ - Add `zlib::Inflate::reset()`. ([`d81b7e3`](https://github.com/Byron/gitoxide/commit/d81b7e3036371d0a2a22f02a92df3c2b2950ff22))
+ - Merge branch 'fix-docs' ([`420553a`](https://github.com/Byron/gitoxide/commit/420553a10d780e0b2dc466cac120989298a5f187))
+ - Cleaning up documentation ([`2578e57`](https://github.com/Byron/gitoxide/commit/2578e576bfa365d194a23a1fb0bf09be230873de))
+ - Merge branch 'auto-clippy' ([`dbf8aa1`](https://github.com/Byron/gitoxide/commit/dbf8aa19d19109195d0274928eae4b94f248cd88))
+ - Autofix map-or-unwrap clippy lint (and manual fix what was left) ([`2087032`](https://github.com/Byron/gitoxide/commit/2087032b5956dcd82bce6ac57e530e8724b57f17))
+ - Merge branch 'main' into auto-clippy ([`3ef5c90`](https://github.com/Byron/gitoxide/commit/3ef5c90aebce23385815f1df674c1d28d58b4b0d))
+ - Auto-fix clippy to remove explicit iter looping ([`3eff567`](https://github.com/Byron/gitoxide/commit/3eff567c683b5c650c14792b68968cbdbc90ec5c))
+ - Merge pull request #865 from nyurik/fix-tests ([`3a45973`](https://github.com/Byron/gitoxide/commit/3a45973c61c4816940b1c9bae4fe60af47a3f6c6))
+ - Merge branch 'blinxen/main' ([`9375cd7`](https://github.com/Byron/gitoxide/commit/9375cd75b01aa22a0e2eed6305fe45fabfd6c1ac))
+ - Include custom clippy settings ([`b057500`](https://github.com/Byron/gitoxide/commit/b057500dd3e6b75be3ebcd258cda0b946bedd9e1))
+ - Make cargo check to pass all tests ([`f4a44f7`](https://github.com/Byron/gitoxide/commit/f4a44f71e894dd8a08dd898a099b743a3ccff557))
+ - Include license files in all crates ([`facaaf6`](https://github.com/Byron/gitoxide/commit/facaaf633f01c857dcf2572c6dbe0a92b7105c1c))
+ - Merge branch 'fix-851' ([`2f275d5`](https://github.com/Byron/gitoxide/commit/2f275d5d3cb49b3b8ba53b30e4b4386fac32662b))
+ - Make `prodash::RawProgress` available. ([`add5ea8`](https://github.com/Byron/gitoxide/commit/add5ea8b83d00972b560536da82f9914ef6080d3))
+</details>
+
+## 0.29.0 (2023-04-19)
+
+### New Features (BREAKING)
+
+ - <csr-id-b645d28f9641c6b4022e1e37ad9fe528922ec747/> remove types that are now available in `gix-os`
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 9 commits contributed to the release over the course of 6 calendar days.
+ - 35 days passed between releases.
+ - 1 commit was understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-utils v0.1.0, gix-hash v0.11.0, gix-date v0.5.0, gix-features v0.29.0, gix-actor v0.20.0, gix-object v0.29.0, gix-archive v0.1.0, gix-fs v0.1.0, safety bump 25 crates ([`8dbd0a6`](https://github.com/Byron/gitoxide/commit/8dbd0a60557a85acfa231800a058cbac0271a8cf))
+ - Prepare changelog prior to release ([`7f06458`](https://github.com/Byron/gitoxide/commit/7f064583bd0e1b078df89a7750f5a25deb70f516))
+ - Support native zlib-ng via flate2's zlib-ng feature ([`9a6e0d7`](https://github.com/Byron/gitoxide/commit/9a6e0d7b418ea721da6a7e4bc48c47b47d4dfa79))
+ - Merge branch 'main' into dev ([`23ee47f`](https://github.com/Byron/gitoxide/commit/23ee47fb24c197f8437bd426544b2aa74e005bdc))
+ - Merge branch 'worktree-stack' ([`3d47919`](https://github.com/Byron/gitoxide/commit/3d47919c1a2f83fc7c1fd7ae590d098057a22626))
+ - Remove types that are now available in `gix-os` ([`b645d28`](https://github.com/Byron/gitoxide/commit/b645d28f9641c6b4022e1e37ad9fe528922ec747))
+ - Use existing concurrency primitive in_parallel ([`c5f3fc8`](https://github.com/Byron/gitoxide/commit/c5f3fc8b5875745eb50bd80005b43a66cf255acb))
+ - Parallel status check ([`d7f250d`](https://github.com/Byron/gitoxide/commit/d7f250ddbd53a994a17db41f86cc780b45e9ee5a))
+ - Release gix-hash v0.10.4, gix-hashtable v0.1.3 ([`b574a39`](https://github.com/Byron/gitoxide/commit/b574a3904203762a6b9e475e16a7c358d7616599))
+</details>
+
+## 0.28.1 (2023-03-14)
+
+A maintenance release without any user-facing changes.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 3 commits contributed to the release over the course of 1 calendar day.
+ - 9 days passed between releases.
+ - 0 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-features v0.28.1, gix-tempfile v5.0.1, gix-ref v0.27.1, gix-pack v0.33.1, gix-packetline v0.15.0, gix-transport v0.29.0, gix-protocol v0.30.0, gix v0.42.0, safety bump 3 crates ([`c1f1bfb`](https://github.com/Byron/gitoxide/commit/c1f1bfb8dc0e73993678353e4492d0614b642ed1))
+ - Prepare changelogs prior to release ([`c66e298`](https://github.com/Byron/gitoxide/commit/c66e2982577e4cd9faef63798986b8cf8ece93a2))
+ - Make fmt ([`3836cc0`](https://github.com/Byron/gitoxide/commit/3836cc0c9c3e1158b56142b924483c8a77217d53))
+</details>
+
+## 0.28.0 (2023-03-04)
+
+### New Features (BREAKING)
+
+ - <csr-id-571ec0d7c3e1eb167d55daa6551bd2b27d3c5b25/> use `std::thread::scope()` instead of `crossbeam-utils::thread::scope()`.
+ This cuts a direct dependency.
+ We can't removed `crossbeam-channel` yet due to the need for single-produce-multiple-consumer
+ channels.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 4 commits contributed to the release over the course of 1 calendar day.
+ - 3 days passed between releases.
+ - 1 commit was understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-features v0.28.0, gix-actor v0.19.0, gix-object v0.28.0, gix-diff v0.28.0, gix-traverse v0.24.0, gix-pack v0.32.0, safety bump 20 crates ([`0f411e9`](https://github.com/Byron/gitoxide/commit/0f411e93ec812592bb9d3a52b751399dd86f76f7))
+ - Prepare changelogs prior to release of `gix-pack` ([`6db30ef`](https://github.com/Byron/gitoxide/commit/6db30ef6b5e931bbf12135507a3d922051de4d4b))
+ - Merge branch 'adjustments-for-cargo' ([`04ab852`](https://github.com/Byron/gitoxide/commit/04ab852f3be76bdf151affa25cf4b999b127bdfe))
+ - Use `std::thread::scope()` instead of `crossbeam-utils::thread::scope()`. ([`571ec0d`](https://github.com/Byron/gitoxide/commit/571ec0d7c3e1eb167d55daa6551bd2b27d3c5b25))
+</details>
+
+## 0.27.0 (2023-03-01)
+
+<csr-id-cce96ee1382d3d56d77820a2aba6e2d17b52f91c/>
+
+### Chore
+
+ - <csr-id-cce96ee1382d3d56d77820a2aba6e2d17b52f91c/> replace `quick-error` with `thiserror`
+ This increases the compile time of the crate alone if there is no proc-macro
+ in the dependency tree, but will ever so slightly improve compile times for `gix`
+ as a whole.
+
+### New Features
+
+ - <csr-id-7a442313c57f58fec5217484f268516711c3d52b/> make `bytesize` available in `progress`.
+ Note that it is stubbed out unless the `progress-unit-bytes` feature is set.
+ - <csr-id-7f6a807ea506358b6dc4fd0c7a648770f1dc91e9/> add `progress::count_with_decimals()` and `progress-unit-*` feature toggles.
+ The new feature toggles allow controlling the inclusion of the `bytesize` and `human_format`
+ crates, which can be toggled with the `progress-unit-bytes` and `progress-unit-human-numbers` respectively.
+
+ Without these features, the respective functions exist but don't provide special formatting, making bytes and
+ larger numbers harder to read.
+
+### Bug Fixes
+
+ - <csr-id-264f78a508d3030cb346623f57ac75add7682169/> remove `num_cpus` in favor of `std::thread::available_parallelism()`.
+ `num_cpus` was needed back in the days when `std` didn't support such
+ functionality yet.
+
+### Changed (BREAKING)
+
+ - <csr-id-0cc548041a861be21001462cbe0ef29b1d61d1c4/> use new `dep:` syntax to hide optional features from feature-set.
+ That way, the set of features is clearly defined and controlled.
+ This migth break applications who relied on direect access to features named
+ after optional dependencies.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 11 commits contributed to the release over the course of 3 calendar days.
+ - 8 days passed between releases.
+ - 5 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-features v0.27.0, gix-actor v0.18.0, gix-quote v0.4.3, gix-attributes v0.9.0, gix-object v0.27.0, gix-ref v0.25.0, gix-config v0.17.0, gix-url v0.14.0, gix-credentials v0.10.0, gix-diff v0.27.0, gix-discover v0.14.0, gix-hashtable v0.1.2, gix-bitmap v0.2.2, gix-traverse v0.23.0, gix-index v0.13.0, gix-mailmap v0.10.0, gix-pack v0.31.0, gix-odb v0.41.0, gix-transport v0.26.0, gix-protocol v0.27.0, gix-revision v0.11.0, gix-refspec v0.8.0, gix-worktree v0.13.0, gix v0.38.0 ([`e6cc618`](https://github.com/Byron/gitoxide/commit/e6cc6184a7a49dbc2503c1c1bdd3688ca5cec5fe))
+ - Adjust manifests prior to release ([`addd789`](https://github.com/Byron/gitoxide/commit/addd78958fdd1e54eb702854e96079539d01965a))
+ - Prepare changelogs prior to release ([`94c99c7`](https://github.com/Byron/gitoxide/commit/94c99c71520f33269cc8dbc26f82a74747cc7e16))
+ - Merge branch 'adjustments-for-cargo' ([`d686d94`](https://github.com/Byron/gitoxide/commit/d686d94e1030a8591ba074757d56927a346c8351))
+ - Depend on latest version of `prodash` for performance improvements. ([`5d00324`](https://github.com/Byron/gitoxide/commit/5d003242abe82b1604e2188d49dec9690ebb2a6a))
+ - Make `bytesize` available in `progress`. ([`7a44231`](https://github.com/Byron/gitoxide/commit/7a442313c57f58fec5217484f268516711c3d52b))
+ - Add `progress::count_with_decimals()` and `progress-unit-*` feature toggles. ([`7f6a807`](https://github.com/Byron/gitoxide/commit/7f6a807ea506358b6dc4fd0c7a648770f1dc91e9))
+ - Use new `dep:` syntax to hide optional features from feature-set. ([`0cc5480`](https://github.com/Byron/gitoxide/commit/0cc548041a861be21001462cbe0ef29b1d61d1c4))
+ - Remove `num_cpus` in favor of `std::thread::available_parallelism()`. ([`264f78a`](https://github.com/Byron/gitoxide/commit/264f78a508d3030cb346623f57ac75add7682169))
+ - Replace `quick-error` with `thiserror` ([`cce96ee`](https://github.com/Byron/gitoxide/commit/cce96ee1382d3d56d77820a2aba6e2d17b52f91c))
+ - Make fmt ([`8ef1cb2`](https://github.com/Byron/gitoxide/commit/8ef1cb293434c7b9e1fda4a6963368e0435920a9))
+</details>
+
+## 0.26.5 (2023-02-20)
+
+### Bug Fixes
+
+ - <csr-id-e14dc7d475373d2c266e84ff8f1826c68a34ab92/> note that crates have been renamed from `git-*` to `gix-*`.
+ This also means that the `git-*` prefixed crates of the `gitoxide` project
+ are effectively unmaintained.
+ Use the crates with the `gix-*` prefix instead.
+
+ If you were using `git-repository`, then `gix` is its substitute.
+ - <csr-id-135d317065aae87af302beb6c26bb6ca8e30b6aa/> compatibility with `bstr` v1.3, use `*.as_bytes()` instead of `.as_ref()`.
+ `as_ref()` relies on a known target type which isn't always present. However, once
+ there is only one implementation, that's no problem, but when that changes compilation
+ fails due to ambiguity.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 2 commits contributed to the release.
+ - 3 days passed between releases.
+ - 1 commit was understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' were seen in commit messages
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **Uncategorized**
+ - Release gix-date v0.4.3, gix-hash v0.10.3, gix-features v0.26.5, gix-actor v0.17.2, gix-glob v0.5.5, gix-path v0.7.2, gix-quote v0.4.2, gix-attributes v0.8.3, gix-validate v0.7.3, gix-object v0.26.2, gix-ref v0.24.1, gix-config v0.16.2, gix-command v0.2.4, gix-url v0.13.3, gix-credentials v0.9.2, gix-discover v0.13.1, gix-index v0.12.4, gix-mailmap v0.9.3, gix-pack v0.30.3, gix-packetline v0.14.3, gix-transport v0.25.6, gix-protocol v0.26.4, gix-revision v0.10.4, gix-refspec v0.7.3, gix-worktree v0.12.3, gix v0.36.1 ([`9604783`](https://github.com/Byron/gitoxide/commit/96047839a20a657a559376b0b14c65aeab96acbd))
+ - Compatibility with `bstr` v1.3, use `*.as_bytes()` instead of `.as_ref()`. ([`135d317`](https://github.com/Byron/gitoxide/commit/135d317065aae87af302beb6c26bb6ca8e30b6aa))
+</details>
+
+## 0.26.4 (2023-02-17)
+
+<csr-id-5bf0034fb3918e57562b7089ceba83d63a1854bf/>
+<csr-id-ab6f98b905f13ed2a7c0c483f34fab63141fbc5b/>
+<csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/>
+<csr-id-361892ca15aa648802f6701ab6a5a30aedde3449/>
+
+### New Features (BREAKING)
+
+ - <csr-id-0f27c67c92fc0bc23a6712b5c4c730ad6a0156bf/> add support for explicit non-parallel iteration.
+ That way we can allow the implementation to choose whether they
+ need greatest speed at some cost or not.
+
+ This also allows us to create a new thread-pool on each iteration
+ as those who expect high cost or many files will likely chose to do
+ that instead of single-threaded iteration, which nicely contains the
+ threads needed and avoids keeping them alive as part of some global pool.
+ - <csr-id-3b29fc18672c0176684c797a0f16f85d09369bf8/> make jwalk fully optional
+ - <csr-id-d078d6ee76a80d1dfaf71608c12d8a402bd670d4/> mild refactor of paths module to waste less on unix
+ Previously it might have performed find-and-replace on unix paths even
+ though they wouldn't have changed afterwards, yet costing an allocation.
+
+ There is also the realization that it should go into its own crate to have
+ neater import paths and more convenience.
+ - <csr-id-8945d95f7fa88562d37ff67ac6e38bead73dd2df/> `interrupt::Iter`, rename `interrupt::Iter` -> `interrupt::IterWithError`
+
+### Chore (BREAKING)
+
+ - <csr-id-5bf0034fb3918e57562b7089ceba83d63a1854bf/> upgrade to prodash v23
+
+### Changed (BREAKING)
+
+ - <csr-id-38446dc8824afef30ef121598de3451d13b9262c/> remove `fs-jwalk-single-threaded` in favor of `fs-walkdir-parallel`.
+ This way, `jwalk` and the dependencies (and troubles) it brings have to
+ be opted in, but also allow other users to actually opt out while
+ allowing the `parallel` feature to be in effect.
+
+ In other words, previously the `parallel` feature conflated `jwalk`
+ dependencies into the tree, which isn't the case anymore.
+ - <csr-id-89a41bf2b37db29b9983b4e5492cfd67ed490b23/> remove local-time-support feature toggle.
+ We treat local time as default feature without a lot of fuzz, and
+ will eventually document that definitive support needs a compile
+ time switch in the compiler (`--cfg unsound_local_offset` or something).
+
+ One day it will perish. Failure is possible anyway and we will write
+ code to deal with it while minimizing the amount of system time
+ fetches when asking for the current local time.
+ - <csr-id-90611ce1527618bcc738440bfc1ccc7a45319974/> remove `path` module in favor of `git-path` crate
+ - <csr-id-61e5cfece4d8f405e35fc1957b00ce1da7526c26/> renamed `progress::Read::reader` -> `progress::Read::inner`
+ - <csr-id-e7526b2a7b51cbac4018e1ab3b623a85987fadc2/> parallel utilities now use `Send + Clone` insted of `Send + Sync`
+ This helps to assure that thread-local computations always work with the
+ kind of types we provide. The ones that are carrying out actions are
+ notably not `Sync` anymore.
+
+ We cater to that by defining our bounds accordingly, but for those
+ who want to use other utilities that need Sync, using types like
+ `Repository` and `thread_local!()` is the only way to make this
+ work.
+
+### Other
+
+ - <csr-id-ab6f98b905f13ed2a7c0c483f34fab63141fbc5b/> try-join with static typing works, but…
+ …seems like a lot of effort. Probably not worth continuing here
+
+### Bug Fixes
+
+ - <csr-id-234cd10ca55482ce1a840ce3244308d249895bcc/> Assure std::io::copy() doesn't hang when we cause an interrupt
+ The user can ask for interruptions which previously used the
+ error kind Interrupted. This however has special meaning and
+ usually means to retry.
+
+### Documentation
+
+ - <csr-id-39ed9eda62b7718d5109135e5ad406fb1fe2978c/> fix typos
+
+### Chore
+
+ - <csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> uniformize deny attributes
+ - <csr-id-361892ca15aa648802f6701ab6a5a30aedde3449/> update sha-1 dependency to 0.10
+
+### New Features
+
+ - <csr-id-a3bd14a7753716e7ad67cd56d24eee1fa099a6fd/> re-export `prodash::progress::(Task|Value)` directly under `progress`
+ This is in addition to the `progress` re-export which allows everything
+ but yields less optimal import paths.
+ - <csr-id-426057247a80821b3da22b4ae5d67bda89ce0631/> re-export `prodash` in `progress` module.
+ That way one can access all types even if they are not re-exported.
+ - <csr-id-c4a7634b0b29c74625e183953e59c65987e9d66c/> export `prodash::progress::Id` in the `progress` module for convenience.
+ - <csr-id-25ad372bf500b851105f53b10369b5a689ba167e/> zlib::inflate::Error can now represent zlib status codes that represent failure.
+ - <csr-id-6d530a1dc77f0f4ac00622a2fd47c7bdb731a77a/> name spawned threads
+ That way it's a bit more obvious what's happening when the CPU goes
+ up in flames.
+ - <csr-id-c8835c6edae784c9ffcb69a674c0a6545dbb2af3/> upgrade to `prodash 21.1` and add `Ids` to all progress instances.
+ That way callers can identify progress they are interested in, say, for
+ selective visualizations.
+ - <csr-id-9076ce33ec167e425a0163d3e40a81a3fd0db6cd/> `fs::Snapshot` can `Clone` if `T` can `Clone`.
+ - <csr-id-a7c11d2cb5f88a4ff322d9a9848459062790d8b3/> perfect granularity for threads processing with `in_parallel_with_slice()`
+ - <csr-id-ff1db66f2dad3afc8bc77610006bca9fea5947d2/> add `progress::Step|StepShared` as types of `prodash`
+ This may help to use the `Progress::counter()` method as part of method
+ signatures, being an `Option<progress::StepShared>`.
+ - <csr-id-cfe46b502afc3ecb312849ddbd7748007d432cd1/> add zlib-ng feature to allow linking against system libz-ng
+ Allow to use zlib-ng (zlib-ng-sys) with native API (no compat mode)
+ that can co-exist with system libz (loaded by e.g. libcurl).
+ This is used in gitoxide package on Alpine Linux.
+ - <csr-id-b1c40b0364ef092cd52d03b34f491b254816b18d/> use docsrs feature in code to show what is feature-gated automatically on docs.rs
+ - <csr-id-517677147f1c17304c62cf97a1dd09f232ebf5db/> pass --cfg docsrs when compiling for https://docs.rs
+ - <csr-id-f498d35baba52e40ecd47381e87c1ce49cf13285/> add `fs-jwalk-single-threaded` feature to specifically decouple `jwalk` from rayon
+ It has been an issue in https://github.com/starship/starship/issues/4251
+ apparently and rayon interactions can be difficult.
+ - <csr-id-7f199f0e5246809efde9880110093fbd11a4f8fe/> `fs::Snapshot` to on-demand reload shared resources.
+ - <csr-id-c76fde7de278b49ded13b655d5345e4eb8c1b134/> initialize `Time` from `now_utc` and `now_local`
+ Localtime support depends on some other factors now, but that
+ will only get better over time.
+
+ We might have to document `unsound_local_time` at some point.
+ - <csr-id-e4d6685064ad2b433f8acd3a74b320bf0169a994/> Add `git_config::values::Path` for a typesafe git path
+ Add a `Path` type to the `git_config::values` which
+ can be interpolated according to gits own path interpolation
+ rules.
+ - <csr-id-3c8581fc294c65c9eb42698969fe3263135a864e/> add new 'path' module for all path-related conversions
+ It's meant to unify all path and byte related handling to help assuring
+ encoding is handled correctly or at least similarly everywhere.
+ - <csr-id-15ff212b17087de93f259e366f4e4b821cfbc28e/> in-manifest and in-lib documentation of feature toggles
+ - <csr-id-cb7e4e784d615f9fa3d6fb9c36240f0592403358/> Add InOrderIter to 'parallel' module
+ This iterator makes possible identifies results using a sequence id
+ and returns only consecutive items.
+
+ Use it to collect unordered results produced by threads.
+ It's advantage to collecting yourself and sorting is the potential
+ for a smaller memory footprint of in-flight results, one doesn't
+ have to collect them all for ordering, necessarily.
+ - <csr-id-ca095ed881db2a8f06a6b067dbaac17e923b0945/> Make a scope-like abstraction available
+ This allows more delicate threading control like is required for the
+ index.
+ - <csr-id-b8400ed80543d67a5895c975ba9b1fc28427411c/> decoding of variable int numbers.
+ It's here only so that we can share the code across crates, for now
+ without any feature toggles.
+ - <csr-id-0a749a22057b5513a8cefa0e26b0a9a268c769d3/> Add `progress::Write` to automatically pass bytes written to a progress instance
+ - <csr-id-7e95d8ab29051ffc892f2dcbaf5369e8c7e7b294/> add threading primitives with feature toggle
+ If the `threading` feature is set, the `threading` module will contain thread-safe primitives
+ for shared ownership and mutation, otherwise these will be their single threaded counterparts.
+
+ This way, single-threaded applications don't have to pay for threaded primitives.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 509 commits contributed to the release over the course of 962 calendar days.
+ - 38 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 21 unique issues were worked on: [#198](https://github.com/Byron/gitoxide/issues/198), [#222](https://github.com/Byron/gitoxide/issues/222), [#259](https://github.com/Byron/gitoxide/issues/259), [#263](https://github.com/Byron/gitoxide/issues/263), [#266](https://github.com/Byron/gitoxide/issues/266), [#279](https://github.com/Byron/gitoxide/issues/279), [#287](https://github.com/Byron/gitoxide/issues/287), [#293](https://github.com/Byron/gitoxide/issues/293), [#298](https://github.com/Byron/gitoxide/issues/298), [#301](https://github.com/Byron/gitoxide/issues/301), [#329](https://github.com/Byron/gitoxide/issues/329), [#331](https://github.com/Byron/gitoxide/issues/331), [#333](https://github.com/Byron/gitoxide/issues/333), [#366](https://github.com/Byron/gitoxide/issues/366), [#427](https://github.com/Byron/gitoxide/issues/427), [#450](https://github.com/Byron/gitoxide/issues/450), [#470](https://github.com/Byron/gitoxide/issues/470), [#503](https://github.com/Byron/gitoxide/issues/503), [#524](https://github.com/Byron/gitoxide/issues/524), [#63](https://github.com/Byron/gitoxide/issues/63), [#691](https://github.com/Byron/gitoxide/issues/691)
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **[#198](https://github.com/Byron/gitoxide/issues/198)**
+ - Handle changelogs with upcoming version section if they were left for editing ([`0f5f47d`](https://github.com/Byron/gitoxide/commit/0f5f47da4662b596cbbbd9c0d83e135e2cc52c11))
+ - Deduplicate conventional message ids ([`e695eda`](https://github.com/Byron/gitoxide/commit/e695eda8cd183f703d9a3e59b7c3c7fa496ea1d2))
+ - Regenerate all changelogs to get links ([`0c81769`](https://github.com/Byron/gitoxide/commit/0c817690bd444f52bed2936b2b451cafd87dde92))
+ - Mention actual issues that where worked on ([`a517e39`](https://github.com/Byron/gitoxide/commit/a517e39a81145b331f6c7a6cc2fc22e25daf42e2))
+ - Allow 'refactor' and 'other' in conventional messages if they have breaking changes ([`4eebaac`](https://github.com/Byron/gitoxide/commit/4eebaac669e590beed112b622752997c64772ef1))
+ - New changelogs for actor and features crates ([`e0d437c`](https://github.com/Byron/gitoxide/commit/e0d437c4cfa06e0792609f41ed5876c390634921))
+ * **[#222](https://github.com/Byron/gitoxide/issues/222)**
+ - Update changelogs prior to release ([`9a493d0`](https://github.com/Byron/gitoxide/commit/9a493d0651b0b6d71cf230dc510a658be7f8cb19))
+ - Stabilize changelogs ([`920e832`](https://github.com/Byron/gitoxide/commit/920e83219911df1c440d3fe42fd5ec3a295b0bb8))
+ - Update changelogs prior to release ([`b3e2252`](https://github.com/Byron/gitoxide/commit/b3e2252f7461a003d9a4612da60ba931dd8c0bef))
+ * **[#259](https://github.com/Byron/gitoxide/issues/259)**
+ - Unify trait bounds for parallel code: prefer Clone over Sync ([`c805d0b`](https://github.com/Byron/gitoxide/commit/c805d0b231cf4d2f51dae7705bfbbc6562f86c32))
+ - Remove trait bounds to allow single-threaded applications to exist ([`3c790e0`](https://github.com/Byron/gitoxide/commit/3c790e01de0dbd3ffa2683d5cf060723d11d64a5))
+ * **[#263](https://github.com/Byron/gitoxide/issues/263)**
+ - Make it possible to return read guards with packed buffers ([`f5c3c8f`](https://github.com/Byron/gitoxide/commit/f5c3c8f7309bf53b9e53f786e75931d701a8585c))
+ - Parallel utilities now use `Send + Clone` insted of `Send + Sync` ([`e7526b2`](https://github.com/Byron/gitoxide/commit/e7526b2a7b51cbac4018e1ab3b623a85987fadc2))
+ - A mad attempt to use thread-local everywhere and avoid Sync… ([`0af5077`](https://github.com/Byron/gitoxide/commit/0af5077e1f028c1c69bbdc098bb567e486282c37))
+ - Add threading primitives with feature toggle ([`7e95d8a`](https://github.com/Byron/gitoxide/commit/7e95d8ab29051ffc892f2dcbaf5369e8c7e7b294))
+ * **[#266](https://github.com/Byron/gitoxide/issues/266)**
+ - Update sha-1 dependency to 0.10 ([`361892c`](https://github.com/Byron/gitoxide/commit/361892ca15aa648802f6701ab6a5a30aedde3449))
+ - Remove slow/unnecessary threading utilities ([`269b7ef`](https://github.com/Byron/gitoxide/commit/269b7efc47bb1d6380b2059f63bd0c53fcd285de))
+ * **[#279](https://github.com/Byron/gitoxide/issues/279)**
+ - Add `progress::Write` to automatically pass bytes written to a progress instance ([`0a749a2`](https://github.com/Byron/gitoxide/commit/0a749a22057b5513a8cefa0e26b0a9a268c769d3))
+ - Renamed `progress::Read::reader` -> `progress::Read::inner` ([`61e5cfe`](https://github.com/Byron/gitoxide/commit/61e5cfece4d8f405e35fc1957b00ce1da7526c26))
+ - Adjust to changes in git-hash and git-pack ([`0cae25b`](https://github.com/Byron/gitoxide/commit/0cae25b1bb3c902ec323f17a1d9743e42fe213d0))
+ * **[#287](https://github.com/Byron/gitoxide/issues/287)**
+ - Upgrade to prodash 17 ([`47860b7`](https://github.com/Byron/gitoxide/commit/47860b7e2769260cfb8522ae455c491605093423))
+ * **[#293](https://github.com/Byron/gitoxide/issues/293)**
+ - Prepare changelogs for git-index and dependencies ([`f54bf4b`](https://github.com/Byron/gitoxide/commit/f54bf4bde92b892b6d425987a6a37e10319c4635))
+ - Fix docs ([`3f89b63`](https://github.com/Byron/gitoxide/commit/3f89b6336e79bc12bc31d40b74221e79a72d2b36))
+ - Fix build ([`e3977fe`](https://github.com/Byron/gitoxide/commit/e3977fe033550bfd3297cdd674934e40476aa38b))
+ - Use InOrderIter from git-features ([`7721b5f`](https://github.com/Byron/gitoxide/commit/7721b5fc7cba86d785e0936fdfab2ea41163219f))
+ - Add InOrderIter to 'parallel' module ([`cb7e4e7`](https://github.com/Byron/gitoxide/commit/cb7e4e784d615f9fa3d6fb9c36240f0592403358))
+ - Make a scope-like abstraction available ([`ca095ed`](https://github.com/Byron/gitoxide/commit/ca095ed881db2a8f06a6b067dbaac17e923b0945))
+ - Single and multi-threaded index tests ([`a22cb0f`](https://github.com/Byron/gitoxide/commit/a22cb0f1ead9a2f32e43eb2fb378281e592a4ed3))
+ - Decoding of variable int numbers. ([`b8400ed`](https://github.com/Byron/gitoxide/commit/b8400ed80543d67a5895c975ba9b1fc28427411c))
+ * **[#298](https://github.com/Byron/gitoxide/issues/298)**
+ - Enforce path conversion on windows gnu, it doesn't seem to like slashes ([`4d55a8f`](https://github.com/Byron/gitoxide/commit/4d55a8f99f2a0b7c0c4ed70a615b7e58b5bee04b))
+ - Use hash_hasher based hash state for better keys/less collisions ([`814de07`](https://github.com/Byron/gitoxide/commit/814de079f4226f42efa49ad334a348bce67184e4))
+ - Upgrade parking_lot and cargo_toml ([`f95c1a0`](https://github.com/Byron/gitoxide/commit/f95c1a0d9c19bcc6feb9b8739a09d86f9970a0e0))
+ * **[#301](https://github.com/Byron/gitoxide/issues/301)**
+ - Update changelogs prior to release ([`84cb256`](https://github.com/Byron/gitoxide/commit/84cb25614a5fcddff297c1713eba4efbb6ff1596))
+ - Remove `path` module in favor of `git-path` crate ([`90611ce`](https://github.com/Byron/gitoxide/commit/90611ce1527618bcc738440bfc1ccc7a45319974))
+ - Mild refactor of paths module to waste less on unix ([`d078d6e`](https://github.com/Byron/gitoxide/commit/d078d6ee76a80d1dfaf71608c12d8a402bd670d4))
+ - Refactor ([`8345b7c`](https://github.com/Byron/gitoxide/commit/8345b7caa0cc1cd8489e41822eea89da4c539e6d))
+ - More stable testing of perviously racy test for new parallelization mechanism ([`0b4b90f`](https://github.com/Byron/gitoxide/commit/0b4b90fa498d9e07a55b72af2f799da4cd2da81f))
+ - Salvage an alternative parallelization approach which might be good for index-creation ([`7e76796`](https://github.com/Byron/gitoxide/commit/7e76796d5c2956961bd998286bec05fca1ba8fc4))
+ - Refactor ([`f86eacc`](https://github.com/Byron/gitoxide/commit/f86eacc5cfaf6d88ead4f8dbd65989d32674c213))
+ - Use hopefully faster crossbeam channel to receive parallelized results ([`3b324b8`](https://github.com/Byron/gitoxide/commit/3b324b868d9d172038797f911eeebfcba8107865))
+ - Switch index checkout to chunk-based operation ([`e5f6943`](https://github.com/Byron/gitoxide/commit/e5f69433e4a6cc7866b666e0baccfa32efb92a7f))
+ - Add thread-count and chunk-size computation; interrupt capability ([`8cbe85d`](https://github.com/Byron/gitoxide/commit/8cbe85d135898826a91939726465a9e295c1e24b))
+ - `interrupt::Iter`, rename `interrupt::Iter` -> `interrupt::IterWithError` ([`8945d95`](https://github.com/Byron/gitoxide/commit/8945d95f7fa88562d37ff67ac6e38bead73dd2df))
+ - Fix `interrupt::Iter` ([`0f0d390`](https://github.com/Byron/gitoxide/commit/0f0d390c475044a75e5db4dcd831d755e74aa3e9))
+ * **[#329](https://github.com/Byron/gitoxide/issues/329)**
+ - In-manifest and in-lib documentation of feature toggles ([`15ff212`](https://github.com/Byron/gitoxide/commit/15ff212b17087de93f259e366f4e4b821cfbc28e))
+ * **[#331](https://github.com/Byron/gitoxide/issues/331)**
+ - Remove local-time-support feature toggle. ([`89a41bf`](https://github.com/Byron/gitoxide/commit/89a41bf2b37db29b9983b4e5492cfd67ed490b23))
+ - Initialize `Time` from `now_utc` and `now_local` ([`c76fde7`](https://github.com/Byron/gitoxide/commit/c76fde7de278b49ded13b655d5345e4eb8c1b134))
+ - A first sketch on how identity management could look like. ([`780f14f`](https://github.com/Byron/gitoxide/commit/780f14f5c270802e51cf039639c2fbdb5ac5a85e))
+ - Update changelog prior to release ([`1d07934`](https://github.com/Byron/gitoxide/commit/1d079346e789b0acc9a4bdf7577b21c1c37b6106))
+ - Remove Option return values in favor of Result ([`493dbae`](https://github.com/Byron/gitoxide/commit/493dbae434e8e4a939e90d03ec3f500744c0725a))
+ - Add `git_config::values::Path` for a typesafe git path ([`e4d6685`](https://github.com/Byron/gitoxide/commit/e4d6685064ad2b433f8acd3a74b320bf0169a994))
+ * **[#333](https://github.com/Byron/gitoxide/issues/333)**
+ - Use git_features::path everywhere where there is a path conversion ([`2e1437c`](https://github.com/Byron/gitoxide/commit/2e1437cb0b5dc77f2317881767f71eaf9b009ebf))
+ - Make real clear panics are only possible on windows ([`6b283dc`](https://github.com/Byron/gitoxide/commit/6b283dc7b9339fd65ea35f56eb29f121f571caf7))
+ - One usage of os_str_bytes down, along with some custom conversion code ([`1cc95ce`](https://github.com/Byron/gitoxide/commit/1cc95cefbd132a4277ec52c2147f7c81fea92d48))
+ - Gitoxide-core without os-str-bytes ([`909aa14`](https://github.com/Byron/gitoxide/commit/909aa1402c82c3128052023613a297b213716e3d))
+ - Remove os_str_bytes from git-pack ([`86f6e50`](https://github.com/Byron/gitoxide/commit/86f6e5054ea11b7aeb9c85321913de090f71e3a1))
+ - Don't use os_str_ext in git-features; adapt git-ref ([`9258b7b`](https://github.com/Byron/gitoxide/commit/9258b7baf0895593c13a152ff9e6f52e036cebe1))
+ - Add new 'path' module for all path-related conversions ([`3c8581f`](https://github.com/Byron/gitoxide/commit/3c8581fc294c65c9eb42698969fe3263135a864e))
+ * **[#366](https://github.com/Byron/gitoxide/issues/366)**
+ - The first possibly working version of loading a mailmap with multiple sources ([`98d745e`](https://github.com/Byron/gitoxide/commit/98d745e8080975a91cff1ce75e187258c851d3f4))
+ - Cleanup bstr usage to not accidentally pull in unicode ([`8ff53af`](https://github.com/Byron/gitoxide/commit/8ff53af9876a5e35bcfd076124ad776e1b6ff331))
+ * **[#427](https://github.com/Byron/gitoxide/issues/427)**
+ - Make fmt ([`4b320e7`](https://github.com/Byron/gitoxide/commit/4b320e773368ac5e8c38dd8a779ef3d6d2d024ec))
+ - Optimize some portions of the Snapshot code for speed. ([`711fd5c`](https://github.com/Byron/gitoxide/commit/711fd5c6c221440917fa68248e45d5278c780a9e))
+ - More convenient API for fs::Snapshots ([`561d2e7`](https://github.com/Byron/gitoxide/commit/561d2e746b1b82ac20f6f14b9c4e3910240075b4))
+ - `fs::Snapshot` to on-demand reload shared resources. ([`7f199f0`](https://github.com/Byron/gitoxide/commit/7f199f0e5246809efde9880110093fbd11a4f8fe))
+ - Use generalized reload-on-demand in `git-ref` ([`8d0cce7`](https://github.com/Byron/gitoxide/commit/8d0cce7d1521374d5199552fc69a417a957519bc))
+ - Now it's possible to update packed refs using the shared code ([`78222c2`](https://github.com/Byron/gitoxide/commit/78222c2e39aa24c84852e999448c042f2fd37db4))
+ - The first step towards using the generalized `ReloadIfChanged` in git-ref ([`e8de0ef`](https://github.com/Byron/gitoxide/commit/e8de0ef38db2f2d83cb277ed101464f23c0e98e4))
+ - Generalized port of packed-refs update logic for use in index ([`e3aff0c`](https://github.com/Byron/gitoxide/commit/e3aff0c2b83720e5745f3d7a8d0f571421a26d99))
+ - Turn on performance mode for sha-1 computation ([`44371a1`](https://github.com/Byron/gitoxide/commit/44371a10f464f32db346aa6b8309e983cfa20933))
+ * **[#450](https://github.com/Byron/gitoxide/issues/450)**
+ - Upgrade to `prodash` v21 ([`a0655dc`](https://github.com/Byron/gitoxide/commit/a0655dc7bc5dff388bc69a648e7f16b44fd1abd9))
+ - `fs::Snapshot` can `Clone` if `T` can `Clone`. ([`9076ce3`](https://github.com/Byron/gitoxide/commit/9076ce33ec167e425a0163d3e40a81a3fd0db6cd))
+ * **[#470](https://github.com/Byron/gitoxide/issues/470)**
+ - Update changelogs prior to release ([`caa7a1b`](https://github.com/Byron/gitoxide/commit/caa7a1bdef74d7d3166a7e38127a59f5ab3cfbdd))
+ - Working progress printing ([`67ec2c7`](https://github.com/Byron/gitoxide/commit/67ec2c7f9a4a6cefdf7148f5c7e48a79f201c4d2))
+ - First attempt to get progress information from stat worker. ([`0947c70`](https://github.com/Byron/gitoxide/commit/0947c703f9cecc31ceba101565e6ecafb00adb08))
+ - Upgrade to prodash 20.1 for `Progress::counter()` feature ([`0ac4a2c`](https://github.com/Byron/gitoxide/commit/0ac4a2c514aeb94d8e90ce28ae7a0e0350c21ab2))
+ * **[#503](https://github.com/Byron/gitoxide/issues/503)**
+ - Prepare changelog ([`3c99e7f`](https://github.com/Byron/gitoxide/commit/3c99e7f02ada72a171856ffc5b870da83fffc703))
+ * **[#524](https://github.com/Byron/gitoxide/issues/524)**
+ - Prepare changelogs prior to release ([`6446b39`](https://github.com/Byron/gitoxide/commit/6446b395d5926565ef899b0c923f35468ccf1921))
+ * **[#63](https://github.com/Byron/gitoxide/issues/63)**
+ - Git-protocol uses `oid` type ([`3930a6f`](https://github.com/Byron/gitoxide/commit/3930a6ff508f5bb2249fb2c2f21e00b74fecda22))
+ - Make ObjectId/oid happen! ([`ca78d15`](https://github.com/Byron/gitoxide/commit/ca78d15373ec988d909be8f240baefe75555e077))
+ - Move git-hash::owned::Id into git-hash::Id ([`fdbe704`](https://github.com/Byron/gitoxide/commit/fdbe704b6c9ace2b8f629f681a0580b24749a238))
+ - Rename `git_hash::*::Digest` to `Id` ([`188d90a`](https://github.com/Byron/gitoxide/commit/188d90ad463d342d715af701b03f0ed392c977fc))
+ * **[#691](https://github.com/Byron/gitoxide/issues/691)**
+ - Set `rust-version` to 1.64 ([`55066ce`](https://github.com/Byron/gitoxide/commit/55066ce5fd71209abb5d84da2998b903504584bb))
+ * **Uncategorized**
+ - Release gix-features v0.26.4, gix-actor v0.17.1, gix-glob v0.5.3, gix-path v0.7.1, gix-quote v0.4.1, gix-attributes v0.8.2, gix-config-value v0.10.1, gix-tempfile v3.0.2, gix-lock v3.0.2, gix-validate v0.7.2, gix-object v0.26.1, gix-ref v0.24.0, gix-sec v0.6.2, gix-config v0.16.1, gix-command v0.2.3, gix-prompt v0.3.2, gix-url v0.13.2, gix-credentials v0.9.1, gix-diff v0.26.1, gix-discover v0.13.0, gix-hashtable v0.1.1, gix-bitmap v0.2.1, gix-traverse v0.22.1, gix-index v0.12.3, gix-mailmap v0.9.2, gix-chunk v0.4.1, gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`6efd0d3`](https://github.com/Byron/gitoxide/commit/6efd0d31fbeca31ab7319aa2ac97bb31dc4ce055))
+ - Release gix-date v0.4.2, gix-hash v0.10.2, gix-features v0.26.4, gix-actor v0.17.1, gix-glob v0.5.3, gix-path v0.7.1, gix-quote v0.4.1, gix-attributes v0.8.2, gix-config-value v0.10.1, gix-tempfile v3.0.2, gix-lock v3.0.2, gix-validate v0.7.2, gix-object v0.26.1, gix-ref v0.24.0, gix-sec v0.6.2, gix-config v0.16.1, gix-command v0.2.3, gix-prompt v0.3.2, gix-url v0.13.2, gix-credentials v0.9.1, gix-diff v0.26.1, gix-discover v0.13.0, gix-hashtable v0.1.1, gix-bitmap v0.2.1, gix-traverse v0.22.1, gix-index v0.12.3, gix-mailmap v0.9.2, gix-chunk v0.4.1, gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`6ccc88a`](https://github.com/Byron/gitoxide/commit/6ccc88a8e4a56973b1a358cf72dc012ee3c75d56))
+ - Merge branch 'rename-crates' into inform-about-gix-rename ([`c9275b9`](https://github.com/Byron/gitoxide/commit/c9275b99ea43949306d93775d9d78c98fb86cfb1))
+ - Rename `git-testtools` to `gix-testtools` ([`b65c33d`](https://github.com/Byron/gitoxide/commit/b65c33d256cfed65d11adeff41132e3e58754089))
+ - Adjust to renaming of `git-pack` to `gix-pack` ([`1ee81ad`](https://github.com/Byron/gitoxide/commit/1ee81ad310285ee4aa118118a2be3810dbace574))
+ - Adjust to renaming of `git-odb` to `gix-odb` ([`476e2ad`](https://github.com/Byron/gitoxide/commit/476e2ad1a64e9e3f0d7c8651d5bcbee36cd78241))
+ - Adjust to renaming of `git-index` to `gix-index` ([`86db5e0`](https://github.com/Byron/gitoxide/commit/86db5e09fc58ce66b252dc13b8d7e2c48e4d5062))
+ - Adjust to renaming of `git-diff` to `gix-diff` ([`49a163e`](https://github.com/Byron/gitoxide/commit/49a163ec8b18f0e5fcd05a315de16d5d8be7650e))
+ - Adjust to renaming of `git-commitgraph` to `gix-commitgraph` ([`f1dd0a3`](https://github.com/Byron/gitoxide/commit/f1dd0a3366e31259af029da73228e8af2f414244))
+ - Adjust to renaming of `git-mailmap` to `gix-mailmap` ([`2e28c56`](https://github.com/Byron/gitoxide/commit/2e28c56bb9f70de6f97439818118d3a25859698f))
+ - Adjust to renaming of `git-discover` to `gix-discover` ([`53adfe1`](https://github.com/Byron/gitoxide/commit/53adfe1c34e9ea3b27067a97b5e7ac80b351c441))
+ - Adjust to renaming of `git-chunk` to `gix-chunk` ([`59194e3`](https://github.com/Byron/gitoxide/commit/59194e3a07853eae0624ebc4907478d1de4f7599))
+ - Adjust to renaming of `git-bitmap` to `gix-bitmap` ([`75f2a07`](https://github.com/Byron/gitoxide/commit/75f2a079b17489f62bc43e1f1d932307375c4f9d))
+ - Adjust to renaming for `git-protocol` to `gix-protocol` ([`823795a`](https://github.com/Byron/gitoxide/commit/823795addea3810243cab7936cd8ec0137cbc224))
+ - Adjust to renaming of `git-refspec` to `gix-refspec` ([`c958802`](https://github.com/Byron/gitoxide/commit/c9588020561577736faa065e7e5b5bb486ca8fe1))
+ - Adjust to renaming of `git-revision` to `gix-revision` ([`ee0ee84`](https://github.com/Byron/gitoxide/commit/ee0ee84607c2ffe11ee75f27a31903db68afed02))
+ - Adjust to renaming of `git-transport` to `gix-transport` ([`b2ccf71`](https://github.com/Byron/gitoxide/commit/b2ccf716dc4425bb96651d4d58806a3cc2da219e))
+ - Adjust to renaming of `git-credentials` to `gix-credentials` ([`6b18abc`](https://github.com/Byron/gitoxide/commit/6b18abcf2856f02ab938d535a65e51ac282bf94a))
+ - Adjust to renaming of `git-prompt` to `gix-prompt` ([`6a4654e`](https://github.com/Byron/gitoxide/commit/6a4654e0d10ab773dd219cb4b731c0fc1471c36d))
+ - Adjust to renaming of `git-command` to `gix-command` ([`d26b8e0`](https://github.com/Byron/gitoxide/commit/d26b8e046496894ae06b0bbfdba77196976cd975))
+ - Adjust to renaming of `git-packetline` to `gix-packetline` ([`5cbd22c`](https://github.com/Byron/gitoxide/commit/5cbd22cf42efb760058561c6c3bbcd4dab8c8be1))
+ - Adjust to renaming of `git-worktree` to `gix-worktree` ([`73a1282`](https://github.com/Byron/gitoxide/commit/73a12821b3d9b66ec1714d07dd27eb7a73e3a544))
+ - Adjust to renamining of `git-hashtable` to `gix-hashtable` ([`26a0c98`](https://github.com/Byron/gitoxide/commit/26a0c98d0a389b03e3dc7bfc758b37155e285244))
+ - Adjust to renamining of `git-worktree` to `gix-worktree` ([`108bb1a`](https://github.com/Byron/gitoxide/commit/108bb1a634f4828853fb590e9fc125f79441dd38))
+ - Adjust to renaming of `git-url` to `gix-url` ([`b50817a`](https://github.com/Byron/gitoxide/commit/b50817aadb143e19f61f64e19b19ec1107d980c6))
+ - Adjust to renaming of `git-date` to `gix-date` ([`9a79ff2`](https://github.com/Byron/gitoxide/commit/9a79ff2d5cc74c1efad9f41e21095ae498cce00b))
+ - Adjust to renamining of `git-attributes` to `gix-attributes` ([`4a8b3b8`](https://github.com/Byron/gitoxide/commit/4a8b3b812ac26f2a2aee8ce8ca81591273383c84))
+ - Adjust to renaminig of `git-quote` to `gix-quote` ([`648025b`](https://github.com/Byron/gitoxide/commit/648025b7ca94411fdd0d90c53e5faede5fde6c8d))
+ - Adjust to renaming of `git-config` to `gix-config` ([`3a861c8`](https://github.com/Byron/gitoxide/commit/3a861c8f049f6502d3bcbdac752659aa1aeda46a))
+ - Adjust to renaming of `git-ref` to `gix-ref` ([`1f5f695`](https://github.com/Byron/gitoxide/commit/1f5f695407b034377d94b172465ff573562b3fc3))
+ - Adjust to renaming of `git-lock` to `gix-lock` ([`2028e78`](https://github.com/Byron/gitoxide/commit/2028e7884ae1821edeec81612f501e88e4722b17))
+ - Adjust to renaming of `git-tempfile` to `gix-tempfile` ([`b6cc3eb`](https://github.com/Byron/gitoxide/commit/b6cc3ebb5137084a6327af16a7d9364d8f092cc9))
+ - Adjust to renaming of `git-object` to `gix-object` ([`fc86a1e`](https://github.com/Byron/gitoxide/commit/fc86a1e710ad7bf076c25cc6f028ddcf1a5a4311))
+ - Adjust to renaming of `git-actor` to `gix-actor` ([`4dc9b44`](https://github.com/Byron/gitoxide/commit/4dc9b44dc52f2486ffa2040585c6897c1bf55df4))
+ - Adjust to renaming of `git-validate` to `gix-validate` ([`5e40ad0`](https://github.com/Byron/gitoxide/commit/5e40ad078af3d08cbc2ca81ce755c0ed8a065b4f))
+ - Adjust to renaming of `git-hash` to `gix-hash` ([`4a9d025`](https://github.com/Byron/gitoxide/commit/4a9d0257110c3efa61d08c8457c4545b200226d1))
+ - Adjust to renaming of `git-features` to `gix-features` ([`e2dd68a`](https://github.com/Byron/gitoxide/commit/e2dd68a417aad229e194ff20dbbfd77668096ec6))
+ - Rename `git-features` to `gix-features` ([`85f7e1a`](https://github.com/Byron/gitoxide/commit/85f7e1a97c936f7cbebfbb3b2952f965601a7cbb))
+ - Adjust to renaming of `git-glob` to `gix-glob` ([`35b2a3a`](https://github.com/Byron/gitoxide/commit/35b2a3acbc8f2a03f151bc0a3863163844e0ca86))
+ - Adjust to renaming of `git-sec` to `gix-sec` ([`eabbb92`](https://github.com/Byron/gitoxide/commit/eabbb923bd5a32fc80fa80f96cfdc2ab7bb2ed17))
+ - Adapt to renaming of `git-path` to `gix-path` ([`d3bbcfc`](https://github.com/Byron/gitoxide/commit/d3bbcfccad80fc44ea8e7bf819f23adaca06ba2d))
+ - Adjust to rename of `git-config-value` to `gix-config-value` ([`622b3e1`](https://github.com/Byron/gitoxide/commit/622b3e1d0bffa0f8db73697960f9712024fac430))
+ - Release git-features v0.26.4 ([`109f434`](https://github.com/Byron/gitoxide/commit/109f434e66559a791d541f86876ded8df10766f1))
+ - Re-export `prodash::progress::(Task|Value)` directly under `progress` ([`a3bd14a`](https://github.com/Byron/gitoxide/commit/a3bd14a7753716e7ad67cd56d24eee1fa099a6fd))
+ - Release git-features v0.26.3 ([`1ecfb7f`](https://github.com/Byron/gitoxide/commit/1ecfb7f8bfb24432690d8f31367488f2e59a642a))
+ - Re-export `prodash` in `progress` module. ([`4260572`](https://github.com/Byron/gitoxide/commit/426057247a80821b3da22b4ae5d67bda89ce0631))
+ - Release git-date v0.4.2, git-hash v0.10.2, git-features v0.26.2, git-actor v0.17.1, git-glob v0.5.3, git-path v0.7.1, git-quote v0.4.1, git-attributes v0.8.2, git-config-value v0.10.1, git-tempfile v3.0.2, git-lock v3.0.2, git-validate v0.7.2, git-object v0.26.1, git-ref v0.24.0, git-sec v0.6.2, git-config v0.16.0, git-command v0.2.3, git-prompt v0.3.2, git-url v0.13.2, git-credentials v0.9.1, git-diff v0.26.1, git-discover v0.13.0, git-hashtable v0.1.1, git-bitmap v0.2.1, git-traverse v0.22.1, git-index v0.12.3, git-mailmap v0.9.2, git-chunk v0.4.1, git-pack v0.30.2, git-odb v0.40.2, git-packetline v0.14.2, git-transport v0.25.4, git-protocol v0.26.3, git-revision v0.10.2, git-refspec v0.7.2, git-worktree v0.12.2, git-repository v0.34.0, safety bump 3 crates ([`c196d20`](https://github.com/Byron/gitoxide/commit/c196d206d57a310b1ce974a1cf0e7e6d6db5c4d6))
+ - Prepare changelogs prior to release ([`7c846d2`](https://github.com/Byron/gitoxide/commit/7c846d2102dc767366771925212712ef8cc9bf07))
+ - Merge branch 'Lioness100/main' ([`1e544e8`](https://github.com/Byron/gitoxide/commit/1e544e82455bf9ecb5e3c2146280eaf7ecd81f16))
+ - Fix typos ([`39ed9ed`](https://github.com/Byron/gitoxide/commit/39ed9eda62b7718d5109135e5ad406fb1fe2978c))
+ - Make fmt ([`e22080e`](https://github.com/Byron/gitoxide/commit/e22080e4a29d0bad15a99d565a5e3e304a8743ec))
+ - Merge branch 'adjustments-for-cargo' ([`7bba270`](https://github.com/Byron/gitoxide/commit/7bba2709488b7eb999b8136dbab03af977241678))
+ - Export `prodash::progress::Id` in the `progress` module for convenience. ([`c4a7634`](https://github.com/Byron/gitoxide/commit/c4a7634b0b29c74625e183953e59c65987e9d66c))
+ - Release git-date v0.4.1, git-features v0.26.1, git-glob v0.5.2, git-attributes v0.8.1, git-tempfile v3.0.1, git-ref v0.23.1, git-sec v0.6.1, git-config v0.15.1, git-prompt v0.3.1, git-url v0.13.1, git-discover v0.12.1, git-index v0.12.2, git-mailmap v0.9.1, git-pack v0.30.1, git-odb v0.40.1, git-transport v0.25.3, git-protocol v0.26.2, git-revision v0.10.1, git-refspec v0.7.1, git-worktree v0.12.1, git-repository v0.33.0 ([`5b5b380`](https://github.com/Byron/gitoxide/commit/5b5b3809faa71c658db38b40dfc410224d08a367))
+ - Prepare changelogs prior to release ([`93bef97`](https://github.com/Byron/gitoxide/commit/93bef97b3c0c75d4bf7119fdd787516e1efc77bf))
+ - Merge branch 'patch-1' ([`b93f0c4`](https://github.com/Byron/gitoxide/commit/b93f0c49fc677b6c19aea332cbfc1445ce475375))
+ - Thanks clippy ([`9e04685`](https://github.com/Byron/gitoxide/commit/9e04685dd3f109bfb27663f9dc7c04102e660bf2))
+ - Release git-features v0.26.0, git-actor v0.16.0, git-attributes v0.8.0, git-object v0.25.0, git-ref v0.22.0, git-config v0.14.0, git-command v0.2.1, git-url v0.13.0, git-credentials v0.9.0, git-diff v0.25.0, git-discover v0.11.0, git-traverse v0.21.0, git-index v0.11.0, git-mailmap v0.8.0, git-pack v0.29.0, git-odb v0.39.0, git-transport v0.25.0, git-protocol v0.26.0, git-revision v0.9.0, git-refspec v0.6.0, git-worktree v0.11.0, git-repository v0.31.0, safety bump 24 crates ([`5ac9fbe`](https://github.com/Byron/gitoxide/commit/5ac9fbe265a5b61c533a2a6b3abfed2bdf7f89ad))
+ - Prepare changelogs prior to release ([`30d8ca1`](https://github.com/Byron/gitoxide/commit/30d8ca19284049dcfbb0de2698cafae1d1a16b0c))
+ - Make fmt ([`511ed00`](https://github.com/Byron/gitoxide/commit/511ed0000397a5b268530c8f5362e7d25b7c1594))
+ - Merge branch 'adjustments-for-cargo' ([`f8c562a`](https://github.com/Byron/gitoxide/commit/f8c562a559e6dc3377583cc7200585dad7c3d481))
+ - Upgrade to prodash v23 ([`5bf0034`](https://github.com/Byron/gitoxide/commit/5bf0034fb3918e57562b7089ceba83d63a1854bf))
+ - Release git-features v0.25.1, git-url v0.12.2, git-odb v0.38.1, git-transport v0.24.2, git-repository v0.30.2 ([`bb0a07b`](https://github.com/Byron/gitoxide/commit/bb0a07b5edd5f980989d1a92e74df7f183febe87))
+ - Merge branch 'loose-find-panic' ([`95cccdd`](https://github.com/Byron/gitoxide/commit/95cccddd3c181eb2a85b12823c27beb054adf5d8))
+ - Zlib::inflate::Error can now represent zlib status codes that represent failure. ([`25ad372`](https://github.com/Byron/gitoxide/commit/25ad372bf500b851105f53b10369b5a689ba167e))
+ - Release git-date v0.3.1, git-features v0.25.0, git-actor v0.15.0, git-glob v0.5.1, git-path v0.7.0, git-attributes v0.7.0, git-config-value v0.10.0, git-lock v3.0.1, git-validate v0.7.1, git-object v0.24.0, git-ref v0.21.0, git-sec v0.6.0, git-config v0.13.0, git-prompt v0.3.0, git-url v0.12.0, git-credentials v0.8.0, git-diff v0.24.0, git-discover v0.10.0, git-traverse v0.20.0, git-index v0.10.0, git-mailmap v0.7.0, git-pack v0.28.0, git-odb v0.38.0, git-packetline v0.14.1, git-transport v0.24.0, git-protocol v0.25.0, git-revision v0.8.0, git-refspec v0.5.0, git-worktree v0.10.0, git-repository v0.30.0, safety bump 26 crates ([`e6b9906`](https://github.com/Byron/gitoxide/commit/e6b9906c486b11057936da16ed6e0ec450a0fb83))
+ - Prepare chnagelogs prior to git-repository release ([`7114bbb`](https://github.com/Byron/gitoxide/commit/7114bbb6732aa8571d4ab74f28ed3e26e9fbe4d0))
+ - Merge branch 'main' into read-split-index ([`c57bdde`](https://github.com/Byron/gitoxide/commit/c57bdde6de37eca9672ea715962bbd02aa3eb055))
+ - Merge branch 'adjustments-for-cargo' ([`083909b`](https://github.com/Byron/gitoxide/commit/083909bc7eb902eeee2002034fdb6ed88280dc5c))
+ - Thanks clippy ([`f1160fb`](https://github.com/Byron/gitoxide/commit/f1160fb42acf59b37cbeda546a7079af3c9bc050))
+ - Add support for explicit non-parallel iteration. ([`0f27c67`](https://github.com/Byron/gitoxide/commit/0f27c67c92fc0bc23a6712b5c4c730ad6a0156bf))
+ - Merge branch 'adjustments-for-cargo' ([`70ccbb2`](https://github.com/Byron/gitoxide/commit/70ccbb21b1113bdeb20b52d274141a9fdb75f579))
+ - Upgrade to prodash v22 for API improvements ([`77ab98d`](https://github.com/Byron/gitoxide/commit/77ab98dd41c3849b674d8b3794ef29219ca1447d))
+ - Release git-hash v0.10.1, git-hashtable v0.1.0 ([`7717170`](https://github.com/Byron/gitoxide/commit/771717095d9a67b0625021eb0928828ab686e772))
+ - Merge branch 'main' into http-config ([`6b9632e`](https://github.com/Byron/gitoxide/commit/6b9632e16c416841ffff1b767ee7a6c89b421220))
+ - Release git-features v0.24.1, git-actor v0.14.1, git-index v0.9.1 ([`7893502`](https://github.com/Byron/gitoxide/commit/789350208efc9d5fc6f9bc4f113f77f9cb445156))
+ - Merge branch 'named-threads' ([`726dd87`](https://github.com/Byron/gitoxide/commit/726dd87b5db45c333ccad898338a1cacea9e3269))
+ - Name spawned threads ([`6d530a1`](https://github.com/Byron/gitoxide/commit/6d530a1dc77f0f4ac00622a2fd47c7bdb731a77a))
+ - Upgrade to `prodash 21.1` and add `Ids` to all progress instances. ([`c8835c6`](https://github.com/Byron/gitoxide/commit/c8835c6edae784c9ffcb69a674c0a6545dbb2af3))
+ - Merge branch 'main' into http-config ([`bcd9654`](https://github.com/Byron/gitoxide/commit/bcd9654e56169799eb706646da6ee1f4ef2021a9))
+ - Release git-hash v0.10.0, git-features v0.24.0, git-date v0.3.0, git-actor v0.14.0, git-glob v0.5.0, git-path v0.6.0, git-quote v0.4.0, git-attributes v0.6.0, git-config-value v0.9.0, git-tempfile v3.0.0, git-lock v3.0.0, git-validate v0.7.0, git-object v0.23.0, git-ref v0.20.0, git-sec v0.5.0, git-config v0.12.0, git-command v0.2.0, git-prompt v0.2.0, git-url v0.11.0, git-credentials v0.7.0, git-diff v0.23.0, git-discover v0.9.0, git-bitmap v0.2.0, git-traverse v0.19.0, git-index v0.9.0, git-mailmap v0.6.0, git-chunk v0.4.0, git-pack v0.27.0, git-odb v0.37.0, git-packetline v0.14.0, git-transport v0.23.0, git-protocol v0.24.0, git-revision v0.7.0, git-refspec v0.4.0, git-worktree v0.9.0, git-repository v0.29.0, git-commitgraph v0.11.0, gitoxide-core v0.21.0, gitoxide v0.19.0, safety bump 28 crates ([`b2c301e`](https://github.com/Byron/gitoxide/commit/b2c301ef131ffe1871314e19f387cf10a8d2ac16))
+ - Prepare changelogs prior to release ([`e4648f8`](https://github.com/Byron/gitoxide/commit/e4648f827c97e9d13636d1bbdc83dd63436e6e5c))
+ - Release git-features v0.23.1, git-glob v0.4.1, git-config-value v0.8.1, git-tempfile v2.0.6, git-object v0.22.1, git-ref v0.18.0, git-sec v0.4.2, git-config v0.10.0, git-prompt v0.1.1, git-url v0.10.1, git-credentials v0.6.1, git-diff v0.21.0, git-discover v0.7.0, git-index v0.7.0, git-pack v0.25.0, git-odb v0.35.0, git-transport v0.21.1, git-protocol v0.22.0, git-refspec v0.3.1, git-worktree v0.7.0, git-repository v0.26.0, git-commitgraph v0.10.0, gitoxide-core v0.19.0, gitoxide v0.17.0, safety bump 9 crates ([`d071583`](https://github.com/Byron/gitoxide/commit/d071583c5576fdf5f7717765ffed5681792aa81f))
+ - Prepare changelogs prior to release ([`423af90`](https://github.com/Byron/gitoxide/commit/423af90c8202d62dc1ea4a76a0df6421d1f0aa06))
+ - Merge branch 'main' into write-sparse-index ([`c4e6849`](https://github.com/Byron/gitoxide/commit/c4e68496c368611ebe17c6693d06c8147c28c717))
+ - Merge branch 'gix-clone' ([`def53b3`](https://github.com/Byron/gitoxide/commit/def53b36c3dec26fa78939ab0584fe4ff930909c))
+ - Thanks clippy ([`ad96233`](https://github.com/Byron/gitoxide/commit/ad96233e1aa77fb7d9185f653f3e9519128cf20f))
+ - Release git-hash v0.9.11, git-features v0.23.0, git-actor v0.13.0, git-attributes v0.5.0, git-object v0.22.0, git-ref v0.17.0, git-sec v0.4.1, git-config v0.9.0, git-url v0.10.0, git-credentials v0.6.0, git-diff v0.20.0, git-discover v0.6.0, git-traverse v0.18.0, git-index v0.6.0, git-mailmap v0.5.0, git-pack v0.24.0, git-odb v0.34.0, git-packetline v0.13.1, git-transport v0.21.0, git-protocol v0.21.0, git-revision v0.6.0, git-refspec v0.3.0, git-worktree v0.6.0, git-repository v0.25.0, safety bump 24 crates ([`104d922`](https://github.com/Byron/gitoxide/commit/104d922add61ab21c534c24ce8ed37cddf3e275a))
+ - Prepare changelogs for release ([`d232567`](https://github.com/Byron/gitoxide/commit/d23256701a95284857dc8d1cb37c7c94cada973c))
+ - Remove `fs-jwalk-single-threaded` in favor of `fs-walkdir-parallel`. ([`38446dc`](https://github.com/Byron/gitoxide/commit/38446dc8824afef30ef121598de3451d13b9262c))
+ - Make jwalk fully optional ([`3b29fc1`](https://github.com/Byron/gitoxide/commit/3b29fc18672c0176684c797a0f16f85d09369bf8))
+ - Merge branch 'main' into new-http-impl ([`702a161`](https://github.com/Byron/gitoxide/commit/702a161ef11fc959611bf44b70e9ffe04561c7ad))
+ - Merge branch 'main' into clone ([`acb0738`](https://github.com/Byron/gitoxide/commit/acb07382a9306d6962bea60e8977d83d021743f4))
+ - Merge branch 'delta-tree-parallelization' ([`cca2ad5`](https://github.com/Byron/gitoxide/commit/cca2ad5ee9483d7da968658e0a4d610dbc4ad4d6))
+ - Don't enforce Send bounds in serial version of `in_parallel_with_slice()` ([`dda661e`](https://github.com/Byron/gitoxide/commit/dda661e1b7cc0ace6cd9504233f20980e1e52387))
+ - Allow discarding the state which could otherwise be used for aggregation. ([`56792fb`](https://github.com/Byron/gitoxide/commit/56792fb53299d52073555c8646360ec0ae88c86d))
+ - Allow input for `in_parallel_with_slice` to be mutable. ([`e928bf7`](https://github.com/Byron/gitoxide/commit/e928bf7c699a7e48ad283c2cf7fd7479c37c70fc))
+ - Perfect granularity for threads processing with `in_parallel_with_slice()` ([`a7c11d2`](https://github.com/Byron/gitoxide/commit/a7c11d2cb5f88a4ff322d9a9848459062790d8b3))
+ - Add `progress::Step|StepShared` as types of `prodash` ([`ff1db66`](https://github.com/Byron/gitoxide/commit/ff1db66f2dad3afc8bc77610006bca9fea5947d2))
+ - Merge branch 'fix-git-features' ([`82fd251`](https://github.com/Byron/gitoxide/commit/82fd251ac80d07bc9da8a4d36e517aa35580d188))
+ - Merge branch 'diff' ([`25a7726`](https://github.com/Byron/gitoxide/commit/25a7726377fbe400ea3c4927d04e9dec99802b7b))
+ - Release git-hash v0.9.10, git-features v0.22.5, git-date v0.2.0, git-actor v0.12.0, git-glob v0.4.0, git-path v0.5.0, git-quote v0.3.0, git-attributes v0.4.0, git-config-value v0.8.0, git-tempfile v2.0.5, git-validate v0.6.0, git-object v0.21.0, git-ref v0.16.0, git-sec v0.4.0, git-config v0.8.0, git-discover v0.5.0, git-traverse v0.17.0, git-index v0.5.0, git-worktree v0.5.0, git-testtools v0.9.0, git-command v0.1.0, git-prompt v0.1.0, git-url v0.9.0, git-credentials v0.5.0, git-diff v0.19.0, git-mailmap v0.4.0, git-chunk v0.3.2, git-pack v0.23.0, git-odb v0.33.0, git-packetline v0.13.0, git-transport v0.20.0, git-protocol v0.20.0, git-revision v0.5.0, git-refspec v0.2.0, git-repository v0.24.0, git-commitgraph v0.9.0, gitoxide-core v0.18.0, gitoxide v0.16.0, safety bump 28 crates ([`29a043b`](https://github.com/Byron/gitoxide/commit/29a043be6808a3e9199a9b26bd076fe843afe4f4))
+ - Release git-features v0.22.6 ([`c9eda72`](https://github.com/Byron/gitoxide/commit/c9eda729d8f8bc266c7516c613d38acfb83a4743))
+ - Update changelog prior to release ([`ff80042`](https://github.com/Byron/gitoxide/commit/ff80042c9691e5dba5834c674174fdf6d3bdfe7d))
+ - Fix git-features docs build ([`e5963fe`](https://github.com/Byron/gitoxide/commit/e5963fea183d81db1fe502121b494146a58bd86e))
+ - Upgrade all dependencies, except for `windows` ([`2968181`](https://github.com/Byron/gitoxide/commit/29681819ffe53d3926d631dc482f71d6200cb549))
+ - Merge branch 'dep-upgrade' ([`59767b1`](https://github.com/Byron/gitoxide/commit/59767b1fc1d07b8a7a9333a719e3716746611bc4))
+ - Upgrade prodash and crosstermion to latest versions ([`ab7ee5b`](https://github.com/Byron/gitoxide/commit/ab7ee5b5d5c15771f431ada9c3b4f53e4be2afdd))
+ - Add zlib-ng feature to allow linking against system libz-ng ([`cfe46b5`](https://github.com/Byron/gitoxide/commit/cfe46b502afc3ecb312849ddbd7748007d432cd1))
+ - Merge branch 'main' into filter-refs-by-spec ([`9aa1d3d`](https://github.com/Byron/gitoxide/commit/9aa1d3dc46d4b1c76af257f573aff3aeef2d3fa8))
+ - Release git-features v0.22.4, git-url v0.8.0, safety bump 4 crates ([`1d4600a`](https://github.com/Byron/gitoxide/commit/1d4600ae51475c2e225f96c16c41e2c4a2b3f2aa))
+ - Merge branch 'main' into filter-refs-by-spec ([`1f6e5ab`](https://github.com/Byron/gitoxide/commit/1f6e5ab15f5fd8d23719b13e6aea59cd231ac0fe))
+ - Merge branch 'fix-522' ([`5869e9f`](https://github.com/Byron/gitoxide/commit/5869e9ff2508d5a93c07635277af8764fcb57713))
+ - Release git-hash v0.9.9 ([`da0716f`](https://github.com/Byron/gitoxide/commit/da0716f8c27b4f29cfff0e5ce7fcb3d7240f4aeb))
+ - Merge branch 'main' into index-from-tree ([`bc64b96`](https://github.com/Byron/gitoxide/commit/bc64b96a2ec781c72d1d4daad38aa7fb8b74f99b))
+ - Merge branch 'main' into filter-refs-by-spec ([`cef0b51`](https://github.com/Byron/gitoxide/commit/cef0b51ade2a3301fa09ede7a425aa1fe3527e78))
+ - Release git-features v0.22.3, git-revision v0.4.4 ([`c2660e2`](https://github.com/Byron/gitoxide/commit/c2660e2503323531ba02519eaa51124ee22fec51))
+ - Merge branch 'main' into filter-refs-by-spec ([`dbfa328`](https://github.com/Byron/gitoxide/commit/dbfa3282cf876596b250b2040c1ec0b761741796))
+ - Merge branch 'zlib-sys' ([`7b48297`](https://github.com/Byron/gitoxide/commit/7b482977a556d28f5d9759e1be33cdf3d85c8665))
+ - Restrict `sha1` `asm` to supported archs ([`b383fab`](https://github.com/Byron/gitoxide/commit/b383fabbe10868317be51b99cfdd9b0981816042))
+ - Add feature to link to traditional zlib for dynamic linking support ([`c954bbf`](https://github.com/Byron/gitoxide/commit/c954bbff60ba70a0f1680e3978dd1f8fc1e3a0e7))
+ - Merge branch 'main' into filter-refs-by-spec ([`cfa1440`](https://github.com/Byron/gitoxide/commit/cfa144031dbcac2707ab0cec012bc35e78f9c475))
+ - Release git-date v0.0.5, git-hash v0.9.8, git-features v0.22.2, git-actor v0.11.3, git-glob v0.3.2, git-quote v0.2.1, git-attributes v0.3.2, git-tempfile v2.0.4, git-lock v2.1.1, git-validate v0.5.5, git-object v0.20.2, git-ref v0.15.2, git-sec v0.3.1, git-config v0.7.0, git-credentials v0.4.0, git-diff v0.17.2, git-discover v0.4.1, git-bitmap v0.1.2, git-index v0.4.2, git-mailmap v0.3.2, git-chunk v0.3.1, git-traverse v0.16.2, git-pack v0.21.2, git-odb v0.31.2, git-packetline v0.12.7, git-url v0.7.2, git-transport v0.19.2, git-protocol v0.19.0, git-revision v0.4.2, git-refspec v0.1.0, git-worktree v0.4.2, git-repository v0.22.0, safety bump 4 crates ([`4974eca`](https://github.com/Byron/gitoxide/commit/4974eca96d525d1ee4f8cad79bb713af7a18bf9d))
+ - Merge branch 'main' into remote-ls-refs ([`e2ee3de`](https://github.com/Byron/gitoxide/commit/e2ee3ded97e5c449933712883535b30d151c7c78))
+ - Merge branch 'docsrs-show-features' ([`31c2351`](https://github.com/Byron/gitoxide/commit/31c235140cad212d16a56195763fbddd971d87ce))
+ - Use docsrs feature in code to show what is feature-gated automatically on docs.rs ([`b1c40b0`](https://github.com/Byron/gitoxide/commit/b1c40b0364ef092cd52d03b34f491b254816b18d))
+ - Uniformize deny attributes ([`f7f136d`](https://github.com/Byron/gitoxide/commit/f7f136dbe4f86e7dee1d54835c420ec07c96cd78))
+ - Pass --cfg docsrs when compiling for https://docs.rs ([`5176771`](https://github.com/Byron/gitoxide/commit/517677147f1c17304c62cf97a1dd09f232ebf5db))
+ - Merge branch 'main' into remote-ls-refs ([`bd5f3e8`](https://github.com/Byron/gitoxide/commit/bd5f3e8db7e0bb4abfb7b0f79f585ab82c3a14ab))
+ - Release git-hash v0.9.7, git-features v0.22.1 ([`232784a`](https://github.com/Byron/gitoxide/commit/232784a59ded3e8016e4257c7e146ad385cdd64a))
+ - Add `fs-jwalk-single-threaded` feature to specifically decouple `jwalk` from rayon ([`f498d35`](https://github.com/Byron/gitoxide/commit/f498d35baba52e40ecd47381e87c1ce49cf13285))
+ - Merge branch 'rev-parse-delegate' ([`2f506c7`](https://github.com/Byron/gitoxide/commit/2f506c7c2988477b0f97d272a9ac9ed47b236457))
+ - Thanks clippy! ([`c072dbb`](https://github.com/Byron/gitoxide/commit/c072dbb3e203e4a42843895b7d99404d900fdccd))
+ - Merge pull request #2 from SidneyDouw/main ([`ce885ad`](https://github.com/Byron/gitoxide/commit/ce885ad4c3324c09c83751c32e014f246c748766))
+ - Merge branch 'Byron:main' into main ([`9b9ea02`](https://github.com/Byron/gitoxide/commit/9b9ea0275f8ff5862f24cf5a4ca53bb1cd610709))
+ - Merge branch 'main' into rev-parse-delegate ([`6da8250`](https://github.com/Byron/gitoxide/commit/6da82507588d3bc849217c11d9a1d398b67f2ed6))
+ - Merge branch 'main' into pathspec ([`7b61506`](https://github.com/Byron/gitoxide/commit/7b615060712565f515515e35a3e8346278ad770c))
+ - Merge branch 'kianmeng-fix-typos' ([`4e7b343`](https://github.com/Byron/gitoxide/commit/4e7b34349c0a01ad8686bbb4eb987e9338259d9c))
+ - Fix typos ([`e9fcb70`](https://github.com/Byron/gitoxide/commit/e9fcb70e429edb2974afa3f58d181f3ef14c3da3))
+ - Release git-hash v0.9.6, git-features v0.22.0, git-date v0.0.2, git-actor v0.11.0, git-glob v0.3.1, git-path v0.4.0, git-attributes v0.3.0, git-tempfile v2.0.2, git-object v0.20.0, git-ref v0.15.0, git-sec v0.3.0, git-config v0.6.0, git-credentials v0.3.0, git-diff v0.17.0, git-discover v0.3.0, git-index v0.4.0, git-mailmap v0.3.0, git-traverse v0.16.0, git-pack v0.21.0, git-odb v0.31.0, git-url v0.7.0, git-transport v0.19.0, git-protocol v0.18.0, git-revision v0.3.0, git-worktree v0.4.0, git-repository v0.20.0, git-commitgraph v0.8.0, gitoxide-core v0.15.0, gitoxide v0.13.0, safety bump 22 crates ([`4737b1e`](https://github.com/Byron/gitoxide/commit/4737b1eea1d4c9a8d5a69fb63ecac5aa5d378ae5))
+ - Prepare changelog prior to release ([`3c50625`](https://github.com/Byron/gitoxide/commit/3c50625fa51350ec885b0f38ec9e92f9444df0f9))
+ - Merge branch 'config-cascade' ([`f144eaf`](https://github.com/Byron/gitoxide/commit/f144eaf5863ae5cac63103f0db51c35fcf03a948))
+ - Merge pull request #1 from Byron/main ([`085e76b`](https://github.com/Byron/gitoxide/commit/085e76b121291ed9bd324139105d2bd4117bedf8))
+ - Git-features' walkdir: 2.3.1 -> 2.3.2 ([`41dd754`](https://github.com/Byron/gitoxide/commit/41dd7545234e6d2637d2bca5bb6d4f6d8bfc8f57))
+ - Merge branch 'main' into pathspec ([`89ea12b`](https://github.com/Byron/gitoxide/commit/89ea12b558bcc056b892193ee8fb44b8664b5da4))
+ - Merge branch 'main' into cont_include_if ([`41ea8ba`](https://github.com/Byron/gitoxide/commit/41ea8ba78e74f5c988148367386a1f4f304cb951))
+ - Release git-date v0.0.1, git-hash v0.9.5, git-features v0.21.1, git-actor v0.10.1, git-path v0.2.0, git-attributes v0.2.0, git-ref v0.14.0, git-sec v0.2.0, git-config v0.5.0, git-credentials v0.2.0, git-discover v0.2.0, git-pack v0.20.0, git-odb v0.30.0, git-url v0.6.0, git-transport v0.18.0, git-protocol v0.17.0, git-revision v0.2.1, git-worktree v0.3.0, git-repository v0.19.0, safety bump 13 crates ([`a417177`](https://github.com/Byron/gitoxide/commit/a41717712578f590f04a33d27adaa63171f25267))
+ - Update changelogs prior to release ([`bb424f5`](https://github.com/Byron/gitoxide/commit/bb424f51068b8a8e762696890a55ab48900ab980))
+ - Assure we used most recent version of crossbeam-utils ([`033f0d3`](https://github.com/Byron/gitoxide/commit/033f0d3e0015b7eead6408c775d2101eb413ffbf))
+ - Merge branch 'main' into SidneyDouw-pathspec ([`a22b1d8`](https://github.com/Byron/gitoxide/commit/a22b1d88a21311d44509018729c3ef1936cf052a))
+ - Merge branch 'main' into git_includeif ([`598c853`](https://github.com/Byron/gitoxide/commit/598c853087fcf8f77299aa5b9803bcec705c0cd0))
+ - Release git-hash v0.9.4, git-features v0.21.0, git-actor v0.10.0, git-glob v0.3.0, git-path v0.1.1, git-attributes v0.1.0, git-sec v0.1.0, git-config v0.3.0, git-credentials v0.1.0, git-validate v0.5.4, git-object v0.19.0, git-diff v0.16.0, git-lock v2.1.0, git-ref v0.13.0, git-discover v0.1.0, git-index v0.3.0, git-mailmap v0.2.0, git-traverse v0.15.0, git-pack v0.19.0, git-odb v0.29.0, git-packetline v0.12.5, git-url v0.5.0, git-transport v0.17.0, git-protocol v0.16.0, git-revision v0.2.0, git-worktree v0.2.0, git-repository v0.17.0, safety bump 20 crates ([`654cf39`](https://github.com/Byron/gitoxide/commit/654cf39c92d5aa4c8d542a6cadf13d4acef6a78e))
+ - Merge branch 'main' into msrv-for-windows ([`7cb1972`](https://github.com/Byron/gitoxide/commit/7cb19729133325bdfacedf44cdc0500cbcf36684))
+ - Merge branch 'worktree-stack' ([`98da8ba`](https://github.com/Byron/gitoxide/commit/98da8ba52cef8ec27f705fcbc84773e5bacc4e10))
+ - Thanks clippy ([`380174f`](https://github.com/Byron/gitoxide/commit/380174f0ad9e60ccafcd4cfb24e244f106137964))
+ - Release git-features v0.20.0, git-config v0.2.0 ([`a6460db`](https://github.com/Byron/gitoxide/commit/a6460db80ba3c49ea37c712465c7cbdefa5c32b6))
+ - Release git-hash v0.9.3, git-features v0.20.0, git-config v0.2.0, safety bump 12 crates ([`f0cbb24`](https://github.com/Byron/gitoxide/commit/f0cbb24b2e3d8f028be0e773f9da530da2656257))
+ - Remove 'unused_mut' warning on windows ([`4733e6c`](https://github.com/Byron/gitoxide/commit/4733e6c6f5ea7d5afa4dd171bbba066cf5120ddc))
+ - Make fmt ([`7cf3545`](https://github.com/Byron/gitoxide/commit/7cf354509b545f7e7c99e159b5989ddfbe86273d))
+ - Commit to using 'unicode' feature of bstr as git-object wants it too ([`471fa62`](https://github.com/Byron/gitoxide/commit/471fa62b142ba744541d7472464d62826f5c6b93))
+ - Assure std::io::copy() doesn't hang when we cause an interrupt ([`234cd10`](https://github.com/Byron/gitoxide/commit/234cd10ca55482ce1a840ce3244308d249895bcc))
+ - Upgrade to prodash 19 ([`90c6c5a`](https://github.com/Byron/gitoxide/commit/90c6c5aec4015ff969d6e2514fa4d49873ee80f5))
+ - Thanks clippy ([`07a4094`](https://github.com/Byron/gitoxide/commit/07a4094965ac1b4eb223da8e5ca5cc4a86c5f596))
+ - Properly document optional features ([`572e57d`](https://github.com/Byron/gitoxide/commit/572e57d5796692764c5c9633969aad25a6f9221a))
+ - Merge branch 'svetli-n-path_value' ([`e8383ca`](https://github.com/Byron/gitoxide/commit/e8383caf6db211beb57d70019fe4ad13ce9066ee))
+ - Small refactoring and documentation. ([`fefb01b`](https://github.com/Byron/gitoxide/commit/fefb01b84f954700b19e010282c4b413de8e03d2))
+ - Upgrade document-features ([`c35e62e`](https://github.com/Byron/gitoxide/commit/c35e62e0da9ac1f7dcb863f5f9c69108c728d32e))
+ - Merge branch 'unify-path-encoding' ([`566ff8a`](https://github.com/Byron/gitoxide/commit/566ff8a3597b889899d41ca15e5b9af7e05f1a4b))
+ - Thanks clippy ([`a8e9497`](https://github.com/Byron/gitoxide/commit/a8e9497caebf1c0e9faac537717cd86378f1acf6))
+ - Release git-features v0.19.1, git-actor v0.8.0, git-config v0.1.10, git-object v0.17.0, git-diff v0.13.0, git-tempfile v1.0.4, git-chunk v0.3.0, git-traverse v0.12.0, git-pack v0.16.0, git-odb v0.26.0, git-packetline v0.12.3, git-url v0.3.5, git-transport v0.15.0, git-protocol v0.14.0, git-ref v0.11.0, git-repository v0.14.0, cargo-smart-release v0.8.0 ([`d78aab7`](https://github.com/Byron/gitoxide/commit/d78aab7b9c4b431d437ac70a0ef96263acb64e46))
+ - Release git-hash v0.9.1, git-features v0.19.1, git-actor v0.8.0, git-config v0.1.10, git-object v0.17.0, git-diff v0.13.0, git-tempfile v1.0.4, git-chunk v0.3.0, git-traverse v0.12.0, git-pack v0.16.0, git-odb v0.26.0, git-packetline v0.12.3, git-url v0.3.5, git-transport v0.15.0, git-protocol v0.14.0, git-ref v0.11.0, git-repository v0.14.0, cargo-smart-release v0.8.0, safety bump 4 crates ([`373cbc8`](https://github.com/Byron/gitoxide/commit/373cbc877f7ad60dac682e57c52a7b90f108ebe3))
+ - Prepare changelogs for release ([`674ec73`](https://github.com/Byron/gitoxide/commit/674ec73b0816baa2c63b4ef1b40b7a41849c5e95))
+ - Prepar changelogs for cargo-smart-release release ([`8900d69`](https://github.com/Byron/gitoxide/commit/8900d699226eb0995be70d66249827ce348261df))
+ - Upgrade to tui 0.17 and prodash 18 ([`eba101a`](https://github.com/Byron/gitoxide/commit/eba101a576ecb7bc0f63357d0dd81eb817b94be4))
+ - Release git-bitmap v0.0.1, git-hash v0.9.0, git-features v0.19.0, git-index v0.1.0, safety bump 9 crates ([`4624725`](https://github.com/Byron/gitoxide/commit/4624725f54a34dd6b35d3632fb3516965922f60a))
+ - Upgrade dependencies ([`968df47`](https://github.com/Byron/gitoxide/commit/968df4746729556dcf4f5039b1d1ed1a1da2705a))
+ - Refactor ([`e7fbd9f`](https://github.com/Byron/gitoxide/commit/e7fbd9f3700496ad7bb7e71226c4d25429f0ccd5))
+ - Merge branch 'sync-db-draft' ([`7d2e20c`](https://github.com/Byron/gitoxide/commit/7d2e20c6fedc2c7e71a307d8d072412fa847a4aa))
+ - Thanks clippy ([`7dd2313`](https://github.com/Byron/gitoxide/commit/7dd2313d980fe7c058319ae66d313b3097e3ae5f))
+ - Release git-features v0.18.0, git-actor v0.7.0, git-config v0.1.9, git-object v0.16.0, git-diff v0.12.0, git-traverse v0.11.0, git-pack v0.15.0, git-odb v0.25.0, git-packetline v0.12.2, git-transport v0.14.0, git-protocol v0.13.0, git-ref v0.10.0, git-repository v0.13.0, cargo-smart-release v0.7.0, safety bump 12 crates ([`acd3737`](https://github.com/Byron/gitoxide/commit/acd37371dcd92ebac3d1f039224d02f2b4e9fa0b))
+ - Adjust changelogs prior to release ([`ec38950`](https://github.com/Byron/gitoxide/commit/ec3895005d141abe79764eaff7c0f04153e38d73))
+ - Thanks clippy ([`db1bb99`](https://github.com/Byron/gitoxide/commit/db1bb99101a9248b464b0df9f526067b8f2a184e))
+ - Merge branch 'pack-consistency' ([`5982406`](https://github.com/Byron/gitoxide/commit/5982406b4e1b26fd383d9ec21a3cf652ec8ab25f))
+ - Release git-hash v0.8.0, git-features v0.17.0, git-actor v0.6.0, git-object v0.15.0, git-diff v0.11.0, git-traverse v0.10.0, git-pack v0.13.0, git-odb v0.23.0, git-packetline v0.12.0, git-transport v0.13.0, git-protocol v0.12.0, git-ref v0.9.0, git-repository v0.11.0, git-commitgraph v0.6.0, gitoxide-core v0.12.0, gitoxide v0.10.0, cargo-smart-release v0.5.0, safety bump 16 crates ([`0e02953`](https://github.com/Byron/gitoxide/commit/0e029537a7f6242d02ccf7e63d8d92f5246e6c5e))
+ - Release git-hash v0.7.0, git-features v0.16.5, git-actor v0.5.3, git-config v0.1.7, git-validate v0.5.3, git-object v0.14.1, git-diff v0.10.0, git-tempfile v1.0.3, git-lock v1.0.1, git-traverse v0.9.0, git-pack v0.12.0, git-odb v0.22.0, git-packetline v0.11.0, git-url v0.3.4, git-transport v0.12.0, git-protocol v0.11.0, git-ref v0.8.0, git-repository v0.10.0, cargo-smart-release v0.4.0 ([`59ffbd9`](https://github.com/Byron/gitoxide/commit/59ffbd9f15583c8248b7f48b3f55ec6faffe7cfe))
+ - Adjusting changelogs prior to release of git-hash v0.7.0, git-features v0.16.5, git-actor v0.5.3, git-validate v0.5.3, git-object v0.14.1, git-diff v0.10.0, git-tempfile v1.0.3, git-lock v1.0.1, git-traverse v0.9.0, git-pack v0.12.0, git-odb v0.22.0, git-packetline v0.11.0, git-url v0.3.4, git-transport v0.12.0, git-protocol v0.11.0, git-ref v0.8.0, git-repository v0.10.0, cargo-smart-release v0.4.0, safety bump 3 crates ([`a474395`](https://github.com/Byron/gitoxide/commit/a47439590e36b1cb8b516b6053fd5cbfc42efed7))
+ - Make fmt, but now it picked up some parts that usually don't get altered… ([`01f7b72`](https://github.com/Byron/gitoxide/commit/01f7b729337bd2c99498321c479a9a13b1858e3e))
+ - Release git-features v0.16.4 ([`fd189c7`](https://github.com/Byron/gitoxide/commit/fd189c7d973ad2a639d319f3761f37aa90712ef6))
+ - Merge branch 'repository-integration' ([`49f5453`](https://github.com/Byron/gitoxide/commit/49f5453629646ac24d752f53c532e5f67eb09374))
+ - Bump git-hash v0.6.0 ([`6efd90d`](https://github.com/Byron/gitoxide/commit/6efd90db54f7f7441b76159dba3be80c15657a3d))
+ - [features #190] be more explicit about why sha1-asm is disabled ([`507d710`](https://github.com/Byron/gitoxide/commit/507d710d837c3911a9329c1c132eee912a37e1a8))
+ - [various #190] rename 'local-offset' to 'local-time-support' ([`3a7d379`](https://github.com/Byron/gitoxide/commit/3a7d3793a235ac872437f3bfedb9dd8fde9b31b1))
+ - [actor #190] methods to get an actor signature at the current time ([`6d0bedd`](https://github.com/Byron/gitoxide/commit/6d0beddb20092a80b113a39c862d6b680d79deb6))
+ - [features #189] simple UTC-offset support for git-features ([`b58134b`](https://github.com/Byron/gitoxide/commit/b58134bbd132f9e685d1adf7859ec5219c16dd25))
+ - [features #???] WIP local time ([`1388ebf`](https://github.com/Byron/gitoxide/commit/1388ebf0925eb326ec3045d7f83bd5beda22a6fe))
+ - [#189] Upgrade to prodash 16… ([`8e98418`](https://github.com/Byron/gitoxide/commit/8e98418652926860f58906a6f21a3210e2f0183f))
+ - [pack #67] Optimize caches based on cache debugging ([`1271c01`](https://github.com/Byron/gitoxide/commit/1271c01d2635ab49474add61a9feb78b98bd6180))
+ - [pack #67] Add cache debugging capabilities to git-features ([`8776c98`](https://github.com/Byron/gitoxide/commit/8776c9834ac4622b3057f5db464a9817ed9acdb0))
+ - Merge branch 'main' into 162-repo-design-sketch ([`e63b634`](https://github.com/Byron/gitoxide/commit/e63b63412c02db469fbdb17da82cd1e9fda1ef0f))
+ - Thanks clippy ([`d689599`](https://github.com/Byron/gitoxide/commit/d689599d1b819c18a3be60075170dbe00462e216))
+ - [features] refactor ([`0958fc8`](https://github.com/Byron/gitoxide/commit/0958fc8dbaa72dda0c1e2d40a88d74b4e18bfe39))
+ - [features] refactor ([`d4605cd`](https://github.com/Byron/gitoxide/commit/d4605cde6d825c0bfaf4282c4cbd85d9f07dc43f))
+ - Release git-features v0.16.2 ([`42861ca`](https://github.com/Byron/gitoxide/commit/42861ca4f0cc9b741d033d4ffa50147b08513b58))
+ - Apply nightly rustfmt rules. ([`5e0edba`](https://github.com/Byron/gitoxide/commit/5e0edbadb39673d4de640f112fa306349fb11814))
+ - (cargo-release) version 0.16.1 ([`e10e55c`](https://github.com/Byron/gitoxide/commit/e10e55c1bf1b40965da9b8b6c87953e6eafda09a))
+ - (cargo-release) version 0.5.0 ([`ae02dab`](https://github.com/Byron/gitoxide/commit/ae02dabae961089a92a21e6a60a7006de4b56dad))
+ - (cargo-release) version 0.16.0 ([`1231dbd`](https://github.com/Byron/gitoxide/commit/1231dbd16dacefb39adec8e067c312d313a82e3c))
+ - Upgrade prodash/crosstermion ([`f109409`](https://github.com/Byron/gitoxide/commit/f1094099de028deabbee3587a70291a7e625e328))
+ - Clippy on tests and thanks clippy ([`a77a71c`](https://github.com/Byron/gitoxide/commit/a77a71cf02d328a2a964388928d6b2a235a0aa85))
+ - [pack] fix build ([`98dd557`](https://github.com/Byron/gitoxide/commit/98dd557b963acfe1c4e717451d222c187c46a5da))
+ - [pack] all tests running for now, but… ([`aec8439`](https://github.com/Byron/gitoxide/commit/aec8439683c639f7b6e344cb76bf1dd9fc769d17))
+ - Refactor sha-1 specification to avoid duplication ([`e23d19c`](https://github.com/Byron/gitoxide/commit/e23d19cd339f0ca5420c82e8125d2c9c7dfcb0da))
+ - Resolver = 2: works! ([`6dc8779`](https://github.com/Byron/gitoxide/commit/6dc877993135ce86649b239821e5b374251743d0))
+ - Try windows one more time: resolver = "2" ([`69d52b8`](https://github.com/Byron/gitoxide/commit/69d52b8ed7a733fe7f31826e576ba8b19619b148))
+ - Fix windows, leave todo, move on ([`2de9e78`](https://github.com/Byron/gitoxide/commit/2de9e78dba35de31456eb553ae703120de23cba6))
+ - See if turning off "asm" support entirely fixes windows ([`b804ef2`](https://github.com/Byron/gitoxide/commit/b804ef2ea6da1ebffaab4d09d0b91eae98ff70c9))
+ - Try to fix build, again ([`c616627`](https://github.com/Byron/gitoxide/commit/c616627cc9984e40798120a801387fc179d6640b))
+ - Don't use ASM on windows for Sha1 as it fails to build there. ([`ba1fb7a`](https://github.com/Byron/gitoxide/commit/ba1fb7ab5bc03f5a23ece32ff1e144544e1eaeae))
+ - [features] enable ASM for everyone… ([`7a1128f`](https://github.com/Byron/gitoxide/commit/7a1128f594c5395a22e5e2b23772bce1d4de7a37))
+ - [ref] reproducible loose ref iteration with built-in sorting ([`e138748`](https://github.com/Byron/gitoxide/commit/e13874807ccc3cbc2b4aacccf63ac5c3dd21c445))
+ - [features] fix docs in the absence of sha1 related features ([`6ca02ac`](https://github.com/Byron/gitoxide/commit/6ca02ace7552c1ffaead81929bc751d96afa713a))
+ - Remove unnecessary pub(crate) exports ([`3d2456e`](https://github.com/Byron/gitoxide/commit/3d2456e11709f0461b37c6df55ecc3861ca4cab5))
+ - [ref] first rough implementation of loose ref iteration ([`918af42`](https://github.com/Byron/gitoxide/commit/918af425298a1fdbb8e7dd6328daefe9eaa10cef))
+ - Refactor ([`2174513`](https://github.com/Byron/gitoxide/commit/21745135ced62411be535ebbc827b3638726318b))
+ - Fix docs ([`e68d460`](https://github.com/Byron/gitoxide/commit/e68d460716dc51c7f4757c11f3c8af6c3881e2cf))
+ - Remove mentions of interrupt handling feature toggles ([`833ac04`](https://github.com/Byron/gitoxide/commit/833ac0464b42bd3ecc76c6263b4b06e8ab4ff182))
+ - Fix everything up so that… ([`5930563`](https://github.com/Byron/gitoxide/commit/5930563601d6c2148cf39e109f69f8b7c7dfcb36))
+ - A first attempt to make intrerupt tools work, but… ([`8fb8d37`](https://github.com/Byron/gitoxide/commit/8fb8d374ecfeffa3ae1bd07bf9bc5014351730f5))
+ - First step towards moving git-features::interrupt… ([`8a741d0`](https://github.com/Byron/gitoxide/commit/8a741d0c5423ed7c35d9382307c760a6b9460ccd))
+ - Fix build ([`ea2bfac`](https://github.com/Byron/gitoxide/commit/ea2bfac65f742ca7617bc77a50376c29156c4ea5))
+ - Refactor ([`7f9be36`](https://github.com/Byron/gitoxide/commit/7f9be36ea909ee67555591287bcb140fdc54c801))
+ - And one less usage of the global interrupt handler… ([`5da57a3`](https://github.com/Byron/gitoxide/commit/5da57a3b0efef75ad82cb4d1cd496fc7fc0f1c23))
+ - Make most interrupts local to the method or function ([`4588993`](https://github.com/Byron/gitoxide/commit/458899306a3f3c8578f185d7ecbf1ade2a7142dd))
+ - Fix build ([`04d919f`](https://github.com/Byron/gitoxide/commit/04d919f9228d287912554275194487870500d18c))
+ - Refactor ([`e0b7f69`](https://github.com/Byron/gitoxide/commit/e0b7f695ee6bd1032544a29d91906f9b75e12d46))
+ - [features] sketch of iterator to auto-check for interruptions ([`61d3a15`](https://github.com/Byron/gitoxide/commit/61d3a15c66b4c1be1d98715b8a60705a3a314455))
+ - [tempfile] integrate with git-features to have a single top-level interrupt… ([`6e9400d`](https://github.com/Byron/gitoxide/commit/6e9400d9cb8e370d870c3aa635718b134c82268f))
+ - [features] protect interrupt handler from multi-initialization ([`592404c`](https://github.com/Byron/gitoxide/commit/592404c2b24dc9d24465ff5f73216213436a277a))
+ - [interrupt] remove any user mesasages as it can't be done in a handler. ([`8a10af7`](https://github.com/Byron/gitoxide/commit/8a10af77db654ebce940bb05f8eefd171036ef40))
+ - [tempfile] a first somewhat working version of signal-hooks for interrupt handling ([`07b3242`](https://github.com/Byron/gitoxide/commit/07b3242e446cb4520dbc54308632ab6221fc19c8))
+ - Update to latest prodash to get rid of ctrlc ([`c070d6f`](https://github.com/Byron/gitoxide/commit/c070d6f5273d7ef9049ddd02fd26332623dc0ae6))
+ - Refactor ([`2e86723`](https://github.com/Byron/gitoxide/commit/2e8672312a4b1e2638e3ffe82a97cc2f87b496cf))
+ - Bump crossbeam-utils from 0.8.4 to 0.8.5 ([`fce4d10`](https://github.com/Byron/gitoxide/commit/fce4d107c7abc778bbdfcd37349c3075e54fd756))
+ - (cargo-release) version 0.4.0 ([`866f86f`](https://github.com/Byron/gitoxide/commit/866f86f59e66652968dcafc1a57912f9849cb21d))
+ - [git-pack] fix docs ([`efd20d4`](https://github.com/Byron/gitoxide/commit/efd20d4e1afbfbe573d620dea4761c06f948a296))
+ - [git-features] fix compilation ([`38c7961`](https://github.com/Byron/gitoxide/commit/38c796142dc5823e1cb14906d9cd4040a8c3be3a))
+ - [git-pack] move hash-writer to git-features as it's quite general purpose ([`80e5640`](https://github.com/Byron/gitoxide/commit/80e5640169363910b4189fda58bb495c6677eaaa))
+ - [git-features] Remove feature that would break licensing agreements ([`cd6ce67`](https://github.com/Byron/gitoxide/commit/cd6ce673308e7e5b1e86fb682ee3ace2ca9ae18c))
+ - [git-features] fix typo ([`c6f342f`](https://github.com/Byron/gitoxide/commit/c6f342f3d29a969a08d037f01eb24555bc03e85e))
+ - [git-features] Finally zlib with feature toggles is working… ([`057016e`](https://github.com/Byron/gitoxide/commit/057016e2df3138992c4857f9b65bf19dc2c9a097))
+ - [git-features] And now zlib finally works! ([`6d887d5`](https://github.com/Byron/gitoxide/commit/6d887d589a57e159986f049c8a9e19c52ce7b85b))
+ - [git-features] simplify even more ([`ca54d97`](https://github.com/Byron/gitoxide/commit/ca54d97d579dd4f16025a2325d5e39431f6e8a36))
+ - [git-features] refactor to help understand a zlib-related logic bug ([`ae826e8`](https://github.com/Byron/gitoxide/commit/ae826e8c3240efd14939beedd33a06695a6c112b))
+ - [git-features] a first step towards supporting a pure rust zlib backend ([`040cab7`](https://github.com/Byron/gitoxide/commit/040cab7f27de83b283957189244d523d71ca1457))
+ - [git-features] Add zlib module to allow changing implementation on the fly ([`4bdf783`](https://github.com/Byron/gitoxide/commit/4bdf7833d99d3c2884b9747614f9c14a06c1e945))
+ - (cargo-release) version 0.15.0 ([`d69d9fb`](https://github.com/Byron/gitoxide/commit/d69d9fb0931f8257cef96ef14a89da9340ad9738))
+ - Put prodash behind a feature toggle, too ([`966058d`](https://github.com/Byron/gitoxide/commit/966058d611c548e90c050462de52e36f1925e775))
+ - Put 'walkdir' behind a feature flag/make it optional. ([`1a3cc5b`](https://github.com/Byron/gitoxide/commit/1a3cc5bea1868ed3ae015403fbe0cdec788be749))
+ - Put 'sha1' behind a feature toggle ([`4f326bc`](https://github.com/Byron/gitoxide/commit/4f326bc261c4e7f0d5510df74ad4215da3580696))
+ - Use crc32fast instead of `crc` ([`11955f9`](https://github.com/Byron/gitoxide/commit/11955f95e200ef75e752a833952d288fbd0fc389))
+ - Put crc functionality behind a feature toggle ([`458fa6e`](https://github.com/Byron/gitoxide/commit/458fa6ec726ec7901c1f6d970cbb1c1ea975dded))
+ - (cargo-release) version 0.14.0 ([`a760f8c`](https://github.com/Byron/gitoxide/commit/a760f8c013e13ba82daa1acf1a4a57e0818a008d))
+ - Upgrade to prodash 13/tui 0.15 ([`1c99f51`](https://github.com/Byron/gitoxide/commit/1c99f51b35b4ba85792a3b32dbb7e48052facc5e))
+ - (cargo-release) version 0.3.0 ([`e9665c7`](https://github.com/Byron/gitoxide/commit/e9665c784ae7e5cdaf662151395ee2355e9b57b6))
+ - Allow calling 'finalize()' on the entries iterator ([`3c617bc`](https://github.com/Byron/gitoxide/commit/3c617bc2ae59adbb12c254308269e745149d462b))
+ - Git-odb without cargo warnings due to using the same test twice ([`8945f95`](https://github.com/Byron/gitoxide/commit/8945f95364b489e7a639d74dd0f28b17e82e70f3))
+ - Fix compile warning for git-features ([`d457faa`](https://github.com/Byron/gitoxide/commit/d457faac6bb56a229b74147c8a4cf2484026bb1a))
+ - Fix doc links ([`870af2a`](https://github.com/Byron/gitoxide/commit/870af2a6949bcb1f7f45bc0ff98d9e9a07014b22))
+ - Run git-odb tests in parallel, too; improved threaded error handling ([`40802fd`](https://github.com/Byron/gitoxide/commit/40802fd8bbb15b8a61249522d67f3a5b28da64b3))
+ - Refactor ([`82c2f42`](https://github.com/Byron/gitoxide/commit/82c2f428e22c3cda79913c9ca2f092c377d692aa))
+ - Refactor ([`7a6b514`](https://github.com/Byron/gitoxide/commit/7a6b514a5b9b93bf574cd3a114f27ad5967e89ac))
+ - Refactor ([`5ef1f22`](https://github.com/Byron/gitoxide/commit/5ef1f22c1e12ff8d607663d4dfbbbfe426a29e0f))
+ - Fix docs #(67) ([`01db10a`](https://github.com/Byron/gitoxide/commit/01db10a27431ad89a68ed3e4eabae810748a6f29))
+ - Refactor ([`3e908bd`](https://github.com/Byron/gitoxide/commit/3e908bd4b4077c4a5d113cefc113f9d71f249133))
+ - Refactor ([`409d763`](https://github.com/Byron/gitoxide/commit/409d763d2fca974a647487c72d15f568a9b62ccb))
+ - Refactor ([`896ab94`](https://github.com/Byron/gitoxide/commit/896ab940bcd475d026e4009b3aa2fa6a025c14bc))
+ - Remove unused dependency ([`26beb2a`](https://github.com/Byron/gitoxide/commit/26beb2a5ad87e173fd3d13d17b0e9676a650cac9))
+ - Don't finish the computation on drop of SteppedReduce ([`6453633`](https://github.com/Byron/gitoxide/commit/6453633f1420327aee07dca2ad27abd8f96108c0))
+ - Thanks clippy ([`c320761`](https://github.com/Byron/gitoxide/commit/c320761821b08946a2b37e219400ded853a86408))
+ - Remove unsafe interface for stepped computation #(67) ([`c856613`](https://github.com/Byron/gitoxide/commit/c856613a35aea7dea1d093bfcfe1ddbde93fdf26))
+ - A first working version of a static parallel iterator #(67) ([`d7d5c68`](https://github.com/Byron/gitoxide/commit/d7d5c6855a038a8b01571a6a16a61fe0d8036d30))
+ - A way iteration won't work with 'static #(67) ([`6fda1f2`](https://github.com/Byron/gitoxide/commit/6fda1f20a57b9dcc1a5818d8d0b656218b383230))
+ - Sketch of machinery for producing pack entries #(67) ([`ac8e7fb`](https://github.com/Byron/gitoxide/commit/ac8e7fb6c8ae4ac42f56482d9d7744aa66132702))
+ - Less restrictive requirements: Clone instead of Copy #(67) ([`410e7d6`](https://github.com/Byron/gitoxide/commit/410e7d64049b5a749113126f5412a61ae4b79887))
+ - Improve Safety docs #(67) ([`15e4748`](https://github.com/Byron/gitoxide/commit/15e47480054d9a517c28f47db3b5fa87968a307e))
+ - A test to assure referenced input and references in 'consume' work #(67) ([`4526d82`](https://github.com/Byron/gitoxide/commit/4526d82fab4d6e8f2ab05497aa5893d5a8f8b253))
+ - Make iterator creation unsafe and document why #(67) ([`593d5df`](https://github.com/Byron/gitoxide/commit/593d5df478e67e28f9b3d48b201ff6830208726f))
+ - First seemingly working version of an iterator which allows controlling threaded work #(67) ([`4a7ef7d`](https://github.com/Byron/gitoxide/commit/4a7ef7d6398c2ff5dd6aac41f8224cd2d61ee189))
+ - Make the parallel SteppedReduce compile #(67) ([`017fdf4`](https://github.com/Byron/gitoxide/commit/017fdf48972a6a09e5155bd76bd437d8e195dae3))
+ - More docs to differentiate SteppedReduce from in_parallel() #(67) ([`153c083`](https://github.com/Byron/gitoxide/commit/153c0837bbf1df3b5cb386e08265f9b06eaee2a9))
+ - Serial version of SteppedReduce seems to be working #(67) ([`779542e`](https://github.com/Byron/gitoxide/commit/779542e4f4c951e9b16d2310146020da9ce36859))
+ - Only store thread state #(67) ([`0bf8a9b`](https://github.com/Byron/gitoxide/commit/0bf8a9b3c4a086732ee04f81c6a214296d49eab9))
+ - Sketch instantiation of iterator adapter #(67) ([`a3083ad`](https://github.com/Byron/gitoxide/commit/a3083ad3aad7984afc6b6d343ca7453f79897062))
+ - A reducer test in preparation for allow it to be used as iterator #(67) ([`1c2adf4`](https://github.com/Byron/gitoxide/commit/1c2adf4a546273489bf8224eb7982dbdf3fb6aca))
+ - (cargo-release) version 0.13.0 ([`ac2eddb`](https://github.com/Byron/gitoxide/commit/ac2eddb06eb3d8a9a3dcdcd796eb54a7e45ab935))
+ - Allow parallel reducers to produce something during 'feed()' #(67) ([`6c04fcd`](https://github.com/Byron/gitoxide/commit/6c04fcd643083d9db633edd3bb838b4f5de8f0db))
+ - (cargo-release) version 0.12.0 ([`3b71e7e`](https://github.com/Byron/gitoxide/commit/3b71e7e8416e550b47e5aed2259c1181497ac9e8))
+ - (cargo-release) version 0.2.0 ([`4ec09f4`](https://github.com/Byron/gitoxide/commit/4ec09f4d2239ea1d44f7145027e64191bf2c158c))
+ - Refactor ([`dee8c66`](https://github.com/Byron/gitoxide/commit/dee8c66e300dc2a2b6e1a6d6c3674a7ce6aac687))
+ - (cargo-release) version 0.11.0 ([`1aa1f5e`](https://github.com/Byron/gitoxide/commit/1aa1f5e84a07427d5d7f3231735fe9c1923f506f))
+ - (cargo-release) version 0.10.1 ([`0dcdfd7`](https://github.com/Byron/gitoxide/commit/0dcdfd754649240f43fe0f4b6e1245e8c7b89635))
+ - Remove usage of gitfeatures::fs in organize subcommand ([`b567d37`](https://github.com/Byron/gitoxide/commit/b567d3709a74e9fdafef54b0fe58ca82721cd773))
+ - Assure basic 'organize' operation is working as expected ([`deb6073`](https://github.com/Byron/gitoxide/commit/deb6073671ae95de674aaef7ca01e03f95b41ca8))
+ - A first stab at finding git repositories ([`e4dc964`](https://github.com/Byron/gitoxide/commit/e4dc96403894f1fe509335905679347ecdf535c7))
+ - Upgrade 'jwalk' ([`cba048f`](https://github.com/Byron/gitoxide/commit/cba048f094858388f4242e37a2409fe0822f8c07))
+ - Upgrade 'bytes' ([`3934392`](https://github.com/Byron/gitoxide/commit/39343922b4a1129394aa788a9591920aee077569))
+ - Upgrade prodash and friends ([`50755bc`](https://github.com/Byron/gitoxide/commit/50755bc83f73072dc629301bf69c5c065d5c2aa4))
+ - Add missing '.' at end of doc comments ([`7136854`](https://github.com/Byron/gitoxide/commit/71368544f97369a4d371d43513607c4805bd0fd0))
+ - Use git-hash in git-features ([`5b307e0`](https://github.com/Byron/gitoxide/commit/5b307e076f6f5975592c8b177c122c91c1d809c6))
+ - (cargo-release) version 0.9.0 ([`a89fdb9`](https://github.com/Byron/gitoxide/commit/a89fdb98f64bb0ca070fa79a1f58f1232bb14090))
+ - (cargo-release) version 0.5.0 ([`fc7d600`](https://github.com/Byron/gitoxide/commit/fc7d600ac2c438c8b6b91f67cb69b0ac5ec37675))
+ - More docs for owned git-object ([`b79101d`](https://github.com/Byron/gitoxide/commit/b79101d714f59a42a30eb47776486a212ec0f738))
+ - Fix io::pipe tests ([`9604154`](https://github.com/Byron/gitoxide/commit/9604154e687813a11f0eee469e408561a6a74a4e))
+ - Uograde everything else ([`0cd79d0`](https://github.com/Byron/gitoxide/commit/0cd79d00bce3f042b5cc849cf48739e29f95fcb0))
+ - Upgrade prodash and tui ([`b5eadca`](https://github.com/Byron/gitoxide/commit/b5eadca343bbaa1af86722b5f1bcd33f4e3939a6))
+ - Add remaining docs to git-features using the missing_docs directive ([`f8aafd6`](https://github.com/Byron/gitoxide/commit/f8aafd6c78687899a2ca3a3e6147d93fc45b8cb9))
+ - (cargo-release) version 0.8.0 ([`47c00c2`](https://github.com/Byron/gitoxide/commit/47c00c2228cf25c79e1fa3eb4229c7ab24de91e5))
+ - Finish git-features documentation ([`934a26c`](https://github.com/Byron/gitoxide/commit/934a26c5e254baf2be9178096b6dead0e4c1ed1d))
+ - Refactor ([`b3a8bb5`](https://github.com/Byron/gitoxide/commit/b3a8bb5f7f0c6e80259922546928c2739c24f7b5))
+ - Refactor ([`f9e8d29`](https://github.com/Byron/gitoxide/commit/f9e8d2932c02c22bf57acd39fb0a9e6d521070bd))
+ - Docs for the git-features::pipe module ([`67a950a`](https://github.com/Byron/gitoxide/commit/67a950a2e0fd56b29565668ed0a0f399d5aa989d))
+ - Document git-features::parallel ([`b899227`](https://github.com/Byron/gitoxide/commit/b8992275cd4310b05494be41c059e9b6049d06b1))
+ - Dependency update ([`fb077f9`](https://github.com/Byron/gitoxide/commit/fb077f9fecb89ed8a60d57b45726401883e838bf))
+ - Finish git_features::interrupt docs ([`471a1bf`](https://github.com/Byron/gitoxide/commit/471a1bf24efee70f21b15839cdc9f8ebe319f917))
+ - Dependency update ([`b3b4aba`](https://github.com/Byron/gitoxide/commit/b3b4aba5e05596befecd17e225067be9315b74fd))
+ - Docs for git-features::hash ([`a3fdecc`](https://github.com/Byron/gitoxide/commit/a3fdecc9a3587b20c01e3b3a2d51190138131c3d))
+ - First sketch of filesystem docs for git-features ([`1a8141c`](https://github.com/Byron/gitoxide/commit/1a8141c2c4a8bcc79d68049a35bd8aba5ab822a3))
+ - (cargo-release) version 0.7.0 ([`7fa7bae`](https://github.com/Byron/gitoxide/commit/7fa7baeb3e7d008a25e4d714eff908e2516c828b))
+ - Merge branch 'commit-graph' into main ([`9cb09b2`](https://github.com/Byron/gitoxide/commit/9cb09b248796f0ff5c9d3f3e857de4731324cfd5))
+ - Specify the hash to create with 'hash::bytes_of_file' ([`c000294`](https://github.com/Byron/gitoxide/commit/c000294423ae0759b978399db3b69ac07c20578d))
+ - Move 'git_odb::hash::bytes_of_file' into git_features::hash ([`c5f6b45`](https://github.com/Byron/gitoxide/commit/c5f6b4587ee4042a080c0505613b0c72fdfe5273))
+ - Remove dash in all repository links ([`98c1360`](https://github.com/Byron/gitoxide/commit/98c1360ba4d2fb3443602b7da8775906224feb1d))
+ - Merge branch 'main' into commit-graph ([`ca5b801`](https://github.com/Byron/gitoxide/commit/ca5b80174b73cc9ac162b3f33b5d3721ef936cb1))
+ - Use parallel walkdir (via jwalk) when parallel feature is enabled ([`f444c85`](https://github.com/Byron/gitoxide/commit/f444c859f5b215ea70a46d5493a2babbf7a98235))
+ - Merge from main. ([`b59bd5e`](https://github.com/Byron/gitoxide/commit/b59bd5e0b0895c7d1d585816cec8be4dea78c278))
+ - Refactor ([`e4bcfe6`](https://github.com/Byron/gitoxide/commit/e4bcfe6406b14feffa63598c7cdcc8ecc73222bd))
+ - (cargo-release) version 0.6.0 ([`9ef184e`](https://github.com/Byron/gitoxide/commit/9ef184e35712f938fb4f9f6da7390a8777a9284e))
+ - Switch to prodash 10 and safe a lot of trait bounds in the process ([`e2fb1d9`](https://github.com/Byron/gitoxide/commit/e2fb1d944b4d803a11c91f868b831d406fb5e35f))
+ - (cargo-release) version 0.5.0 ([`82b7313`](https://github.com/Byron/gitoxide/commit/82b73131b79ec3c42a712dad1c0766a72209d737))
+ - [clone] This actually works: first MVP of retrieving packs via clone ([`c06d819`](https://github.com/Byron/gitoxide/commit/c06d8194173f9ec468ddd0faf72dd6d8dbf7d35d))
+ - [clone] test (and fix) for piped line reading ([`afe2996`](https://github.com/Byron/gitoxide/commit/afe2996689b5bea915ac5f142d320056faf49899))
+ - [clone] Send headers with BufReaders ([`6a95aaa`](https://github.com/Byron/gitoxide/commit/6a95aaab582941c6d1697dde6982c0aa8896c73d))
+ - [clone] pipe allows to send errors as well ([`69286ec`](https://github.com/Byron/gitoxide/commit/69286ecb3680b5071693ef0d9fb2e9345b2722d4))
+ - [clone] BufRead for Reader… ([`bf1d40f`](https://github.com/Byron/gitoxide/commit/bf1d40f2d44a9b04ffe2134ddcd3779985cdafc4))
+ - [clone] a piped iterator ([`5148c85`](https://github.com/Byron/gitoxide/commit/5148c85efc70c0ec06be3ebce267ce727c8ee4e1))
+ - [clone] pipe probably shouldn't abort on empty writes ([`9cfa9b7`](https://github.com/Byron/gitoxide/commit/9cfa9b79841187167f0f96abfd1c17a37b4c365d))
+ - Thanks clippy ([`c4f570f`](https://github.com/Byron/gitoxide/commit/c4f570fcae7e21745a37a4265b05d21e6149157b))
+ - [clone] more pipe tests ([`1652a74`](https://github.com/Byron/gitoxide/commit/1652a74761631cadfc6feab366adc0808d83063d))
+ - [clone] first working pipe implementation ([`490a9b9`](https://github.com/Byron/gitoxide/commit/490a9b96915a760e339e576d9f49737b43a8739f))
+ - [clone] frame for implementing 'pipe' support ([`c555681`](https://github.com/Byron/gitoxide/commit/c55568127ff943cc6749dba5054d7b3e93c049eb))
+ - Fix git-features hash tests ([`35e8809`](https://github.com/Byron/gitoxide/commit/35e8809f6bc7d19ed9e0bac8e3af85f433978901))
+ - Bump git-features to 0.4 to allow publishes after breaking changes ([`9d6b879`](https://github.com/Byron/gitoxide/commit/9d6b8790e2edd7fa01b3239adff86a7cd2393f10))
+ - [protocol] properly implement remote progress reporting ([`a81954a`](https://github.com/Byron/gitoxide/commit/a81954a6a37afacd51add6661a656b8fb663ca54))
+ - Allow dual-licensing with Apache 2.0 ([`ea353eb`](https://github.com/Byron/gitoxide/commit/ea353eb02fd4f75508600cc5676107bc7e627f1e))
+ - Add 'disable-interrupts' feature flag ([`ccd9c3e`](https://github.com/Byron/gitoxide/commit/ccd9c3e2d37aa6898dc17f47a82c187baa810b03))
+ - Refactor ([`b4a6e16`](https://github.com/Byron/gitoxide/commit/b4a6e16364822c0dccb56f98dbfb0ca4c8007069))
+ - Bump minor version to 0.3 ([`4351e28`](https://github.com/Byron/gitoxide/commit/4351e2871c9dcf342b8471fffa74cae338a53269))
+ - Thanks clippy ([`6725104`](https://github.com/Byron/gitoxide/commit/6725104d2841e6518db641d06e3e107cf4f40f96))
+ - First step towards parallelizing file hashes and traversal! ([`9573836`](https://github.com/Byron/gitoxide/commit/95738369e0d3accf7f6239c8cd966a7f5c36825a))
+ - Better usability for units ([`b226253`](https://github.com/Byron/gitoxide/commit/b226253636d8146a084a7bcd7c0c320e37f9d2fb))
+ - Update dependencie ([`ade06b4`](https://github.com/Byron/gitoxide/commit/ade06b46bb3c16ac1e26dbbb4a7045f0c09f2d8e))
+ - Make obvious that interrupt request was received ([`34b2373`](https://github.com/Byron/gitoxide/commit/34b23737f560fe52d4f98fb886eba754652f9a5e))
+ - Remove once_cell dependency as it is really not required anymore ([`5ac9538`](https://github.com/Byron/gitoxide/commit/5ac95385cc8d1c50c16da6e5fb0c66ac138f9966))
+ - Make interrupt handler work reliably ([`e71da0f`](https://github.com/Byron/gitoxide/commit/e71da0fce6d6eab68f7b81b13cdc78ce8e9b7ee3))
+ - Conditionally use an eager iterator… ([`e9b5511`](https://github.com/Byron/gitoxide/commit/e9b5511568f4e64968596994855783f19672d678))
+ - Refactor ([`d14f0f6`](https://github.com/Byron/gitoxide/commit/d14f0f6c3b5f303df75b33aadbf16653075d2272))
+ - Allow eager iterator to behave properly when used with index writing ([`66ebc5f`](https://github.com/Byron/gitoxide/commit/66ebc5f1ad5f262eb464dc7ca0892ec952d34382))
+ - First successful test of moving the streaming iterator into its own thread ([`c9fcb68`](https://github.com/Byron/gitoxide/commit/c9fcb68c644c96a15cb9956a754bec7b65bb5fbd))
+ - Now it's order preserving ([`4c8711e`](https://github.com/Byron/gitoxide/commit/4c8711e51efd88e0f159ad02de2692c4cb72ce27))
+ - First sketch of order-destroying eager iterator ([`20fca45`](https://github.com/Byron/gitoxide/commit/20fca4515f6e9ea320d0bf21c15cd6d2c3cff742))
+ - Print read throughput automatically ([`0a71b48`](https://github.com/Byron/gitoxide/commit/0a71b482310a129aa8757475290b3b24a200b702))
+ - Make sure interrupt logic works even without an interrupt handler… ([`66b1644`](https://github.com/Byron/gitoxide/commit/66b164472f5893f9e634ac1f9147a41dc742296d))
+ - Add percentage and throughput to tasks that matter ([`763d7ca`](https://github.com/Byron/gitoxide/commit/763d7caa4c70111b7cb3ef5733d2c3c697758c28))
+ - Upgrade to latest iteration of prodash ([`3a4faec`](https://github.com/Byron/gitoxide/commit/3a4faecab56e37670c553e6563f11a46d740c333))
+ - First part of migration to prodash 8.0, but… ([`6901a09`](https://github.com/Byron/gitoxide/commit/6901a098641820c8d974ce56a24d6cdca779730d))
+ - Thanks clippy ([`ed5882d`](https://github.com/Byron/gitoxide/commit/ed5882d75e0a9fceb0628e84302eb49a66277fa6))
+ - Write about user interfaces and the use/non-use of async ([`91ba045`](https://github.com/Byron/gitoxide/commit/91ba0457745f860b7a68cb38b13e69754747e8d9))
+ - Interrupt support for pretty plumbing ([`bca7ce2`](https://github.com/Byron/gitoxide/commit/bca7ce2e668a4be2600d2d04d00f46b21c82eee2))
+ - Support for interruptible operations ([`a025593`](https://github.com/Byron/gitoxide/commit/a02559378f9165df97a217f24834a851be719b08))
+ - Refactor ([`413968d`](https://github.com/Byron/gitoxide/commit/413968dfee5e5a66ed9e63823f6bda5a5a22753e))
+ - Receive progress information when reading packs in bundle ([`759091d`](https://github.com/Byron/gitoxide/commit/759091d3c6696b427d7b5aab1b6da05a0d268c04))
+ - Initial batch of progress usage for index creation… ([`b10e5c6`](https://github.com/Byron/gitoxide/commit/b10e5c664be9bd1bdb2b72b858ebaf35c1ed4cb4))
+ - First stab at streaming pack header encoding ([`3c6e78b`](https://github.com/Byron/gitoxide/commit/3c6e78bec9cbd4df842919cc8dc3c575414ed002))
+ - We can now restore (possibly half-written) packs ([`b1daa46`](https://github.com/Byron/gitoxide/commit/b1daa465c40ea8c7c9de69a18e467d69459d911e))
+ - See how big a Sha1 hasher really is ([`26b271d`](https://github.com/Byron/gitoxide/commit/26b271d44863fb184b0a947c3a9da2b3252f9a78))
+ - First sketch of new verify expressed in terms of traversal ([`4cb570f`](https://github.com/Byron/gitoxide/commit/4cb570f96ddd7ee2faa62e54927afd78ba7822af))
+ - (cargo-release) version 0.2.0 ([`0bb8314`](https://github.com/Byron/gitoxide/commit/0bb831480d8657e1bb29ee7009aeac673471403e))
+ - Incorporate dynamic chunking into 'less-time' algorithm ([`295aa2f`](https://github.com/Byron/gitoxide/commit/295aa2f01dc596a8880cd2f68a8d83bc6913ce48))
+ - Integrate new chunk size code into lookup code ([`a8422cf`](https://github.com/Byron/gitoxide/commit/a8422cf0b0c9ff4d3275cc17a68a74811b5bd01f))
+ - First round of number tuning done ([`a647b2d`](https://github.com/Byron/gitoxide/commit/a647b2da2905c4079e646ea44cbec778f3f7c71f))
+ - Somehow handle chunk size in absence of known chunk amount ([`acfccad`](https://github.com/Byron/gitoxide/commit/acfccadef40ebcc67f8dea4e58c02392b7e2e7de))
+ - Chunk computation seems alright, what about realistic values ([`973e6bb`](https://github.com/Byron/gitoxide/commit/973e6bb3d67d89eec2faf2467a129d992b90ed72))
+ - Getting there… ([`a1b5d56`](https://github.com/Byron/gitoxide/commit/a1b5d565f305f0f2666fd59272d9bf9c62ae2962))
+ - First step towards computing better chunk sizes and thread limits ([`1cdde7d`](https://github.com/Byron/gitoxide/commit/1cdde7d339a6ed3650c54f9b48154089d7da9919))
+ - Add 'inc()' convenience methods to progress ([`2e46c9b`](https://github.com/Byron/gitoxide/commit/2e46c9b72a2a5b90bcdac249de07ffbc124cfb04))
+ - (more) graceful shutdown of failing parallel tasks ([`163f50f`](https://github.com/Byron/gitoxide/commit/163f50fab81b425e6e306ec54fb1eb60a7c02cf8))
+ - Respect thread limit in 'in_parallel' ([`babfd84`](https://github.com/Byron/gitoxide/commit/babfd84cba77ef7a0f541ba921b31ebd3f3c50e3))
+ - Make crates publishable ([`5688a34`](https://github.com/Byron/gitoxide/commit/5688a3427ff3673e1422d43106f4d685fa837aed))
+ - Flume isn't actually needed for that… ([`c750022`](https://github.com/Byron/gitoxide/commit/c750022394928aa37a8400611f6fdf4ee77c0f69))
+ - Don't just ignore send errors - we should panic for now ([`f128117`](https://github.com/Byron/gitoxide/commit/f128117138b24de780a00bb96e7c1c9f987e8aa0))
+ - Proper implementation of line renderer into 'lean' CLI ([`e98e7c2`](https://github.com/Byron/gitoxide/commit/e98e7c280d73e9d9ebd13202afb93a56cb2f7c9c))
+ - Upgrade to prodash version 7 ([`af02b46`](https://github.com/Byron/gitoxide/commit/af02b46cc1eff5ba1da7da20d3f524a79fad686f))
+ - Update prodash to verion 6.0 ([`a4731a3`](https://github.com/Byron/gitoxide/commit/a4731a3aca159f8916b29d9ce5a71856089c5a6b))
+ - Add metadata to allow docs.rs build all featueres ([`10f9386`](https://github.com/Byron/gitoxide/commit/10f9386a12decc1f13999aee72be484c8f6d48ce))
+ - Switch to prodash 5.0 for windows support ([`88542e1`](https://github.com/Byron/gitoxide/commit/88542e117dd1c2e7606fcbe88b30c51b4c115989))
+ - Allow to limit the logging depth for less cluttered output ([`fce7035`](https://github.com/Byron/gitoxide/commit/fce703531d7006f7d961d6ffa66f51f6c9bc0efc))
+ - Finally speed up logging progress properly - needs input throttling ([`1a550c6`](https://github.com/Byron/gitoxide/commit/1a550c6458b10fad2e42b641899216c5517c6e26))
+ - Avoid calling system time too often in logs, it reduced performance ([`b17bd76`](https://github.com/Byron/gitoxide/commit/b17bd76d35822b3af174c74af3d6fac887889fe2))
+ - Revert "ABORT: try-join with static typing works, but…" ([`b8b979b`](https://github.com/Byron/gitoxide/commit/b8b979b99b5f3848e0a6884c58594ba2b481a147))
+ - Try-join with static typing works, but… ([`ab6f98b`](https://github.com/Byron/gitoxide/commit/ab6f98b905f13ed2a7c0c483f34fab63141fbc5b))
+ - Remove dependency to git-object from git-features - it better remains free ([`67c3a6a`](https://github.com/Byron/gitoxide/commit/67c3a6ab4cc32358a1406c2f863e26a4c2929867))
+ - \#[forbid(unsafe)] for all crates ([`afda803`](https://github.com/Byron/gitoxide/commit/afda8039259b7a30cfed5dbcdd9caf4773b4c234))
+ - Allow for more screen space when formatting ([`6794300`](https://github.com/Byron/gitoxide/commit/67943002e7f4215b5383bd0538786ce2857f011e))
+ - Refactor ([`7add82c`](https://github.com/Byron/gitoxide/commit/7add82c39169e3c2fff76c48cdd318fe6040d7bc))
+ - Automatically close the TUI when there is no progress anymore. ([`c416152`](https://github.com/Byron/gitoxide/commit/c416152b04051958de7bd161a8a2ee42ca163275))
+ - Pretty progress in a generalized form ([`caa883b`](https://github.com/Byron/gitoxide/commit/caa883b96827deb63b5c8787ed820d22f2c85249))
+ - Express DoOrDiscard in terms of Either (progress) ([`cb29a45`](https://github.com/Byron/gitoxide/commit/cb29a45f4e73bfaa25cbf623b1cda2435673028b))
+ - Provide 'either' type with implementation for Progress ([`237bb5e`](https://github.com/Byron/gitoxide/commit/237bb5ee1c2b677f5bfd9ca7fdea9d9d2db865b3))
+ - Better trait bounds of `in_parallel_if`… ([`6264f2f`](https://github.com/Byron/gitoxide/commit/6264f2f99929ffaa4d50cdcae7bc296e1b4762f4))
+ - First implementation of logging per thread ([`477dd90`](https://github.com/Byron/gitoxide/commit/477dd90ce5e102875b19489bf8ae9877522ef9c8))
+ - Support for providing progress to threads ([`2815858`](https://github.com/Byron/gitoxide/commit/2815858adf7ac0f7b4cbc88cf05df0ea6aef4116))
+ - First very basic progress implementation ([`b820717`](https://github.com/Byron/gitoxide/commit/b8207177daee8a9ffa23c7c052cf9ca651b15804))
+ - Pass progress everywhere, for now just to discard it ([`da3ae1c`](https://github.com/Byron/gitoxide/commit/da3ae1c82cd726b8fae9b8d26069719930e9ba99))
+ - Implement `Progress` trait for prodash::tree::Item ([`0eeb6d7`](https://github.com/Byron/gitoxide/commit/0eeb6d770d58621427bc88107a20860b89b86a24))
+ - Implement progress trait for logs with throttling ([`287eca9`](https://github.com/Byron/gitoxide/commit/287eca91b244ccbc703cb275b1ae032bfeb02532))
+ - Add 'fast-sha1' to git-features ([`b22541f`](https://github.com/Byron/gitoxide/commit/b22541f0c39af470877119b136e4eb1b82dff2db))
+ - A new crate to represent features that can toggle from the top-level ([`23c420c`](https://github.com/Byron/gitoxide/commit/23c420cc95219dc7c04d3905aaa03281cb51724e))
+</details>
+
+## 0.26.3 (2023-02-14)
+
+### New Features
+
+ - <csr-id-426057247a80821b3da22b4ae5d67bda89ce0631/> re-export `prodash` in `progress` module.
+ That way one can access all types even if they are not re-exported.
+
+## 0.26.2 (2023-02-09)
+
+### Documentation
+
+ - <csr-id-39ed9eda62b7718d5109135e5ad406fb1fe2978c/> fix typos
+
+### New Features
+
+ - <csr-id-c4a7634b0b29c74625e183953e59c65987e9d66c/> export `prodash::progress::Id` in the `progress` module for convenience.
+
+## 0.26.1 (2023-01-10)
+
+A maintenance release without user-facing changes.
+
+## 0.26.0 (2022-12-30)
+
+<csr-id-5bf0034fb3918e57562b7089ceba83d63a1854bf/>
+
+### Chore (BREAKING)
+
+ - <csr-id-5bf0034fb3918e57562b7089ceba83d63a1854bf/> upgrade to prodash v23
+
+## 0.25.1 (2022-12-26)
+
+### New Features
+
+ - <csr-id-25ad372bf500b851105f53b10369b5a689ba167e/> zlib::inflate::Error can now represent zlib status codes that represent failure.
+
+## 0.25.0 (2022-12-19)
+
+### New Features (BREAKING)
+
+ - <csr-id-0f27c67c92fc0bc23a6712b5c4c730ad6a0156bf/> add support for explicit non-parallel iteration.
+ That way we can allow the implementation to choose whether they
+ need greatest speed at some cost or not.
+
+ This also allows us to create a new thread-pool on each iteration
+ as those who expect high cost or many files will likely chose to do
+ that instead of single-threaded iteration, which nicely contains the
+ threads needed and avoids keeping them alive as part of some global pool.
+
+## 0.24.1 (2022-11-27)
+
+### New Features
+
+ - <csr-id-6d530a1dc77f0f4ac00622a2fd47c7bdb731a77a/> name spawned threads
+ That way it's a bit more obvious what's happening when the CPU goes
+ up in flames.
+ - <csr-id-c8835c6edae784c9ffcb69a674c0a6545dbb2af3/> upgrade to `prodash 21.1` and add `Ids` to all progress instances.
+ That way callers can identify progress they are interested in, say, for
+ selective visualizations.
+
+## 0.24.0 (2022-11-21)
+
+A maintenance release without user facing changes.
+
+## 0.23.1 (2022-11-06)
+
+### New Features
+
+ - <csr-id-9076ce33ec167e425a0163d3e40a81a3fd0db6cd/> `fs::Snapshot` can `Clone` if `T` can `Clone`.
+
+## 0.23.0 (2022-10-10)
+
+### New Features
+
+ - <csr-id-a7c11d2cb5f88a4ff322d9a9848459062790d8b3/> perfect granularity for threads processing with `in_parallel_with_slice()`
+ - <csr-id-ff1db66f2dad3afc8bc77610006bca9fea5947d2/> add `progress::Step|StepShared` as types of `prodash`
+ This may help to use the `Progress::counter()` method as part of method
+ signatures, being an `Option<progress::StepShared>`.
+
+### Changed (BREAKING)
+
+ - <csr-id-38446dc8824afef30ef121598de3451d13b9262c/> remove `fs-jwalk-single-threaded` in favor of `fs-walkdir-parallel`.
+ This way, `jwalk` and the dependencies (and troubles) it brings have to
+ be opted in, but also allow other users to actually opt out while
+ allowing the `parallel` feature to be in effect.
+
+ In other words, previously the `parallel` feature conflated `jwalk`
+ dependencies into the tree, which isn't the case anymore.
+
+### New Features (BREAKING)
+
+ - <csr-id-3b29fc18672c0176684c797a0f16f85d09369bf8/> make jwalk fully optional
+
+## 0.22.6 (2022-09-16)
+
+Fix docs.rs rendering.
+
+### New Features
+
+ - <csr-id-cfe46b502afc3ecb312849ddbd7748007d432cd1/> add zlib-ng feature to allow linking against system libz-ng
+ Allow to use zlib-ng (zlib-ng-sys) with native API (no compat mode)
+ that can co-exist with system libz (loaded by e.g. libcurl).
+ This is used in gitoxide package on Alpine Linux.
+
+## 0.22.5 (2022-09-20)
+
+### New Features
+
+ - <csr-id-cfe46b502afc3ecb312849ddbd7748007d432cd1/> add zlib-ng feature to allow linking against system libz-ng
+ Allow to use zlib-ng (zlib-ng-sys) with native API (no compat mode)
+ that can co-exist with system libz (loaded by e.g. libcurl).
+ This is used in gitoxide package on Alpine Linux.
+
+## 0.22.4 (2022-09-04)
+
+A maintenance release without breaking changes.
+
+## 0.22.3 (2022-08-27)
+
+### Fix
+
+- restrict `sha1` `asm` to supported archs ([`b383fab`](https://github.com/Byron/gitoxide/commit/b383fabbe10868317be51b99cfdd9b0981816042))
+
+## 0.22.2 (2022-08-24)
+
+<csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/>
+
+### Chore
+
+ - <csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> uniformize deny attributes
+
+### New Features
+
+ - <csr-id-b1c40b0364ef092cd52d03b34f491b254816b18d/> use docsrs feature in code to show what is feature-gated automatically on docs.rs
+ - <csr-id-517677147f1c17304c62cf97a1dd09f232ebf5db/> pass --cfg docsrs when compiling for https://docs.rs
+
+## 0.22.1 (2022-08-15)
+
+### New Features
+
+ - <csr-id-f498d35baba52e40ecd47381e87c1ce49cf13285/> add `fs-jwalk-single-threaded` feature to specifically decouple `jwalk` from rayon
+ It has been an issue in https://github.com/starship/starship/issues/4251
+ apparently and rayon interactions can be difficult.
+ - <csr-id-7f199f0e5246809efde9880110093fbd11a4f8fe/> `fs::Snapshot` to on-demand reload shared resources.
+
+## 0.22.0 (2022-07-22)
+
+### New Features
+
+ - <csr-id-c76fde7de278b49ded13b655d5345e4eb8c1b134/> initialize `Time` from `now_utc` and `now_local`
+ Localtime support depends on some other factors now, but that
+ will only get better over time.
+
+ We might have to document `unsound_local_time` at some point.
+
+### Changed (BREAKING)
+
+ - <csr-id-89a41bf2b37db29b9983b4e5492cfd67ed490b23/> remove local-time-support feature toggle.
+ We treat local time as default feature without a lot of fuzz, and
+ will eventually document that definitive support needs a compile
+ time switch in the compiler (`--cfg unsound_local_offset` or something).
+
+ One day it will perish. Failure is possible anyway and we will write
+ code to deal with it while minimizing the amount of system time
+ fetches when asking for the current local time.
+
+## 0.21.1 (2022-06-13)
+
+A maintenance release without user-facing changes.
+
+## 0.21.0 (2022-05-18)
+
+### Changed (BREAKING)
+
+ - <csr-id-90611ce1527618bcc738440bfc1ccc7a45319974/> remove `path` module in favor of `gix-path` crate
+
+### New Features (BREAKING)
+
+ - <csr-id-d078d6ee76a80d1dfaf71608c12d8a402bd670d4/> mild refactor of paths module to waste less on unix
+ Previously it might have performed find-and-replace on unix paths even
+ though they wouldn't have changed afterwards, yet costing an allocation.
+
+ There is also the realization that it should go into its own crate to have
+ neater import paths and more convenience.
+
+## 0.20.0 (2022-04-02)
+
+### New Features
+
+ - <csr-id-e4d6685064ad2b433f8acd3a74b320bf0169a994/> Add `gix_config::values::Path` for a typesafe git path
+ Add a `Path` type to the `gix_config::values` which
+ can be interpolated according to gits own path interpolation
+ rules.
+ - <csr-id-3c8581fc294c65c9eb42698969fe3263135a864e/> add new 'path' module for all path-related conversions
+ It's meant to unify all path and byte related handling to help assuring
+ encoding is handled correctly or at least similarly everywhere.
+ - <csr-id-15ff212b17087de93f259e366f4e4b821cfbc28e/> in-manifest and in-lib documentation of feature toggles
+
+### Bug Fixes
+
+ - <csr-id-234cd10ca55482ce1a840ce3244308d249895bcc/> Assure std::io::copy() doesn't hang when we cause an interrupt
+ The user can ask for interruptions which previously used the
+ error kind Interrupted. This however has special meaning and
+ usually means to retry.
+
+### New Features (BREAKING)
+
+ - <csr-id-8945d95f7fa88562d37ff67ac6e38bead73dd2df/> `interrupt::Iter`, rename `interrupt::Iter` -> `interrupt::IterWithError`
+
+## 0.19.1 (2022-01-23)
+
+<csr-id-361892ca15aa648802f6701ab6a5a30aedde3449/>
+
+A maintenance release thanks to upgrade to `prodash` 18.
+
+### Changed (BREAKING)
+
+ - <csr-id-61e5cfece4d8f405e35fc1957b00ce1da7526c26/> renamed `progress::Read::reader` -> `progress::Read::inner`
+
+### New Features
+
+ - <csr-id-cb7e4e784d615f9fa3d6fb9c36240f0592403358/> Add InOrderIter to 'parallel' module
+ This iterator makes possible identifies results using a sequence id
+ and returns only consecutive items.
+
+ Use it to collect unordered results produced by threads.
+ It's advantage to collecting yourself and sorting is the potential
+ for a smaller memory footprint of in-flight results, one doesn't
+ have to collect them all for ordering, necessarily.
+ - <csr-id-ca095ed881db2a8f06a6b067dbaac17e923b0945/> Make a scope-like abstraction available
+ This allows more delicate threading control like is required for the
+ index.
+ - <csr-id-b8400ed80543d67a5895c975ba9b1fc28427411c/> decoding of variable int numbers.
+ It's here only so that we can share the code across crates, for now
+ without any feature toggles.
+ - <csr-id-0a749a22057b5513a8cefa0e26b0a9a268c769d3/> Add `progress::Write` to automatically pass bytes written to a progress instance
+
+### Chore
+
+ - <csr-id-361892ca15aa648802f6701ab6a5a30aedde3449/> update sha-1 dependency to 0.10
+
+## 0.19.0 (2022-01-19)
+
+<csr-id-361892ca15aa648802f6701ab6a5a30aedde3449/>
+
+### Chore
+
+ - <csr-id-361892ca15aa648802f6701ab6a5a30aedde3449/> update sha-1 dependency to 0.10
+
+### New Features
+
+ - <csr-id-cb7e4e784d615f9fa3d6fb9c36240f0592403358/> Add InOrderIter to 'parallel' module
+ This iterator makes possible identifies results using a sequence id
+ and returns only consecutive items.
+
+ Use it to collect unordered results produced by threads.
+ It's advantage to collecting yourself and sorting is the potential
+ for a smaller memory footprint of in-flight results, one doesn't
+ have to collect them all for ordering, necessarily.
+ - <csr-id-ca095ed881db2a8f06a6b067dbaac17e923b0945/> Make a scope-like abstraction available
+ This allows more delicate threading control like is required for the
+ index.
+ - <csr-id-b8400ed80543d67a5895c975ba9b1fc28427411c/> decoding of variable int numbers.
+ It's here only so that we can share the code across crates, for now
+ without any feature toggles.
+ - <csr-id-0a749a22057b5513a8cefa0e26b0a9a268c769d3/> Add `progress::Write` to automatically pass bytes written to a progress instance
+
+### Changed (BREAKING)
+
+ - <csr-id-61e5cfece4d8f405e35fc1957b00ce1da7526c26/> renamed `progress::Read::reader` -> `progress::Read::inner`
+
+## 0.18.0 (2021-11-29)
+
+### New Features
+
+ - <csr-id-7e95d8ab29051ffc892f2dcbaf5369e8c7e7b294/> add threading primitives with feature toggle
+ If the `threading` feature is set, the `threading` module will contain thread-safe primitives
+ for shared ownership and mutation, otherwise these will be their single threaded counterparts.
+
+ This way, single-threaded applications don't have to pay for threaded primitives.
+
+### Changed (BREAKING)
+
+ - <csr-id-e7526b2a7b51cbac4018e1ab3b623a85987fadc2/> parallel utilities now use `Send + Clone` instead of `Send + Sync`
+ This helps to assure that thread-local computations always work with the
+ kind of types we provide. The ones that are carrying out actions are
+ notably not `Sync` anymore.
+
+ We cater to that by defining our bounds accordingly, but for those
+ who want to use other utilities that need Sync, using types like
+ `Repository` and `thread_local!()` is the only way to make this
+ work.
+
+## v0.17.0 (2021-10-19)
+
+A maintenance release due to properly dealing with previously breaking changes in `gix-hash`.
+
+## v0.16.5 (2021-10-15)
+
+This release contains no functional changes.
+
+## v0.16.4 (2021-09-07)
+
+## v0.16.3 (2021-08-27)
+
+## v0.16.2 (2021-08-17)
+
+## v0.16.1 (2021-08-10)
+
+## v0.16.0 (2021-08-10)
+
+## v0.14.0 (2021-05-08)
+
+## v0.13.0 (2021-04-30)
+
+## v0.12.0 (2021-04-08)
+
+## v0.11.0 (2021-01-24)
+
+## v0.10.1 (2021-01-24)
+
+## v0.10.0 (2020-12-16)
+
+## v0.9.0 (2020-12-15)
+
+## v0.8.0 (2020-11-26)
+
+## v0.7.0 (2020-11-18)
+
+## v0.6.0 (2020-09-14)
+
+## v0.5.0 (2020-09-12)
+
+## v0.4.0 (2020-08-18)
+
+## v0.3.0 (2020-08-12)
+
+## v0.2.0 (2020-07-23)
+
+## v0.1.0 (2020-07-12)
+
+<csr-id-ab6f98b905f13ed2a7c0c483f34fab63141fbc5b/>
+
+### Other
+
+ - <csr-id-ab6f98b905f13ed2a7c0c483f34fab63141fbc5b/> try-join with static typing works, but…
+ …seems like a lot of effort. Probably not worth continuing here
+
diff --git a/vendor/gix-features-0.35.0/Cargo.toml b/vendor/gix-features-0.35.0/Cargo.toml
new file mode 100644
index 000000000..114f245c1
--- /dev/null
+++ b/vendor/gix-features-0.35.0/Cargo.toml
@@ -0,0 +1,184 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2021"
+rust-version = "1.65"
+name = "gix-features"
+version = "0.35.0"
+authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"]
+description = "A crate to integrate various capabilities using compile-time feature flags"
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/Byron/gitoxide"
+
+[package.metadata.docs.rs]
+all-features = true
+features = ["document-features"]
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
+[lib]
+test = false
+doctest = false
+
+[[test]]
+name = "hash"
+path = "tests/hash.rs"
+required-features = ["rustsha1"]
+
+[[test]]
+name = "parallel"
+path = "tests/parallel_threaded.rs"
+required-features = [
+ "parallel",
+ "rustsha1",
+]
+
+[[test]]
+name = "multi-threaded"
+path = "tests/parallel_shared_threaded.rs"
+required-features = [
+ "parallel",
+ "rustsha1",
+]
+
+[[test]]
+name = "single-threaded"
+path = "tests/parallel_shared.rs"
+required-features = ["rustsha1"]
+
+[[test]]
+name = "pipe"
+path = "tests/pipe.rs"
+required-features = ["io-pipe"]
+
+[dependencies.bytes]
+version = "1.0.0"
+optional = true
+
+[dependencies.bytesize]
+version = "1.0.1"
+optional = true
+
+[dependencies.crc32fast]
+version = "1.2.1"
+optional = true
+
+[dependencies.crossbeam-channel]
+version = "0.5.0"
+optional = true
+
+[dependencies.document-features]
+version = "0.2.0"
+optional = true
+
+[dependencies.flate2]
+version = "1.0.25"
+optional = true
+default-features = false
+
+[dependencies.gix-hash]
+version = "^0.13.0"
+
+[dependencies.gix-trace]
+version = "^0.1.3"
+
+[dependencies.jwalk]
+version = "0.8.1"
+optional = true
+
+[dependencies.once_cell]
+version = "1.13.0"
+optional = true
+
+[dependencies.parking_lot]
+version = "0.12.0"
+optional = true
+default-features = false
+
+[dependencies.prodash]
+version = "26.2.2"
+optional = true
+default-features = false
+
+[dependencies.sha1]
+version = "0.10.0"
+optional = true
+
+[dependencies.sha1_smol]
+version = "1.0.0"
+optional = true
+
+[dependencies.thiserror]
+version = "1.0.38"
+optional = true
+
+[dependencies.walkdir]
+version = "2.3.2"
+optional = true
+
+[dev-dependencies.bstr]
+version = "1.3.0"
+default-features = false
+
+[features]
+cache-efficiency-debug = []
+crc32 = ["dep:crc32fast"]
+default = []
+fast-sha1 = ["dep:sha1"]
+fs-walkdir-parallel = ["dep:jwalk"]
+io-pipe = ["dep:bytes"]
+once_cell = ["dep:once_cell"]
+parallel = [
+ "dep:crossbeam-channel",
+ "dep:parking_lot",
+]
+progress = ["prodash"]
+progress-unit-bytes = [
+ "dep:bytesize",
+ "prodash?/unit-bytes",
+]
+progress-unit-human-numbers = ["prodash?/unit-human"]
+rustsha1 = ["dep:sha1_smol"]
+tracing = ["gix-trace/tracing"]
+tracing-detail = ["gix-trace/tracing-detail"]
+walkdir = ["dep:walkdir"]
+zlib = [
+ "dep:flate2",
+ "flate2?/rust_backend",
+ "dep:thiserror",
+]
+zlib-ng = [
+ "zlib",
+ "flate2?/zlib-ng",
+]
+zlib-ng-compat = [
+ "zlib",
+ "flate2?/zlib-ng-compat",
+]
+zlib-rust-backend = [
+ "zlib",
+ "flate2?/rust_backend",
+]
+zlib-stock = [
+ "zlib",
+ "flate2?/zlib",
+]
+
+[target."cfg(all(any(target_arch = \"aarch64\", target_arch = \"x86\", target_arch = \"x86_64\"), not(target_env = \"msvc\")))".dependencies.sha1]
+version = "0.10.0"
+features = ["asm"]
+optional = true
+
+[target."cfg(unix)".dependencies.libc]
+version = "0.2.119"
diff --git a/vendor/gix-features-0.35.0/LICENSE-APACHE b/vendor/gix-features-0.35.0/LICENSE-APACHE
new file mode 100644
index 000000000..a51f59a06
--- /dev/null
+++ b/vendor/gix-features-0.35.0/LICENSE-APACHE
@@ -0,0 +1,191 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ Copyright 2018-2021 Sebastian Thiel, and [contributors](https://github.com/byron/gitoxide/contributors)
+
+ 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.
diff --git a/vendor/gix-features-0.35.0/LICENSE-MIT b/vendor/gix-features-0.35.0/LICENSE-MIT
new file mode 100644
index 000000000..b58e818f1
--- /dev/null
+++ b/vendor/gix-features-0.35.0/LICENSE-MIT
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018-2021 Sebastian Thiel, and [contributors](https://github.com/byron/gitoxide/contributors).
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/gix-features-0.35.0/src/cache.rs b/vendor/gix-features-0.35.0/src/cache.rs
new file mode 100644
index 000000000..c56a34e12
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/cache.rs
@@ -0,0 +1,76 @@
+#[cfg(feature = "cache-efficiency-debug")]
+mod impl_ {
+ /// A helper to collect useful information about cache efficiency.
+ pub struct Debug {
+ owner: String,
+ hits: usize,
+ puts: usize,
+ misses: usize,
+ }
+
+ impl Debug {
+ /// Create a new instance
+ #[inline]
+ pub fn new(owner: String) -> Self {
+ Debug {
+ owner,
+ hits: 0,
+ puts: 0,
+ misses: 0,
+ }
+ }
+ /// Count cache insertions
+ #[inline]
+ pub fn put(&mut self) {
+ self.puts += 1;
+ }
+ /// Count hits
+ #[inline]
+ pub fn hit(&mut self) {
+ self.hits += 1;
+ }
+ /// Count misses
+ #[inline]
+ pub fn miss(&mut self) {
+ self.misses += 1;
+ }
+ }
+
+ impl Drop for Debug {
+ fn drop(&mut self) {
+ let hits = self.hits;
+ let misses = self.misses;
+ let ratio = hits as f32 / misses as f32;
+ eprintln!(
+ "{}[{:0x}]: {} / {} (hits/misses) = {:.02}%, puts = {}",
+ self.owner,
+ self as *const _ as usize,
+ hits,
+ misses,
+ ratio * 100.0,
+ self.puts
+ );
+ }
+ }
+}
+#[cfg(not(feature = "cache-efficiency-debug"))]
+mod impl_ {
+ /// The disabled, zero size do-nothing equivalent
+ pub struct Debug;
+
+ impl Debug {
+ /// Create a new instance
+ #[inline]
+ pub fn new(_owner: String) -> Self {
+ Debug
+ }
+ /// noop
+ pub fn put(&mut self) {}
+ /// noop
+ pub fn hit(&mut self) {}
+ /// noop
+ pub fn miss(&mut self) {}
+ }
+}
+
+pub use impl_::Debug;
diff --git a/vendor/gix-features-0.35.0/src/decode.rs b/vendor/gix-features-0.35.0/src/decode.rs
new file mode 100644
index 000000000..0df38710d
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/decode.rs
@@ -0,0 +1,38 @@
+use std::io::Read;
+
+/// Decode variable int numbers from a `Read` implementation.
+///
+/// Note: currently overflow checks are only done in debug mode.
+#[inline]
+pub fn leb64_from_read(mut r: impl Read) -> Result<(u64, usize), std::io::Error> {
+ let mut b = [0u8; 1];
+ let mut i = 0;
+ r.read_exact(&mut b)?;
+ i += 1;
+ let mut value = b[0] as u64 & 0x7f;
+ while b[0] & 0x80 != 0 {
+ r.read_exact(&mut b)?;
+ i += 1;
+ debug_assert!(i <= 10, "Would overflow value at 11th iteration");
+ value += 1;
+ value = (value << 7) + (b[0] as u64 & 0x7f)
+ }
+ Ok((value, i))
+}
+
+/// Decode variable int numbers.
+#[inline]
+pub fn leb64(d: &[u8]) -> (u64, usize) {
+ let mut i = 0;
+ let mut c = d[i];
+ i += 1;
+ let mut value = c as u64 & 0x7f;
+ while c & 0x80 != 0 {
+ c = d[i];
+ i += 1;
+ debug_assert!(i <= 10, "Would overflow value at 11th iteration");
+ value += 1;
+ value = (value << 7) + (c as u64 & 0x7f)
+ }
+ (value, i)
+}
diff --git a/vendor/gix-features-0.35.0/src/fs.rs b/vendor/gix-features-0.35.0/src/fs.rs
new file mode 100644
index 000000000..8b3a7d3e7
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/fs.rs
@@ -0,0 +1,118 @@
+//! Filesystem utilities
+//!
+//! These are will be parallel if the `parallel` feature is enabled, at the expense of compiling additional dependencies
+//! 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
+
+#[cfg(any(feature = "walkdir", feature = "fs-walkdir-parallel"))]
+mod shared {
+ /// The desired level of parallelism.
+ pub enum Parallelism {
+ /// Do not parallelize at all by making a serial traversal on the current thread.
+ Serial,
+ /// Create a new thread pool for each traversal with up to 16 threads or the amount of logical cores of the machine.
+ ThreadPoolPerTraversal {
+ /// The base name of the threads we create as part of the thread-pool.
+ thread_name: &'static str,
+ },
+ }
+}
+
+///
+#[cfg(feature = "fs-walkdir-parallel")]
+pub mod walkdir {
+ use std::path::Path;
+
+ pub use jwalk::{DirEntry as DirEntryGeneric, DirEntryIter as DirEntryIterGeneric, Error, WalkDir};
+
+ pub use super::shared::Parallelism;
+
+ /// An alias for an uncustomized directory entry to match the one of the non-parallel version offered by `walkdir`.
+ pub type DirEntry = DirEntryGeneric<((), ())>;
+
+ impl From<Parallelism> for jwalk::Parallelism {
+ fn from(v: Parallelism) -> Self {
+ match v {
+ Parallelism::Serial => jwalk::Parallelism::Serial,
+ Parallelism::ThreadPoolPerTraversal { thread_name } => std::thread::available_parallelism()
+ .map_or_else(
+ |_| Parallelism::Serial.into(),
+ |threads| {
+ let pool = jwalk::rayon::ThreadPoolBuilder::new()
+ .num_threads(threads.get().min(16))
+ .stack_size(128 * 1024)
+ .thread_name(move |idx| format!("{thread_name} {idx}"))
+ .build()
+ .expect("we only set options that can't cause a build failure");
+ jwalk::Parallelism::RayonExistingPool {
+ pool: pool.into(),
+ busy_timeout: None,
+ }
+ },
+ ),
+ }
+ }
+ }
+
+ /// Instantiate a new directory iterator which will not skip hidden files, with the given level of `parallelism`.
+ pub fn walkdir_new(root: &Path, parallelism: Parallelism) -> WalkDir {
+ WalkDir::new(root).skip_hidden(false).parallelism(parallelism.into())
+ }
+
+ /// Instantiate a new directory iterator which will not skip hidden files and is sorted
+ pub fn walkdir_sorted_new(root: &Path, parallelism: Parallelism) -> WalkDir {
+ WalkDir::new(root)
+ .skip_hidden(false)
+ .sort(true)
+ .parallelism(parallelism.into())
+ }
+
+ /// The Iterator yielding directory items
+ pub type DirEntryIter = DirEntryIterGeneric<((), ())>;
+}
+
+#[cfg(all(feature = "walkdir", not(feature = "fs-walkdir-parallel")))]
+///
+pub mod walkdir {
+ use std::path::Path;
+
+ pub use walkdir::{DirEntry, Error, WalkDir};
+
+ pub use super::shared::Parallelism;
+
+ /// Instantiate a new directory iterator which will not skip hidden files, with the given level of `parallelism`.
+ pub fn walkdir_new(root: &Path, _: Parallelism) -> WalkDir {
+ WalkDir::new(root)
+ }
+
+ /// Instantiate a new directory iterator which will not skip hidden files and is sorted, with the given level of `parallelism`.
+ pub fn walkdir_sorted_new(root: &Path, _: Parallelism) -> WalkDir {
+ WalkDir::new(root).sort_by_file_name()
+ }
+
+ /// The Iterator yielding directory items
+ pub type DirEntryIter = walkdir::IntoIter;
+}
+
+#[cfg(any(feature = "walkdir", feature = "fs-walkdir-parallel"))]
+pub use self::walkdir::{walkdir_new, walkdir_sorted_new, WalkDir};
+
+/// Prepare open options which won't follow symlinks when the file is opened.
+///
+/// Note: only effective on unix currently.
+pub fn open_options_no_follow() -> std::fs::OpenOptions {
+ #[cfg_attr(not(unix), allow(unused_mut))]
+ let mut options = std::fs::OpenOptions::new();
+ #[cfg(unix)]
+ {
+ /// Make sure that it's impossible to follow through to the target of symlinks.
+ /// Note that this will still follow symlinks in the path, which is what we assume
+ /// has been checked separately.
+ use std::os::unix::fs::OpenOptionsExt;
+ options.custom_flags(libc::O_NOFOLLOW);
+ }
+ options
+}
diff --git a/vendor/gix-features-0.35.0/src/hash.rs b/vendor/gix-features-0.35.0/src/hash.rs
new file mode 100644
index 000000000..435e018e9
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/hash.rs
@@ -0,0 +1,190 @@
+//! Hash functions and hash utilities
+//!
+//! With the `fast-sha1` feature, the `Sha1` hash type will use a more elaborate implementation utilizing hardware support
+//! in case it is available. Otherwise the `rustsha1` feature should be set. `fast-sha1` will take precedence.
+//! Otherwise, a minimal yet performant implementation is used instead for a decent trade-off between compile times and run-time performance.
+#[cfg(all(feature = "rustsha1", not(feature = "fast-sha1")))]
+mod _impl {
+ use super::Sha1Digest;
+
+ /// A implementation of the Sha1 hash, which can be used once.
+ #[derive(Default, Clone)]
+ pub struct Sha1(sha1_smol::Sha1);
+
+ impl Sha1 {
+ /// Digest the given `bytes`.
+ pub fn update(&mut self, bytes: &[u8]) {
+ self.0.update(bytes)
+ }
+ /// Finalize the hash and produce a digest.
+ pub fn digest(self) -> Sha1Digest {
+ self.0.digest().bytes()
+ }
+ }
+}
+
+/// A 20 bytes digest produced by a [`Sha1`] hash implementation.
+#[cfg(any(feature = "fast-sha1", feature = "rustsha1"))]
+pub type Sha1Digest = [u8; 20];
+
+#[cfg(feature = "fast-sha1")]
+mod _impl {
+ use sha1::Digest;
+
+ use super::Sha1Digest;
+
+ /// A implementation of the Sha1 hash, which can be used once.
+ #[derive(Default, Clone)]
+ pub struct Sha1(sha1::Sha1);
+
+ impl Sha1 {
+ /// Digest the given `bytes`.
+ pub fn update(&mut self, bytes: &[u8]) {
+ self.0.update(bytes)
+ }
+ /// Finalize the hash and produce a digest.
+ pub fn digest(self) -> Sha1Digest {
+ self.0.finalize().into()
+ }
+ }
+}
+
+#[cfg(any(feature = "rustsha1", feature = "fast-sha1"))]
+pub use _impl::Sha1;
+
+/// Compute a CRC32 hash from the given `bytes`, returning the CRC32 hash.
+///
+/// When calling this function for the first time, `previous_value` should be `0`. Otherwise it
+/// should be the previous return value of this function to provide a hash of multiple sequential
+/// chunks of `bytes`.
+#[cfg(feature = "crc32")]
+pub fn crc32_update(previous_value: u32, bytes: &[u8]) -> u32 {
+ let mut h = crc32fast::Hasher::new_with_initial(previous_value);
+ h.update(bytes);
+ h.finalize()
+}
+
+/// Compute a CRC32 value of the given input `bytes`.
+///
+/// In case multiple chunks of `bytes` are present, one should use [`crc32_update()`] instead.
+#[cfg(feature = "crc32")]
+pub fn crc32(bytes: &[u8]) -> u32 {
+ let mut h = crc32fast::Hasher::new();
+ h.update(bytes);
+ h.finalize()
+}
+
+/// Produce a hasher suitable for the given kind of hash.
+#[cfg(any(feature = "rustsha1", feature = "fast-sha1"))]
+pub fn hasher(kind: gix_hash::Kind) -> Sha1 {
+ match kind {
+ gix_hash::Kind::Sha1 => Sha1::default(),
+ }
+}
+
+/// Compute the hash of `kind` for the bytes in the file at `path`, hashing only the first `num_bytes_from_start`
+/// while initializing and calling `progress`.
+///
+/// `num_bytes_from_start` is useful to avoid reading trailing hashes, which are never part of the hash itself,
+/// denoting the amount of bytes to hash starting from the beginning of the file.
+///
+/// # Note
+///
+/// * Only available with the `gix-object` feature enabled due to usage of the [`gix_hash::Kind`] enum and the
+/// [`gix_hash::ObjectId`] return value.
+/// * [Interrupts][crate::interrupt] are supported.
+#[cfg(all(feature = "progress", any(feature = "rustsha1", feature = "fast-sha1")))]
+pub fn bytes_of_file(
+ path: &std::path::Path,
+ num_bytes_from_start: usize,
+ kind: gix_hash::Kind,
+ progress: &mut dyn crate::progress::Progress,
+ should_interrupt: &std::sync::atomic::AtomicBool,
+) -> std::io::Result<gix_hash::ObjectId> {
+ bytes(
+ &mut std::fs::File::open(path)?,
+ num_bytes_from_start,
+ kind,
+ progress,
+ should_interrupt,
+ )
+}
+
+/// Similar to [`bytes_of_file`], but operates on an already open file.
+#[cfg(all(feature = "progress", any(feature = "rustsha1", feature = "fast-sha1")))]
+pub fn bytes(
+ read: &mut dyn std::io::Read,
+ num_bytes_from_start: usize,
+ kind: gix_hash::Kind,
+ progress: &mut dyn crate::progress::Progress,
+ should_interrupt: &std::sync::atomic::AtomicBool,
+) -> std::io::Result<gix_hash::ObjectId> {
+ let mut hasher = hasher(kind);
+ let start = std::time::Instant::now();
+ // init progress before the possibility for failure, as convenience in case people want to recover
+ progress.init(Some(num_bytes_from_start), crate::progress::bytes());
+
+ const BUF_SIZE: usize = u16::MAX as usize;
+ let mut buf = [0u8; BUF_SIZE];
+ let mut bytes_left = num_bytes_from_start;
+
+ while bytes_left > 0 {
+ let out = &mut buf[..BUF_SIZE.min(bytes_left)];
+ read.read_exact(out)?;
+ bytes_left -= out.len();
+ progress.inc_by(out.len());
+ hasher.update(out);
+ if should_interrupt.load(std::sync::atomic::Ordering::SeqCst) {
+ return Err(std::io::Error::new(std::io::ErrorKind::Other, "Interrupted"));
+ }
+ }
+
+ let id = gix_hash::ObjectId::from(hasher.digest());
+ progress.show_throughput(start);
+ Ok(id)
+}
+
+#[cfg(any(feature = "rustsha1", feature = "fast-sha1"))]
+mod write {
+ use crate::hash::Sha1;
+
+ /// A utility to automatically generate a hash while writing into an inner writer.
+ pub struct Write<T> {
+ /// The hash implementation.
+ pub hash: Sha1,
+ /// The inner writer.
+ pub inner: T,
+ }
+
+ impl<T> std::io::Write for Write<T>
+ where
+ T: std::io::Write,
+ {
+ fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+ let written = self.inner.write(buf)?;
+ self.hash.update(&buf[..written]);
+ Ok(written)
+ }
+
+ fn flush(&mut self) -> std::io::Result<()> {
+ self.inner.flush()
+ }
+ }
+
+ impl<T> Write<T>
+ where
+ T: std::io::Write,
+ {
+ /// Create a new hash writer which hashes all bytes written to `inner` with a hash of `kind`.
+ pub fn new(inner: T, object_hash: gix_hash::Kind) -> Self {
+ match object_hash {
+ gix_hash::Kind::Sha1 => Write {
+ inner,
+ hash: Sha1::default(),
+ },
+ }
+ }
+ }
+}
+#[cfg(any(feature = "rustsha1", feature = "fast-sha1"))]
+pub use write::Write;
diff --git a/vendor/gix-features-0.35.0/src/interrupt.rs b/vendor/gix-features-0.35.0/src/interrupt.rs
new file mode 100644
index 000000000..dc7a2db17
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/interrupt.rs
@@ -0,0 +1,161 @@
+//! Utilities to cause interruptions in common traits, like Read/Write and Iterator.
+use std::{
+ io,
+ sync::atomic::{AtomicBool, Ordering},
+};
+
+/// A wrapper for an inner iterator which will check for interruptions on each iteration, stopping the iteration when
+/// that is requested.
+pub struct Iter<'a, I> {
+ /// The actual iterator to yield elements from.
+ pub inner: I,
+ should_interrupt: &'a AtomicBool,
+}
+
+impl<'a, I> Iter<'a, I>
+where
+ I: Iterator,
+{
+ /// Create a new iterator over `inner` which checks for interruptions on each iteration on `should_interrupt`.
+ ///
+ /// Note that this means the consumer of the iterator data should also be able to access `should_interrupt` and
+ /// consider it when producing the final result to avoid claiming success even though the operation is only partially
+ /// complete.
+ pub fn new(inner: I, should_interrupt: &'a AtomicBool) -> Self {
+ Iter {
+ inner,
+ should_interrupt,
+ }
+ }
+}
+
+impl<'a, I> Iterator for Iter<'a, I>
+where
+ I: Iterator,
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.should_interrupt.load(Ordering::Relaxed) {
+ return None;
+ }
+ self.inner.next()
+ }
+}
+
+/// A wrapper for an inner iterator which will check for interruptions on each iteration.
+pub struct IterWithErr<'a, I, EFN> {
+ /// The actual iterator to yield elements from.
+ pub inner: I,
+ make_err: Option<EFN>,
+ should_interrupt: &'a AtomicBool,
+}
+
+impl<'a, I, EFN, E> IterWithErr<'a, I, EFN>
+where
+ I: Iterator,
+ EFN: FnOnce() -> E,
+{
+ /// Create a new iterator over `inner` which checks for interruptions on each iteration and calls `make_err()` to
+ /// signal an interruption happened, causing no further items to be iterated from that point on.
+ pub fn new(inner: I, make_err: EFN, should_interrupt: &'a AtomicBool) -> Self {
+ IterWithErr {
+ inner,
+ make_err: Some(make_err),
+ should_interrupt,
+ }
+ }
+}
+
+impl<'a, I, EFN, E> Iterator for IterWithErr<'a, I, EFN>
+where
+ I: Iterator,
+ EFN: FnOnce() -> E,
+{
+ type Item = Result<I::Item, E>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.make_err.as_ref()?;
+ if self.should_interrupt.load(Ordering::Relaxed) {
+ return self.make_err.take().map(|f| Err(f()));
+ }
+ match self.inner.next() {
+ Some(next) => Some(Ok(next)),
+ None => {
+ self.make_err = None;
+ None
+ }
+ }
+ }
+}
+
+/// A wrapper for implementors of [`std::io::Read`] or [`std::io::BufRead`] with interrupt support.
+///
+/// It fails a [read][std::io::Read::read] while an interrupt was requested.
+pub struct Read<'a, R> {
+ /// The actual implementor of [`std::io::Read`] to which interrupt support will be added.
+ pub inner: R,
+ /// The flag to trigger interruption
+ pub should_interrupt: &'a AtomicBool,
+}
+
+impl<'a, R> io::Read for Read<'a, R>
+where
+ R: io::Read,
+{
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ if self.should_interrupt.load(Ordering::Relaxed) {
+ return Err(std::io::Error::new(std::io::ErrorKind::Other, "Interrupted"));
+ }
+ self.inner.read(buf)
+ }
+}
+
+impl<'a, R> io::BufRead for Read<'a, R>
+where
+ R: io::BufRead,
+{
+ fn fill_buf(&mut self) -> io::Result<&[u8]> {
+ self.inner.fill_buf()
+ }
+
+ fn consume(&mut self, amt: usize) {
+ self.inner.consume(amt)
+ }
+}
+
+/// A wrapper for implementors of [`std::io::Write`] with interrupt checks on each write call.
+///
+/// It fails a [write][std::io::Write::write] while an interrupt was requested.
+pub struct Write<'a, W> {
+ /// The actual implementor of [`std::io::Write`] to which interrupt support will be added.
+ pub inner: W,
+ /// The flag to trigger interruption
+ pub should_interrupt: &'a AtomicBool,
+}
+
+impl<W> io::Write for Write<'_, W>
+where
+ W: std::io::Write,
+{
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ if self.should_interrupt.load(Ordering::Relaxed) {
+ return Err(std::io::Error::new(std::io::ErrorKind::Other, "Interrupted"));
+ }
+ self.inner.write(buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ // Don't interrupt here, allow flushes to happen to prefer disk consistency.
+ self.inner.flush()
+ }
+}
+
+impl<W> io::Seek for Write<'_, W>
+where
+ W: std::io::Seek,
+{
+ fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
+ self.inner.seek(pos)
+ }
+}
diff --git a/vendor/gix-features-0.35.0/src/io.rs b/vendor/gix-features-0.35.0/src/io.rs
new file mode 100644
index 000000000..fba273693
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/io.rs
@@ -0,0 +1,94 @@
+//!A unidirectional pipe for bytes, analogous to a unix pipe. Available with the `io-pipe` feature toggle.
+
+/// A unidirectional pipe for bytes, analogous to a unix pipe. Available with the `io-pipe` feature toggle.
+#[cfg(feature = "io-pipe")]
+pub mod pipe {
+ use std::io;
+
+ use bytes::{Buf, BufMut, BytesMut};
+
+ /// The write-end of the pipe, receiving items to become available in the [`Reader`].
+ ///
+ /// It's commonly used with the [`std::io::Write`] trait it implements.
+ pub struct Writer {
+ /// The channel through which bytes are transferred. Useful for sending [`std::io::Error`]s instead.
+ pub channel: std::sync::mpsc::SyncSender<io::Result<BytesMut>>,
+ buf: BytesMut,
+ }
+
+ /// The read-end of the pipe, implementing the [`std::io::Read`] trait.
+ pub struct Reader {
+ channel: std::sync::mpsc::Receiver<io::Result<BytesMut>>,
+ buf: BytesMut,
+ }
+
+ impl io::BufRead for Reader {
+ fn fill_buf(&mut self) -> io::Result<&[u8]> {
+ if self.buf.is_empty() {
+ match self.channel.recv() {
+ Ok(Ok(buf)) => self.buf = buf,
+ Ok(Err(err)) => return Err(err),
+ Err(_) => {}
+ }
+ };
+ Ok(&self.buf)
+ }
+
+ fn consume(&mut self, amt: usize) {
+ self.buf.advance(amt.min(self.buf.len()));
+ }
+ }
+
+ impl io::Read for Reader {
+ fn read(&mut self, mut out: &mut [u8]) -> io::Result<usize> {
+ let mut written = 0;
+ while !out.is_empty() {
+ if self.buf.is_empty() {
+ match self.channel.recv() {
+ Ok(Ok(buf)) => self.buf = buf,
+ Ok(Err(err)) => return Err(err),
+ Err(_) => break,
+ }
+ }
+ let bytes_to_write = self.buf.len().min(out.len());
+ let (to_write, rest) = out.split_at_mut(bytes_to_write);
+ self.buf.split_to(bytes_to_write).copy_to_slice(to_write);
+ out = rest;
+ written += bytes_to_write;
+ }
+ Ok(written)
+ }
+ }
+
+ impl io::Write for Writer {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.buf.put_slice(buf);
+ self.channel
+ .send(Ok(self.buf.split()))
+ .map_err(|err| io::Error::new(io::ErrorKind::BrokenPipe, err))?;
+ Ok(buf.len())
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ Ok(())
+ }
+ }
+
+ /// Returns the _([`write`][Writer], [`read`][Reader])_ ends of a pipe for transferring bytes, analogous to a unix pipe.
+ ///
+ /// * `in_flight_writes` defines the amount of chunks of bytes to keep in memory until the `write` end will block when writing.
+ /// If `0`, the `write` end will always block until the `read` end consumes the transferred bytes.
+ pub fn unidirectional(in_flight_writes: usize) -> (Writer, Reader) {
+ let (tx, rx) = std::sync::mpsc::sync_channel(in_flight_writes);
+ (
+ Writer {
+ channel: tx,
+ buf: BytesMut::with_capacity(4096),
+ },
+ Reader {
+ channel: rx,
+ buf: BytesMut::new(),
+ },
+ )
+ }
+}
diff --git a/vendor/gix-features-0.35.0/src/lib.rs b/vendor/gix-features-0.35.0/src/lib.rs
new file mode 100644
index 000000000..f343b2647
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/lib.rs
@@ -0,0 +1,66 @@
+//! A crate providing foundational capabilities to other `git-*` crates with trade-offs between compile time, binary size or speed
+//! selectable using cargo feature toggles.
+//!
+//! It's designed to allow the application level crate to configure feature toggles, affecting all other `git-*` crates using
+//! this one.
+//!
+//! Thus all features provided here commonly have a 'cheap' base implementation, with the option to pull in
+//! counterparts with higher performance.
+//! ## Feature Flags
+#![cfg_attr(
+ feature = "document-features",
+ cfg_attr(doc, doc = ::document_features::document_features!())
+)]
+#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
+#![deny(missing_docs, rust_2018_idioms, unsafe_code)]
+
+///
+pub mod cache;
+///
+pub mod decode;
+pub mod fs;
+pub mod hash;
+pub mod interrupt;
+#[cfg(feature = "io-pipe")]
+pub mod io;
+pub mod parallel;
+#[cfg(feature = "progress")]
+pub mod progress;
+pub mod threading;
+pub use gix_trace as trace;
+
+///
+#[cfg(feature = "zlib")]
+pub mod zlib;
+
+///
+pub mod iter {
+ /// An iterator over chunks of input, producing `Vec<Item>` with a size of `size`, with the last chunk being the remainder and thus
+ /// potentially smaller than `size`.
+ pub struct Chunks<I> {
+ /// The inner iterator to ask for items.
+ pub inner: I,
+ /// The size of chunks to produce
+ pub size: usize,
+ }
+
+ impl<I, Item> Iterator for Chunks<I>
+ where
+ I: Iterator<Item = Item>,
+ {
+ type Item = Vec<Item>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let mut res = Vec::with_capacity(self.size);
+ let mut items_left = self.size;
+ for item in &mut self.inner {
+ res.push(item);
+ items_left -= 1;
+ if items_left == 0 {
+ break;
+ }
+ }
+ (!res.is_empty()).then_some(res)
+ }
+ }
+}
diff --git a/vendor/gix-features-0.35.0/src/parallel/eager_iter.rs b/vendor/gix-features-0.35.0/src/parallel/eager_iter.rs
new file mode 100644
index 000000000..9a1735f72
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/parallel/eager_iter.rs
@@ -0,0 +1,124 @@
+/// Evaluate any iterator in their own thread.
+///
+/// This is particularly useful if the wrapped iterator performs IO and/or heavy computations.
+/// Use [`EagerIter::new()`] for instantiation.
+pub struct EagerIter<I: Iterator> {
+ receiver: std::sync::mpsc::Receiver<Vec<I::Item>>,
+ chunk: Option<std::vec::IntoIter<I::Item>>,
+ size_hint: (usize, Option<usize>),
+}
+
+impl<I> EagerIter<I>
+where
+ I: Iterator + Send + 'static,
+ <I as Iterator>::Item: Send,
+{
+ /// Return a new `EagerIter` which evaluates `iter` in its own thread,
+ /// with a given `chunk_size` allowing a maximum `chunks_in_flight`.
+ ///
+ /// * `chunk_size` describes how many items returned by `iter` will be a single item of this `EagerIter`.
+ /// This helps to reduce the overhead imposed by transferring many small items.
+ /// If this number is 1, each item will become a single chunk. 0 is invalid.
+ /// * `chunks_in_flight` describes how many chunks can be kept in memory in case the consumer of the `EagerIter`s items
+ /// isn't consuming them fast enough. Setting this number to 0 effectively turns off any caching, but blocks `EagerIter`
+ /// if its items aren't consumed fast enough.
+ pub fn new(iter: I, chunk_size: usize, chunks_in_flight: usize) -> Self {
+ let (sender, receiver) = std::sync::mpsc::sync_channel(chunks_in_flight);
+ let size_hint = iter.size_hint();
+ assert!(chunk_size > 0, "non-zero chunk size is needed");
+
+ std::thread::spawn(move || {
+ let mut out = Vec::with_capacity(chunk_size);
+ for item in iter {
+ out.push(item);
+ if out.len() == chunk_size {
+ if sender.send(out).is_err() {
+ return;
+ }
+ out = Vec::with_capacity(chunk_size);
+ }
+ }
+ if !out.is_empty() {
+ sender.send(out).ok();
+ }
+ });
+ EagerIter {
+ receiver,
+ chunk: None,
+ size_hint,
+ }
+ }
+
+ fn fill_buf_and_pop(&mut self) -> Option<I::Item> {
+ self.chunk = self.receiver.recv().ok().map(|v| {
+ assert!(!v.is_empty());
+ v.into_iter()
+ });
+ self.chunk.as_mut().and_then(Iterator::next)
+ }
+}
+
+impl<I> Iterator for EagerIter<I>
+where
+ I: Iterator + Send + 'static,
+ <I as Iterator>::Item: Send,
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.chunk.as_mut() {
+ Some(chunk) => chunk.next().or_else(|| self.fill_buf_and_pop()),
+ None => self.fill_buf_and_pop(),
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.size_hint
+ }
+}
+
+/// An conditional `EagerIter`, which may become a just-in-time iterator running in the main thread depending on a condition.
+pub enum EagerIterIf<I: Iterator> {
+ /// A separate thread will eagerly evaluate iterator `I`.
+ Eager(EagerIter<I>),
+ /// The current thread evaluates `I`.
+ OnDemand(I),
+}
+
+impl<I> EagerIterIf<I>
+where
+ I: Iterator + Send + 'static,
+ <I as Iterator>::Item: Send,
+{
+ /// Return a new `EagerIterIf` if `condition()` returns true.
+ ///
+ /// For all other parameters, please see [`EagerIter::new()`].
+ pub fn new(condition: impl FnOnce() -> bool, iter: I, chunk_size: usize, chunks_in_flight: usize) -> Self {
+ if condition() {
+ EagerIterIf::Eager(EagerIter::new(iter, chunk_size, chunks_in_flight))
+ } else {
+ EagerIterIf::OnDemand(iter)
+ }
+ }
+}
+impl<I> Iterator for EagerIterIf<I>
+where
+ I: Iterator + Send + 'static,
+ <I as Iterator>::Item: Send,
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self {
+ EagerIterIf::OnDemand(i) => i.next(),
+ EagerIterIf::Eager(i) => i.next(),
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ match self {
+ EagerIterIf::OnDemand(i) => i.size_hint(),
+ EagerIterIf::Eager(i) => i.size_hint(),
+ }
+ }
+}
diff --git a/vendor/gix-features-0.35.0/src/parallel/in_order.rs b/vendor/gix-features-0.35.0/src/parallel/in_order.rs
new file mode 100644
index 000000000..7928ac692
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/parallel/in_order.rs
@@ -0,0 +1,83 @@
+use std::{cmp::Ordering, collections::BTreeMap};
+
+/// A counter for items that are in sequence, to be able to put them back into original order later.
+pub type SequenceId = usize;
+
+/// An iterator which olds iterated items with a **sequential** ID starting at 0 long enough to dispense them in order.
+pub struct InOrderIter<T, I> {
+ /// The iterator yielding the out-of-order elements we are to yield in order.
+ pub inner: I,
+ store: BTreeMap<SequenceId, T>,
+ next_chunk: SequenceId,
+ is_done: bool,
+}
+
+impl<T, E, I> From<I> for InOrderIter<T, I>
+where
+ I: Iterator<Item = Result<(SequenceId, T), E>>,
+{
+ fn from(iter: I) -> Self {
+ InOrderIter {
+ inner: iter,
+ store: Default::default(),
+ next_chunk: 0,
+ is_done: false,
+ }
+ }
+}
+
+impl<T, E, I> Iterator for InOrderIter<T, I>
+where
+ I: Iterator<Item = Result<(SequenceId, T), E>>,
+{
+ type Item = Result<T, E>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.is_done {
+ return None;
+ }
+ 'find_next_in_sequence: loop {
+ match self.inner.next() {
+ Some(Ok((c, v))) => match c.cmp(&self.next_chunk) {
+ Ordering::Equal => {
+ self.next_chunk += 1;
+ return Some(Ok(v));
+ }
+ Ordering::Less => {
+ unreachable!("in a correctly ordered sequence we can never see keys again, got {}", c)
+ }
+ Ordering::Greater => {
+ let previous = self.store.insert(c, v);
+ assert!(
+ previous.is_none(),
+ "Chunks are returned only once, input is an invalid sequence"
+ );
+ if let Some(v) = self.store.remove(&self.next_chunk) {
+ self.next_chunk += 1;
+ return Some(Ok(v));
+ }
+ continue 'find_next_in_sequence;
+ }
+ },
+ Some(Err(e)) => {
+ self.is_done = true;
+ self.store.clear();
+ return Some(Err(e));
+ }
+ None => match self.store.remove(&self.next_chunk) {
+ Some(v) => {
+ self.next_chunk += 1;
+ return Some(Ok(v));
+ }
+ None => {
+ debug_assert!(
+ self.store.is_empty(),
+ "When iteration is done we should not have stored items left"
+ );
+ return None;
+ }
+ },
+ }
+ }
+ }
+}
diff --git a/vendor/gix-features-0.35.0/src/parallel/in_parallel.rs b/vendor/gix-features-0.35.0/src/parallel/in_parallel.rs
new file mode 100644
index 000000000..a80762bad
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/parallel/in_parallel.rs
@@ -0,0 +1,301 @@
+use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering};
+
+use crate::parallel::{num_threads, Reduce};
+
+/// A scope to start threads within.
+pub type Scope<'scope, 'env> = std::thread::Scope<'scope, 'env>;
+
+/// Runs `left` and `right` in parallel, returning their output when both are done.
+pub fn join<O1: Send, O2: Send>(left: impl FnOnce() -> O1 + Send, right: impl FnOnce() -> O2 + Send) -> (O1, O2) {
+ std::thread::scope(|s| {
+ let left = std::thread::Builder::new()
+ .name("gitoxide.join.left".into())
+ .spawn_scoped(s, left)
+ .expect("valid name");
+ let right = std::thread::Builder::new()
+ .name("gitoxide.join.right".into())
+ .spawn_scoped(s, right)
+ .expect("valid name");
+ (left.join().unwrap(), right.join().unwrap())
+ })
+}
+
+/// Runs `f` with a scope to be used for spawning threads that will not outlive the function call.
+/// That way it's possible to handle threads without needing the 'static lifetime for data they interact with.
+///
+/// Note that the threads should not rely on actual parallelism as threading might be turned off entirely, hence should not
+/// connect each other with channels as deadlock would occur in single-threaded mode.
+pub fn threads<'env, F, R>(f: F) -> R
+where
+ F: for<'scope> FnOnce(&'scope std::thread::Scope<'scope, 'env>) -> R,
+{
+ std::thread::scope(f)
+}
+
+/// Create a builder for threads which allows them to be spawned into a scope and configured prior to spawning.
+pub fn build_thread() -> std::thread::Builder {
+ std::thread::Builder::new()
+}
+
+/// Read items from `input` and `consume` them in multiple threads,
+/// whose output output is collected by a `reducer`. Its task is to
+/// aggregate these outputs into the final result returned by this function with the benefit of not having to be thread-safe.
+///
+/// * if `thread_limit` is `Some`, the given amount of threads will be used. If `None`, all logical cores will be used.
+/// * `new_thread_state(thread_number) -> State` produces thread-local state once per thread to be based to `consume`
+/// * `consume(Item, &mut State) -> Output` produces an output given an input obtained by `input` along with mutable state initially
+/// created by `new_thread_state(…)`.
+/// * For `reducer`, see the [`Reduce`] trait
+pub fn in_parallel<I, S, O, R>(
+ input: impl Iterator<Item = I> + Send,
+ thread_limit: Option<usize>,
+ new_thread_state: impl FnOnce(usize) -> S + Send + Clone,
+ consume: impl FnMut(I, &mut S) -> O + Send + Clone,
+ mut reducer: R,
+) -> Result<<R as Reduce>::Output, <R as Reduce>::Error>
+where
+ R: Reduce<Input = O>,
+ I: Send,
+ O: Send,
+{
+ let num_threads = num_threads(thread_limit);
+ std::thread::scope(move |s| {
+ let receive_result = {
+ let (send_input, receive_input) = crossbeam_channel::bounded::<I>(num_threads);
+ let (send_result, receive_result) = crossbeam_channel::bounded::<O>(num_threads);
+ for thread_id in 0..num_threads {
+ std::thread::Builder::new()
+ .name(format!("gitoxide.in_parallel.produce.{thread_id}"))
+ .spawn_scoped(s, {
+ let send_result = send_result.clone();
+ let receive_input = receive_input.clone();
+ let new_thread_state = new_thread_state.clone();
+ let mut consume = consume.clone();
+ move || {
+ let mut state = new_thread_state(thread_id);
+ for item in receive_input {
+ if send_result.send(consume(item, &mut state)).is_err() {
+ break;
+ }
+ }
+ }
+ })
+ .expect("valid name");
+ }
+ std::thread::Builder::new()
+ .name("gitoxide.in_parallel.feed".into())
+ .spawn_scoped(s, move || {
+ for item in input {
+ if send_input.send(item).is_err() {
+ break;
+ }
+ }
+ })
+ .expect("valid name");
+ receive_result
+ };
+
+ for item in receive_result {
+ drop(reducer.feed(item)?);
+ }
+ reducer.finalize()
+ })
+}
+
+/// Read items from `input` and `consume` them in multiple threads,
+/// whose output output is collected by a `reducer`. Its task is to
+/// aggregate these outputs into the final result returned by this function with the benefit of not having to be thread-safe.
+/// Caall `finalize` to finish the computation, once per thread, if there was no error sending results earlier.
+///
+/// * if `thread_limit` is `Some`, the given amount of threads will be used. If `None`, all logical cores will be used.
+/// * `new_thread_state(thread_number) -> State` produces thread-local state once per thread to be based to `consume`
+/// * `consume(Item, &mut State) -> Output` produces an output given an input obtained by `input` along with mutable state initially
+/// created by `new_thread_state(…)`.
+/// * `finalize(State) -> Output` is called to potentially process remaining work that was placed in `State`.
+/// * For `reducer`, see the [`Reduce`] trait
+pub fn in_parallel_with_finalize<I, S, O, R>(
+ input: impl Iterator<Item = I> + Send,
+ thread_limit: Option<usize>,
+ new_thread_state: impl FnOnce(usize) -> S + Send + Clone,
+ consume: impl FnMut(I, &mut S) -> O + Send + Clone,
+ finalize: impl FnOnce(S) -> O + Send + Clone,
+ mut reducer: R,
+) -> Result<<R as Reduce>::Output, <R as Reduce>::Error>
+where
+ R: Reduce<Input = O>,
+ I: Send,
+ O: Send,
+{
+ let num_threads = num_threads(thread_limit);
+ std::thread::scope(move |s| {
+ let receive_result = {
+ let (send_input, receive_input) = crossbeam_channel::bounded::<I>(num_threads);
+ let (send_result, receive_result) = crossbeam_channel::bounded::<O>(num_threads);
+ for thread_id in 0..num_threads {
+ std::thread::Builder::new()
+ .name(format!("gitoxide.in_parallel.produce.{thread_id}"))
+ .spawn_scoped(s, {
+ let send_result = send_result.clone();
+ let receive_input = receive_input.clone();
+ let new_thread_state = new_thread_state.clone();
+ let mut consume = consume.clone();
+ let finalize = finalize.clone();
+ move || {
+ let mut state = new_thread_state(thread_id);
+ let mut can_send = true;
+ for item in receive_input {
+ if send_result.send(consume(item, &mut state)).is_err() {
+ can_send = false;
+ break;
+ }
+ }
+ if can_send {
+ send_result.send(finalize(state)).ok();
+ }
+ }
+ })
+ .expect("valid name");
+ }
+ std::thread::Builder::new()
+ .name("gitoxide.in_parallel.feed".into())
+ .spawn_scoped(s, move || {
+ for item in input {
+ if send_input.send(item).is_err() {
+ break;
+ }
+ }
+ })
+ .expect("valid name");
+ receive_result
+ };
+
+ for item in receive_result {
+ drop(reducer.feed(item)?);
+ }
+ reducer.finalize()
+ })
+}
+
+/// An experiment to have fine-grained per-item parallelization with built-in aggregation via thread state.
+/// This is only good for operations where near-random access isn't detrimental, so it's not usually great
+/// for file-io as it won't make use of sorted inputs well.
+/// Note that `periodic` is not guaranteed to be called in case other threads come up first and finish too fast.
+/// `consume(&mut item, &mut stat, &Scope, &threads_available, &should_interrupt)` is called for performing the actual computation.
+/// Note that `threads_available` should be decremented to start a thread that can steal your own work (as stored in `item`),
+/// which allows callees to implement their own work-stealing in case the work is distributed unevenly.
+/// Work stealing should only start after having processed at least one item to give all threads naturally operating on the slice
+/// some time to start. Starting threads while slice-workers are still starting up would lead to over-allocation of threads,
+/// which is why the number of threads left may turn negative. Once threads are started and stopped, be sure to adjust
+/// the thread-count accordingly.
+// TODO: better docs
+pub fn in_parallel_with_slice<I, S, R, E>(
+ input: &mut [I],
+ thread_limit: Option<usize>,
+ new_thread_state: impl FnOnce(usize) -> S + Send + Clone,
+ consume: impl FnMut(&mut I, &mut S, &AtomicIsize, &AtomicBool) -> Result<(), E> + Send + Clone,
+ mut periodic: impl FnMut() -> Option<std::time::Duration> + Send,
+ state_to_rval: impl FnOnce(S) -> R + Send + Clone,
+) -> Result<Vec<R>, E>
+where
+ I: Send,
+ E: Send,
+ R: Send,
+{
+ let num_threads = num_threads(thread_limit);
+ let mut results = Vec::with_capacity(num_threads);
+ let stop_everything = &AtomicBool::default();
+ let index = &AtomicUsize::default();
+ let threads_left = &AtomicIsize::new(num_threads as isize);
+
+ std::thread::scope({
+ move |s| {
+ std::thread::Builder::new()
+ .name("gitoxide.in_parallel_with_slice.watch-interrupts".into())
+ .spawn_scoped(s, {
+ move || loop {
+ if stop_everything.load(Ordering::Relaxed) {
+ break;
+ }
+
+ match periodic() {
+ Some(duration) => std::thread::sleep(duration),
+ None => {
+ stop_everything.store(true, Ordering::Relaxed);
+ break;
+ }
+ }
+ }
+ })
+ .expect("valid name");
+
+ let input_len = input.len();
+ struct Input<I>(*mut [I])
+ where
+ I: Send;
+
+ // SAFETY: I is Send + Sync, so is a *mut [I]
+ #[allow(unsafe_code)]
+ unsafe impl<I> Send for Input<I> where I: Send {}
+
+ let threads: Vec<_> = (0..num_threads)
+ .map(|thread_id| {
+ std::thread::Builder::new()
+ .name(format!("gitoxide.in_parallel_with_slice.produce.{thread_id}"))
+ .spawn_scoped(s, {
+ let new_thread_state = new_thread_state.clone();
+ let state_to_rval = state_to_rval.clone();
+ let mut consume = consume.clone();
+ let input = Input(input as *mut [I]);
+ move || {
+ let _ = &input;
+ threads_left.fetch_sub(1, Ordering::SeqCst);
+ let mut state = new_thread_state(thread_id);
+ let res = (|| {
+ while let Ok(input_index) =
+ index.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
+ (x < input_len).then_some(x + 1)
+ })
+ {
+ if stop_everything.load(Ordering::Relaxed) {
+ break;
+ }
+ // SAFETY: our atomic counter for `input_index` is only ever incremented, yielding
+ // each item exactly once.
+ let item = {
+ #[allow(unsafe_code)]
+ unsafe {
+ &mut (&mut *input.0)[input_index]
+ }
+ };
+ if let Err(err) = consume(item, &mut state, threads_left, stop_everything) {
+ stop_everything.store(true, Ordering::Relaxed);
+ return Err(err);
+ }
+ }
+ Ok(state_to_rval(state))
+ })();
+ threads_left.fetch_add(1, Ordering::SeqCst);
+ res
+ }
+ })
+ .expect("valid name")
+ })
+ .collect();
+ for thread in threads {
+ match thread.join() {
+ Ok(res) => {
+ results.push(res?);
+ }
+ Err(err) => {
+ // a panic happened, stop the world gracefully (even though we panic later)
+ stop_everything.store(true, Ordering::Relaxed);
+ std::panic::resume_unwind(err);
+ }
+ }
+ }
+
+ stop_everything.store(true, Ordering::Relaxed);
+ Ok(results)
+ }
+ })
+}
diff --git a/vendor/gix-features-0.35.0/src/parallel/mod.rs b/vendor/gix-features-0.35.0/src/parallel/mod.rs
new file mode 100644
index 000000000..5a0a4b589
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/parallel/mod.rs
@@ -0,0 +1,178 @@
+//! Run computations in parallel, or not based the `parallel` feature toggle.
+//!
+//! ### `in_parallel`(…)
+//!
+//! The [`in_parallel(…)`][in_parallel()] is the typical fan-out-fan-in mode of parallelism, with thread local storage
+//! made available to a `consume(…)` function to process input. The result is sent to the [`Reduce`] running in the calling
+//! thread to aggregate the results into a single output, which is returned by [`in_parallel()`].
+//!
+//! Interruptions can be achieved by letting the reducers [`feed(…)`][Reduce::feed()] method fail.
+//!
+//! It gets a boost in usability as it allows threads to borrow variables from the stack, most commonly the repository itself
+//! or the data to work on.
+//!
+//! This mode of operation doesn't lend itself perfectly to being wrapped for `async` as it appears like a single long-running
+//! operation which runs as fast as possible, which is cancellable only by merit of stopping the input or stopping the output
+//! aggregation.
+//!
+//! ### `reduce::Stepwise`
+//!
+//! The [`Stepwise`][reduce::Stepwise] iterator works exactly as [`in_parallel()`] except that the processing of the output produced by
+//! `consume(I, &mut State) -> O` is made accessible by the `Iterator` trait's `next()` method. As produced work is not
+//! buffered, the owner of the iterator controls the progress made.
+//!
+//! Getting the final output of the [`Reduce`] is achieved through the consuming [`Stepwise::finalize()`][reduce::Stepwise::finalize()] method, which
+//! is functionally equivalent to calling [`in_parallel()`].
+//!
+//! In an `async` context this means that progress is only made each time `next()` is called on the iterator, while merely dropping
+//! the iterator will wind down the computation without any result.
+//!
+//! #### Maintaining Safety
+//!
+//! In order to assure that threads don't outlive the data they borrow because their handles are leaked, we enforce
+//! the `'static` lifetime for its inputs, making it less intuitive to use. It is, however, possible to produce
+//! suitable input iterators as long as they can hold something on the heap.
+#[cfg(feature = "parallel")]
+mod in_parallel;
+#[cfg(feature = "parallel")]
+pub use in_parallel::{
+ build_thread, in_parallel, in_parallel_with_finalize, in_parallel_with_slice, join, threads, Scope,
+};
+
+mod serial;
+#[cfg(not(feature = "parallel"))]
+pub use serial::{build_thread, in_parallel, in_parallel_with_finalize, in_parallel_with_slice, join, threads, Scope};
+
+mod in_order;
+pub use in_order::{InOrderIter, SequenceId};
+
+mod eager_iter;
+pub use eager_iter::{EagerIter, EagerIterIf};
+
+/// A no-op returning the input _(`desired_chunk_size`, `Some(thread_limit)`, `thread_limit)_ used
+/// when the `parallel` feature toggle is not set.
+#[cfg(not(feature = "parallel"))]
+pub fn optimize_chunk_size_and_thread_limit(
+ desired_chunk_size: usize,
+ _num_items: Option<usize>,
+ thread_limit: Option<usize>,
+ _available_threads: Option<usize>,
+) -> (usize, Option<usize>, usize) {
+ (desired_chunk_size, thread_limit, num_threads(thread_limit))
+}
+
+/// Return the 'optimal' _(`size of chunks`, `amount of threads as Option`, `amount of threads`)_ to use in [`in_parallel()`] for the given
+/// `desired_chunk_size`, `num_items`, `thread_limit` and `available_threads`.
+///
+/// * `desired_chunk_size` is the amount of items per chunk you think should be used.
+/// * `num_items` is the total amount of items in the iteration, if `Some`.
+/// Otherwise this knowledge will not affect the output of this function.
+/// * `thread_limit` is the amount of threads to use at most, if `Some`.
+/// Otherwise this knowledge will not affect the output of this function.
+/// * `available_threads` is the total amount of threads available, if `Some`.
+/// Otherwise the actual amount of available threads is determined by querying the system.
+///
+/// `Note` that this implementation is available only if the `parallel` feature toggle is set.
+#[cfg(feature = "parallel")]
+pub fn optimize_chunk_size_and_thread_limit(
+ desired_chunk_size: usize,
+ num_items: Option<usize>,
+ thread_limit: Option<usize>,
+ available_threads: Option<usize>,
+) -> (usize, Option<usize>, usize) {
+ let available_threads =
+ available_threads.unwrap_or_else(|| std::thread::available_parallelism().map_or(1, Into::into));
+ let available_threads = thread_limit.map_or(available_threads, |l| if l == 0 { available_threads } else { l });
+
+ let (lower, upper) = (50, 1000);
+ let (chunk_size, thread_limit) = num_items.map_or(
+ {
+ let chunk_size = if available_threads == 1 {
+ desired_chunk_size
+ } else if desired_chunk_size < lower {
+ lower
+ } else {
+ desired_chunk_size.min(upper)
+ };
+ (chunk_size, available_threads)
+ },
+ |num_items| {
+ let desired_chunks_per_thread_at_least = 2;
+ let items = num_items;
+ let chunk_size = (items / (available_threads * desired_chunks_per_thread_at_least)).clamp(1, upper);
+ let num_chunks = items / chunk_size;
+ let thread_limit = if num_chunks <= available_threads {
+ (num_chunks / desired_chunks_per_thread_at_least).max(1)
+ } else {
+ available_threads
+ };
+ (chunk_size, thread_limit)
+ },
+ );
+ (chunk_size, Some(thread_limit), thread_limit)
+}
+
+/// Always returns 1, available when the `parallel` feature toggle is unset.
+#[cfg(not(feature = "parallel"))]
+pub fn num_threads(_thread_limit: Option<usize>) -> usize {
+ 1
+}
+
+/// Returns the amount of threads the system can effectively use as the amount of its logical cores.
+///
+/// Only available with the `parallel` feature toggle set.
+#[cfg(feature = "parallel")]
+pub fn num_threads(thread_limit: Option<usize>) -> usize {
+ let logical_cores = std::thread::available_parallelism().map_or(1, Into::into);
+ thread_limit.map_or(logical_cores, |l| if l == 0 { logical_cores } else { l })
+}
+
+/// Run [`in_parallel()`] only if the given `condition()` returns true when eagerly evaluated.
+///
+/// For parameters, see the documentation of [`in_parallel()`]
+#[cfg(feature = "parallel")]
+pub fn in_parallel_if<I, S, O, R>(
+ condition: impl FnOnce() -> bool,
+ input: impl Iterator<Item = I> + Send,
+ thread_limit: Option<usize>,
+ new_thread_state: impl FnOnce(usize) -> S + Send + Clone,
+ consume: impl FnMut(I, &mut S) -> O + Send + Clone,
+ reducer: R,
+) -> Result<<R as Reduce>::Output, <R as Reduce>::Error>
+where
+ R: Reduce<Input = O>,
+ I: Send,
+ O: Send,
+{
+ if num_threads(thread_limit) > 1 && condition() {
+ in_parallel(input, thread_limit, new_thread_state, consume, reducer)
+ } else {
+ serial::in_parallel(input, thread_limit, new_thread_state, consume, reducer)
+ }
+}
+
+/// Run [`in_parallel()`] only if the given `condition()` returns true when eagerly evaluated.
+///
+/// For parameters, see the documentation of [`in_parallel()`]
+///
+/// Note that the non-parallel version is equivalent to [`in_parallel()`].
+#[cfg(not(feature = "parallel"))]
+pub fn in_parallel_if<I, S, O, R>(
+ _condition: impl FnOnce() -> bool,
+ input: impl Iterator<Item = I>,
+ thread_limit: Option<usize>,
+ new_thread_state: impl FnOnce(usize) -> S,
+ consume: impl FnMut(I, &mut S) -> O,
+ reducer: R,
+) -> Result<<R as Reduce>::Output, <R as Reduce>::Error>
+where
+ R: Reduce<Input = O>,
+ I: Send,
+ O: Send,
+{
+ serial::in_parallel(input, thread_limit, new_thread_state, consume, reducer)
+}
+
+///
+pub mod reduce;
+pub use reduce::Reduce;
diff --git a/vendor/gix-features-0.35.0/src/parallel/reduce.rs b/vendor/gix-features-0.35.0/src/parallel/reduce.rs
new file mode 100644
index 000000000..f9992cfd2
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/parallel/reduce.rs
@@ -0,0 +1,279 @@
+#[cfg(feature = "parallel")]
+mod stepped {
+ use crate::parallel::num_threads;
+
+ /// An iterator adaptor to allow running computations using [`in_parallel()`][crate::parallel::in_parallel()] in a step-wise manner, see the [module docs][crate::parallel]
+ /// for details.
+ pub struct Stepwise<Reduce: super::Reduce> {
+ /// This field is first to assure it's dropped first and cause threads that are dropped next to stop their loops
+ /// as sending results fails when the receiver is dropped.
+ receive_result: std::sync::mpsc::Receiver<Reduce::Input>,
+ /// `join()` will be called on these guards to assure every thread tries to send through a closed channel. When
+ /// that happens, they break out of their loops.
+ threads: Vec<std::thread::JoinHandle<()>>,
+ /// The reducer is called only in the thread using the iterator, dropping it has no side effects.
+ reducer: Option<Reduce>,
+ }
+
+ impl<Reduce: super::Reduce> Drop for Stepwise<Reduce> {
+ fn drop(&mut self) {
+ let (_, sink) = std::sync::mpsc::channel();
+ drop(std::mem::replace(&mut self.receive_result, sink));
+
+ let mut last_err = None;
+ for handle in std::mem::take(&mut self.threads) {
+ if let Err(err) = handle.join() {
+ last_err = Some(err);
+ };
+ }
+ if let Some(thread_err) = last_err {
+ std::panic::resume_unwind(thread_err);
+ }
+ }
+ }
+
+ impl<Reduce: super::Reduce> Stepwise<Reduce> {
+ /// Instantiate a new iterator and start working in threads.
+ /// For a description of parameters, see [`in_parallel()`][crate::parallel::in_parallel()].
+ pub fn new<InputIter, ThreadStateFn, ConsumeFn, I, O, S>(
+ input: InputIter,
+ thread_limit: Option<usize>,
+ new_thread_state: ThreadStateFn,
+ consume: ConsumeFn,
+ reducer: Reduce,
+ ) -> Self
+ where
+ InputIter: Iterator<Item = I> + Send + 'static,
+ ThreadStateFn: Fn(usize) -> S + Send + Clone + 'static,
+ ConsumeFn: Fn(I, &mut S) -> O + Send + Clone + 'static,
+ Reduce: super::Reduce<Input = O> + 'static,
+ I: Send + 'static,
+ O: Send + 'static,
+ {
+ let num_threads = num_threads(thread_limit);
+ let mut threads = Vec::with_capacity(num_threads + 1);
+ let receive_result = {
+ let (send_input, receive_input) = crossbeam_channel::bounded::<I>(num_threads);
+ let (send_result, receive_result) = std::sync::mpsc::sync_channel::<O>(num_threads);
+ for thread_id in 0..num_threads {
+ let handle = std::thread::spawn({
+ let send_result = send_result.clone();
+ let receive_input = receive_input.clone();
+ let new_thread_state = new_thread_state.clone();
+ let consume = consume.clone();
+ move || {
+ let mut state = new_thread_state(thread_id);
+ for item in receive_input {
+ if send_result.send(consume(item, &mut state)).is_err() {
+ break;
+ }
+ }
+ }
+ });
+ threads.push(handle);
+ }
+ threads.push(std::thread::spawn(move || {
+ for item in input {
+ if send_input.send(item).is_err() {
+ break;
+ }
+ }
+ }));
+ receive_result
+ };
+ Stepwise {
+ threads,
+ receive_result,
+ reducer: Some(reducer),
+ }
+ }
+
+ /// Consume the iterator by finishing its iteration and calling [`Reduce::finalize()`][crate::parallel::Reduce::finalize()].
+ pub fn finalize(mut self) -> Result<Reduce::Output, Reduce::Error> {
+ for value in self.by_ref() {
+ drop(value?);
+ }
+ self.reducer
+ .take()
+ .expect("this is the last call before consumption")
+ .finalize()
+ }
+ }
+
+ impl<Reduce: super::Reduce> Iterator for Stepwise<Reduce> {
+ type Item = Result<Reduce::FeedProduce, Reduce::Error>;
+
+ fn next(&mut self) -> Option<<Self as Iterator>::Item> {
+ self.receive_result
+ .recv()
+ .ok()
+ .and_then(|input| self.reducer.as_mut().map(|r| r.feed(input)))
+ }
+ }
+
+ impl<R: super::Reduce> super::Finalize for Stepwise<R> {
+ type Reduce = R;
+
+ fn finalize(
+ self,
+ ) -> Result<
+ <<Self as super::Finalize>::Reduce as super::Reduce>::Output,
+ <<Self as super::Finalize>::Reduce as super::Reduce>::Error,
+ > {
+ Stepwise::finalize(self)
+ }
+ }
+}
+
+#[cfg(not(feature = "parallel"))]
+mod stepped {
+ /// An iterator adaptor to allow running computations using [`in_parallel()`][crate::parallel::in_parallel()] in a step-wise manner, see the [module docs][crate::parallel]
+ /// for details.
+ pub struct Stepwise<InputIter, ConsumeFn, ThreadState, Reduce> {
+ input: InputIter,
+ consume: ConsumeFn,
+ thread_state: ThreadState,
+ reducer: Reduce,
+ }
+
+ impl<InputIter, ConsumeFn, Reduce, I, O, S> Stepwise<InputIter, ConsumeFn, S, Reduce>
+ where
+ InputIter: Iterator<Item = I>,
+ ConsumeFn: Fn(I, &mut S) -> O,
+ Reduce: super::Reduce<Input = O>,
+ {
+ /// Instantiate a new iterator.
+ /// For a description of parameters, see [`in_parallel()`][crate::parallel::in_parallel()].
+ pub fn new<ThreadStateFn>(
+ input: InputIter,
+ _thread_limit: Option<usize>,
+ new_thread_state: ThreadStateFn,
+ consume: ConsumeFn,
+ reducer: Reduce,
+ ) -> Self
+ where
+ ThreadStateFn: Fn(usize) -> S,
+ {
+ Stepwise {
+ input,
+ consume,
+ thread_state: new_thread_state(0),
+ reducer,
+ }
+ }
+
+ /// Consume the iterator by finishing its iteration and calling [`Reduce::finalize()`][crate::parallel::Reduce::finalize()].
+ pub fn finalize(mut self) -> Result<Reduce::Output, Reduce::Error> {
+ for value in self.by_ref() {
+ drop(value?);
+ }
+ self.reducer.finalize()
+ }
+ }
+
+ impl<InputIter, ConsumeFn, ThreadState, Reduce, I, O> Iterator for Stepwise<InputIter, ConsumeFn, ThreadState, Reduce>
+ where
+ InputIter: Iterator<Item = I>,
+ ConsumeFn: Fn(I, &mut ThreadState) -> O,
+ Reduce: super::Reduce<Input = O>,
+ {
+ type Item = Result<Reduce::FeedProduce, Reduce::Error>;
+
+ fn next(&mut self) -> Option<<Self as Iterator>::Item> {
+ self.input
+ .next()
+ .map(|input| self.reducer.feed((self.consume)(input, &mut self.thread_state)))
+ }
+ }
+
+ impl<InputIter, ConsumeFn, R, I, O, S> super::Finalize for Stepwise<InputIter, ConsumeFn, S, R>
+ where
+ InputIter: Iterator<Item = I>,
+ ConsumeFn: Fn(I, &mut S) -> O,
+ R: super::Reduce<Input = O>,
+ {
+ type Reduce = R;
+
+ fn finalize(
+ self,
+ ) -> Result<
+ <<Self as super::Finalize>::Reduce as super::Reduce>::Output,
+ <<Self as super::Finalize>::Reduce as super::Reduce>::Error,
+ > {
+ Stepwise::finalize(self)
+ }
+ }
+}
+
+use std::marker::PhantomData;
+
+pub use stepped::Stepwise;
+
+/// An trait for aggregating items commonly produced in threads into a single result, without itself
+/// needing to be thread safe.
+pub trait Reduce {
+ /// The type fed to the reducer in the [`feed()`][Reduce::feed()] method.
+ ///
+ /// It's produced by a function that may run on multiple threads.
+ type Input;
+ /// The type produced in Ok(…) by [`feed()`][Reduce::feed()].
+ /// Most reducers by nature use `()` here as the value is in the aggregation.
+ /// However, some may use it to collect statistics only and return their Input
+ /// in some form as a result here for [`Stepwise`] to be useful.
+ type FeedProduce;
+ /// The type produced once by the [`finalize()`][Reduce::finalize()] method.
+ ///
+ /// For traditional reducers, this is the value produced by the entire operation.
+ /// For those made for step-wise iteration this may be aggregated statistics.
+ type Output;
+ /// The error type to use for all methods of this trait.
+ type Error;
+ /// Called each time a new `item` was produced in order to aggregate it into the final result.
+ ///
+ /// If an `Error` is returned, the entire operation will be stopped.
+ fn feed(&mut self, item: Self::Input) -> Result<Self::FeedProduce, Self::Error>;
+ /// Called once once all items where passed to `feed()`, producing the final `Output` of the operation or an `Error`.
+ fn finalize(self) -> Result<Self::Output, Self::Error>;
+}
+
+/// An identity reducer for those who want to use [`Stepwise`] or [`in_parallel()`][crate::parallel::in_parallel()]
+/// without the use of non-threaded reduction of products created in threads.
+pub struct IdentityWithResult<Input, Error> {
+ _input: PhantomData<Input>,
+ _error: PhantomData<Error>,
+}
+
+impl<Input, Error> Default for IdentityWithResult<Input, Error> {
+ fn default() -> Self {
+ IdentityWithResult {
+ _input: Default::default(),
+ _error: Default::default(),
+ }
+ }
+}
+
+impl<Input, Error> Reduce for IdentityWithResult<Input, Error> {
+ type Input = Result<Input, Self::Error>;
+ type FeedProduce = Input;
+ type Output = ();
+ type Error = Error;
+
+ fn feed(&mut self, item: Self::Input) -> Result<Self::FeedProduce, Self::Error> {
+ item
+ }
+
+ fn finalize(self) -> Result<Self::Output, Self::Error> {
+ Ok(())
+ }
+}
+
+/// A trait reflecting the `finalize()` method of [`Reduce`] implementations
+pub trait Finalize {
+ /// An implementation of [`Reduce`]
+ type Reduce: self::Reduce;
+
+ /// Similar to the [`Reduce::finalize()`] method
+ fn finalize(
+ self,
+ ) -> Result<<<Self as Finalize>::Reduce as self::Reduce>::Output, <<Self as Finalize>::Reduce as self::Reduce>::Error>;
+}
diff --git a/vendor/gix-features-0.35.0/src/parallel/serial.rs b/vendor/gix-features-0.35.0/src/parallel/serial.rs
new file mode 100644
index 000000000..7665d3ffa
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/parallel/serial.rs
@@ -0,0 +1,174 @@
+use crate::parallel::Reduce;
+
+#[cfg(not(feature = "parallel"))]
+mod not_parallel {
+ use std::sync::atomic::{AtomicBool, AtomicIsize};
+
+ /// Runs `left` and then `right`, one after another, returning their output when both are done.
+ pub fn join<O1, O2>(left: impl FnOnce() -> O1, right: impl FnOnce() -> O2) -> (O1, O2) {
+ (left(), right())
+ }
+
+ /// A scope for spawning threads.
+ pub struct Scope<'scope, 'env: 'scope> {
+ _scope: std::marker::PhantomData<&'scope mut &'scope ()>,
+ _env: std::marker::PhantomData<&'env mut &'env ()>,
+ }
+
+ pub struct ThreadBuilder;
+
+ /// Create a builder for threads which allows them to be spawned into a scope and configured prior to spawning.
+ pub fn build_thread() -> ThreadBuilder {
+ ThreadBuilder
+ }
+
+ #[allow(unsafe_code)]
+ unsafe impl Sync for Scope<'_, '_> {}
+
+ impl ThreadBuilder {
+ pub fn name(self, _new: String) -> Self {
+ self
+ }
+ pub fn spawn_scoped<'scope, 'env, F, T>(
+ &self,
+ scope: &'scope Scope<'scope, 'env>,
+ f: F,
+ ) -> std::io::Result<ScopedJoinHandle<'scope, T>>
+ where
+ F: FnOnce() -> T + 'scope,
+ T: 'scope,
+ {
+ Ok(scope.spawn(f))
+ }
+ }
+
+ impl<'scope, 'env> Scope<'scope, 'env> {
+ /// Provided with this scope, let `f` start new threads that live within it.
+ pub fn spawn<F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T>
+ where
+ F: FnOnce() -> T + 'scope,
+ T: 'scope,
+ {
+ ScopedJoinHandle {
+ result: f(),
+ _marker: Default::default(),
+ }
+ }
+ }
+
+ /// Runs `f` with a scope to be used for spawning threads that will not outlive the function call.
+ /// Note that this implementation will run the spawned functions immediately.
+ pub fn threads<'env, F, R>(f: F) -> R
+ where
+ F: for<'scope> FnOnce(&'scope Scope<'scope, 'env>) -> R,
+ {
+ f(&Scope {
+ _scope: Default::default(),
+ _env: Default::default(),
+ })
+ }
+
+ /// A handle that can be used to join its scoped thread.
+ ///
+ /// This struct is created by the [`Scope::spawn`] method and the
+ /// [`ScopedThreadBuilder::spawn`] method.
+ pub struct ScopedJoinHandle<'scope, T> {
+ /// Holds the result of the inner closure.
+ result: T,
+ _marker: std::marker::PhantomData<&'scope mut &'scope ()>,
+ }
+
+ impl<T> ScopedJoinHandle<'_, T> {
+ pub fn join(self) -> std::thread::Result<T> {
+ Ok(self.result)
+ }
+ pub fn is_finished(&self) -> bool {
+ true
+ }
+ }
+
+ /// An experiment to have fine-grained per-item parallelization with built-in aggregation via thread state.
+ /// This is only good for operations where near-random access isn't detrimental, so it's not usually great
+ /// for file-io as it won't make use of sorted inputs well.
+ // TODO: better docs
+ pub fn in_parallel_with_slice<I, S, R, E>(
+ input: &mut [I],
+ _thread_limit: Option<usize>,
+ new_thread_state: impl FnOnce(usize) -> S + Clone,
+ mut consume: impl FnMut(&mut I, &mut S, &AtomicIsize, &AtomicBool) -> Result<(), E> + Clone,
+ mut periodic: impl FnMut() -> Option<std::time::Duration>,
+ state_to_rval: impl FnOnce(S) -> R + Clone,
+ ) -> Result<Vec<R>, E> {
+ let mut state = new_thread_state(0);
+ let should_interrupt = &AtomicBool::default();
+ let threads_left = &AtomicIsize::default();
+ for item in input {
+ consume(item, &mut state, threads_left, should_interrupt)?;
+ if periodic().is_none() {
+ break;
+ }
+ }
+ Ok(vec![state_to_rval(state)])
+ }
+}
+
+#[cfg(not(feature = "parallel"))]
+pub use not_parallel::{build_thread, in_parallel_with_slice, join, threads, Scope, ScopedJoinHandle};
+
+/// Read items from `input` and `consume` them in a single thread, producing an output to be collected by a `reducer`,
+/// whose task is to aggregate these outputs into the final result returned by this function.
+///
+/// * `new_thread_state(thread_number) -> State` produces thread-local state once per thread to be based to `consume`
+/// * `consume(Item, &mut State) -> Output` produces an output given an input along with mutable state.
+/// * For `reducer`, see the [`Reduce`] trait
+/// * if `thread_limit` has no effect as everything is run on the main thread, but is present to keep the signature
+/// similar to the parallel version.
+///
+/// **This serial version performing all calculations on the current thread.**
+pub fn in_parallel<I, S, O, R>(
+ input: impl Iterator<Item = I>,
+ _thread_limit: Option<usize>,
+ new_thread_state: impl FnOnce(usize) -> S,
+ mut consume: impl FnMut(I, &mut S) -> O,
+ mut reducer: R,
+) -> Result<<R as Reduce>::Output, <R as Reduce>::Error>
+where
+ R: Reduce<Input = O>,
+{
+ let mut state = new_thread_state(0);
+ for item in input {
+ drop(reducer.feed(consume(item, &mut state))?);
+ }
+ reducer.finalize()
+}
+
+/// Read items from `input` and `consume` them in multiple threads,
+/// whose output output is collected by a `reducer`. Its task is to
+/// aggregate these outputs into the final result returned by this function with the benefit of not having to be thread-safe.
+/// Caall `finalize` to finish the computation, once per thread, if there was no error sending results earlier.
+///
+/// * if `thread_limit` is `Some`, the given amount of threads will be used. If `None`, all logical cores will be used.
+/// * `new_thread_state(thread_number) -> State` produces thread-local state once per thread to be based to `consume`
+/// * `consume(Item, &mut State) -> Output` produces an output given an input obtained by `input` along with mutable state initially
+/// created by `new_thread_state(…)`.
+/// * `finalize(State) -> Output` is called to potentially process remaining work that was placed in `State`.
+/// * For `reducer`, see the [`Reduce`] trait
+#[cfg(not(feature = "parallel"))]
+pub fn in_parallel_with_finalize<I, S, O, R>(
+ input: impl Iterator<Item = I>,
+ _thread_limit: Option<usize>,
+ new_thread_state: impl FnOnce(usize) -> S,
+ mut consume: impl FnMut(I, &mut S) -> O,
+ finalize: impl FnOnce(S) -> O + Send + Clone,
+ mut reducer: R,
+) -> Result<<R as Reduce>::Output, <R as Reduce>::Error>
+where
+ R: Reduce<Input = O>,
+{
+ let mut state = new_thread_state(0);
+ for item in input {
+ drop(reducer.feed(consume(item, &mut state))?);
+ }
+ reducer.feed(finalize(state))?;
+ reducer.finalize()
+}
diff --git a/vendor/gix-features-0.35.0/src/progress.rs b/vendor/gix-features-0.35.0/src/progress.rs
new file mode 100644
index 000000000..6a8c9e1bd
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/progress.rs
@@ -0,0 +1,150 @@
+//! Various `prodash` types along with various utilities for comfort.
+use std::io;
+
+#[cfg(feature = "progress-unit-bytes")]
+pub use bytesize;
+pub use prodash::{
+ self,
+ messages::MessageLevel,
+ progress::{
+ AtomicStep, Discard, DoOrDiscard, Either, Id, Step, StepShared, Task, ThroughputOnDrop, Value, UNKNOWN,
+ },
+ unit, BoxedDynNestedProgress, Count, DynNestedProgress, DynNestedProgressToNestedProgress, NestedProgress,
+ Progress, Unit,
+};
+/// A stub for the portions of the `bytesize` crate that we use internally in `gitoxide`.
+#[cfg(not(feature = "progress-unit-bytes"))]
+pub mod bytesize {
+ /// A stub for the `ByteSize` wrapper.
+ pub struct ByteSize(pub u64);
+
+ impl std::fmt::Display for ByteSize {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.0.fmt(f)
+ }
+ }
+}
+
+/// A unit for displaying bytes with throughput and progress percentage.
+#[cfg(feature = "progress-unit-bytes")]
+pub fn bytes() -> Option<Unit> {
+ Some(unit::dynamic_and_mode(
+ unit::Bytes,
+ unit::display::Mode::with_throughput().and_percentage(),
+ ))
+}
+
+/// A unit for displaying bytes with throughput and progress percentage.
+#[cfg(not(feature = "progress-unit-bytes"))]
+pub fn bytes() -> Option<Unit> {
+ Some(unit::label_and_mode(
+ "B",
+ unit::display::Mode::with_throughput().and_percentage(),
+ ))
+}
+
+/// A unit for displaying human readable numbers with throughput and progress percentage, and a single decimal place.
+pub fn count(name: &'static str) -> Option<Unit> {
+ count_with_decimals(name, 1)
+}
+
+/// A unit for displaying human readable numbers with `name` suffix,
+/// with throughput and progress percentage, and `decimals` decimal places.
+#[cfg(feature = "progress-unit-human-numbers")]
+pub fn count_with_decimals(name: &'static str, decimals: usize) -> Option<Unit> {
+ Some(unit::dynamic_and_mode(
+ unit::Human::new(
+ {
+ let mut f = unit::human::Formatter::new();
+ f.with_decimals(decimals);
+ f
+ },
+ name,
+ ),
+ unit::display::Mode::with_throughput().and_percentage(),
+ ))
+}
+
+/// A unit for displaying human readable numbers with `name` suffix,
+/// with throughput and progress percentage, and `decimals` decimal places.
+#[cfg(not(feature = "progress-unit-human-numbers"))]
+pub fn count_with_decimals(name: &'static str, _decimals: usize) -> Option<Unit> {
+ Some(unit::label_and_mode(
+ name,
+ unit::display::Mode::with_throughput().and_percentage(),
+ ))
+}
+
+/// A predefined unit for displaying a multi-step progress
+pub fn steps() -> Option<Unit> {
+ Some(unit::dynamic(unit::Range::new("steps")))
+}
+
+/// A structure passing every [`read`](std::io::Read::read()) call through to the contained Progress instance using [`inc_by(bytes_read)`](Count::inc_by()).
+pub struct Read<T, P> {
+ /// The implementor of [`std::io::Read`] to which progress is added
+ pub inner: T,
+ /// The progress instance receiving progress information on each invocation of `reader`
+ pub progress: P,
+}
+
+impl<T, P> io::Read for Read<T, P>
+where
+ T: io::Read,
+ P: Progress,
+{
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ let bytes_read = self.inner.read(buf)?;
+ self.progress.inc_by(bytes_read);
+ Ok(bytes_read)
+ }
+}
+
+impl<T, P> io::BufRead for Read<T, P>
+where
+ T: io::BufRead,
+ P: Progress,
+{
+ fn fill_buf(&mut self) -> io::Result<&[u8]> {
+ self.inner.fill_buf()
+ }
+
+ fn consume(&mut self, amt: usize) {
+ self.inner.consume(amt)
+ }
+}
+
+/// A structure passing every [`write`][std::io::Write::write()] call through to the contained Progress instance using [`inc_by(bytes_written)`](Count::inc_by()).
+///
+/// This is particularly useful if the final size of the bytes to write is known or can be estimated precisely enough.
+pub struct Write<T, P> {
+ /// The implementor of [`std::io::Write`] to which progress is added
+ pub inner: T,
+ /// The progress instance receiving progress information on each invocation of `reader`
+ pub progress: P,
+}
+
+impl<T, P> io::Write for Write<T, P>
+where
+ T: io::Write,
+ P: Progress,
+{
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ let written = self.inner.write(buf)?;
+ self.progress.inc_by(written);
+ Ok(written)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.inner.flush()
+ }
+}
+
+impl<T, P> io::Seek for Write<T, P>
+where
+ T: io::Seek,
+{
+ fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
+ self.inner.seek(pos)
+ }
+}
diff --git a/vendor/gix-features-0.35.0/src/threading.rs b/vendor/gix-features-0.35.0/src/threading.rs
new file mode 100644
index 000000000..5f92ba2a8
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/threading.rs
@@ -0,0 +1,110 @@
+//! Type definitions for putting shared ownership and synchronized mutation behind the `threading` feature toggle.
+//!
+//! That way, single-threaded applications will not have to use thread-safe primitives, and simply do not specify the 'threading' feature.
+
+#[cfg(feature = "parallel")]
+mod _impl {
+ use std::sync::Arc;
+
+ /// A thread-safe cell which can be written to only once.
+ #[cfg(feature = "once_cell")]
+ pub type OnceCell<T> = once_cell::sync::OnceCell<T>;
+ /// A reference counted pointer type for shared ownership.
+ pub type OwnShared<T> = Arc<T>;
+ /// A synchronization primitive which can start read-only and transition to support mutation.
+ pub type MutableOnDemand<T> = parking_lot::RwLock<T>;
+ /// A synchronization primitive which provides read-write access right away.
+ pub type Mutable<T> = parking_lot::Mutex<T>;
+ /// A guarded reference suitable for safekeeping in a struct.
+ pub type RefGuard<'a, T> = parking_lot::RwLockReadGuard<'a, T>;
+ /// A mapped reference created from a `RefGuard`
+ pub type MappedRefGuard<'a, U> = parking_lot::MappedRwLockReadGuard<'a, U>;
+
+ /// Get a shared reference through a [`MutableOnDemand`] for read-only access.
+ pub fn get_ref<T>(v: &MutableOnDemand<T>) -> RefGuard<'_, T> {
+ v.read()
+ }
+
+ /// Get a mutable reference through a [`MutableOnDemand`] for read-write access.
+ pub fn get_mut<T>(v: &MutableOnDemand<T>) -> parking_lot::RwLockWriteGuard<'_, T> {
+ v.write()
+ }
+
+ /// Get a mutable reference to the underlying data, with semantics similar to [Arc::make_mut()].
+ pub fn make_mut<T: Clone>(this: &mut OwnShared<T>) -> &mut T {
+ OwnShared::make_mut(this)
+ }
+
+ /// Get a mutable reference through a [`Mutable`] for read-write access.
+ pub fn lock<T>(v: &Mutable<T>) -> parking_lot::MutexGuard<'_, T> {
+ v.lock()
+ }
+
+ /// Downgrade a handle previously obtained with [`get_mut()`] to drop mutation support.
+ pub fn downgrade_mut_to_ref<'a, T>(
+ v: parking_lot::RwLockWriteGuard<'a, T>,
+ _orig: &'a MutableOnDemand<T>,
+ ) -> RefGuard<'a, T> {
+ parking_lot::RwLockWriteGuard::downgrade(v)
+ }
+
+ /// Map a read guard into a sub-type it contains.
+ pub fn map_ref<T, U: ?Sized>(v: RefGuard<'_, T>, f: impl FnOnce(&T) -> &U) -> MappedRefGuard<'_, U> {
+ parking_lot::RwLockReadGuard::map(v, f)
+ }
+}
+
+#[cfg(not(feature = "parallel"))]
+mod _impl {
+ use std::{
+ cell::{Ref, RefCell, RefMut},
+ rc::Rc,
+ };
+
+ /// A thread-safe cell which can be written to only once.
+ #[cfg(feature = "once_cell")]
+ pub type OnceCell<T> = once_cell::unsync::OnceCell<T>;
+ /// A reference counted pointer type for shared ownership.
+ pub type OwnShared<T> = Rc<T>;
+ /// A synchronization primitive which can start read-only and transition to support mutation.
+ pub type MutableOnDemand<T> = RefCell<T>;
+ /// A synchronization primitive which provides read-write access right away.
+ pub type Mutable<T> = RefCell<T>;
+ /// A guarded reference suitable for safekeeping in a struct.
+ pub type RefGuard<'a, T> = Ref<'a, T>;
+ /// A mapped reference created from a RefGuard
+ pub type MappedRefGuard<'a, U> = Ref<'a, U>;
+
+ /// Get a shared reference through a [`MutableOnDemand`] for read-only access.
+ pub fn get_mut<T>(v: &RefCell<T>) -> RefMut<'_, T> {
+ v.borrow_mut()
+ }
+
+ /// Get a mutable reference to the underlying data, with semantics similar to [Rc::make_mut()].
+ pub fn make_mut<T: Clone>(this: &mut OwnShared<T>) -> &mut T {
+ OwnShared::make_mut(this)
+ }
+
+ /// Get a mutable reference through a [`Mutable`] for read-write access.
+ pub fn lock<T>(v: &Mutable<T>) -> RefMut<'_, T> {
+ v.borrow_mut()
+ }
+
+ /// Get a mutable reference through a [`MutableOnDemand`] for read-write access.
+ pub fn get_ref<T>(v: &RefCell<T>) -> RefGuard<'_, T> {
+ v.borrow()
+ }
+
+ /// Downgrade a handle previously obtained with [`upgrade_ref_to_mut()`] to drop mutation support.
+ pub fn downgrade_mut_to_ref<'a, T>(v: RefMut<'a, T>, orig: &'a RefCell<T>) -> RefGuard<'a, T> {
+ drop(v);
+ orig.borrow()
+ }
+
+ /// Map a read guard into a sub-type it contains.
+ pub fn map_ref<T, U: ?Sized>(v: RefGuard<'_, T>, f: impl FnOnce(&T) -> &U) -> MappedRefGuard<'_, U> {
+ Ref::map(v, f)
+ }
+}
+
+pub use _impl::*;
diff --git a/vendor/gix-features-0.35.0/src/zlib/mod.rs b/vendor/gix-features-0.35.0/src/zlib/mod.rs
new file mode 100644
index 000000000..f55660075
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/zlib/mod.rs
@@ -0,0 +1,52 @@
+pub use flate2::{Decompress, Status};
+
+/// non-streaming interfaces for decompression
+pub mod inflate {
+ /// The error returned by various [Inflate methods][super::Inflate]
+ #[derive(Debug, thiserror::Error)]
+ #[allow(missing_docs)]
+ pub enum Error {
+ #[error("Could not write all bytes when decompressing content")]
+ WriteInflated(#[from] std::io::Error),
+ #[error("Could not decode zip stream, status was '{0:?}'")]
+ Inflate(#[from] flate2::DecompressError),
+ #[error("The zlib status indicated an error, status was '{0:?}'")]
+ Status(flate2::Status),
+ }
+}
+
+/// Decompress a few bytes of a zlib stream without allocation
+pub struct Inflate {
+ /// The actual decompressor doing all the work.
+ pub state: Decompress,
+}
+
+impl Default for Inflate {
+ fn default() -> Self {
+ Inflate {
+ state: Decompress::new(true),
+ }
+ }
+}
+
+impl Inflate {
+ /// Run the decompressor exactly once. Cannot be run multiple times
+ pub fn once(&mut self, input: &[u8], out: &mut [u8]) -> Result<(flate2::Status, usize, usize), inflate::Error> {
+ let before_in = self.state.total_in();
+ let before_out = self.state.total_out();
+ let status = self.state.decompress(input, out, flate2::FlushDecompress::None)?;
+ Ok((
+ status,
+ (self.state.total_in() - before_in) as usize,
+ (self.state.total_out() - before_out) as usize,
+ ))
+ }
+
+ /// Ready this instance for decoding another data stream.
+ pub fn reset(&mut self) {
+ self.state.reset(true);
+ }
+}
+
+///
+pub mod stream;
diff --git a/vendor/gix-features-0.35.0/src/zlib/stream/deflate/mod.rs b/vendor/gix-features-0.35.0/src/zlib/stream/deflate/mod.rs
new file mode 100644
index 000000000..567e8fece
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/zlib/stream/deflate/mod.rs
@@ -0,0 +1,113 @@
+use flate2::Compress;
+
+const BUF_SIZE: usize = 4096 * 8;
+
+/// A utility to zlib compress anything that is written via its [Write][std::io::Write] implementation.
+///
+/// Be sure to call `flush()` when done to finalize the deflate stream.
+pub struct Write<W> {
+ compressor: Compress,
+ inner: W,
+ buf: [u8; BUF_SIZE],
+}
+
+impl<W> Clone for Write<W>
+where
+ W: Clone,
+{
+ fn clone(&self) -> Self {
+ Write {
+ compressor: impls::new_compress(),
+ inner: self.inner.clone(),
+ buf: self.buf,
+ }
+ }
+}
+
+mod impls {
+ use std::io;
+
+ use flate2::{Compress, Compression, FlushCompress, Status};
+
+ use crate::zlib::stream::deflate;
+
+ pub(crate) fn new_compress() -> Compress {
+ Compress::new(Compression::fast(), true)
+ }
+
+ impl<W> deflate::Write<W>
+ where
+ W: io::Write,
+ {
+ /// Create a new instance writing compressed bytes to `inner`.
+ pub fn new(inner: W) -> deflate::Write<W> {
+ deflate::Write {
+ compressor: new_compress(),
+ inner,
+ buf: [0; deflate::BUF_SIZE],
+ }
+ }
+
+ /// Reset the compressor, starting a new compression stream.
+ ///
+ /// That way multiple streams can be written to the same inner writer.
+ pub fn reset(&mut self) {
+ self.compressor.reset();
+ }
+
+ /// Consume `self` and return the inner writer.
+ pub fn into_inner(self) -> W {
+ self.inner
+ }
+
+ fn write_inner(&mut self, mut buf: &[u8], flush: FlushCompress) -> io::Result<usize> {
+ let total_in_when_start = self.compressor.total_in();
+ loop {
+ let last_total_in = self.compressor.total_in();
+ let last_total_out = self.compressor.total_out();
+
+ let status = self
+ .compressor
+ .compress(buf, &mut self.buf, flush)
+ .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
+
+ let written = self.compressor.total_out() - last_total_out;
+ if written > 0 {
+ self.inner.write_all(&self.buf[..written as usize])?;
+ }
+
+ match status {
+ Status::StreamEnd => return Ok((self.compressor.total_in() - total_in_when_start) as usize),
+ Status::Ok | Status::BufError => {
+ let consumed = self.compressor.total_in() - last_total_in;
+ buf = &buf[consumed as usize..];
+
+ // output buffer still makes progress
+ if self.compressor.total_out() > last_total_out {
+ continue;
+ }
+ // input still makes progress
+ if self.compressor.total_in() > last_total_in {
+ continue;
+ }
+ // input also makes no progress anymore, need more so leave with what we have
+ return Ok((self.compressor.total_in() - total_in_when_start) as usize);
+ }
+ }
+ }
+ }
+ }
+
+ impl<W: io::Write> io::Write for deflate::Write<W> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.write_inner(buf, FlushCompress::None)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.write_inner(&[], FlushCompress::Finish).map(|_| ())
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests;
diff --git a/vendor/gix-features-0.35.0/src/zlib/stream/deflate/tests.rs b/vendor/gix-features-0.35.0/src/zlib/stream/deflate/tests.rs
new file mode 100644
index 000000000..7c5865e0b
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/zlib/stream/deflate/tests.rs
@@ -0,0 +1,101 @@
+mod deflate_stream {
+ use std::{
+ io,
+ io::{Read, Write},
+ };
+
+ use bstr::ByteSlice;
+ use flate2::Decompress;
+
+ use crate::zlib::stream::deflate;
+
+ /// Provide streaming decompression using the `std::io::Read` trait.
+ /// If `std::io::BufReader` is used, an allocation for the input buffer will be performed.
+ struct InflateReader<R> {
+ inner: R,
+ decompressor: Decompress,
+ }
+
+ impl<R> InflateReader<R>
+ where
+ R: io::BufRead,
+ {
+ pub fn from_read(read: R) -> InflateReader<R> {
+ InflateReader {
+ decompressor: Decompress::new(true),
+ inner: read,
+ }
+ }
+ }
+
+ impl<R> io::Read for InflateReader<R>
+ where
+ R: io::BufRead,
+ {
+ fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
+ crate::zlib::stream::inflate::read(&mut self.inner, &mut self.decompressor, into)
+ }
+ }
+
+ #[test]
+ fn small_file_decompress() -> Result<(), Box<dyn std::error::Error>> {
+ fn fixture_path(path: &str) -> std::path::PathBuf {
+ std::path::PathBuf::from("tests/fixtures").join(path)
+ }
+ let r = InflateReader::from_read(io::BufReader::new(std::fs::File::open(fixture_path(
+ "objects/37/d4e6c5c48ba0d245164c4e10d5f41140cab980",
+ ))?));
+ let mut bytes = r.bytes();
+ let content = bytes.by_ref().take(16).collect::<Result<Vec<_>, _>>()?;
+ assert_eq!(content.as_slice().as_bstr(), b"blob 9\0hi there\n".as_bstr());
+ assert!(bytes.next().is_none());
+ Ok(())
+ }
+
+ #[test]
+ fn all_at_once() -> Result<(), Box<dyn std::error::Error>> {
+ let mut w = deflate::Write::new(Vec::new());
+ assert_eq!(w.write(b"hello")?, 5);
+ w.flush()?;
+
+ let out = w.inner;
+ assert!(out.len() == 12 || out.len() == 13);
+
+ assert_deflate_buffer(out, b"hello")
+ }
+
+ fn assert_deflate_buffer(out: Vec<u8>, expected: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
+ let mut actual = Vec::new();
+ InflateReader::from_read(out.as_slice()).read_to_end(&mut actual)?;
+ assert_eq!(actual, expected);
+ Ok(())
+ }
+
+ #[test]
+ fn big_file_small_writes() -> Result<(), Box<dyn std::error::Error>> {
+ let mut w = deflate::Write::new(Vec::new());
+ let bytes = include_bytes!(
+ "../../../../../gix-odb/tests/fixtures/objects/pack/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.pack"
+ );
+ for chunk in bytes.chunks(2) {
+ assert_eq!(w.write(chunk)?, chunk.len());
+ }
+ w.flush()?;
+
+ assert_deflate_buffer(w.inner, bytes)
+ }
+
+ #[test]
+ fn big_file_a_few_big_writes() -> Result<(), Box<dyn std::error::Error>> {
+ let mut w = deflate::Write::new(Vec::new());
+ let bytes = include_bytes!(
+ "../../../../../gix-odb/tests/fixtures/objects/pack/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.pack"
+ );
+ for chunk in bytes.chunks(4096 * 9) {
+ assert_eq!(w.write(chunk)?, chunk.len());
+ }
+ w.flush()?;
+
+ assert_deflate_buffer(w.inner, bytes)
+ }
+}
diff --git a/vendor/gix-features-0.35.0/src/zlib/stream/inflate.rs b/vendor/gix-features-0.35.0/src/zlib/stream/inflate.rs
new file mode 100644
index 000000000..11dc92800
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/zlib/stream/inflate.rs
@@ -0,0 +1,40 @@
+use std::{io, io::BufRead};
+
+use flate2::{Decompress, FlushDecompress, Status};
+
+/// Read bytes from `rd` and decompress them using `state` into a pre-allocated fitting buffer `dst`, returning the amount of bytes written.
+pub fn read(rd: &mut impl BufRead, state: &mut Decompress, mut dst: &mut [u8]) -> io::Result<usize> {
+ let mut total_written = 0;
+ loop {
+ let (written, consumed, ret, eof);
+ {
+ let input = rd.fill_buf()?;
+ eof = input.is_empty();
+ let before_out = state.total_out();
+ let before_in = state.total_in();
+ let flush = if eof {
+ FlushDecompress::Finish
+ } else {
+ FlushDecompress::None
+ };
+ ret = state.decompress(input, dst, flush);
+ written = (state.total_out() - before_out) as usize;
+ total_written += written;
+ dst = &mut dst[written..];
+ consumed = (state.total_in() - before_in) as usize;
+ }
+ rd.consume(consumed);
+
+ match ret {
+ // The stream has officially ended, nothing more to do here.
+ Ok(Status::StreamEnd) => return Ok(total_written),
+ // Either input our output are depleted even though the stream is not depleted yet.
+ Ok(Status::Ok | Status::BufError) if eof || dst.is_empty() => return Ok(total_written),
+ // Some progress was made in both the input and the output, it must continue to reach the end.
+ Ok(Status::Ok | Status::BufError) if consumed != 0 || written != 0 => continue,
+ // A strange state, where zlib makes no progress but isn't done either. Call it out.
+ Ok(Status::Ok | Status::BufError) => unreachable!("Definitely a bug somewhere"),
+ Err(..) => return Err(io::Error::new(io::ErrorKind::InvalidInput, "corrupt deflate stream")),
+ }
+ }
+}
diff --git a/vendor/gix-features-0.35.0/src/zlib/stream/mod.rs b/vendor/gix-features-0.35.0/src/zlib/stream/mod.rs
new file mode 100644
index 000000000..7fb239d36
--- /dev/null
+++ b/vendor/gix-features-0.35.0/src/zlib/stream/mod.rs
@@ -0,0 +1,4 @@
+///
+pub mod deflate;
+///
+pub mod inflate;
diff --git a/vendor/gix-features-0.35.0/tests/features.rs b/vendor/gix-features-0.35.0/tests/features.rs
new file mode 100644
index 000000000..fc1f25c36
--- /dev/null
+++ b/vendor/gix-features-0.35.0/tests/features.rs
@@ -0,0 +1 @@
+mod trace;
diff --git a/vendor/gix-features-0.35.0/tests/hash.rs b/vendor/gix-features-0.35.0/tests/hash.rs
new file mode 100644
index 000000000..c8e48da57
--- /dev/null
+++ b/vendor/gix-features-0.35.0/tests/hash.rs
@@ -0,0 +1,13 @@
+use gix_features::hash::Sha1;
+
+#[cfg(not(feature = "fast-sha1"))]
+#[test]
+fn size_of_sha1() {
+ assert_eq!(std::mem::size_of::<Sha1>(), 96)
+}
+
+#[cfg(feature = "fast-sha1")]
+#[test]
+fn size_of_sha1() {
+ assert_eq!(std::mem::size_of::<Sha1>(), 104)
+}
diff --git a/vendor/gix-features-0.35.0/tests/parallel/in_order_iter.rs b/vendor/gix-features-0.35.0/tests/parallel/in_order_iter.rs
new file mode 100644
index 000000000..9e1881215
--- /dev/null
+++ b/vendor/gix-features-0.35.0/tests/parallel/in_order_iter.rs
@@ -0,0 +1,54 @@
+use std::convert::Infallible;
+
+use gix_features::parallel::InOrderIter;
+
+#[test]
+fn in_order_stays_in_order() {
+ assert_eq!(
+ InOrderIter::from(vec![Ok::<_, Infallible>((0usize, 'a')), Ok((1, 'b')), Ok((2, 'c'))].into_iter())
+ .collect::<Result<Vec<_>, _>>()
+ .expect("infallible"),
+ vec!['a', 'b', 'c']
+ )
+}
+
+#[test]
+fn out_of_order_items_are_held_until_the_sequence_is_complete() {
+ assert_eq!(
+ InOrderIter::from(
+ vec![
+ Ok::<_, Infallible>((2usize, 'c')),
+ Ok((1, 'b')),
+ Ok((0, 'a')),
+ Ok((3, 'd'))
+ ]
+ .into_iter()
+ )
+ .collect::<Result<Vec<_>, _>>()
+ .expect("infallible"),
+ vec!['a', 'b', 'c', 'd']
+ )
+}
+
+#[test]
+fn in_sequence_errors_immediately_trigger_a_fuse() {
+ let mut iter = InOrderIter::from(vec![Ok::<_, &'static str>((0usize, 'a')), Err("err"), Ok((1, 'b'))].into_iter());
+ assert_eq!(iter.next(), Some(Ok('a')));
+ assert_eq!(iter.next(), Some(Err("err")));
+ assert_eq!(
+ iter.next(),
+ None,
+ "fuse should have triggered so we don't see anything else"
+ );
+}
+
+#[test]
+fn out_of_sequence_errors_immediately_trigger_a_fuse() {
+ let mut iter = InOrderIter::from(vec![Ok::<_, &'static str>((1usize, 'b')), Err("err"), Ok((0, 'a'))].into_iter());
+ assert_eq!(iter.next(), Some(Err("err")));
+ assert_eq!(
+ iter.next(),
+ None,
+ "fuse should have triggered so we don't see anything else"
+ );
+}
diff --git a/vendor/gix-features-0.35.0/tests/parallel/mod.rs b/vendor/gix-features-0.35.0/tests/parallel/mod.rs
new file mode 100644
index 000000000..cc824332d
--- /dev/null
+++ b/vendor/gix-features-0.35.0/tests/parallel/mod.rs
@@ -0,0 +1,125 @@
+//! Tests that are working similarly in parallel and serial mode
+use gix_features::parallel;
+
+mod in_order_iter;
+
+#[derive(Default)]
+struct Adder {
+ count: usize,
+}
+
+impl parallel::Reduce for Adder {
+ type Input = usize;
+ type FeedProduce = usize;
+ type Output = usize;
+ type Error = ();
+
+ fn feed(&mut self, item: Self::Input) -> Result<Self::FeedProduce, Self::Error> {
+ self.count += item;
+ Ok(item)
+ }
+
+ fn finalize(self) -> Result<Self::Output, Self::Error> {
+ Ok(self.count)
+ }
+}
+
+#[test]
+fn in_parallel() {
+ let res = parallel::in_parallel(
+ std::iter::from_fn(|| Some(1)).take(100),
+ None,
+ |_n| (),
+ |input, _state| input,
+ Adder::default(),
+ )
+ .expect("successful computation");
+ assert_eq!(res, 100);
+}
+
+#[test]
+fn in_parallel_with_mut_slice_in_chunks() {
+ let num_items = 33;
+ let mut input: Vec<_> = std::iter::repeat(1).take(num_items).collect();
+ let counts = parallel::in_parallel_with_slice(
+ &mut input,
+ None,
+ |_| 0usize,
+ |item, acc, _threads_eft, _should_interrupt| {
+ *acc += *item;
+ *item += 1;
+ Ok::<_, ()>(())
+ },
+ || Some(std::time::Duration::from_millis(10)),
+ std::convert::identity,
+ )
+ .unwrap();
+ let expected = std::iter::repeat(1).take(num_items).sum::<usize>();
+ assert_eq!(counts.iter().sum::<usize>(), expected);
+ assert_eq!(input.iter().sum::<usize>(), expected * 2, "we increment each entry");
+}
+
+#[test]
+fn stepped_reduce_next() {
+ let mut iter = parallel::reduce::Stepwise::new(
+ std::iter::from_fn(|| Some(1)).take(100),
+ None,
+ |_n| (),
+ |input, _state| input,
+ Adder::default(),
+ );
+
+ let mut aggregate = 0;
+ for value in iter.by_ref() {
+ aggregate += value.expect("success");
+ }
+ assert_eq!(aggregate, 100);
+}
+
+#[test]
+fn stepped_reduce_ref_input_and_consume() {
+ let seq = std::sync::Arc::new(vec![0usize, 1, 2]);
+ struct ArcIter(std::sync::Arc<Vec<usize>>, usize);
+ impl Iterator for ArcIter {
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let n = self.0.get(self.1).copied();
+ self.1 += 1;
+ n
+ }
+ }
+
+ let mut iter = parallel::reduce::Stepwise::new(
+ ArcIter(seq.clone(), 0).enumerate(),
+ None,
+ {
+ let seq = std::sync::Arc::clone(&seq);
+ move |_n| seq.len()
+ },
+ {
+ let seq = std::sync::Arc::clone(&seq);
+ move |(idx, ref_val): (usize, usize), _state| seq[idx] * ref_val
+ },
+ Adder::default(),
+ );
+
+ let mut aggregate = 0;
+ for value in iter.by_ref() {
+ aggregate += value.expect("success");
+ }
+ assert_eq!(aggregate, 5);
+}
+
+#[test]
+fn stepped_reduce_finalize() {
+ let iter = parallel::reduce::Stepwise::new(
+ std::iter::from_fn(|| Some(1)).take(100),
+ None,
+ |_n| (),
+ |input, _state| input,
+ Adder::default(),
+ );
+
+ assert_eq!(iter.finalize().expect("success"), 100);
+}
diff --git a/vendor/gix-features-0.35.0/tests/parallel_shared.rs b/vendor/gix-features-0.35.0/tests/parallel_shared.rs
new file mode 100644
index 000000000..055a899ea
--- /dev/null
+++ b/vendor/gix-features-0.35.0/tests/parallel_shared.rs
@@ -0,0 +1 @@
+mod parallel;
diff --git a/vendor/gix-features-0.35.0/tests/parallel_shared_threaded.rs b/vendor/gix-features-0.35.0/tests/parallel_shared_threaded.rs
new file mode 100644
index 000000000..055a899ea
--- /dev/null
+++ b/vendor/gix-features-0.35.0/tests/parallel_shared_threaded.rs
@@ -0,0 +1 @@
+mod parallel;
diff --git a/vendor/gix-features-0.35.0/tests/parallel_threaded.rs b/vendor/gix-features-0.35.0/tests/parallel_threaded.rs
new file mode 100644
index 000000000..05f49d195
--- /dev/null
+++ b/vendor/gix-features-0.35.0/tests/parallel_threaded.rs
@@ -0,0 +1,122 @@
+mod optimize_chunk_size_and_thread_limit {
+ use gix_features::parallel::optimize_chunk_size_and_thread_limit;
+
+ #[test]
+ fn not_enough_chunks_for_threads() {
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(1, Some(10), None, Some(10)),
+ (1, Some(5), 5)
+ );
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(1, Some(10), Some(3), Some(10)),
+ (1, Some(3), 3),
+ "the thread limit is always respected"
+ );
+ }
+
+ #[test]
+ fn some_more_chunks_per_thread() {
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(1, Some(30), None, Some(10)),
+ (1, Some(10), 10)
+ );
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(1, Some(30), Some(5), Some(10)),
+ (3, Some(5), 5),
+ "the thread limit is always respected"
+ );
+ }
+
+ #[test]
+ fn chunk_size_too_small() {
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(1, Some(100), None, Some(10)),
+ (5, Some(10), 10)
+ );
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(1, Some(100), Some(5), Some(10)),
+ (10, Some(5), 5),
+ "the thread limit is always respected"
+ );
+ }
+
+ #[test]
+ fn chunk_size_too_big() {
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(50, Some(100), None, Some(10)),
+ (5, Some(10), 10)
+ );
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(50, Some(100), Some(5), Some(10)),
+ (10, Some(5), 5),
+ "the thread limit is always respected"
+ );
+ }
+
+ mod unknown_chunk_count {
+ use gix_features::parallel::optimize_chunk_size_and_thread_limit;
+
+ #[test]
+ fn medium_chunk_size_many_threads() {
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(50, None, None, Some(4)),
+ (50, Some(4), 4),
+ "really, what do we know"
+ );
+ }
+
+ #[test]
+ fn medium_chunk_size_single_thread() {
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(50, None, None, Some(1)),
+ (50, Some(1), 1),
+ "single threaded - we don't touch that"
+ );
+ }
+
+ #[test]
+ fn small_chunk_size_single_thread() {
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(1, None, None, Some(1)),
+ (1, Some(1), 1),
+ "single threaded - we don't touch that"
+ );
+ }
+
+ #[test]
+ fn small_chunk_size_many_threads() {
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(1, None, None, Some(4)),
+ (50, Some(4), 4),
+ "we prefer an arbitrary number, which should really be based on effort, but the caller has to adjust for that"
+ );
+ }
+ }
+
+ mod real_values {
+ use gix_features::parallel::optimize_chunk_size_and_thread_limit;
+
+ #[test]
+ fn linux_kernel_pack_my_machine_lookup() {
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(10000, Some(7_500_000), None, Some(4)),
+ (1000, Some(4), 4),
+ "the bucket size is capped actually, somewhat arbitrarily"
+ );
+ }
+
+ #[test]
+ fn linux_kernel_pack_my_machine_indexed() {
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(1, None, None, Some(4)),
+ (50, Some(4), 4),
+ "low values are raised to arbitrary value"
+ );
+ assert_eq!(
+ optimize_chunk_size_and_thread_limit(10000, None, None, Some(4)),
+ (1000, Some(4), 4),
+ "high values are capped"
+ );
+ }
+ }
+}
diff --git a/vendor/gix-features-0.35.0/tests/pipe.rs b/vendor/gix-features-0.35.0/tests/pipe.rs
new file mode 100644
index 000000000..38cd8e598
--- /dev/null
+++ b/vendor/gix-features-0.35.0/tests/pipe.rs
@@ -0,0 +1,117 @@
+mod io {
+ use std::io::{BufRead, ErrorKind, Read, Write};
+
+ use gix_features::io;
+
+ #[test]
+ fn threaded_read_to_end() {
+ let (mut writer, mut reader) = gix_features::io::pipe::unidirectional(0);
+
+ let message = "Hello, world!";
+ std::thread::spawn(move || {
+ writer
+ .write_all(message.as_bytes())
+ .expect("writes to work if reader is present")
+ });
+
+ let mut received = String::new();
+ reader.read_to_string(&mut received).unwrap();
+
+ assert_eq!(&received, message);
+ }
+
+ #[test]
+ fn lack_of_reader_fails_with_broken_pipe() {
+ let (mut writer, _) = io::pipe::unidirectional(0);
+ assert_eq!(
+ writer.write_all(b"must fail").unwrap_err().kind(),
+ ErrorKind::BrokenPipe
+ );
+ }
+ #[test]
+ fn line_reading_one_by_one() {
+ let (mut writer, mut reader) = io::pipe::unidirectional(2);
+ writer.write_all(b"a\n").expect("success");
+ writer.write_all(b"b\nc").expect("success");
+ drop(writer);
+ let mut buf = String::new();
+ for expected in &["a\n", "b\n", "c"] {
+ buf.clear();
+ assert_eq!(reader.read_line(&mut buf).expect("success"), expected.len());
+ assert_eq!(buf, *expected);
+ }
+ }
+
+ #[test]
+ fn line_reading() {
+ let (mut writer, reader) = io::pipe::unidirectional(2);
+ writer.write_all(b"a\n").expect("success");
+ writer.write_all(b"b\nc\n").expect("success");
+ drop(writer);
+ assert_eq!(
+ reader.lines().map_while(Result::ok).collect::<Vec<_>>(),
+ vec!["a", "b", "c"]
+ )
+ }
+
+ #[test]
+ fn writer_can_inject_errors() {
+ let (writer, mut reader) = io::pipe::unidirectional(1);
+ writer
+ .channel
+ .send(Err(std::io::Error::new(std::io::ErrorKind::Other, "the error")))
+ .expect("send success");
+ let mut buf = [0];
+ assert_eq!(
+ reader.read(&mut buf).unwrap_err().to_string(),
+ "the error",
+ "using Read trait, errors are propagated"
+ );
+
+ writer
+ .channel
+ .send(Err(std::io::Error::new(std::io::ErrorKind::Other, "the error")))
+ .expect("send success");
+ assert_eq!(
+ reader.fill_buf().unwrap_err().to_string(),
+ "the error",
+ "using BufRead trait, errors are propagated"
+ );
+ }
+
+ #[test]
+ fn continue_on_empty_writes() {
+ let (mut writer, mut reader) = io::pipe::unidirectional(2);
+ writer.write_all(&[]).expect("write successful and non-blocking");
+ let input = b"hello";
+ writer
+ .write_all(input)
+ .expect("second write works as well as there is capacity");
+ let mut buf = vec![0u8; input.len()];
+ assert_eq!(reader.read(&mut buf).expect("read succeeds"), input.len());
+ assert_eq!(buf, &input[..]);
+ }
+
+ #[test]
+ fn small_reads() {
+ const BLOCK_SIZE: usize = 20;
+ let block_count = 20;
+ let (mut writer, mut reader) = io::pipe::unidirectional(4);
+ std::thread::spawn(move || {
+ for _ in 0..block_count {
+ let data = &[0; BLOCK_SIZE];
+ writer.write_all(data).unwrap();
+ }
+ });
+
+ let mut small_read_buf = [0; BLOCK_SIZE / 2];
+ let mut bytes_read = 0;
+ while let Ok(size) = reader.read(&mut small_read_buf) {
+ if size == 0 {
+ break;
+ }
+ bytes_read += size;
+ }
+ assert_eq!(block_count * BLOCK_SIZE, bytes_read);
+ }
+}
diff --git a/vendor/gix-features-0.35.0/tests/trace/mod.rs b/vendor/gix-features-0.35.0/tests/trace/mod.rs
new file mode 100644
index 000000000..614a0bb62
--- /dev/null
+++ b/vendor/gix-features-0.35.0/tests/trace/mod.rs
@@ -0,0 +1,15 @@
+use gix_features::trace::{coarse, detail, span};
+#[test]
+fn span() {
+ let _x = span!(gix_features::trace::Level::Coarse, "hello");
+ span!(gix_features::trace::Level::Coarse, "hello", x = "value", y = 42);
+ span!(target: "other", gix_features::trace::Level::Coarse, "hello", x = "value", y = 42);
+
+ let _x = coarse!("hello");
+ coarse!("hello", x = "value", y = 42);
+ coarse!(target: "other", "hello", x = "value", y = 42);
+
+ let _y = detail!("hello");
+ detail!("hello", x = "value", y = 42);
+ detail!(target: "other", "hello", x = "value", y = 42);
+}