diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
commit | 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch) | |
tree | bdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/gix-worktree | |
parent | Releasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff) | |
download | rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip |
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-worktree')
-rw-r--r-- | vendor/gix-worktree/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | vendor/gix-worktree/CHANGELOG.md | 597 | ||||
-rw-r--r-- | vendor/gix-worktree/Cargo.toml | 108 | ||||
-rw-r--r-- | vendor/gix-worktree/src/fs/cache/mod.rs | 148 | ||||
-rw-r--r-- | vendor/gix-worktree/src/fs/cache/platform.rs | 171 | ||||
-rw-r--r-- | vendor/gix-worktree/src/fs/cache/state.rs | 301 | ||||
-rw-r--r-- | vendor/gix-worktree/src/fs/capabilities.rs | 122 | ||||
-rw-r--r-- | vendor/gix-worktree/src/fs/mod.rs | 81 | ||||
-rw-r--r-- | vendor/gix-worktree/src/fs/stack.rs | 123 | ||||
-rw-r--r-- | vendor/gix-worktree/src/index/checkout.rs | 95 | ||||
-rw-r--r-- | vendor/gix-worktree/src/index/entry.rs | 189 | ||||
-rw-r--r-- | vendor/gix-worktree/src/index/mod.rs | 311 | ||||
-rw-r--r-- | vendor/gix-worktree/src/lib.rs | 15 | ||||
-rw-r--r-- | vendor/gix-worktree/src/os.rs | 50 |
14 files changed, 2312 insertions, 0 deletions
diff --git a/vendor/gix-worktree/.cargo-checksum.json b/vendor/gix-worktree/.cargo-checksum.json new file mode 100644 index 000000000..05ef2d67d --- /dev/null +++ b/vendor/gix-worktree/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"f27480a1ff03330e21aa31af5771a5f43680eb181ee3d8f277d30cf5cd7b5dbe","Cargo.toml":"471d9f4276e104d25f1d93d1910887e5718a0b896c5864553ebed7364f763041","src/fs/cache/mod.rs":"d0dc1e6d696969a276c43ff0ff579a2eee3db024ea67f2596f96ae516b7fb744","src/fs/cache/platform.rs":"dd33b4e7abfe13909be4adb5dd85edc324d21c77a7b5e3f31e39b22e14ac18af","src/fs/cache/state.rs":"970d3a9de3d8a99265484ec12e457657b09d25e5346760529441faba7bf82c78","src/fs/capabilities.rs":"f82c1b0f1dd6ba2d838183aa9a2be4057b1dae39839f67ed318ffcdc2afbb9d4","src/fs/mod.rs":"d12e465fe856b0e3b1d074996c794e6bf0a67dda2b72451281c6d4d2bdf8696b","src/fs/stack.rs":"de9fadcdd88fb0482c723dd865cbab873fc02c3e54e5f8b7aaaf9273f374171d","src/index/checkout.rs":"b7dc669308076580aa0a74dc1918b1469d9fa2ec770e1c110a2bde68ba22a707","src/index/entry.rs":"5025018a17c7d6dfa584f9571cbf4221816d8ee683e65e2c9b4819a8aebf3833","src/index/mod.rs":"fcfafe9e31f89db0271783ac7c2f8780cfd96237c59157b10469da21c9678024","src/lib.rs":"f9b93c4d0edc40fe1823609b7ec34c28329db212239bcc6b4f191d524abe7512","src/os.rs":"c86c0768c04f57972deb921dd949d90a8b05fdf4d86e7c5c5614703c9339039d"},"package":"b7cb9af6e56152953d8fe113c4f9d7cf60cf7a982362711e9200a255579b49cb"}
\ No newline at end of file diff --git a/vendor/gix-worktree/CHANGELOG.md b/vendor/gix-worktree/CHANGELOG.md new file mode 100644 index 000000000..40b551689 --- /dev/null +++ b/vendor/gix-worktree/CHANGELOG.md @@ -0,0 +1,597 @@ +# 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.14.0 (2023-03-04) + +A maintenance release without user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 2 commits contributed to the release. + - 3 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** + - Prepare changelogs prior to release ([`895e482`](https://github.com/Byron/gitoxide/commit/895e482badf01e953bb9144001eebd5e1b1c4d84)) + - 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)) +</details> + +## 0.13.0 (2023-03-01) + +A maintenance release without user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 5 commits contributed to the release over the course of 2 calendar days. + - 8 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-tempfile v4.1.0, gix-lock v4.0.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, safety bump 6 crates ([`ea9fd1d`](https://github.com/Byron/gitoxide/commit/ea9fd1d9b60e1e9e17042e9e37c06525823c40a5)) + - 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)) + - Prepare for git-tempfile release ([`56c005b`](https://github.com/Byron/gitoxide/commit/56c005b13c44376f71e61781e73c0bf93416d0e4)) +</details> + +## 0.12.3 (2023-02-20) + +### Bug Fixes + + - <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/> + + - 3 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)) + - Release gix-glob v0.5.4 ([`c56d336`](https://github.com/Byron/gitoxide/commit/c56d3365fde21120cf6101cf34f8b5669804977c)) +</details> + +## 0.12.2 (2023-02-17) + +<csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> +<csr-id-533e887e80c5f7ede8392884562e1c5ba56fb9a8/> + +### New Features (BREAKING) + + - <csr-id-3d8fa8fef9800b1576beab8a5bc39b821157a5ed/> upgrade edition to 2021 in most crates. + MSRV for this is 1.56, and we are now at 1.60 so should be compatible. + This isn't more than a patch release as it should break nobody + who is adhering to the MSRV, but let's be careful and mark it + breaking. + + Note that `git-features` and `git-pack` are still on edition 2018 + as they make use of a workaround to support (safe) mutable access + to non-overlapping entries in a slice which doesn't work anymore + in edition 2021. + +### Changed (BREAKING) + + - <csr-id-d7ee622cfa9fc3cf7a97b823dd70f0aa1355365e/> Simplify `Cache` by removing its lifetime. + The lifetime was more of a premature optimization that makes actually using + the cache much harder than it needs to be. + - <csr-id-99905bacace8aed42b16d43f0f04cae996cb971c/> upgrade `bstr` to `1.0.1` + +### 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 + +### Chore + + - <csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> uniformize deny attributes + - <csr-id-533e887e80c5f7ede8392884562e1c5ba56fb9a8/> remove default link to cargo doc everywhere + +### Documentation + + - <csr-id-39ed9eda62b7718d5109135e5ad406fb1fe2978c/> fix typos + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 340 commits contributed to the release over the course of 405 calendar days. + - 8 commits were understood as [conventional](https://www.conventionalcommits.org). + - 11 unique issues were worked on: [#293](https://github.com/Byron/gitoxide/issues/293), [#298](https://github.com/Byron/gitoxide/issues/298), [#301](https://github.com/Byron/gitoxide/issues/301), [#331](https://github.com/Byron/gitoxide/issues/331), [#333](https://github.com/Byron/gitoxide/issues/333), [#364](https://github.com/Byron/gitoxide/issues/364), [#366](https://github.com/Byron/gitoxide/issues/366), [#384](https://github.com/Byron/gitoxide/issues/384), [#450](https://github.com/Byron/gitoxide/issues/450), [#470](https://github.com/Byron/gitoxide/issues/470), [#691](https://github.com/Byron/gitoxide/issues/691) + +### Thanks Clippy + +<csr-read-only-do-not-edit/> + +[Clippy](https://github.com/rust-lang/rust-clippy) helped 11 times to make code idiomatic. + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **[#293](https://github.com/Byron/gitoxide/issues/293)** + - Update changelog ([`b3ee7c6`](https://github.com/Byron/gitoxide/commit/b3ee7c6f7553de6bff4934bbdf38f6c6ea2cf349)) + - Preempt the eventual need for a worktree implementation ([`bce67d8`](https://github.com/Byron/gitoxide/commit/bce67d8ec58f78a1fce1c76f7b93d9650f9f550e)) + * **[#298](https://github.com/Byron/gitoxide/issues/298)** + - Use hash_hasher based hash state for better keys/less collisions ([`814de07`](https://github.com/Byron/gitoxide/commit/814de079f4226f42efa49ad334a348bce67184e4)) + * **[#301](https://github.com/Byron/gitoxide/issues/301)** + - Update changelogs prior to release ([`84cb256`](https://github.com/Byron/gitoxide/commit/84cb25614a5fcddff297c1713eba4efbb6ff1596)) + - Status quo test that shows gitoxide has the same limitation as git ([`5f6c2fb`](https://github.com/Byron/gitoxide/commit/5f6c2fb7787e674aa05af6185e665d6a33860f02)) + - Refactor ([`36fa167`](https://github.com/Byron/gitoxide/commit/36fa16761bd59d9c314e29b1b0911608ae409c1f)) + - Improve how directory excludes are handled ([`bea5ea5`](https://github.com/Byron/gitoxide/commit/bea5ea5cb3d304e73260fc1139b8fdc1acc139d7)) + - Fix inverted logic for matching non-negative pattern in `is_excluded()` ([`6d5784f`](https://github.com/Byron/gitoxide/commit/6d5784fc961c08fda7affffa4601baaea0000b98)) + - Reorganize types to properly represent worktrees in their various 'states' ([`b46bff5`](https://github.com/Byron/gitoxide/commit/b46bff58e40bb9805af7ee7f96272f0dc19c0ac7)) + - A sketch for worktree state ([`55e17a4`](https://github.com/Byron/gitoxide/commit/55e17a402c70be64609f0ffa98d1eaeee5146439)) + - Basic prefix support as well the first working version of `exclude query` ([`9cb8385`](https://github.com/Byron/gitoxide/commit/9cb83859f9bb76f38ab5bbd0ae6d6f20a691e9e1)) + - Revert "Turn attribute files into a Cow to support other usecases…" ([`ed7f223`](https://github.com/Byron/gitoxide/commit/ed7f223b1bee688dbd257a59f3317f39bf5eb2cd)) + - Turn attribute files into a Cow to support other usecases… ([`d0c8407`](https://github.com/Byron/gitoxide/commit/d0c84079bdd4bb7746f47f132868ed4743f5dda0)) + - Make use of new git-glob::Pattern::to_string() feature ([`d29932d`](https://github.com/Byron/gitoxide/commit/d29932dc579f0579990bca1dcfc656ac020be50e)) + - Some tests to check pattern negation ([`2672a25`](https://github.com/Byron/gitoxide/commit/2672a25dae546f85807a7e5ec1939240221a5a14)) + - Test for case-sensitivity as well ([`120675d`](https://github.com/Byron/gitoxide/commit/120675db0508a6bb9d1e0eca45edf3f15632cd2f)) + - The stack now allows to change a non-dir into a dir ([`6793bab`](https://github.com/Byron/gitoxide/commit/6793bab687bf492da545981e0116322dab4455cb)) + - Allow check-ignore style queries with API that doesn't remove trailing slashes ([`e68cd69`](https://github.com/Byron/gitoxide/commit/e68cd692b5230592ca2ca17418d9b9fda9f3e317)) + - More tests and fixes to assure directory logic in stack works ([`2010ddd`](https://github.com/Byron/gitoxide/commit/2010dddf244335f3967d0debb5d8e0f3ffdac6a7)) + - Improved testing… ([`e191b72`](https://github.com/Byron/gitoxide/commit/e191b7220c5286bb0d0038398810ae344de626d3)) + - Refactor ([`21d4076`](https://github.com/Byron/gitoxide/commit/21d407638285b728d0c64fabf2abe0e1948e9bec)) + - Don't hardcode case in state::Ignore ([`a6532e7`](https://github.com/Byron/gitoxide/commit/a6532e7fd94757dc5b4b231b63cb2cbcacf1e602)) + - The first indication that directory-based excludes work ([`e868acc`](https://github.com/Byron/gitoxide/commit/e868acce2e7c3e2501497bf630e3a54f349ad38e)) + - Adapt to all changes in git-path with bstr support ([`f158648`](https://github.com/Byron/gitoxide/commit/f158648aef8ad94d86550ceb2eeb20efb3df7596)) + - Use `git-path` crate instead of `git_features::path` ([`47e607d`](https://github.com/Byron/gitoxide/commit/47e607dc256a43a3411406c645eb7ff04239dd3a)) + - Adjustments to go along with changes in git-features ([`c55cac6`](https://github.com/Byron/gitoxide/commit/c55cac6a1ada77619bb5723717a5a6d757499fa9)) + - Refactor ([`8345b7c`](https://github.com/Byron/gitoxide/commit/8345b7caa0cc1cd8489e41822eea89da4c539e6d)) + - Customize stack operation to support the notion of directories ([`2659816`](https://github.com/Byron/gitoxide/commit/26598163ce0a029e7eb92d862f899bdaadad3e90)) + - And finally, we can read ignore files from the index, too ([`910d500`](https://github.com/Byron/gitoxide/commit/910d5000d479939c14e330b6f1a12d50dd57cdd6)) + - Wire everything up to have all data where it needs to be, but… ([`34d0d5c`](https://github.com/Byron/gitoxide/commit/34d0d5c5bedae5ed069fd147c19cfb7414b66fb5)) + - Refactor ([`883d78d`](https://github.com/Byron/gitoxide/commit/883d78d3d17cae1b3bdd9801abb3ee6f9452c1a0)) + - Fix MSRV ([`63f0839`](https://github.com/Byron/gitoxide/commit/63f08391af5da3901190797532566758e3dff9e3)) + - Support for shared attribute file names ([`e4044a4`](https://github.com/Byron/gitoxide/commit/e4044a48c606497e5de0fd711c7a5ce7afc44117)) + - Use a separate path mapping to enable clone-avoidance ([`e525b5e`](https://github.com/Byron/gitoxide/commit/e525b5e5138ec0050f1ff178b5985cc7ce440b3a)) + - Fix borrow check issues the fast way, but… ([`514e2f4`](https://github.com/Byron/gitoxide/commit/514e2f424fa4976693393c6d0911b724f94b1c70)) + - Try to keep borrows to path backing alive but… ([`4234b84`](https://github.com/Byron/gitoxide/commit/4234b8497e3819eaae66f4c0462b5fc29509d675)) + - Refactor ([`b14904b`](https://github.com/Byron/gitoxide/commit/b14904b54587f99f8741fa59eda6c2b9db98fff7)) + - Doing things directly works fortunately ([`6f74f85`](https://github.com/Byron/gitoxide/commit/6f74f8516ba73c35b1b327aae491f70f83eefafd)) + - An attempt to build a lookup table of attribute files, but… ([`9841efb`](https://github.com/Byron/gitoxide/commit/9841efb566748dae6c79c5990c4fd1ecbc468aef)) + - Refactor ([`475aa6a`](https://github.com/Byron/gitoxide/commit/475aa6a3e08f63df627a0988cd16c20494960c79)) + - Make .gitignore name overridable ([`155bb82`](https://github.com/Byron/gitoxide/commit/155bb820be03d4ac210b6ae4a76ecfb33445271e)) + - A test to check skip-worktree special case with ignore files ([`dec9f33`](https://github.com/Byron/gitoxide/commit/dec9f332ecd2eaf7bad8ce0f94194d68624d9ac7)) + - A baseline test that indicates how excludes aren't using data from the index initially ([`e58b771`](https://github.com/Byron/gitoxide/commit/e58b771cd514024e63c1ab7af7c0d0abad00797d)) + - First primitive ignore pattern test works ([`0424136`](https://github.com/Byron/gitoxide/commit/04241367e8ce99ce6c7583d5dac4955fad3d6542)) + - Refactor to make push/pop with mutable state work; prepare to read .gitignore files ([`8d1000b`](https://github.com/Byron/gitoxide/commit/8d1000b30257675564195202b15dca1ab1538227)) + - Add baseline test to motivate implementing ignore file stack ([`ce40add`](https://github.com/Byron/gitoxide/commit/ce40add21add518374d9ff6d40fe488e2f29ce6d)) + - Re-export `git-glob` as its `Case` type is part of the public API ([`4b72045`](https://github.com/Byron/gitoxide/commit/4b7204516a7c61162a2940eb66e8a7c64bf78ce7)) + - Sketch state for handling attributes as well ([`d87d62d`](https://github.com/Byron/gitoxide/commit/d87d62db5cf327397390ec7888c1d1155619ba38)) + - Sketch state for handling excludes ([`eb525f7`](https://github.com/Byron/gitoxide/commit/eb525f76134a2ffd770848941c976ec456fcc296)) + - Sketch how attribute globals could be used in worktrees ([`97ee03d`](https://github.com/Byron/gitoxide/commit/97ee03d5e4703b583dd5bb741dbf43f310404882)) + - Adjustments to support lower MSRV ([`16a0973`](https://github.com/Byron/gitoxide/commit/16a09737f0e81654cc7a5bbc9043385528524ca5)) + - Remove `git-dir` for `checkout()` as it's something to be dealt with elsewhere ([`f7996b8`](https://github.com/Byron/gitoxide/commit/f7996b8f6a877275b8725804c558b51732e8b469)) + - An idea on how to test excludes, but… ([`9c036e8`](https://github.com/Byron/gitoxide/commit/9c036e81b3abcd5dcde2b023459a15cbd281824d)) + - Make attributes and ignore configuration possible, but… ([`8a75fd7`](https://github.com/Byron/gitoxide/commit/8a75fd745a194786f0da7c1fd660211446ea51f7)) + - Refactor ([`80af734`](https://github.com/Byron/gitoxide/commit/80af734a5ddfd0785ec946a3609887b5d503d03d)) + - Provide a platform for multiple queries at a dir cache level ([`48be382`](https://github.com/Byron/gitoxide/commit/48be3828ea07124c4d21cb10121780f596116bcb)) + - Be explicit about the cache-modes that actually happen ([`dc12f88`](https://github.com/Byron/gitoxide/commit/dc12f88a5d2e54e2ff987127bab37e5bd7ce314a)) + - Refactor ([`5d30018`](https://github.com/Byron/gitoxide/commit/5d300181c0696430c75bec7070da35cb308a1b9a)) + - Refactor ([`fe46078`](https://github.com/Byron/gitoxide/commit/fe46078dd9496744b048165fba548df5c3f76991)) + - Port PathCache over to `Stack` ([`ebfea8d`](https://github.com/Byron/gitoxide/commit/ebfea8d4be1afb3bd47bcffbaf5d705bed2d1ed6)) + - A sketch for a generalized version of a path stack ([`0d3ba1a`](https://github.com/Byron/gitoxide/commit/0d3ba1a02f076d32334d85f68d99e6b8033844ad)) + - Refactor ([`fe6641c`](https://github.com/Byron/gitoxide/commit/fe6641c86704df67b020510700e9c087fff5a52c)) + - Refactor ([`f86eacc`](https://github.com/Byron/gitoxide/commit/f86eacc5cfaf6d88ead4f8dbd65989d32674c213)) + - Use io-close instead of close-file - works ([`279461b`](https://github.com/Byron/gitoxide/commit/279461ba1741ace0399127ca9089230082bbf3e0)) + - Better error handling on close ([`a28c9b3`](https://github.com/Byron/gitoxide/commit/a28c9b32466a431450a504e313d2e49926e36a98)) + - Try close_file crate and see tests fail for some reason ([`c7e1400`](https://github.com/Byron/gitoxide/commit/c7e140094a3a5947cf59107d5a621245ea2ecbeb)) + - More multi-threaded test stability ([`be5a19e`](https://github.com/Byron/gitoxide/commit/be5a19e0eb2e895d03b80afc24c7b8d2d436458d)) + - Avoid racyness in worktree tests ([`c8a1319`](https://github.com/Byron/gitoxide/commit/c8a13198a12939befa473b30131e5a763c6fc28c)) + - Stabilize assertions in parallel mode ([`21d6f88`](https://github.com/Byron/gitoxide/commit/21d6f880293de4e8ffc6a8472eb1b54d8b1b105a)) + - A reducer which produces progress reporting each time it feeds ([`e83079d`](https://github.com/Byron/gitoxide/commit/e83079d219c96692725ab8af1c0e656cb331ecd8)) + - Call chunk processing in threaded processor ([`6bfd865`](https://github.com/Byron/gitoxide/commit/6bfd865a0578eeacd8d19eaa89d8914ac947c62a)) + - Conversions from Rc to arc for Handle ([`c19331e`](https://github.com/Byron/gitoxide/commit/c19331e001e587e4fca74f3e9fec28a7df922c0a)) + - Basic parallelization, without proper reducer, just so it compiles ([`5f29c0f`](https://github.com/Byron/gitoxide/commit/5f29c0f66d0aa6c045bfdf6f39a806ce8c4a5100)) + - Decouple amount of bytes written from progress ([`9ecdade`](https://github.com/Byron/gitoxide/commit/9ecdade0f117b966c98f48d1879bdba21ccaafd7)) + - Parallel and non-parallel tests ([`1cd7eb3`](https://github.com/Byron/gitoxide/commit/1cd7eb3f720e8b66792c942a99d7d9d85069ec03)) + - Switch index checkout to chunk-based operation ([`e5f6943`](https://github.com/Byron/gitoxide/commit/e5f69433e4a6cc7866b666e0baccfa32efb92a7f)) + - Proper handling of interruptions during checkout ([`7575a58`](https://github.com/Byron/gitoxide/commit/7575a5854ebe61a5941177efb470143192223ef3)) + - Add thread-count and chunk-size computation; interrupt capability ([`8cbe85d`](https://github.com/Byron/gitoxide/commit/8cbe85d135898826a91939726465a9e295c1e24b)) + - Refactor ([`542f49b`](https://github.com/Byron/gitoxide/commit/542f49beb811f7f9bf9dff3cd19694498f6cf9e2)) + - Refactor ([`c3c31af`](https://github.com/Byron/gitoxide/commit/c3c31afb9dee5040abef7a8d6f8e1e2cba29e2d7)) + - Fix windows test expecations for good ([`81bcb8d`](https://github.com/Byron/gitoxide/commit/81bcb8d281099e952a5e3c075d9578f15f2f2a0d)) + - Try to fix windows once again ([`ff95265`](https://github.com/Byron/gitoxide/commit/ff95265a35fb9f340c3a9fa78f8beba24d6734ff)) + - Some more debugging on windows ([`0c18443`](https://github.com/Byron/gitoxide/commit/0c18443f5195e10c99504c4f527c1882fcf84e45)) + - Debug mode for windows ([`8f3bc5a`](https://github.com/Byron/gitoxide/commit/8f3bc5a3195770753b0b6445259ce20ab609b393)) + - See if we can remove symlinks this way on windows ([`0bc9489`](https://github.com/Byron/gitoxide/commit/0bc94891c92f324d3940e064e8918b117db4641d)) + - Delete directories recursively on overwrite-existing ([`ea561e6`](https://github.com/Byron/gitoxide/commit/ea561e6f7d398991f214957dbd92e1b6a81e9ab0)) + - Better symlink checking on ubuntu ([`facad25`](https://github.com/Byron/gitoxide/commit/facad25c08b82a975eda70493d4818ca7c560aa8)) + - Overwrite-existing support with tests ([`49d1d34`](https://github.com/Byron/gitoxide/commit/49d1d34dff76d8b1e5e7fa9d08e6ead4e8bca018)) + - Fix dir-cache to properly handle its valiity which fixes test ([`52c0058`](https://github.com/Byron/gitoxide/commit/52c0058531df1a0f3fc755c5c51e71d34841cb77)) + - Delayed symlink creation for everyone, but… ([`ab5cd3d`](https://github.com/Byron/gitoxide/commit/ab5cd3d383c3c6cb31a7b8d387daedacb9e3838f)) + - Delayed symlink creation for windows, but… ([`77b053d`](https://github.com/Byron/gitoxide/commit/77b053dfd38e30a8ab397704059283a4766b9601)) + - Prepare for first overwrite test… ([`cd6e086`](https://github.com/Byron/gitoxide/commit/cd6e08644df3a2b52aa70a2f37e988ec10b280f0)) + - Fix case-insensitive tests ([`ccd25cb`](https://github.com/Byron/gitoxide/commit/ccd25cb5929554c69ea1250c6d2762fdd6ef5bbd)) + - Allow symlinks to dirs to be returned, too ([`d3d7a7c`](https://github.com/Byron/gitoxide/commit/d3d7a7c3c67868ba0fda6b04e6874aa2f91f638b)) + - Try to fix tests on linux ([`9f9d36d`](https://github.com/Byron/gitoxide/commit/9f9d36d7d7bba443fba5917e9920911596fd64f6)) + - A stab at making file writes safer… ([`805c0da`](https://github.com/Byron/gitoxide/commit/805c0da62204b8c4675c9c098e10eb0fe2bc12a9)) + - Mior refactor and notes towards parallelization ([`99de1ef`](https://github.com/Byron/gitoxide/commit/99de1ef494719cb4d46e3414474e619225fe7bd4)) + - Return proper errors during checkout object lookup ([`f9beac0`](https://github.com/Byron/gitoxide/commit/f9beac0471a38cb4c3b070ecb576ed1a39456bd6)) + - Switch worktree to thiserror ([`bacc654`](https://github.com/Byron/gitoxide/commit/bacc65481d4ff5ecfbdf3755383b60f354deaf47)) + - Sub-command to print multi-index entries ([`6c10e09`](https://github.com/Byron/gitoxide/commit/6c10e097a432d81b930008abc00c6821ed7ac9be)) + - Bring back more detailed errors in case of keep-going ([`8198817`](https://github.com/Byron/gitoxide/commit/8198817507a5e9c6e6fb847a45ac47bd38de68f6)) + - Use progress to print errors right when they happen ([`af03686`](https://github.com/Byron/gitoxide/commit/af03686b5abf9548300a83329500b27acd66e16a)) + - Implement 'keep-going' for index checkout ([`ecebc55`](https://github.com/Byron/gitoxide/commit/ecebc55f8321c67f57111f8d0002e75388dd3734)) + - Support for forceful removal of symlinks or files during dir creation ([`749c310`](https://github.com/Byron/gitoxide/commit/749c3100d785f7ac373bdb109fda21f2ac62d5c0)) + - Forbid symlinks and files in the path ([`de58f50`](https://github.com/Byron/gitoxide/commit/de58f50748bd70e39d29e503a7f4b1e6c9b20093)) + - Avoid popping the entire cached path ([`a3501df`](https://github.com/Byron/gitoxide/commit/a3501df6eb8d2fd3176434c80c443316e91dabb6)) + - Basic impl of the dir cache which already avoids unnecessary allocations ([`cb36d56`](https://github.com/Byron/gitoxide/commit/cb36d5691294971e1b0e097ed11908768283731a)) + - Sketch out dir cache and realize that git uses chdir ([`f4621cc`](https://github.com/Byron/gitoxide/commit/f4621cc4dd48fcd4b1aba294c811bc92f2715981)) + - Allow writing empty files during checkout but also query the odb ([`5388d80`](https://github.com/Byron/gitoxide/commit/5388d8091ef02cf927478a1492847ae1666040d4)) + - Basic version of index checkout via command-line ([`f23b8d2`](https://github.com/Byron/gitoxide/commit/f23b8d2f1c4b767d337ec51888afaa8b3719798c)) + - Basic progress reporting for checkout ([`039e822`](https://github.com/Byron/gitoxide/commit/039e822bb4e56e49432db5c53081e0eb39588d66)) + - Support for unicode-precomposition for gix apps ([`e90c123`](https://github.com/Byron/gitoxide/commit/e90c123675a98ab62fc6bb22019f889cee8b7301)) + - Fix symlink creation on windows, hopefully ([`4b1650b`](https://github.com/Byron/gitoxide/commit/4b1650ba1988f52a7a91ce4f5327eca350f32520)) + - Gather more information about test failure on windows ([`be5e3fb`](https://github.com/Byron/gitoxide/commit/be5e3fb3a19f86e37244b17055bf31cc455e78e8)) + - Hopefully fix symlink creation on windows ([`acb8acd`](https://github.com/Byron/gitoxide/commit/acb8acd905c4a7ec0fbc831b159f626962c0a37d)) + - Refactor ([`48dc401`](https://github.com/Byron/gitoxide/commit/48dc40195fd3d41d1fa5cd6326422ae18266dd7d)) + - Also validate symlink collisions ([`322c316`](https://github.com/Byron/gitoxide/commit/322c3161947cd5c10e3122c097d5a888726d42c1)) + - Fix compile warnings ([`58145bc`](https://github.com/Byron/gitoxide/commit/58145bc0fc329c370638a336215679fa727a9f0f)) + - Try to fix windows ([`5c1e727`](https://github.com/Byron/gitoxide/commit/5c1e727a1af4b9a0b5b7dcfca0d1ef5a533a66b6)) + - Finally an understanding on collision checking ([`0454e4a`](https://github.com/Byron/gitoxide/commit/0454e4a6f039541255728c4c8e076578236f0d86)) + - Add check_stat and trust_ctime options to index checkout ([`1a502c7`](https://github.com/Byron/gitoxide/commit/1a502c7e456a191d8639b799648ea33eb5a7dac2)) + - Validate that colliding files are checked out ([`09fecd9`](https://github.com/Byron/gitoxide/commit/09fecd9687cf3271f7138bca9214ba99c17b5ef7)) + - Support for executable bit check ([`267e3a7`](https://github.com/Byron/gitoxide/commit/267e3a7f4718c8f724e3e4488dd24dcebfc69413)) + - Probe precompose unicode ([`0c1c006`](https://github.com/Byron/gitoxide/commit/0c1c00689000dfc943ed25cd52eac42e3642a78c)) + - Refactor ([`fc816bd`](https://github.com/Byron/gitoxide/commit/fc816bd12f142d1df4d10429ee5b56e9eb5fbf4d)) + - Determine filesystem case ([`f8e1de0`](https://github.com/Byron/gitoxide/commit/f8e1de0dc031ad73084b2da6a6d39960b9b78b4b)) + - Basic test for filesystem probing ([`adbed12`](https://github.com/Byron/gitoxide/commit/adbed121f969a05b622d0325b434b3c6d44ae248)) + - Symlink probing ([`1bfbf1d`](https://github.com/Byron/gitoxide/commit/1bfbf1d120e31474367cd2008e1715c50af19071)) + - Make clear that we are currently only dealing with checkout during clone ([`178beb4`](https://github.com/Byron/gitoxide/commit/178beb42eaf1112143299eafa7fc93106eb9fc5b)) + - Refactor for checkout to use fs::Context ([`8914fcc`](https://github.com/Byron/gitoxide/commit/8914fcc114cdf920f2f4162e71d4d390007f6f3b)) + - Document-features support for git-index and git-worktree ([`1367cf5`](https://github.com/Byron/gitoxide/commit/1367cf5bc5908639e67e12f78f57835c5fd68a90)) + - Support for 'serde1' feature in git-worktree ([`f11929c`](https://github.com/Byron/gitoxide/commit/f11929c9652b2f414029f2ad02dacee238a138d1)) + - Sketch filesystem context, without probing for now ([`de3749e`](https://github.com/Byron/gitoxide/commit/de3749e1426d48a1d31a0ddc1fddfdb394a01078)) + - Refactor ([`004394a`](https://github.com/Byron/gitoxide/commit/004394ad04a965b631c5d75a7eced632540d9e1e)) + - Restructure tests ([`831c429`](https://github.com/Byron/gitoxide/commit/831c4294c87aae0594e1238177dd71efb997cbde)) + - Make fmt ([`636fa8a`](https://github.com/Byron/gitoxide/commit/636fa8a97ce56982c76dffc64ee084e31d39afad)) + - Strucural refactor ([`cdca1df`](https://github.com/Byron/gitoxide/commit/cdca1dfec590d24dd42f34294e21f4bdf61d36ad)) + - Allow mutation of entries during iteration, while obtaining their path ([`d0c4563`](https://github.com/Byron/gitoxide/commit/d0c4563f71ea18aaf8ae21dd8646ab256a550594)) + - Refactor ([`72af261`](https://github.com/Byron/gitoxide/commit/72af261603ee38651e15015547871d0510ce6370)) + * **[#331](https://github.com/Byron/gitoxide/issues/331)** + - Fix build ([`f6d9693`](https://github.com/Byron/gitoxide/commit/f6d969370b8ef05b3b29983dcd9f6fa11d6225f2)) + * **[#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)) + * **[#364](https://github.com/Byron/gitoxide/issues/364)** + - Update changelogs prior to release ([`746a676`](https://github.com/Byron/gitoxide/commit/746a676056cd4907da7137a00798344b5bdb4419)) + * **[#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)) + * **[#384](https://github.com/Byron/gitoxide/issues/384)** + - Prevent line-ending conversions for shell scripts on windows ([`96bb4d4`](https://github.com/Byron/gitoxide/commit/96bb4d460db420e18dfd0f925109c740e971820d)) + - No need to isolate archives by crate name ([`19d46f3`](https://github.com/Byron/gitoxide/commit/19d46f35440419b9911b6e2bca2cfc975865dce9)) + - Add archive files via git-lfs ([`7202a1c`](https://github.com/Byron/gitoxide/commit/7202a1c4734ad904c026ee3e4e2143c0461d51a2)) + - Assure we don't pick up unnecessary files during publishing ([`545b2d5`](https://github.com/Byron/gitoxide/commit/545b2d5121ba64efaee7564d5191cec37661efd7)) + - Auto-set commit.gpgsign=false when executing git ([`c23feb6`](https://github.com/Byron/gitoxide/commit/c23feb64ad157180cfba8a11c882b829733ea8f6)) + * **[#450](https://github.com/Byron/gitoxide/issues/450)** + - Make it possible to clone empty remote repositories ([`e97eeda`](https://github.com/Byron/gitoxide/commit/e97eeda45c9cc0736273c735a9959ac1ff29fc9d)) + - Refactor ([`dd3b336`](https://github.com/Byron/gitoxide/commit/dd3b336656f5282f386c1cba0974abd2b09d81e9)) + - Upgrade `bstr` to `1.0.1` ([`99905ba`](https://github.com/Byron/gitoxide/commit/99905bacace8aed42b16d43f0f04cae996cb971c)) + * **[#470](https://github.com/Byron/gitoxide/issues/470)** + - Update changelogs prior to release ([`caa7a1b`](https://github.com/Byron/gitoxide/commit/caa7a1bdef74d7d3166a7e38127a59f5ab3cfbdd)) + * **[#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-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 ([`7fc00f8`](https://github.com/Byron/gitoxide/commit/7fc00f87d74aedf631ce4032be1cdfe1804c7e7d)) + - Release 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 ([`59e9fac`](https://github.com/Byron/gitoxide/commit/59e9fac67d1b353e124300435b55f6b5468d7deb)) + - Release 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 ([`48f5bd2`](https://github.com/Byron/gitoxide/commit/48f5bd2014fa3dda6fbd60d091065c5537f69453)) + - Release 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 ([`a5869e0`](https://github.com/Byron/gitoxide/commit/a5869e0b223406820bca836e3e3a7fae2bfd9b04)) + - Release 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 ([`41d57b9`](https://github.com/Byron/gitoxide/commit/41d57b98964094fc1528adb09f69ca824229bf25)) + - Release 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 ([`e313112`](https://github.com/Byron/gitoxide/commit/e31311257bd138b52042dea5fc40c3abab7f269b)) + - 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-lfs` to `gix-lfs` ([`b9225c8`](https://github.com/Byron/gitoxide/commit/b9225c830daf1388484ee7e05f727990fdeff43c)) + - 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)) + - Rename `git-worktree` to `gix-worktree` ([`2b59ff2`](https://github.com/Byron/gitoxide/commit/2b59ff25fd095cac93f7d607594f68a5e329861e)) + - 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)) + - 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)) + - Release git-features v0.26.3 ([`1ecfb7f`](https://github.com/Byron/gitoxide/commit/1ecfb7f8bfb24432690d8f31367488f2e59a642a)) + - Release git-worktree v0.12.2 ([`0780f35`](https://github.com/Byron/gitoxide/commit/0780f354aaa2fa16200b33b0f76c0cec21e79cfc)) + - 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)) + - Thanks clippy ([`bac57dd`](https://github.com/Byron/gitoxide/commit/bac57dd05ea2d5a4ee45ef9350fa3f2e19474bc0)) + - Make fmt ([`e22080e`](https://github.com/Byron/gitoxide/commit/e22080e4a29d0bad15a99d565a5e3e304a8743ec)) + - Break cyclical dev dependencies ([`1fea18f`](https://github.com/Byron/gitoxide/commit/1fea18f5f8b4189a23dc4fa3f041a672f6fbcfb3)) + - 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-ref v0.23.0, git-config v0.15.0, git-command v0.2.2, git-diff v0.26.0, git-discover v0.12.0, git-mailmap v0.9.0, git-pack v0.30.0, git-odb v0.40.0, git-transport v0.25.2, git-protocol v0.26.1, git-revision v0.10.0, git-refspec v0.7.0, git-worktree v0.12.0, git-repository v0.32.0 ([`ffb5b6a`](https://github.com/Byron/gitoxide/commit/ffb5b6a21cb415315db6fd5294940c7c6deb4538)) + - Prepare changelogs prior to release ([`4381a03`](https://github.com/Byron/gitoxide/commit/4381a03a34c305f31713cce234c2afbf8ac60f01)) + - Release git-index v0.12.1 ([`8aa5c1d`](https://github.com/Byron/gitoxide/commit/8aa5c1db9e342cc49dfa588d5b4b9f893067dbf7)) + - Release git-date v0.4.0, git-actor v0.17.0, git-object v0.26.0, git-traverse v0.22.0, git-index v0.12.0, safety bump 15 crates ([`0e3d0a5`](https://github.com/Byron/gitoxide/commit/0e3d0a56d7e6a60c6578138f2690b4fa54a2072d)) + - 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)) + - Simplify `Cache` by removing its lifetime. ([`d7ee622`](https://github.com/Byron/gitoxide/commit/d7ee622cfa9fc3cf7a97b823dd70f0aa1355365e)) + - 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)) + - Adjust to changes in `git-testtools` ([`4eb842c`](https://github.com/Byron/gitoxide/commit/4eb842c7150b980e1c2637217e1f9657a671cea7)) + - 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 '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)) + - Merge branch 'version2021' ([`0e4462d`](https://github.com/Byron/gitoxide/commit/0e4462df7a5166fe85c23a779462cdca8ee013e8)) + - Upgrade edition to 2021 in most crates. ([`3d8fa8f`](https://github.com/Byron/gitoxide/commit/3d8fa8fef9800b1576beab8a5bc39b821157a5ed)) + - Release git-glob v0.4.2, git-config-value v0.8.2, git-lock v2.2.0, git-ref v0.19.0, git-config v0.11.0, git-discover v0.8.0, git-index v0.8.0, git-transport v0.22.0, git-protocol v0.23.0, git-worktree v0.8.0, git-repository v0.28.0, gitoxide-core v0.20.0, gitoxide v0.18.0, safety bump 9 crates ([`0c253b1`](https://github.com/Byron/gitoxide/commit/0c253b15143dcedfe4c66d64ab1ea6e097030651)) + - Prepare changelogs prior to release ([`fe5721f`](https://github.com/Byron/gitoxide/commit/fe5721f888c64c79fe9a734a9e33b94a282f8d97)) + - 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 (upgrade to Rust 1.65) ([`5406630`](https://github.com/Byron/gitoxide/commit/5406630466145990b5adbdadb59151036993060d)) + - Thanks clippy ([`04cfa63`](https://github.com/Byron/gitoxide/commit/04cfa635a65ae34ad6d22391f2febd2ca7eabca9)) + - 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)) + - Improved working of docs ([`1ef704e`](https://github.com/Byron/gitoxide/commit/1ef704e7daa83e298d99d94a3493296739338110)) + - Merge branch 'main' into gix-clone ([`de4fe06`](https://github.com/Byron/gitoxide/commit/de4fe06202906ea5c62e667826b42cf7b57b1ff0)) + - Merge branch 'fix-gix-index-from-tree' ([`da5f63c`](https://github.com/Byron/gitoxide/commit/da5f63cbc7506990f46d310f8064678decb86928)) + - Fix build ([`bb81abe`](https://github.com/Byron/gitoxide/commit/bb81abece95f466c38567d7488c0e6ae1a22e06b)) + - 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)) + - 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)) + - Merge branch 'filter-refs' ([`fd14489`](https://github.com/Byron/gitoxide/commit/fd14489f729172d615d0fa1e8dbd605e9eacf69d)) + - Release git-features v0.22.6 ([`c9eda72`](https://github.com/Byron/gitoxide/commit/c9eda729d8f8bc266c7516c613d38acfb83a4743)) + - Merge branch 'filter-refs-by-spec' ([`5c05198`](https://github.com/Byron/gitoxide/commit/5c051986bd89590a9287d85d84c713d83dfab83a)) + - 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)) + - Release git-path v0.4.2, git-config-value v0.7.0 ([`c48fb31`](https://github.com/Byron/gitoxide/commit/c48fb3107d29f9a06868b0c6de40567063a656d1)) + - Merge branch 'main' into filter-refs-by-spec ([`cef0b51`](https://github.com/Byron/gitoxide/commit/cef0b51ade2a3301fa09ede7a425aa1fe3527e78)) + - Release git-worktree v0.4.3, git-testtools v0.8.0 ([`b2e4bf2`](https://github.com/Byron/gitoxide/commit/b2e4bf2c11ff2c3c32efcb91837fb5677714bdf9)) + - Release git-attributes v0.3.3, git-ref v0.15.3, git-index v0.4.3, git-worktree v0.4.3, git-testtools v0.8.0 ([`baad4ce`](https://github.com/Byron/gitoxide/commit/baad4ce51fe0e8c0c1de1b08148d8303878ca37b)) + - Prepare changelogs prior to release of git-testtools ([`7668e38`](https://github.com/Byron/gitoxide/commit/7668e38fab8891ed7e73fae3a6f5a8772e0f0d0b)) + - 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 ([`cfa1440`](https://github.com/Byron/gitoxide/commit/cfa144031dbcac2707ab0cec012bc35e78f9c475)) + - Release git-worktree v0.4.2, git-repository v0.22.0 ([`2f0f530`](https://github.com/Byron/gitoxide/commit/2f0f530fb1d644bc0694e04f3c9309149f526e42)) + - 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)) + - Release git-path v0.4.1 ([`5e82346`](https://github.com/Byron/gitoxide/commit/5e823462b3deb904f5d6154a7bf114cef1988224)) + - 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)) + - Remove default link to cargo doc everywhere ([`533e887`](https://github.com/Byron/gitoxide/commit/533e887e80c5f7ede8392884562e1c5ba56fb9a8)) + - Merge branch 'main' into remote-ls-refs ([`bd5f3e8`](https://github.com/Byron/gitoxide/commit/bd5f3e8db7e0bb4abfb7b0f79f585ab82c3a14ab)) + - Release git-worktree v0.4.1, git-repository v0.21.0 ([`ee383f3`](https://github.com/Byron/gitoxide/commit/ee383f347371007f1c4d3a2a98c5511d7e0793a8)) + - Release git-date v0.0.3, git-actor v0.11.1, git-attributes v0.3.1, git-tempfile v2.0.3, git-object v0.20.1, git-ref v0.15.1, git-config v0.6.1, git-diff v0.17.1, git-discover v0.4.0, git-bitmap v0.1.1, git-index v0.4.1, git-mailmap v0.3.1, git-traverse v0.16.1, git-pack v0.21.1, git-odb v0.31.1, git-packetline v0.12.6, git-url v0.7.1, git-transport v0.19.1, git-protocol v0.18.1, git-revision v0.4.0, git-worktree v0.4.1, git-repository v0.21.0, safety bump 5 crates ([`c96473d`](https://github.com/Byron/gitoxide/commit/c96473dce21c3464aacbc0a62d520c1a33172611)) + - Prepare changelogs prior to reelase ([`c06ae1c`](https://github.com/Byron/gitoxide/commit/c06ae1c606b6af9c2a12021103d99c2810750d60)) + - Release git-hash v0.9.7, git-features v0.22.1 ([`232784a`](https://github.com/Byron/gitoxide/commit/232784a59ded3e8016e4257c7e146ad385cdd64a)) + - 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-worktree v0.4.0, git-repository v0.20.0, git-commitgraph v0.8.0, gitoxide-core v0.15.0, gitoxide v0.13.0 ([`d4df661`](https://github.com/Byron/gitoxide/commit/d4df661dbf60dad75d07002ef9979cabe8a86935)) + - Release 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 ([`aa639d8`](https://github.com/Byron/gitoxide/commit/aa639d8c43f3098cc4a5b50614c5ae94a8156928)) + - 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 pull request #1 from Byron/main ([`085e76b`](https://github.com/Byron/gitoxide/commit/085e76b121291ed9bd324139105d2bd4117bedf8)) + - Merge branch 'main' into pathspec ([`89ea12b`](https://github.com/Byron/gitoxide/commit/89ea12b558bcc056b892193ee8fb44b8664b5da4)) + - Merge branch 'main' into cont_include_if ([`daa71c3`](https://github.com/Byron/gitoxide/commit/daa71c3b753c6d76a3d652c29237906b3e28728f)) + - Make it harder to forget documentation in git-worktree ([`15d87ee`](https://github.com/Byron/gitoxide/commit/15d87ee99ef269985e8f378bb2ab9c8931e8fd7d)) + - Merge branch 'main' into cont_include_if ([`41ea8ba`](https://github.com/Byron/gitoxide/commit/41ea8ba78e74f5c988148367386a1f4f304cb951)) + - Release git-path v0.3.0, safety bump 14 crates ([`400c9be`](https://github.com/Byron/gitoxide/commit/400c9bec49e4ec5351dc9357b246e7677a63ea35)) + - Release git-worktree v0.3.0, git-repository v0.19.0 ([`0d8e856`](https://github.com/Byron/gitoxide/commit/0d8e8566dc5c6955487d67e235f86fbc75a3a88a)) + - 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)) + - 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-worktree v0.2.0, git-repository v0.17.0 ([`3f71246`](https://github.com/Byron/gitoxide/commit/3f7124616ab9752007b8cf03e1c6a3a796ffee0b)) + - Release git-worktree v0.2.0, git-repository v0.17.0 ([`5845934`](https://github.com/Byron/gitoxide/commit/584593448b560afdd60dbdbdff901d267082765e)) + - Release 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 ([`349c590`](https://github.com/Byron/gitoxide/commit/349c5904b0dac350838a896759d51576b66880a7)) + - 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 git_includeif ([`b1bfc8f`](https://github.com/Byron/gitoxide/commit/b1bfc8fe8efb6d8941f54dddd0fcad99aa13ed6c)) + - Merge branch 'basic-worktree-support' ([`e058bda`](https://github.com/Byron/gitoxide/commit/e058bdabf8449b6a6fdff851e3929137d9b71568)) + - Merge branch 'main' into git_includeif ([`05eb340`](https://github.com/Byron/gitoxide/commit/05eb34023933918c51c03cf2afd774db89cc5a33)) + - Merge branch 'main' into msrv-for-windows ([`7cb1972`](https://github.com/Byron/gitoxide/commit/7cb19729133325bdfacedf44cdc0500cbcf36684)) + - Make fmt ([`251b6df`](https://github.com/Byron/gitoxide/commit/251b6df5dbdda24b7bdc452085f808f3acef69d8)) + - Merge branch 'worktree-stack' ([`98da8ba`](https://github.com/Byron/gitoxide/commit/98da8ba52cef8ec27f705fcbc84773e5bacc4e10)) + - Thanks clippy ([`aeebc5f`](https://github.com/Byron/gitoxide/commit/aeebc5fe743faa7d436b1d0a30d60aafbbaeeb3d)) + - Thanks clippy ([`b199367`](https://github.com/Byron/gitoxide/commit/b1993672f5a7c516611814fd7c5d6bf796419082)) + - Merge branch 'main' into worktree-stack ([`8674c11`](https://github.com/Byron/gitoxide/commit/8674c11973e5282d087e35a71c70e418b6cc75be)) + - Fix release build ([`f7c1920`](https://github.com/Byron/gitoxide/commit/f7c1920214ebfc38676d1d53cc064b0f3d8ece4e)) + - Fix release build ([`2705679`](https://github.com/Byron/gitoxide/commit/2705679ddf7e5fe12e93ad214c15d5006c073818)) + - Merge branch 'worktree-stack' ([`39046e9`](https://github.com/Byron/gitoxide/commit/39046e98098da7d490757477986479126a45b3e5)) + - Thanks clippy ([`1d365d2`](https://github.com/Byron/gitoxide/commit/1d365d2c6fe19ac8e27c60e3d2596a583a183728)) + - Merge branch 'main' into repo-status ([`0eb2372`](https://github.com/Byron/gitoxide/commit/0eb23721dca78f6e6bf864c5c3a3e44df8b419f0)) + - Merge branch 'test-archive-support' ([`350df01`](https://github.com/Byron/gitoxide/commit/350df01042d6ca8b93f8737fa101e69b50535a0f)) + - Release git-diff v0.14.0, git-bitmap v0.1.0, git-index v0.2.0, git-tempfile v2.0.1, git-lock v2.0.0, git-mailmap v0.1.0, git-traverse v0.13.0, git-pack v0.17.0, git-quote v0.2.0, git-odb v0.27.0, git-packetline v0.12.4, git-url v0.4.0, git-transport v0.16.0, git-protocol v0.15.0, git-ref v0.12.0, git-worktree v0.1.0, git-repository v0.15.0, cargo-smart-release v0.9.0, safety bump 5 crates ([`e58dc30`](https://github.com/Byron/gitoxide/commit/e58dc3084cf17a9f618ae3a6554a7323e44428bf)) + - 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)) + - Make fmt ([`7cf3545`](https://github.com/Byron/gitoxide/commit/7cf354509b545f7e7c99e159b5989ddfbe86273d)) + - Thanks clippy ([`07a4094`](https://github.com/Byron/gitoxide/commit/07a4094965ac1b4eb223da8e5ca5cc4a86c5f596)) + - Thanks clippy ([`0e2a243`](https://github.com/Byron/gitoxide/commit/0e2a2438da35c0abb412682b103e5be171b1c3ad)) + - Thanks clippy ([`3229240`](https://github.com/Byron/gitoxide/commit/322924037a1710f35e4134e5a35c82b3d4266a1f)) + - Merge branch 'svetli-n-path_value' ([`e8383ca`](https://github.com/Byron/gitoxide/commit/e8383caf6db211beb57d70019fe4ad13ce9066ee)) + - Merge branch 'unify-path-encoding' ([`566ff8a`](https://github.com/Byron/gitoxide/commit/566ff8a3597b889899d41ca15e5b9af7e05f1a4b)) + - Thanks clippy ([`a8e9497`](https://github.com/Byron/gitoxide/commit/a8e9497caebf1c0e9faac537717cd86378f1acf6)) + - Thanks clippy ([`e04cba8`](https://github.com/Byron/gitoxide/commit/e04cba8837340d1ca0f102a340e52e8610fb0750)) + - Merge branch 'AP2008-implement-worktree' ([`f32c669`](https://github.com/Byron/gitoxide/commit/f32c669bc519d59a1f1d90d61cc48a422c86aede)) + - Refactored code and tests ([`a4b880c`](https://github.com/Byron/gitoxide/commit/a4b880cf17665b61e3f7f193de57704b1db5318f)) + - Refactored tests ([`25a9dc1`](https://github.com/Byron/gitoxide/commit/25a9dc16dbb26e9aa0f3379b2af53cc0baa96663)) + - Reduce io calls ([`e838eaa`](https://github.com/Byron/gitoxide/commit/e838eaa5721d8b1b13155aa81234c9c44d9b15fe)) + - Refactor errors and remove unwraps ([`eaee855`](https://github.com/Byron/gitoxide/commit/eaee85595dc658549e62e3292b025ec016e70abd)) + - Implemented git-worktree ([`4177d72`](https://github.com/Byron/gitoxide/commit/4177d72c95bd94cf6a49e917dc21918044e8250b)) + - Release git-worktree v0.0.0 ([`ddb1bf4`](https://github.com/Byron/gitoxide/commit/ddb1bf49e3b5b663fcf166d8cbce416e78d9fc18)) +</details> + +## 0.12.1 (2023-01-10) + +A maintenance release without user-facing changes. + +## 0.12.0 (2023-01-09) + +A maintenance release without user-facing changes. + +## 0.11.0 (2022-12-30) + +### Changed (BREAKING) + + - <csr-id-d7ee622cfa9fc3cf7a97b823dd70f0aa1355365e/> Simplify `Cache` by removing its lifetime. + The lifetime was more of a premature optimization that makes actually using + the cache much harder than it needs to be. + +## 0.10.0 (2022-12-19) + +A maintenance release without user-facing changes. + +## 0.9.0 (2022-11-21) + +### New Features (BREAKING) + + - <csr-id-3d8fa8fef9800b1576beab8a5bc39b821157a5ed/> upgrade edition to 2021 in most crates. + MSRV for this is 1.56, and we are now at 1.60 so should be compatible. + This isn't more than a patch release as it should break nobody + who is adhering to the MSRV, but let's be careful and mark it + breaking. + + Note that `gix-features` and `gix-pack` are still on edition 2018 + as they make use of a workaround to support (safe) mutable access + to non-overlapping entries in a slice which doesn't work anymore + in edition 2021. + +## 0.8.0 (2022-11-17) + +A maintenance release without user-facing changes. + +## 0.7.0 (2022-11-06) + +A maintenance release without user-facing changes. + +## 0.6.0 (2022-10-10) + +Maintenance release without user-facing changes. + +## 0.5.0 (2022-09-20) + +### Changed (BREAKING) + + - <csr-id-99905bacace8aed42b16d43f0f04cae996cb971c/> upgrade `bstr` to `1.0.1` + +## 0.4.3 (2022-08-27) + +Maintenance release without user-facing changes. + +## 0.4.2 (2022-08-24) + +<csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> +<csr-id-533e887e80c5f7ede8392884562e1c5ba56fb9a8/> + +### Chore + + - <csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> uniformize deny attributes + - <csr-id-533e887e80c5f7ede8392884562e1c5ba56fb9a8/> remove default link to cargo doc everywhere + +### 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.4.1 (2022-08-17) + +A maintenance release without user facing changes. + +## 0.4.0 (2022-07-22) + +This is a maintenance release with no functional changes. + +## 0.3.0 (2022-06-13) + +A maintenance release without user-facing changes. + +## 0.2.0 (2022-05-18) + +A maintenance release without documented changes. + +## 0.1.0 (2022-04-03) + +An initial release with the ability to checkout indices with simple files only. + +## 0.0.0 (2022-01-08) + +Reserve the name for a necessary crate of the `gitoxide` project. + diff --git a/vendor/gix-worktree/Cargo.toml b/vendor/gix-worktree/Cargo.toml new file mode 100644 index 000000000..4932633f7 --- /dev/null +++ b/vendor/gix-worktree/Cargo.toml @@ -0,0 +1,108 @@ +# 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.64" +name = "gix-worktree" +version = "0.14.0" +authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"] +include = [ + "src/**/*", + "CHANGELOG.md", +] +description = "A WIP crate of the gitoxide project dedicated implementing everything around working trees and git excludes" +license = "MIT/Apache-2.0" +repository = "https://github.com/Byron/gitoxide" + +[package.metadata.docs.rs] +features = [ + "document-features", + "serde1", +] +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[lib] +doctest = false + +[[test]] +name = "multi-threaded" +path = "tests/worktree-multi-threaded.rs" +required-features = ["internal-testing-gix-features-parallel"] + +[[test]] +name = "single-threaded" +path = "tests/worktree-single-threaded.rs" +required-features = ["internal-testing-to-avoid-being-run-by-cargo-test-all"] + +[dependencies.bstr] +version = "1.3.0" +default-features = false + +[dependencies.document-features] +version = "0.2.0" +optional = true + +[dependencies.gix-attributes] +version = "^0.10.0" + +[dependencies.gix-features] +version = "^0.28.0" + +[dependencies.gix-glob] +version = "^0.5.5" + +[dependencies.gix-hash] +version = "^0.10.3" + +[dependencies.gix-index] +version = "^0.14.0" + +[dependencies.gix-object] +version = "^0.28.0" + +[dependencies.gix-path] +version = "^0.7.2" + +[dependencies.io-close] +version = "0.3.7" + +[dependencies.serde] +version = "1.0.114" +features = ["derive"] +optional = true +default-features = false + +[dependencies.thiserror] +version = "1.0.26" + +[dev-dependencies.symlink] +version = "0.1.0" + +[dev-dependencies.tempfile] +version = "3.2.0" + +[dev-dependencies.walkdir] +version = "2.3.2" + +[features] +internal-testing-gix-features-parallel = ["gix-features/parallel"] +internal-testing-to-avoid-being-run-by-cargo-test-all = [] +serde1 = [ + "serde", + "bstr/serde", + "gix-index/serde1", + "gix-hash/serde1", + "gix-object/serde1", +] diff --git a/vendor/gix-worktree/src/fs/cache/mod.rs b/vendor/gix-worktree/src/fs/cache/mod.rs new file mode 100644 index 000000000..1f7710e59 --- /dev/null +++ b/vendor/gix-worktree/src/fs/cache/mod.rs @@ -0,0 +1,148 @@ +#![allow(missing_docs)] +use std::path::{Path, PathBuf}; + +use bstr::{BStr, ByteSlice}; +use gix_hash::oid; + +use super::Cache; +use crate::{fs, fs::PathOidMapping}; + +#[derive(Clone)] +pub enum State { + /// Useful for checkout where directories need creation, but we need to access attributes as well. + CreateDirectoryAndAttributesStack { + /// If there is a symlink or a file in our path, try to unlink it before creating the directory. + unlink_on_collision: bool, + + /// just for testing + #[cfg(debug_assertions)] + test_mkdir_calls: usize, + /// State to handle attribute information + attributes: state::Attributes, + }, + /// Used when adding files, requiring access to both attributes and ignore information, for example during add operations. + AttributesAndIgnoreStack { + /// State to handle attribute information + attributes: state::Attributes, + /// State to handle exclusion information + ignore: state::Ignore, + }, + /// Used when providing worktree status information. + IgnoreStack(state::Ignore), +} + +#[cfg(debug_assertions)] +impl Cache { + pub fn set_case(&mut self, case: gix_glob::pattern::Case) { + self.case = case; + } + pub fn num_mkdir_calls(&self) -> usize { + match self.state { + State::CreateDirectoryAndAttributesStack { test_mkdir_calls, .. } => test_mkdir_calls, + _ => 0, + } + } + + pub fn reset_mkdir_calls(&mut self) { + if let State::CreateDirectoryAndAttributesStack { test_mkdir_calls, .. } = &mut self.state { + *test_mkdir_calls = 0; + } + } + + pub fn unlink_on_collision(&mut self, value: bool) { + if let State::CreateDirectoryAndAttributesStack { + unlink_on_collision, .. + } = &mut self.state + { + *unlink_on_collision = value; + } + } +} + +#[must_use] +pub struct Platform<'a> { + parent: &'a Cache, + is_dir: Option<bool>, +} + +impl Cache { + /// Create a new instance with `worktree_root` being the base for all future paths we handle, assuming it to be valid which includes + /// symbolic links to be included in it as well. + /// The `case` configures attribute and exclusion query case sensitivity. + pub fn new( + worktree_root: impl Into<PathBuf>, + state: State, + case: gix_glob::pattern::Case, + buf: Vec<u8>, + attribute_files_in_index: Vec<PathOidMapping>, + ) -> Self { + let root = worktree_root.into(); + Cache { + stack: fs::Stack::new(root), + state, + case, + buf, + attribute_files_in_index, + } + } + + /// Append the `relative` path to the root directory the cache contains and efficiently create leading directories + /// unless `is_dir` is known (`Some(…)`) then `relative` points to a directory itself in which case the entire resulting + /// path is created as directory. If it's not known it is assumed to be a file. + /// + /// Provide access to cached information for that `relative` entry via the platform returned. + pub fn at_path<Find, E>( + &mut self, + relative: impl AsRef<Path>, + is_dir: Option<bool>, + find: Find, + ) -> std::io::Result<Platform<'_>> + where + Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E>, + E: std::error::Error + Send + Sync + 'static, + { + let mut delegate = platform::StackDelegate { + state: &mut self.state, + buf: &mut self.buf, + is_dir: is_dir.unwrap_or(false), + attribute_files_in_index: &self.attribute_files_in_index, + find, + }; + self.stack.make_relative_path_current(relative, &mut delegate)?; + Ok(Platform { parent: self, is_dir }) + } + + /// **Panics** on illformed UTF8 in `relative` + // TODO: more docs + pub fn at_entry<'r, Find, E>( + &mut self, + relative: impl Into<&'r BStr>, + is_dir: Option<bool>, + find: Find, + ) -> std::io::Result<Platform<'_>> + where + Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E>, + E: std::error::Error + Send + Sync + 'static, + { + let relative = relative.into(); + let relative_path = gix_path::from_bstr(relative); + + self.at_path( + relative_path, + is_dir.or_else(|| relative.ends_with_str("/").then_some(true)), + // is_dir, + find, + ) + } + + /// Return the base path against which all entries or paths should be relative to when querying. + /// + /// Note that this path _may_ not be canonicalized. + pub fn base(&self) -> &Path { + self.stack.root() + } +} + +mod platform; +/// +pub mod state; diff --git a/vendor/gix-worktree/src/fs/cache/platform.rs b/vendor/gix-worktree/src/fs/cache/platform.rs new file mode 100644 index 000000000..90bbdbe3c --- /dev/null +++ b/vendor/gix-worktree/src/fs/cache/platform.rs @@ -0,0 +1,171 @@ +use std::path::Path; + +use bstr::ByteSlice; +use gix_hash::oid; + +use crate::{ + fs, + fs::{ + cache::{Platform, State}, + PathOidMapping, + }, +}; + +impl<'a> Platform<'a> { + /// The full path to `relative` will be returned for use on the file system. + pub fn path(&self) -> &'a Path { + self.parent.stack.current() + } + + /// See if the currently set entry is excluded as per exclude and git-ignore files. + /// + /// # Panics + /// + /// If the cache was configured without exclude patterns. + pub fn is_excluded(&self) -> bool { + self.matching_exclude_pattern() + .map_or(false, |m| !m.pattern.is_negative()) + } + + /// Check all exclude patterns to see if the currently set path matches any of them. + /// + /// Note that this pattern might be negated, and means this path in included. + /// + /// # Panics + /// + /// If the cache was configured without exclude patterns. + pub fn matching_exclude_pattern(&self) -> Option<gix_attributes::Match<'_, ()>> { + let ignore = self.parent.state.ignore_or_panic(); + let relative_path = + gix_path::to_unix_separators_on_windows(gix_path::into_bstr(self.parent.stack.current_relative.as_path())); + ignore.matching_exclude_pattern(relative_path.as_bstr(), self.is_dir, self.parent.case) + } +} + +impl<'a> std::fmt::Debug for Platform<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Debug::fmt(&self.path(), f) + } +} + +pub struct StackDelegate<'a, Find> { + pub state: &'a mut State, + pub buf: &'a mut Vec<u8>, + pub is_dir: bool, + pub attribute_files_in_index: &'a Vec<PathOidMapping>, + pub find: Find, +} + +impl<'a, Find, E> fs::stack::Delegate for StackDelegate<'a, Find> +where + Find: for<'b> FnMut(&oid, &'b mut Vec<u8>) -> Result<gix_object::BlobRef<'b>, E>, + E: std::error::Error + Send + Sync + 'static, +{ + fn push_directory(&mut self, stack: &fs::Stack) -> std::io::Result<()> { + match &mut self.state { + State::CreateDirectoryAndAttributesStack { attributes: _, .. } => { + // TODO: attributes + } + State::AttributesAndIgnoreStack { ignore, attributes: _ } => { + // TODO: attributes + ignore.push_directory( + &stack.root, + &stack.current, + self.buf, + self.attribute_files_in_index, + &mut self.find, + )? + } + State::IgnoreStack(ignore) => ignore.push_directory( + &stack.root, + &stack.current, + self.buf, + self.attribute_files_in_index, + &mut self.find, + )?, + } + Ok(()) + } + + fn push(&mut self, is_last_component: bool, stack: &fs::Stack) -> std::io::Result<()> { + match &mut self.state { + State::CreateDirectoryAndAttributesStack { + #[cfg(debug_assertions)] + test_mkdir_calls, + unlink_on_collision, + attributes: _, + } => { + #[cfg(debug_assertions)] + { + create_leading_directory( + is_last_component, + stack, + self.is_dir, + test_mkdir_calls, + *unlink_on_collision, + )? + } + #[cfg(not(debug_assertions))] + { + create_leading_directory(is_last_component, stack, self.is_dir, *unlink_on_collision)? + } + } + State::AttributesAndIgnoreStack { .. } | State::IgnoreStack(_) => {} + } + Ok(()) + } + + fn pop_directory(&mut self) { + match &mut self.state { + State::CreateDirectoryAndAttributesStack { attributes: _, .. } => { + // TODO: attributes + } + State::AttributesAndIgnoreStack { attributes: _, ignore } => { + // TODO: attributes + ignore.pop_directory(); + } + State::IgnoreStack(ignore) => { + ignore.pop_directory(); + } + } + } +} + +fn create_leading_directory( + is_last_component: bool, + stack: &fs::Stack, + is_dir: bool, + #[cfg(debug_assertions)] mkdir_calls: &mut usize, + unlink_on_collision: bool, +) -> std::io::Result<()> { + if is_last_component && !is_dir { + return Ok(()); + } + #[cfg(debug_assertions)] + { + *mkdir_calls += 1; + } + match std::fs::create_dir(stack.current()) { + Ok(()) => Ok(()), + Err(err) if err.kind() == std::io::ErrorKind::AlreadyExists => { + let meta = stack.current().symlink_metadata()?; + if meta.is_dir() { + Ok(()) + } else if unlink_on_collision { + if meta.file_type().is_symlink() { + crate::os::remove_symlink(stack.current())?; + } else { + std::fs::remove_file(stack.current())?; + } + #[cfg(debug_assertions)] + { + *mkdir_calls += 1; + } + std::fs::create_dir(stack.current()) + } else { + Err(err) + } + } + Err(err) => Err(err), + } +} diff --git a/vendor/gix-worktree/src/fs/cache/state.rs b/vendor/gix-worktree/src/fs/cache/state.rs new file mode 100644 index 000000000..1692bfa5e --- /dev/null +++ b/vendor/gix-worktree/src/fs/cache/state.rs @@ -0,0 +1,301 @@ +use std::path::Path; + +use bstr::{BStr, BString, ByteSlice}; +use gix_glob::pattern::Case; +use gix_hash::oid; + +use crate::fs::{cache::State, PathOidMapping}; + +type AttributeMatchGroup = gix_attributes::MatchGroup<gix_attributes::Attributes>; +type IgnoreMatchGroup = gix_attributes::MatchGroup<gix_attributes::Ignore>; + +/// State related to attributes associated with files in the repository. +#[derive(Default, Clone)] +#[allow(unused)] +pub struct Attributes { + /// Attribute patterns that match the currently set directory (in the stack). + pub stack: AttributeMatchGroup, + /// Attribute patterns which aren't tied to the repository root, hence are global. They are consulted last. + pub globals: AttributeMatchGroup, +} + +/// State related to the exclusion of files. +#[derive(Default, Clone)] +#[allow(unused)] +pub struct Ignore { + /// Ignore patterns passed as overrides to everything else, typically passed on the command-line and the first patterns to + /// be consulted. + overrides: IgnoreMatchGroup, + /// Ignore patterns that match the currently set director (in the stack), which is pushed and popped as needed. + stack: IgnoreMatchGroup, + /// Ignore patterns which aren't tied to the repository root, hence are global. They are consulted last. + globals: IgnoreMatchGroup, + /// A matching stack of pattern indices which is empty if we have just been initialized to indicate that the + /// currently set directory had a pattern matched. Note that this one could be negated. + /// (index into match groups, index into list of pattern lists, index into pattern list) + matched_directory_patterns_stack: Vec<Option<(usize, usize, usize)>>, + /// The name of the file to look for in directories. + exclude_file_name_for_directories: BString, + /// The case to use when matching directories as they are pushed onto the stack. We run them against the exclude engine + /// to know if an entire path can be ignored as a parent directory is ignored. + case: Case, +} + +impl Ignore { + /// The `exclude_file_name_for_directories` is an optional override for the filename to use when checking per-directory + /// ignore files within the repository, defaults to`.gitignore`. + // TODO: more docs + pub fn new( + overrides: IgnoreMatchGroup, + globals: IgnoreMatchGroup, + exclude_file_name_for_directories: Option<&BStr>, + case: Case, + ) -> Self { + Ignore { + case, + overrides, + globals, + stack: Default::default(), + matched_directory_patterns_stack: Vec::with_capacity(6), + exclude_file_name_for_directories: exclude_file_name_for_directories + .map(ToOwned::to_owned) + .unwrap_or_else(|| ".gitignore".into()), + } + } +} + +impl Ignore { + pub(crate) fn pop_directory(&mut self) { + self.matched_directory_patterns_stack.pop().expect("something to pop"); + self.stack.patterns.pop().expect("something to pop"); + } + /// The match groups from lowest priority to highest. + pub(crate) fn match_groups(&self) -> [&IgnoreMatchGroup; 3] { + [&self.globals, &self.stack, &self.overrides] + } + + pub(crate) fn matching_exclude_pattern( + &self, + relative_path: &BStr, + is_dir: Option<bool>, + case: Case, + ) -> Option<gix_attributes::Match<'_, ()>> { + let groups = self.match_groups(); + let mut dir_match = None; + if let Some((source, mapping)) = self + .matched_directory_patterns_stack + .iter() + .rev() + .filter_map(|v| *v) + .map(|(gidx, plidx, pidx)| { + let list = &groups[gidx].patterns[plidx]; + (list.source.as_deref(), &list.patterns[pidx]) + }) + .next() + { + let match_ = gix_attributes::Match { + pattern: &mapping.pattern, + value: &mapping.value, + sequence_number: mapping.sequence_number, + source, + }; + if mapping.pattern.is_negative() { + dir_match = Some(match_); + } else { + // Note that returning here is wrong if this pattern _was_ preceded by a negative pattern that + // didn't match the directory, but would match now. + // Git does it similarly so we do too even though it's incorrect. + // To fix this, one would probably keep track of whether there was a preceding negative pattern, and + // if so we check the path in full and only use the dir match if there was no match, similar to the negative + // case above whose fix fortunately won't change the overall result. + return match_.into(); + } + } + groups + .iter() + .rev() + .find_map(|group| group.pattern_matching_relative_path(relative_path.as_bytes(), is_dir, case)) + .or(dir_match) + } + + /// Like `matching_exclude_pattern()` but without checking if the current directory is excluded. + /// It returns a triple-index into our data structure from which a match can be reconstructed. + pub(crate) fn matching_exclude_pattern_no_dir( + &self, + relative_path: &BStr, + is_dir: Option<bool>, + case: Case, + ) -> Option<(usize, usize, usize)> { + let groups = self.match_groups(); + groups.iter().enumerate().rev().find_map(|(gidx, group)| { + let basename_pos = relative_path.rfind(b"/").map(|p| p + 1); + group + .patterns + .iter() + .enumerate() + .rev() + .find_map(|(plidx, pl)| { + pl.pattern_idx_matching_relative_path(relative_path, basename_pos, is_dir, case) + .map(|idx| (plidx, idx)) + }) + .map(|(plidx, pidx)| (gidx, plidx, pidx)) + }) + } + + pub(crate) fn push_directory<Find, E>( + &mut self, + root: &Path, + dir: &Path, + buf: &mut Vec<u8>, + attribute_files_in_index: &[PathOidMapping], + mut find: Find, + ) -> std::io::Result<()> + where + Find: for<'b> FnMut(&oid, &'b mut Vec<u8>) -> Result<gix_object::BlobRef<'b>, E>, + E: std::error::Error + Send + Sync + 'static, + { + let rela_dir = dir.strip_prefix(root).expect("dir in root"); + self.matched_directory_patterns_stack + .push(self.matching_exclude_pattern_no_dir(gix_path::into_bstr(rela_dir).as_ref(), Some(true), self.case)); + + let ignore_path_relative = rela_dir.join(".gitignore"); + let ignore_path_relative = gix_path::to_unix_separators_on_windows(gix_path::into_bstr(ignore_path_relative)); + let ignore_file_in_index = + attribute_files_in_index.binary_search_by(|t| t.0.as_bstr().cmp(ignore_path_relative.as_ref())); + let follow_symlinks = ignore_file_in_index.is_err(); + if !self + .stack + .add_patterns_file(dir.join(".gitignore"), follow_symlinks, Some(root), buf)? + { + match ignore_file_in_index { + Ok(idx) => { + let ignore_blob = find(&attribute_files_in_index[idx].1, buf) + .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?; + let ignore_path = gix_path::from_bstring(ignore_path_relative.into_owned()); + self.stack + .add_patterns_buffer(ignore_blob.data, ignore_path, Some(root)); + } + Err(_) => { + // Need one stack level per component so push and pop matches. + self.stack.patterns.push(Default::default()) + } + } + } + Ok(()) + } +} + +impl Attributes { + /// Create a new instance from an attribute match group that represents `globals`. + /// + /// A stack of attributes will be applied on top of it later. + pub fn new(globals: AttributeMatchGroup) -> Self { + Attributes { + globals, + stack: Default::default(), + } + } +} + +impl From<AttributeMatchGroup> for Attributes { + fn from(group: AttributeMatchGroup) -> Self { + Attributes::new(group) + } +} + +impl State { + /// Configure a state to be suitable for checking out files. + pub fn for_checkout(unlink_on_collision: bool, attributes: Attributes) -> Self { + State::CreateDirectoryAndAttributesStack { + unlink_on_collision, + #[cfg(debug_assertions)] + test_mkdir_calls: 0, + attributes, + } + } + + /// Configure a state for adding files. + pub fn for_add(attributes: Attributes, ignore: Ignore) -> Self { + State::AttributesAndIgnoreStack { attributes, ignore } + } + + /// Configure a state for status retrieval. + pub fn for_status(ignore: Ignore) -> Self { + State::IgnoreStack(ignore) + } +} + +impl State { + /// Returns a vec of tuples of relative index paths along with the best usable OID for either ignore, attribute files or both. + /// + /// - ignores entries which aren't blobs + /// - ignores ignore entries which are not skip-worktree + /// - within merges, picks 'our' stage both for ignore and attribute files. + pub fn build_attribute_list( + &self, + index: &gix_index::State, + paths: &gix_index::PathStorageRef, + case: Case, + ) -> Vec<PathOidMapping> { + let a1_backing; + let a2_backing; + let names = match self { + State::IgnoreStack(v) => { + a1_backing = [(v.exclude_file_name_for_directories.as_bytes().as_bstr(), true)]; + a1_backing.as_ref() + } + State::AttributesAndIgnoreStack { ignore, .. } => { + a2_backing = [ + (ignore.exclude_file_name_for_directories.as_bytes().as_bstr(), true), + (".gitattributes".into(), false), + ]; + a2_backing.as_ref() + } + State::CreateDirectoryAndAttributesStack { .. } => { + a1_backing = [(".gitattributes".into(), true)]; + a1_backing.as_ref() + } + }; + + index + .entries() + .iter() + .filter_map(move |entry| { + let path = entry.path_in(paths); + + // Stage 0 means there is no merge going on, stage 2 means it's 'our' side of the merge, but then + // there won't be a stage 0. + if entry.mode == gix_index::entry::Mode::FILE && (entry.stage() == 0 || entry.stage() == 2) { + let basename = path + .rfind_byte(b'/') + .map(|pos| path[pos + 1..].as_bstr()) + .unwrap_or(path); + let is_ignore = names.iter().find_map(|t| { + match case { + Case::Sensitive => basename == t.0, + Case::Fold => basename.eq_ignore_ascii_case(t.0), + } + .then_some(t.1) + })?; + // See https://github.com/git/git/blob/master/dir.c#L912:L912 + if is_ignore && !entry.flags.contains(gix_index::entry::Flags::SKIP_WORKTREE) { + return None; + } + Some((path.to_owned(), entry.id)) + } else { + None + } + }) + .collect() + } + + pub(crate) fn ignore_or_panic(&self) -> &Ignore { + match self { + State::IgnoreStack(v) => v, + State::AttributesAndIgnoreStack { ignore, .. } => ignore, + State::CreateDirectoryAndAttributesStack { .. } => { + unreachable!("BUG: must not try to check excludes without it being setup") + } + } + } +} diff --git a/vendor/gix-worktree/src/fs/capabilities.rs b/vendor/gix-worktree/src/fs/capabilities.rs new file mode 100644 index 000000000..64daab9ce --- /dev/null +++ b/vendor/gix-worktree/src/fs/capabilities.rs @@ -0,0 +1,122 @@ +use std::path::Path; + +use crate::fs::Capabilities; + +#[cfg(windows)] +impl Default for Capabilities { + fn default() -> Self { + Capabilities { + precompose_unicode: false, + ignore_case: true, + executable_bit: false, + symlink: false, + } + } +} + +#[cfg(target_os = "macos")] +impl Default for Capabilities { + fn default() -> Self { + Capabilities { + precompose_unicode: true, + ignore_case: true, + executable_bit: true, + symlink: true, + } + } +} + +#[cfg(all(unix, not(target_os = "macos")))] +impl Default for Capabilities { + fn default() -> Self { + Capabilities { + precompose_unicode: false, + ignore_case: false, + executable_bit: true, + symlink: true, + } + } +} + +impl Capabilities { + /// try to determine all values in this context by probing them in the given `git_dir`, which + /// should be on the file system the git repository is located on. + /// `git_dir` is a typical git repository, expected to be populated with the typical files like `config`. + /// + /// All errors are ignored and interpreted on top of the default for the platform the binary is compiled for. + pub fn probe(git_dir: impl AsRef<Path>) -> Self { + let root = git_dir.as_ref(); + let ctx = Capabilities::default(); + Capabilities { + symlink: Self::probe_symlink(root).unwrap_or(ctx.symlink), + ignore_case: Self::probe_ignore_case(root).unwrap_or(ctx.ignore_case), + precompose_unicode: Self::probe_precompose_unicode(root).unwrap_or(ctx.precompose_unicode), + executable_bit: Self::probe_file_mode(root).unwrap_or(ctx.executable_bit), + } + } + + #[cfg(unix)] + fn probe_file_mode(root: &Path) -> std::io::Result<bool> { + use std::os::unix::fs::{MetadataExt, OpenOptionsExt}; + + // test it exactly as we typically create executable files, not using chmod. + let test_path = root.join("_test_executable_bit"); + let res = std::fs::OpenOptions::new() + .create_new(true) + .write(true) + .mode(0o777) + .open(&test_path) + .and_then(|f| f.metadata().map(|m| m.mode() & 0o100 == 0o100)); + std::fs::remove_file(test_path)?; + res + } + + #[cfg(not(unix))] + fn probe_file_mode(_root: &Path) -> std::io::Result<bool> { + Ok(false) + } + + fn probe_ignore_case(git_dir: &Path) -> std::io::Result<bool> { + std::fs::metadata(git_dir.join("cOnFiG")).map(|_| true).or_else(|err| { + if err.kind() == std::io::ErrorKind::NotFound { + Ok(false) + } else { + Err(err) + } + }) + } + + fn probe_precompose_unicode(root: &Path) -> std::io::Result<bool> { + let precomposed = "ä"; + let decomposed = "a\u{308}"; + + let precomposed = root.join(precomposed); + std::fs::OpenOptions::new() + .create_new(true) + .write(true) + .open(&precomposed)?; + let res = root.join(decomposed).symlink_metadata().map(|_| true); + std::fs::remove_file(precomposed)?; + res + } + + fn probe_symlink(root: &Path) -> std::io::Result<bool> { + let src_path = root.join("__link_src_file"); + std::fs::OpenOptions::new() + .create_new(true) + .write(true) + .open(&src_path)?; + let link_path = root.join("__file_link"); + if crate::os::create_symlink(&src_path, &link_path).is_err() { + std::fs::remove_file(&src_path)?; + return Ok(false); + } + + let res = std::fs::symlink_metadata(&link_path).map(|m| m.file_type().is_symlink()); + + let cleanup = crate::os::remove_symlink(&link_path).or_else(|_| std::fs::remove_file(&link_path)); + std::fs::remove_file(&src_path).and(cleanup)?; + + res + } +} diff --git a/vendor/gix-worktree/src/fs/mod.rs b/vendor/gix-worktree/src/fs/mod.rs new file mode 100644 index 000000000..a58c461fe --- /dev/null +++ b/vendor/gix-worktree/src/fs/mod.rs @@ -0,0 +1,81 @@ +use std::path::PathBuf; + +use bstr::BString; + +/// Common knowledge about the worktree that is needed across most interactions with the work tree +#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] +#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] +pub struct Capabilities { + /// If true, the filesystem will store paths as decomposed unicode, i.e. `ä` becomes `"a\u{308}"`, which means that + /// we have to turn these forms back from decomposed to precomposed unicode before storing it in the index or generally + /// using it. This also applies to input received from the command-line, so callers may have to be aware of this and + /// perform conversions accordingly. + /// If false, no conversions will be performed. + pub precompose_unicode: bool, + /// If true, the filesystem ignores the case of input, which makes `A` the same file as `a`. + /// This is also called case-folding. + pub ignore_case: bool, + /// If true, we assume the the executable bit is honored as part of the files mode. If false, we assume the file system + /// ignores the executable bit, hence it will be reported as 'off' even though we just tried to set it to be on. + pub executable_bit: bool, + /// If true, the file system supports symbolic links and we should try to create them. Otherwise symbolic links will be checked + /// out as files which contain the link as text. + pub symlink: bool, +} + +/// A stack of path components with the delegation of side-effects as the currently set path changes, component by component. +#[derive(Clone)] +pub struct Stack { + /// The prefix/root for all paths we handle. + root: PathBuf, + /// the most recent known cached that we know is valid. + current: PathBuf, + /// The relative portion of `valid` that was added previously. + current_relative: PathBuf, + /// The amount of path components of 'current' beyond the roots components. + valid_components: usize, + /// If set, we assume the `current` element is a directory to affect calls to `(push|pop)_directory()`. + current_is_directory: bool, +} + +/// A cache for efficiently executing operations on directories and files which are encountered in sorted order. +/// That way, these operations can be re-used for subsequent invocations in the same directory. +/// +/// This cache can be configured to create directories efficiently, read git-ignore files and git-attribute files, +/// in any combination. +/// +/// A cache for directory creation to reduce the amount of stat calls when creating +/// directories safely, that is without following symlinks that might be on the way. +/// +/// As a special case, it offers a 'prefix' which (by itself) is assumed to exist and may contain symlinks. +/// Everything past that prefix boundary must not contain a symlink. We do this by allowing any input path. +/// +/// Another added benefit is its ability to store the path of full path of the entry to which leading directories +/// are to be created to avoid allocating memory. +/// +/// For this to work, it remembers the last 'good' path to a directory and assumes that all components of it +/// are still valid, too. +/// As directories are created, the cache will be adjusted to reflect the latest seen directory. +/// +/// The caching is only useful if consecutive calls to create a directory are using a sorted list of entries. +#[derive(Clone)] +pub struct Cache { + stack: Stack, + /// tells us what to do as we change paths. + state: cache::State, + /// A buffer used when reading attribute or ignore files or their respective objects from the object database. + buf: Vec<u8>, + /// If case folding should happen when looking up attributes or exclusions. + case: gix_glob::pattern::Case, + /// A lookup table for object ids to read from in some situations when looking up attributes or exclusions. + attribute_files_in_index: Vec<PathOidMapping>, +} + +pub(crate) type PathOidMapping = (BString, gix_hash::ObjectId); + +/// +pub mod cache; +/// +pub mod stack; + +mod capabilities; diff --git a/vendor/gix-worktree/src/fs/stack.rs b/vendor/gix-worktree/src/fs/stack.rs new file mode 100644 index 000000000..734a4988b --- /dev/null +++ b/vendor/gix-worktree/src/fs/stack.rs @@ -0,0 +1,123 @@ +use std::path::{Path, PathBuf}; + +use crate::fs::Stack; + +impl Stack { + /// Returns the top-level path of the stack. + pub fn root(&self) -> &Path { + &self.root + } + + /// Returns the absolute path the currently set path. + pub fn current(&self) -> &Path { + &self.current + } + + /// Returns the currently set path relative to the [`root()`][Stack::root()]. + pub fn current_relative(&self) -> &Path { + &self.current_relative + } +} + +/// A delegate for use in a [`Stack`]. +pub trait Delegate { + /// Called whenever we push a directory on top of the stack, after the fact. + /// + /// It is also called if the currently acted on path is a directory in itself. + /// Use `stack.current()` to see the directory. + fn push_directory(&mut self, stack: &Stack) -> std::io::Result<()>; + + /// Called after any component was pushed, with the path available at `stack.current()`. + /// + /// `is_last_component` is true if the path is completely built. + fn push(&mut self, is_last_component: bool, stack: &Stack) -> std::io::Result<()>; + + /// Called right after a directory-component was popped off the stack. + /// + /// Use it to pop information off internal data structures. + fn pop_directory(&mut self); +} + +impl Stack { + /// Create a new instance with `root` being the base for all future paths we handle, assuming it to be valid which includes + /// symbolic links to be included in it as well. + pub fn new(root: impl Into<PathBuf>) -> Self { + let root = root.into(); + Stack { + current: root.clone(), + current_relative: PathBuf::with_capacity(128), + valid_components: 0, + root, + current_is_directory: true, + } + } + + /// Set the current stack to point to the `relative` path and call `push_comp()` each time a new path component is popped + /// along with the stacks state for inspection to perform an operation that produces some data. + /// + /// The full path to `relative` will be returned along with the data returned by push_comp. + /// Note that this only works correctly for the delegate's `push_directory()` and `pop_directory()` methods if + /// `relative` paths are terminal, so point to their designated file or directory. + pub fn make_relative_path_current( + &mut self, + relative: impl AsRef<Path>, + delegate: &mut impl Delegate, + ) -> std::io::Result<()> { + let relative = relative.as_ref(); + debug_assert!( + relative.is_relative(), + "only index paths are handled correctly here, must be relative" + ); + debug_assert!(!relative.to_string_lossy().is_empty(), "empty paths are not allowed"); + + if self.valid_components == 0 { + delegate.push_directory(self)?; + } + + let mut components = relative.components().peekable(); + let mut existing_components = self.current_relative.components(); + let mut matching_components = 0; + while let (Some(existing_comp), Some(new_comp)) = (existing_components.next(), components.peek()) { + if existing_comp == *new_comp { + components.next(); + matching_components += 1; + } else { + break; + } + } + + for _ in 0..self.valid_components - matching_components { + self.current.pop(); + self.current_relative.pop(); + if self.current_is_directory { + delegate.pop_directory(); + } + self.current_is_directory = true; + } + self.valid_components = matching_components; + + if !self.current_is_directory && components.peek().is_some() { + delegate.push_directory(self)?; + } + + while let Some(comp) = components.next() { + let is_last_component = components.peek().is_none(); + self.current_is_directory = !is_last_component; + self.current.push(comp); + self.current_relative.push(comp); + self.valid_components += 1; + let res = delegate.push(is_last_component, self); + if self.current_is_directory { + delegate.push_directory(self)?; + } + + if let Err(err) = res { + self.current.pop(); + self.current_relative.pop(); + self.valid_components -= 1; + return Err(err); + } + } + Ok(()) + } +} diff --git a/vendor/gix-worktree/src/index/checkout.rs b/vendor/gix-worktree/src/index/checkout.rs new file mode 100644 index 000000000..6bc465375 --- /dev/null +++ b/vendor/gix-worktree/src/index/checkout.rs @@ -0,0 +1,95 @@ +#![allow(missing_docs)] +use bstr::BString; +use gix_attributes::Attributes; + +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct Collision { + /// the path that collided with something already present on disk. + pub path: BString, + /// The io error we encountered when checking out `path`. + pub error_kind: std::io::ErrorKind, +} + +pub struct ErrorRecord { + /// the path that encountered the error. + pub path: BString, + /// The error + pub error: Box<dyn std::error::Error + Send + Sync + 'static>, +} + +#[derive(Default)] +pub struct Outcome { + /// The amount of files updated, or created. + pub files_updated: usize, + /// The amount of bytes written to disk, + pub bytes_written: u64, + pub collisions: Vec<Collision>, + pub errors: Vec<ErrorRecord>, +} + +#[derive(Clone)] +pub struct Options { + /// capabilities of the file system + pub fs: crate::fs::Capabilities, + /// If set, don't use more than this amount of threads. + /// Otherwise, usually use as many threads as there are logical cores. + /// A value of 0 is interpreted as no-limit + pub thread_limit: Option<usize>, + /// If true, we assume no file to exist in the target directory, and want exclusive access to it. + /// This should be enabled when cloning to avoid checks for freshness of files. This also enables + /// detection of collisions based on whether or not exclusive file creation succeeds or fails. + pub destination_is_initially_empty: bool, + /// If true, default false, worktree entries on disk will be overwritten with content from the index + /// even if they appear to be changed. When creating directories that clash with existing worktree entries, + /// these will try to delete the existing entry. + /// This is similar in behaviour as `git checkout --force`. + pub overwrite_existing: bool, + /// If true, default false, try to checkout as much as possible and don't abort on first error which isn't + /// due to a conflict. + /// The checkout operation will never fail, but count the encountered errors instead along with their paths. + pub keep_going: bool, + /// If true, a files creation time is taken into consideration when checking if a file changed. + /// Can be set to false in case other tools alter the creation time in ways that interfere with our operation. + /// + /// Default true. + pub trust_ctime: bool, + /// If true, all stat fields will be used when checking for up-to-date'ness of the entry. Otherwise + /// nano-second parts of mtime and ctime,uid, gid, inode and device number _will not_ be used, leaving only + /// the whole-second part of ctime and mtime and the file size to be checked. + /// + /// Default true. + pub check_stat: bool, + /// A group of attribute patterns that are applied globally, i.e. aren't rooted within the repository itself. + pub attribute_globals: gix_attributes::MatchGroup<Attributes>, +} + +impl Default for Options { + fn default() -> Self { + Options { + fs: Default::default(), + thread_limit: None, + destination_is_initially_empty: false, + keep_going: false, + trust_ctime: true, + check_stat: true, + overwrite_existing: false, + attribute_globals: Default::default(), + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum Error<E: std::error::Error + Send + Sync + 'static> { + #[error("Could not convert path to UTF8: {}", .path)] + IllformedUtf8 { path: BString }, + #[error("The clock was off when reading file related metadata after updating a file on disk")] + Time(#[from] std::time::SystemTimeError), + #[error("IO error while writing blob or reading file metadata or changing filetype")] + Io(#[from] std::io::Error), + #[error("object {} for checkout at {} could not be retrieved from object database", .oid.to_hex(), .path.display())] + Find { + #[source] + err: E, + oid: gix_hash::ObjectId, + path: std::path::PathBuf, + }, +} diff --git a/vendor/gix-worktree/src/index/entry.rs b/vendor/gix-worktree/src/index/entry.rs new file mode 100644 index 000000000..32628c4e0 --- /dev/null +++ b/vendor/gix-worktree/src/index/entry.rs @@ -0,0 +1,189 @@ +use std::{convert::TryInto, fs::OpenOptions, io::Write, path::Path, time::Duration}; + +use bstr::BStr; +use gix_hash::oid; +use gix_index::Entry; +use io_close::Close; + +use crate::{fs, index, os}; + +pub struct Context<'a, Find> { + pub find: &'a mut Find, + pub path_cache: &'a mut fs::Cache, + pub buf: &'a mut Vec<u8>, +} + +#[cfg_attr(not(unix), allow(unused_variables))] +pub fn checkout<Find, E>( + entry: &mut Entry, + entry_path: &BStr, + Context { find, path_cache, buf }: Context<'_, Find>, + index::checkout::Options { + fs: fs::Capabilities { + symlink, + executable_bit, + .. + }, + destination_is_initially_empty, + overwrite_existing, + .. + }: index::checkout::Options, +) -> Result<usize, index::checkout::Error<E>> +where + Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E>, + E: std::error::Error + Send + Sync + 'static, +{ + let dest_relative = gix_path::try_from_bstr(entry_path).map_err(|_| index::checkout::Error::IllformedUtf8 { + path: entry_path.to_owned(), + })?; + let is_dir = Some(entry.mode == gix_index::entry::Mode::COMMIT || entry.mode == gix_index::entry::Mode::DIR); + let dest = path_cache.at_path(dest_relative, is_dir, &mut *find)?.path(); + + let object_size = match entry.mode { + gix_index::entry::Mode::FILE | gix_index::entry::Mode::FILE_EXECUTABLE => { + let obj = find(&entry.id, buf).map_err(|err| index::checkout::Error::Find { + err, + oid: entry.id, + path: dest.to_path_buf(), + })?; + + #[cfg_attr(not(unix), allow(unused_mut))] + let mut options = open_options(dest, destination_is_initially_empty, overwrite_existing); + let needs_executable_bit = executable_bit && entry.mode == gix_index::entry::Mode::FILE_EXECUTABLE; + #[cfg(unix)] + if needs_executable_bit && destination_is_initially_empty { + use std::os::unix::fs::OpenOptionsExt; + // Note that these only work if the file was newly created, but won't if it's already + // existing, possibly without the executable bit set. Thus we do this only if the file is new. + options.mode(0o777); + } + + let mut file = try_write_or_unlink(dest, overwrite_existing, |p| options.open(p))?; + file.write_all(obj.data)?; + + // For possibly existing, overwritten files, we must change the file mode explicitly. + #[cfg(unix)] + if needs_executable_bit && !destination_is_initially_empty { + use std::os::unix::fs::PermissionsExt; + let mut perm = std::fs::symlink_metadata(dest)?.permissions(); + perm.set_mode(0o777); + std::fs::set_permissions(dest, perm)?; + } + // NOTE: we don't call `file.sync_all()` here knowing that some filesystems don't handle this well. + // revisit this once there is a bug to fix. + update_fstat(entry, file.metadata()?)?; + file.close()?; + obj.data.len() + } + gix_index::entry::Mode::SYMLINK => { + let obj = find(&entry.id, buf).map_err(|err| index::checkout::Error::Find { + err, + oid: entry.id, + path: dest.to_path_buf(), + })?; + let symlink_destination = gix_path::try_from_byte_slice(obj.data) + .map_err(|_| index::checkout::Error::IllformedUtf8 { path: obj.data.into() })?; + + if symlink { + try_write_or_unlink(dest, overwrite_existing, |p| os::create_symlink(symlink_destination, p))?; + } else { + let mut file = try_write_or_unlink(dest, overwrite_existing, |p| { + open_options(p, destination_is_initially_empty, overwrite_existing).open(dest) + })?; + file.write_all(obj.data)?; + file.close()?; + } + + update_fstat(entry, std::fs::symlink_metadata(dest)?)?; + obj.data.len() + } + gix_index::entry::Mode::DIR => todo!(), + gix_index::entry::Mode::COMMIT => todo!(), + _ => unreachable!(), + }; + Ok(object_size) +} + +/// Note that this works only because we assume to not race ourselves when symlinks are involved, and we do this by +/// delaying symlink creation to the end and will always do that sequentially. +/// It's still possible to fall for a race if other actors create symlinks in our path, but that's nothing to defend against. +fn try_write_or_unlink<T>( + path: &Path, + overwrite_existing: bool, + op: impl Fn(&Path) -> std::io::Result<T>, +) -> std::io::Result<T> { + if overwrite_existing { + match op(path) { + Ok(res) => Ok(res), + Err(err) if os::indicates_collision(&err) => { + try_unlink_path_recursively(path, &std::fs::symlink_metadata(path)?)?; + op(path) + } + Err(err) => Err(err), + } + } else { + op(path) + } +} + +fn try_unlink_path_recursively(path: &Path, path_meta: &std::fs::Metadata) -> std::io::Result<()> { + if path_meta.is_dir() { + std::fs::remove_dir_all(path) + } else if path_meta.file_type().is_symlink() { + os::remove_symlink(path) + } else { + std::fs::remove_file(path) + } +} + +#[cfg(not(debug_assertions))] +fn debug_assert_dest_is_no_symlink(_path: &Path) {} + +/// This is a debug assertion as we expect the machinery calling this to prevent this possibility in the first place +#[cfg(debug_assertions)] +fn debug_assert_dest_is_no_symlink(path: &Path) { + if let Ok(meta) = path.metadata() { + debug_assert!( + !meta.file_type().is_symlink(), + "BUG: should not ever allow to overwrite/write-into the target of a symbolic link: {}", + path.display() + ); + } +} + +fn open_options(path: &Path, destination_is_initially_empty: bool, overwrite_existing: bool) -> OpenOptions { + if overwrite_existing || !destination_is_initially_empty { + debug_assert_dest_is_no_symlink(path); + } + let mut options = gix_features::fs::open_options_no_follow(); + options + .create_new(destination_is_initially_empty && !overwrite_existing) + .create(!destination_is_initially_empty || overwrite_existing) + .write(true); + options +} + +fn update_fstat<E>(entry: &mut Entry, meta: std::fs::Metadata) -> Result<(), index::checkout::Error<E>> +where + E: std::error::Error + Send + Sync + 'static, +{ + let ctime = meta + .created() + .map_or(Ok(Duration::default()), |x| x.duration_since(std::time::UNIX_EPOCH))?; + let mtime = meta + .modified() + .map_or(Ok(Duration::default()), |x| x.duration_since(std::time::UNIX_EPOCH))?; + + let stat = &mut entry.stat; + stat.mtime.secs = mtime + .as_secs() + .try_into() + .expect("by 2038 we found a solution for this"); + stat.mtime.nsecs = mtime.subsec_nanos(); + stat.ctime.secs = ctime + .as_secs() + .try_into() + .expect("by 2038 we found a solution for this"); + stat.ctime.nsecs = ctime.subsec_nanos(); + Ok(()) +} diff --git a/vendor/gix-worktree/src/index/mod.rs b/vendor/gix-worktree/src/index/mod.rs new file mode 100644 index 000000000..684d1cae9 --- /dev/null +++ b/vendor/gix-worktree/src/index/mod.rs @@ -0,0 +1,311 @@ +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; + +use gix_features::{interrupt, parallel::in_parallel, progress, progress::Progress}; +use gix_hash::oid; + +use crate::fs; + +pub mod checkout; +pub(crate) mod entry; + +/// Note that interruption still produce an `Ok(…)` value, so the caller should look at `should_interrupt` to communicate the outcome. +/// `dir` is the directory into which to checkout the `index`. +/// `git_dir` is the `.git` directory for reading additional per-repository configuration files. +#[allow(clippy::too_many_arguments)] +pub fn checkout<Find, E>( + index: &mut gix_index::State, + dir: impl Into<std::path::PathBuf>, + find: Find, + files: &mut impl Progress, + bytes: &mut impl Progress, + should_interrupt: &AtomicBool, + options: checkout::Options, +) -> Result<checkout::Outcome, checkout::Error<E>> +where + Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E> + Send + Clone, + E: std::error::Error + Send + Sync + 'static, +{ + let paths = index.take_path_backing(); + let res = checkout_inner(index, &paths, dir, find, files, bytes, should_interrupt, options); + index.return_path_backing(paths); + res +} +#[allow(clippy::too_many_arguments)] +fn checkout_inner<Find, E>( + index: &mut gix_index::State, + paths: &gix_index::PathStorage, + dir: impl Into<std::path::PathBuf>, + find: Find, + files: &mut impl Progress, + bytes: &mut impl Progress, + should_interrupt: &AtomicBool, + options: checkout::Options, +) -> Result<checkout::Outcome, checkout::Error<E>> +where + Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E> + Send + Clone, + E: std::error::Error + Send + Sync + 'static, +{ + let num_files = AtomicUsize::default(); + let dir = dir.into(); + let case = if options.fs.ignore_case { + gix_glob::pattern::Case::Fold + } else { + gix_glob::pattern::Case::Sensitive + }; + let (chunk_size, thread_limit, num_threads) = gix_features::parallel::optimize_chunk_size_and_thread_limit( + 100, + index.entries().len().into(), + options.thread_limit, + None, + ); + + let state = fs::cache::State::for_checkout(options.overwrite_existing, options.attribute_globals.clone().into()); + let attribute_files = state.build_attribute_list(index, paths, case); + let mut ctx = chunk::Context { + buf: Vec::new(), + path_cache: fs::Cache::new(dir, state, case, Vec::with_capacity(512), attribute_files), + find, + options, + num_files: &num_files, + }; + + let chunk::Outcome { + mut collisions, + mut errors, + mut bytes_written, + delayed, + } = if num_threads == 1 { + let entries_with_paths = interrupt::Iter::new(index.entries_mut_with_paths_in(paths), should_interrupt); + chunk::process(entries_with_paths, files, bytes, &mut ctx)? + } else { + let entries_with_paths = interrupt::Iter::new(index.entries_mut_with_paths_in(paths), should_interrupt); + in_parallel( + gix_features::iter::Chunks { + inner: entries_with_paths, + size: chunk_size, + }, + thread_limit, + { + let ctx = ctx.clone(); + move |_| (progress::Discard, progress::Discard, ctx.clone()) + }, + |chunk, (files, bytes, ctx)| chunk::process(chunk.into_iter(), files, bytes, ctx), + chunk::Reduce { + files, + bytes, + num_files: &num_files, + aggregate: Default::default(), + marker: Default::default(), + }, + )? + }; + + for (entry, entry_path) in delayed { + bytes_written += chunk::checkout_entry_handle_result( + entry, + entry_path, + &mut errors, + &mut collisions, + files, + bytes, + &mut ctx, + )? as u64; + } + + Ok(checkout::Outcome { + files_updated: num_files.load(Ordering::Relaxed), + collisions, + errors, + bytes_written, + }) +} + +mod chunk { + use std::sync::atomic::{AtomicUsize, Ordering}; + + use bstr::BStr; + use gix_features::progress::Progress; + use gix_hash::oid; + + use crate::{ + fs, index, + index::{checkout, entry}, + os, + }; + + mod reduce { + use std::{ + marker::PhantomData, + sync::atomic::{AtomicUsize, Ordering}, + }; + + use gix_features::progress::Progress; + + use crate::index::checkout; + + pub struct Reduce<'a, 'entry, P1, P2, E> { + pub files: &'a mut P1, + pub bytes: &'a mut P2, + pub num_files: &'a AtomicUsize, + pub aggregate: super::Outcome<'entry>, + pub marker: PhantomData<E>, + } + + impl<'a, 'entry, P1, P2, E> gix_features::parallel::Reduce for Reduce<'a, 'entry, P1, P2, E> + where + P1: Progress, + P2: Progress, + E: std::error::Error + Send + Sync + 'static, + { + type Input = Result<super::Outcome<'entry>, checkout::Error<E>>; + type FeedProduce = (); + type Output = super::Outcome<'entry>; + type Error = checkout::Error<E>; + + fn feed(&mut self, item: Self::Input) -> Result<Self::FeedProduce, Self::Error> { + let item = item?; + let super::Outcome { + bytes_written, + delayed, + errors, + collisions, + } = item; + self.aggregate.bytes_written += bytes_written; + self.aggregate.delayed.extend(delayed); + self.aggregate.errors.extend(errors); + self.aggregate.collisions.extend(collisions); + + self.bytes.set(self.aggregate.bytes_written as usize); + self.files.set(self.num_files.load(Ordering::Relaxed)); + + Ok(()) + } + + fn finalize(self) -> Result<Self::Output, Self::Error> { + Ok(self.aggregate) + } + } + } + pub use reduce::Reduce; + + #[derive(Default)] + pub struct Outcome<'a> { + pub collisions: Vec<checkout::Collision>, + pub errors: Vec<checkout::ErrorRecord>, + pub delayed: Vec<(&'a mut gix_index::Entry, &'a BStr)>, + pub bytes_written: u64, + } + + #[derive(Clone)] + pub struct Context<'a, Find: Clone> { + pub find: Find, + pub path_cache: fs::Cache, + pub buf: Vec<u8>, + pub options: checkout::Options, + /// We keep these shared so that there is the chance for printing numbers that aren't looking like + /// multiple of chunk sizes. Purely cosmetic. Otherwise it's the same as `files`. + pub num_files: &'a AtomicUsize, + } + + pub fn process<'entry, Find, E>( + entries_with_paths: impl Iterator<Item = (&'entry mut gix_index::Entry, &'entry BStr)>, + files: &mut impl Progress, + bytes: &mut impl Progress, + ctx: &mut Context<'_, Find>, + ) -> Result<Outcome<'entry>, checkout::Error<E>> + where + Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E> + Clone, + E: std::error::Error + Send + Sync + 'static, + { + let mut delayed = Vec::new(); + let mut collisions = Vec::new(); + let mut errors = Vec::new(); + let mut bytes_written = 0; + + for (entry, entry_path) in entries_with_paths { + // TODO: write test for that + if entry.flags.contains(gix_index::entry::Flags::SKIP_WORKTREE) { + files.inc(); + continue; + } + + // Symlinks always have to be delayed on windows as they have to point to something that exists on creation. + // And even if not, there is a distinction between file and directory symlinks, hence we have to check what the target is + // before creating it. + // And to keep things sane, we just do the same on non-windows as well which is similar to what git does and adds some safety + // around writing through symlinks (even though we handle this). + // This also means that we prefer content in files over symlinks in case of collisions, which probably is for the better, too. + if entry.mode == gix_index::entry::Mode::SYMLINK { + delayed.push((entry, entry_path)); + continue; + } + + bytes_written += + checkout_entry_handle_result(entry, entry_path, &mut errors, &mut collisions, files, bytes, ctx)? + as u64; + } + + Ok(Outcome { + bytes_written, + errors, + collisions, + delayed, + }) + } + + pub fn checkout_entry_handle_result<Find, E>( + entry: &mut gix_index::Entry, + entry_path: &BStr, + errors: &mut Vec<checkout::ErrorRecord>, + collisions: &mut Vec<checkout::Collision>, + files: &mut impl Progress, + bytes: &mut impl Progress, + Context { + find, + path_cache, + buf, + options, + num_files, + }: &mut Context<'_, Find>, + ) -> Result<usize, checkout::Error<E>> + where + Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E> + Clone, + E: std::error::Error + Send + Sync + 'static, + { + let res = entry::checkout( + entry, + entry_path, + entry::Context { find, path_cache, buf }, + options.clone(), + ); + files.inc(); + num_files.fetch_add(1, Ordering::SeqCst); + match res { + Ok(object_size) => { + bytes.inc_by(object_size); + Ok(object_size) + } + Err(index::checkout::Error::Io(err)) if os::indicates_collision(&err) => { + // We are here because a file existed or was blocked by a directory which shouldn't be possible unless + // we are on a file insensitive file system. + files.fail(format!("{}: collided ({:?})", entry_path, err.kind())); + collisions.push(checkout::Collision { + path: entry_path.into(), + error_kind: err.kind(), + }); + Ok(0) + } + Err(err) => { + if options.keep_going { + errors.push(checkout::ErrorRecord { + path: entry_path.into(), + error: Box::new(err), + }); + Ok(0) + } else { + Err(err) + } + } + } + } +} diff --git a/vendor/gix-worktree/src/lib.rs b/vendor/gix-worktree/src/lib.rs new file mode 100644 index 000000000..9a67e0289 --- /dev/null +++ b/vendor/gix-worktree/src/lib.rs @@ -0,0 +1,15 @@ +//! ## 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)] + +/// file system related utilities +pub mod fs; + +/// +pub mod index; + +pub(crate) mod os; diff --git a/vendor/gix-worktree/src/os.rs b/vendor/gix-worktree/src/os.rs new file mode 100644 index 000000000..a297e73cd --- /dev/null +++ b/vendor/gix-worktree/src/os.rs @@ -0,0 +1,50 @@ +use std::{io, io::ErrorKind::AlreadyExists, path::Path}; + +#[cfg(not(windows))] +pub fn create_symlink(original: &Path, link: &Path) -> io::Result<()> { + std::os::unix::fs::symlink(original, link) +} + +#[cfg(not(windows))] +pub fn remove_symlink(path: &Path) -> io::Result<()> { + std::fs::remove_file(path) +} + +// TODO: use the `symlink` crate once it can delete directory symlinks +#[cfg(windows)] +pub fn remove_symlink(path: &Path) -> io::Result<()> { + if let Ok(meta) = std::fs::metadata(path) { + if meta.is_file() { + std::fs::remove_file(path) // this removes the link itself + } else { + std::fs::remove_dir(path) // however, this sees the destination directory, which isn't the right thing actually + } + } else { + std::fs::remove_file(path).or_else(|_| std::fs::remove_dir(path)) + } +} + +#[cfg(windows)] +pub fn create_symlink(original: &Path, link: &Path) -> io::Result<()> { + use std::os::windows::fs::{symlink_dir, symlink_file}; + // TODO: figure out if links to links count as files or whatever they point at + if std::fs::metadata(link.parent().expect("dir for link").join(original))?.is_dir() { + symlink_dir(original, link) + } else { + symlink_file(original, link) + } +} + +#[cfg(not(windows))] +pub fn indicates_collision(err: &std::io::Error) -> bool { + // TODO: use ::IsDirectory as well when stabilized instead of raw_os_error(), and ::FileSystemLoop respectively + err.kind() == AlreadyExists + || err.raw_os_error() == Some(21) + || err.raw_os_error() == Some(62) // no-follow on symlnk on mac-os + || err.raw_os_error() == Some(40) // no-follow on symlnk on ubuntu +} + +#[cfg(windows)] +pub fn indicates_collision(err: &std::io::Error) -> bool { + err.kind() == AlreadyExists || err.kind() == std::io::ErrorKind::PermissionDenied +} |