summaryrefslogtreecommitdiffstats
path: root/vendor/gix-tempfile
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-tempfile')
-rw-r--r--vendor/gix-tempfile/.cargo-checksum.json1
-rw-r--r--vendor/gix-tempfile/CHANGELOG.md579
-rw-r--r--vendor/gix-tempfile/Cargo.lock283
-rw-r--r--vendor/gix-tempfile/Cargo.toml97
-rw-r--r--vendor/gix-tempfile/LICENSE-APACHE191
-rw-r--r--vendor/gix-tempfile/LICENSE-MIT21
-rw-r--r--vendor/gix-tempfile/README.md12
-rw-r--r--vendor/gix-tempfile/src/forksafe.rs107
-rw-r--r--vendor/gix-tempfile/src/fs/create_dir.rs202
-rw-r--r--vendor/gix-tempfile/src/fs/mod.rs2
-rw-r--r--vendor/gix-tempfile/src/fs/remove_dir.rs108
-rw-r--r--vendor/gix-tempfile/src/handle.rs319
-rw-r--r--vendor/gix-tempfile/src/lib.rs216
-rw-r--r--vendor/gix-tempfile/src/registry.rs67
-rw-r--r--vendor/gix-tempfile/src/signal.rs100
15 files changed, 2305 insertions, 0 deletions
diff --git a/vendor/gix-tempfile/.cargo-checksum.json b/vendor/gix-tempfile/.cargo-checksum.json
new file mode 100644
index 000000000..336aec6e0
--- /dev/null
+++ b/vendor/gix-tempfile/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"8e84348c84cbacca0a00f9e4e961f0080a65d07915906faeafe05d8d89881f59","Cargo.lock":"9e94cbd0fee1702d881d6ae5964a7b6714a9af1bde7cf1b0cedb32e0398be6a3","Cargo.toml":"c1e4ca420265b3d1bf3fd14d46f5421126cabed082cc1f24cbc5601cba357882","LICENSE-APACHE":"cb4780590812826851ba250f90bed0ed19506ec98f6865a0e2e20bbf62391ff9","LICENSE-MIT":"49df47913ab2beafe8dc45607877ae64198bf0eee64aaad3e82ed9e4d27424e8","README.md":"48a31dad99a7ea256f4b0eb80726e12c77d3796069d3d40c0dada3790520617c","src/forksafe.rs":"654a2309e91e9e3761b9354ef2ffbc88bae65befb63deff5d7103b76613c043d","src/fs/create_dir.rs":"f06c1b0166b841b86ffb1bf443cdbfbde68f7b77b7f846f4ada106a1b9bc5578","src/fs/mod.rs":"3fb683d1373f4839b6e0e0440f59b208246b79a2d997906cd125bae42e9615ec","src/fs/remove_dir.rs":"0e4f9236826598a7c048476c2f8c6674bb6dbdb9b6ae7d6373ac97f38aa7bf4b","src/handle.rs":"77c242edd62d576e266c9bd2472037a535a732d6826d91ba75d835f9a0e6d387","src/lib.rs":"862e84f45b8468983d779b2363ecf479461175eaec2d94aefa1c5959eadf8fa3","src/registry.rs":"7ca1b062ef696d9cfbd92d162c14820b15891e845556cb8b68b5e120635de6d8","src/signal.rs":"b6551e99f675a1ff82de9b882524800844484c72ad3ad9d15b8ca0f545420074"},"package":"88751f247234b1f73c8e8056fd835a0999b04e596e052302cb71186005dc4b27"} \ No newline at end of file
diff --git a/vendor/gix-tempfile/CHANGELOG.md b/vendor/gix-tempfile/CHANGELOG.md
new file mode 100644
index 000000000..7e85250af
--- /dev/null
+++ b/vendor/gix-tempfile/CHANGELOG.md
@@ -0,0 +1,579 @@
+# 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).
+
+## 4.1.1 (2023-03-07)
+
+### Bug Fixes
+
+ - <csr-id-6778c5f6874ec2a44859de25428e6603dd4e9e8a/> switch `tempfile` to `~3.3.0` to help with `cargo` build.
+ `gix-tempfile` is now used in `cargo`, and `tempfile` seems to cause trouble
+ in at least one tier (see https://github.com/rust-lang/rust/pull/108665#issuecomment-1457677883).
+
+ This change pins `tempfile` to a working version until this is sorted out together with
+ the tempfile maintainers.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 1 commit contributed to the release.
+ - 6 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**
+ - Switch `tempfile` to `~3.3.0` to help with `cargo` build. ([`6778c5f`](https://github.com/Byron/gitoxide/commit/6778c5f6874ec2a44859de25428e6603dd4e9e8a))
+</details>
+
+## 4.1.0 (2023-03-01)
+
+### New Features
+
+ - <csr-id-1ff1342da793442859526df3dd0ec1ed968a6ded/> add `hp-hashmap` feature toggle (enabled by default).
+ This allows avoiding the `dashmap` dependency, and to optimize load
+ for different applications. It seems that this simple implementation
+ has performance benefits in some situations at least even though it
+ may leave all tempfiles in place if a signal handler tries to cleanup
+ while a lock is held.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 5 commits contributed to the release over the course of 1 calendar day.
+ - 2 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-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))
+ - Prepare changelogs prior to release ([`94c99c7`](https://github.com/Byron/gitoxide/commit/94c99c71520f33269cc8dbc26f82a74747cc7e16))
+ - Merge branch 'adjustments-for-cargo' ([`d686d94`](https://github.com/Byron/gitoxide/commit/d686d94e1030a8591ba074757d56927a346c8351))
+ - Add `hp-hashmap` feature toggle (enabled by default). ([`1ff1342`](https://github.com/Byron/gitoxide/commit/1ff1342da793442859526df3dd0ec1ed968a6ded))
+ - Avoid clearing the registry while running tests ([`d635fb7`](https://github.com/Byron/gitoxide/commit/d635fb7a060bfbc5b584bec9976549383d369f47))
+</details>
+
+## 4.0.0 (2023-02-26)
+
+### New Features (BREAKING)
+
+ - <csr-id-441f5ac4dd2f0636ec07065f8095e8bae5ce6985/> gate all signal handling behind the `signals` feature toggle.
+ This change also consolidates all signal handling into its own module called
+ `signal` to provide reusable handlers and as well as well as signal initialization.
+
+ Note that the functions to cleanup tempfiles don't interact with the signal registry,
+ hence they still can be called without the `signals` feature enabled.
+
+ Note that this change sneakily fixes a bug that could have caused a `write_all()`
+ on a tempfile that was removed by a signal to enter an infinite loop.
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 5 commits contributed to the release.
+ - 9 days passed between releases.
+ - 1 commit was understood as [conventional](https://www.conventionalcommits.org).
+ - 1 unique issue was worked on: [#339](https://github.com/Byron/gitoxide/issues/339)
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **[#339](https://github.com/Byron/gitoxide/issues/339)**
+ - Gate all signal handling behind the `signals` feature toggle. ([`441f5ac`](https://github.com/Byron/gitoxide/commit/441f5ac4dd2f0636ec07065f8095e8bae5ce6985))
+ * **Uncategorized**
+ - Release gix-tempfile v4.0.0 ([`ad23f1d`](https://github.com/Byron/gitoxide/commit/ad23f1dd58b3eabf5a12d02c4a1de8b1835051d5))
+ - Prepare for git-tempfile release ([`56c005b`](https://github.com/Byron/gitoxide/commit/56c005b13c44376f71e61781e73c0bf93416d0e4))
+ - Merge branch 'tempfile-upgrades' ([`3522cba`](https://github.com/Byron/gitoxide/commit/3522cbaac721c8079605be51b9053014bc5e863a))
+ - Upgrade `tempfile` to `3.4` ([`2670938`](https://github.com/Byron/gitoxide/commit/2670938df5f6a3ed155b793e301ea0ab64b8cec1))
+</details>
+
+## 3.0.3 (2023-02-17)
+
+### Bug Fixes
+
+ - <csr-id-e14dc7d475373d2c266e84ff8f1826c68a34ab92/> note that crates have been renamed from `git-*` to `gix-*`.
+ This also means that the `git-*` prefixed crates of the `gitoxide` project
+ are effectively unmaintained.
+ Use the crates with the `gix-*` prefix instead.
+
+ If you were using `git-repository`, then `gix` is its substitute.
+
+## 3.0.2 (2023-02-17)
+
+<csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/>
+<csr-id-533e887e80c5f7ede8392884562e1c5ba56fb9a8/>
+<csr-id-25209454d3f7e27e12e8ddca92e43b1ff01d58aa/>
+
+### Bug Fixes (BREAKING)
+
+ - <csr-id-c863ea5b34fa9ee3dac21c1f85587da16045f8d8/> do not install signal handlers by default
+ The previous behaviour is meant to be convenient for the casual
+ user even though it
+ ends up being surprising when used in applications that install
+ their own signal handlers and need more control over how the program
+ shuts down.
+
+ This is now fixed by **requiring an explicit `setup()`** call before
+ the first tempfile is created, which makes it a breaking change.
+
+### 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.
+
+### Bug Fixes
+
+ - <csr-id-81ed5f5e7a3634f0fab681ca59e40099f0118f75/> Assure interrupt based tempfile cleanup can't deadlock
+ We do this by using the `try_entry()` API provided by the most recent
+ dashmap, at the cost of potentially trying to access a lot of indices
+ that don't exist in the map anymore. The cost of this are expected
+ to be low though especially since interrupts are the uncommmon case.
+
+ A side-effect of this is that tempfiles that are currently being
+ removed for writing to them, for example, won't be cleaned up.
+
+ It will be up to the code running after the interrupt, if the case
+ at all, to deal with the tempfile, which is what it does anyway.
+ - <csr-id-d9451e8d7fc39c252042f9d2447061262c16ae7a/> downgrade dashmap to 4.0 to avoid unsoundness.
+ See https://github.com/xacrimon/dashmap/issues/167 for tracking
+ progress on resolving the issue.
+
+### Chore
+
+ - <csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> uniformize deny attributes
+ - <csr-id-533e887e80c5f7ede8392884562e1c5ba56fb9a8/> remove default link to cargo doc everywhere
+ - <csr-id-25209454d3f7e27e12e8ddca92e43b1ff01d58aa/> upgrade dashmap to 5.1.0 (with security fix)
+
+### Documentation
+
+ - <csr-id-39ed9eda62b7718d5109135e5ad406fb1fe2978c/> fix typos
+
+### Commit Statistics
+
+<csr-read-only-do-not-edit/>
+
+ - 238 commits contributed to the release over the course of 612 calendar days.
+ - 8 commits were understood as [conventional](https://www.conventionalcommits.org).
+ - 9 unique issues were worked on: [#198](https://github.com/Byron/gitoxide/issues/198), [#266](https://github.com/Byron/gitoxide/issues/266), [#298](https://github.com/Byron/gitoxide/issues/298), [#328](https://github.com/Byron/gitoxide/issues/328), [#336](https://github.com/Byron/gitoxide/issues/336), [#364](https://github.com/Byron/gitoxide/issues/364), [#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 8 times to make code idiomatic.
+
+### Commit Details
+
+<csr-read-only-do-not-edit/>
+
+<details><summary>view details</summary>
+
+ * **[#198](https://github.com/Byron/gitoxide/issues/198)**
+ - Adjust all changelogs to fulfil requirements for publishing ([`04b9ca0`](https://github.com/Byron/gitoxide/commit/04b9ca025a1667529b2221ab4280bd3c8dae01cf))
+ - Handle changelogs with upcoming version section if they were left for editing ([`0f5f47d`](https://github.com/Byron/gitoxide/commit/0f5f47da4662b596cbbbd9c0d83e135e2cc52c11))
+ - Deduplicate conventional message ids ([`e695eda`](https://github.com/Byron/gitoxide/commit/e695eda8cd183f703d9a3e59b7c3c7fa496ea1d2))
+ - Regenerate all changelogs to get links ([`0c81769`](https://github.com/Byron/gitoxide/commit/0c817690bd444f52bed2936b2b451cafd87dde92))
+ - Mention actual issues that where worked on ([`a517e39`](https://github.com/Byron/gitoxide/commit/a517e39a81145b331f6c7a6cc2fc22e25daf42e2))
+ - Respect release-wide ignore list to allow removing entire conventional headlines ([`145103d`](https://github.com/Byron/gitoxide/commit/145103d4aa715386da9d4953f7f85fadc49fff9a))
+ - Rebuild all changelogs to assure properly ordered headlines ([`4a9a05f`](https://github.com/Byron/gitoxide/commit/4a9a05f95930bad5938d4ce9c517ebf0e0b990f1))
+ - Sort all commits by time, descending… ([`f536bad`](https://github.com/Byron/gitoxide/commit/f536bad20ffbac4dc353dfeb1a917bb88becbb78))
+ - Greatly reduce changelog size now that the traversal fix is applied ([`a0bc98c`](https://github.com/Byron/gitoxide/commit/a0bc98c06c349de2fd6e0d4593606e68b98def72))
+ - Fixup remaining changelogs… ([`2f75db2`](https://github.com/Byron/gitoxide/commit/2f75db294fcf20c325555822f65629611be52971))
+ * **[#266](https://github.com/Byron/gitoxide/issues/266)**
+ - Upgrade dashmap to latest version ([`52d4fe5`](https://github.com/Byron/gitoxide/commit/52d4fe55b6dd88f72479abd4015cab063ddaaf97))
+ * **[#298](https://github.com/Byron/gitoxide/issues/298)**
+ - Refactor ([`591b533`](https://github.com/Byron/gitoxide/commit/591b5338ecdc0da33151baa0781fd8dc1ee8d5a9))
+ - Use hash_hasher based hash state for better keys/less collisions ([`814de07`](https://github.com/Byron/gitoxide/commit/814de079f4226f42efa49ad334a348bce67184e4))
+ * **[#328](https://github.com/Byron/gitoxide/issues/328)**
+ - A stress test to try conjure deadlocks in handlers ([`3bdecb5`](https://github.com/Byron/gitoxide/commit/3bdecb54570b46e4c140e783f49ff23ef465582d))
+ - Prepare changelog ([`8e92494`](https://github.com/Byron/gitoxide/commit/8e924948dfa366d3d39227b63053c7ff00a5382a))
+ - Assure interrupt based tempfile cleanup can't deadlock ([`81ed5f5`](https://github.com/Byron/gitoxide/commit/81ed5f5e7a3634f0fab681ca59e40099f0118f75))
+ * **[#336](https://github.com/Byron/gitoxide/issues/336)**
+ - Update changelog ([`2cfbe9c`](https://github.com/Byron/gitoxide/commit/2cfbe9ce81f611c0b541b9c0fd4fffd2d99dfa0a))
+ - Do not install signal handlers by default ([`c863ea5`](https://github.com/Byron/gitoxide/commit/c863ea5b34fa9ee3dac21c1f85587da16045f8d8))
+ * **[#364](https://github.com/Byron/gitoxide/issues/364)**
+ - Update changelogs prior to release ([`746a676`](https://github.com/Byron/gitoxide/commit/746a676056cd4907da7137a00798344b5bdb4419))
+ * **[#450](https://github.com/Byron/gitoxide/issues/450)**
+ - Add safety notes ([`910fa06`](https://github.com/Byron/gitoxide/commit/910fa06f39c9839c58d59467bca05ad511c23bef))
+ * **[#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-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-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-worktree` to `gix-worktree` ([`108bb1a`](https://github.com/Byron/gitoxide/commit/108bb1a634f4828853fb590e9fc125f79441dd38))
+ - Adjust to renaming of `git-url` to `gix-url` ([`b50817a`](https://github.com/Byron/gitoxide/commit/b50817aadb143e19f61f64e19b19ec1107d980c6))
+ - Adjust to renaming of `git-date` to `gix-date` ([`9a79ff2`](https://github.com/Byron/gitoxide/commit/9a79ff2d5cc74c1efad9f41e21095ae498cce00b))
+ - Adjust to renamining of `git-attributes` to `gix-attributes` ([`4a8b3b8`](https://github.com/Byron/gitoxide/commit/4a8b3b812ac26f2a2aee8ce8ca81591273383c84))
+ - Adjust to renaminig of `git-quote` to `gix-quote` ([`648025b`](https://github.com/Byron/gitoxide/commit/648025b7ca94411fdd0d90c53e5faede5fde6c8d))
+ - Adjust to renaming of `git-config` to `gix-config` ([`3a861c8`](https://github.com/Byron/gitoxide/commit/3a861c8f049f6502d3bcbdac752659aa1aeda46a))
+ - Adjust to renaming of `git-ref` to `gix-ref` ([`1f5f695`](https://github.com/Byron/gitoxide/commit/1f5f695407b034377d94b172465ff573562b3fc3))
+ - Adjust to renaming of `git-lock` to `gix-lock` ([`2028e78`](https://github.com/Byron/gitoxide/commit/2028e7884ae1821edeec81612f501e88e4722b17))
+ - Adjust to renaming of `git-tempfile` to `gix-tempfile` ([`b6cc3eb`](https://github.com/Byron/gitoxide/commit/b6cc3ebb5137084a6327af16a7d9364d8f092cc9))
+ - Rename `git-tempfile` to `gix-tempfile` ([`192ed5d`](https://github.com/Byron/gitoxide/commit/192ed5d15c04fdfb330b3ab553eeaaf09f7fccd4))
+ - 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))
+ - Merge branch 'rename-crates' ([`6461c3d`](https://github.com/Byron/gitoxide/commit/6461c3da4d6daee857606d94294c3f87fc36965a))
+ - Rename `git-repository` to `gix` ([`7bed2a9`](https://github.com/Byron/gitoxide/commit/7bed2a96604397fa990f427b1a970ddeb6f09f1c))
+ - 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))
+ - 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))
+ - 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-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 '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-by-spec' ([`5c05198`](https://github.com/Byron/gitoxide/commit/5c051986bd89590a9287d85d84c713d83dfab83a))
+ - Merge branch 'main' into index-from-tree ([`bc64b96`](https://github.com/Byron/gitoxide/commit/bc64b96a2ec781c72d1d4daad38aa7fb8b74f99b))
+ - Merge branch 'main' into filter-refs-by-spec ([`cfa1440`](https://github.com/Byron/gitoxide/commit/cfa144031dbcac2707ab0cec012bc35e78f9c475))
+ - Release git-date v0.0.5, git-hash v0.9.8, git-features v0.22.2, git-actor v0.11.3, git-glob v0.3.2, git-quote v0.2.1, git-attributes v0.3.2, git-tempfile v2.0.4, git-lock v2.1.1, git-validate v0.5.5, git-object v0.20.2, git-ref v0.15.2, git-sec v0.3.1, git-config v0.7.0, git-credentials v0.4.0, git-diff v0.17.2, git-discover v0.4.1, git-bitmap v0.1.2, git-index v0.4.2, git-mailmap v0.3.2, git-chunk v0.3.1, git-traverse v0.16.2, git-pack v0.21.2, git-odb v0.31.2, git-packetline v0.12.7, git-url v0.7.2, git-transport v0.19.2, git-protocol v0.19.0, git-revision v0.4.2, git-refspec v0.1.0, git-worktree v0.4.2, git-repository v0.22.0, safety bump 4 crates ([`4974eca`](https://github.com/Byron/gitoxide/commit/4974eca96d525d1ee4f8cad79bb713af7a18bf9d))
+ - Merge branch 'main' into remote-ls-refs ([`95f2f4f`](https://github.com/Byron/gitoxide/commit/95f2f4f17f7eae174a64c7d9f6a1513d73b21bbb))
+ - Thanks clippy ([`f90d772`](https://github.com/Byron/gitoxide/commit/f90d772cf625afea605e42c92db15ed870d7e120))
+ - 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))
+ - Uniformize deny attributes ([`f7f136d`](https://github.com/Byron/gitoxide/commit/f7f136dbe4f86e7dee1d54835c420ec07c96cd78))
+ - 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-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))
+ - Merge pull request #2 from SidneyDouw/main ([`ce885ad`](https://github.com/Byron/gitoxide/commit/ce885ad4c3324c09c83751c32e014f246c748766))
+ - Merge branch 'Byron:main' into main ([`9b9ea02`](https://github.com/Byron/gitoxide/commit/9b9ea0275f8ff5862f24cf5a4ca53bb1cd610709))
+ - Merge branch 'main' into rev-parse-delegate ([`6da8250`](https://github.com/Byron/gitoxide/commit/6da82507588d3bc849217c11d9a1d398b67f2ed6))
+ - Merge branch 'main' into pathspec ([`7b61506`](https://github.com/Byron/gitoxide/commit/7b615060712565f515515e35a3e8346278ad770c))
+ - Merge branch 'kianmeng-fix-typos' ([`4e7b343`](https://github.com/Byron/gitoxide/commit/4e7b34349c0a01ad8686bbb4eb987e9338259d9c))
+ - Fix typos ([`e9fcb70`](https://github.com/Byron/gitoxide/commit/e9fcb70e429edb2974afa3f58d181f3ef14c3da3))
+ - Release git-hash v0.9.6, git-features v0.22.0, git-date v0.0.2, git-actor v0.11.0, git-glob v0.3.1, git-path v0.4.0, git-attributes v0.3.0, git-tempfile v2.0.2, git-object v0.20.0, git-ref v0.15.0, git-sec v0.3.0, git-config v0.6.0, git-credentials v0.3.0, git-diff v0.17.0, git-discover v0.3.0, git-index v0.4.0, git-mailmap v0.3.0, git-traverse v0.16.0, git-pack v0.21.0, git-odb v0.31.0, git-url v0.7.0, git-transport v0.19.0, git-protocol v0.18.0, git-revision v0.3.0, git-worktree v0.4.0, git-repository v0.20.0, git-commitgraph v0.8.0, gitoxide-core v0.15.0, gitoxide v0.13.0, safety bump 22 crates ([`4737b1e`](https://github.com/Byron/gitoxide/commit/4737b1eea1d4c9a8d5a69fb63ecac5aa5d378ae5))
+ - Prepare changelog prior to release ([`3c50625`](https://github.com/Byron/gitoxide/commit/3c50625fa51350ec885b0f38ec9e92f9444df0f9))
+ - Merge 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))
+ - Thanks clippy ([`e1003d5`](https://github.com/Byron/gitoxide/commit/e1003d5fdee5d4439c0cf0286c67dec9b5e34f53))
+ - 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))
+ - Make fmt ([`7cf3545`](https://github.com/Byron/gitoxide/commit/7cf354509b545f7e7c99e159b5989ddfbe86273d))
+ - Merge branch 'short-id' ([`5849d5b`](https://github.com/Byron/gitoxide/commit/5849d5b326b83f98a16cf1d956c720c7f0fd4445))
+ - Release git-tempfile v2.0.0, safety bump 6 crates ([`90b1c42`](https://github.com/Byron/gitoxide/commit/90b1c42d5487904a9f329362d185b035d0ddb975))
+ - Release git-tempfile v1.0.6 ([`bd3f8ee`](https://github.com/Byron/gitoxide/commit/bd3f8ee28b51fa556a0f37c9bd62569f0ce7d49d))
+ - Upgrade dashmap to 5.1.0 (with security fix) ([`2520945`](https://github.com/Byron/gitoxide/commit/25209454d3f7e27e12e8ddca92e43b1ff01d58aa))
+ - Release git-tempfile v1.0.5 ([`d811154`](https://github.com/Byron/gitoxide/commit/d81115473cf04f5c3ae25b657b88c3f049451227))
+ - Downgrade dashmap to 4.0 to avoid unsoundness. ([`d9451e8`](https://github.com/Byron/gitoxide/commit/d9451e8d7fc39c252042f9d2447061262c16ae7a))
+ - Release git-diff v0.13.0, git-tempfile v1.0.4, git-chunk v0.3.0, git-traverse v0.12.0, git-pack v0.16.0, git-odb v0.26.0, git-packetline v0.12.3, git-url v0.3.5, git-transport v0.15.0, git-protocol v0.14.0, git-ref v0.11.0, git-repository v0.14.0, cargo-smart-release v0.8.0 ([`1b76119`](https://github.com/Byron/gitoxide/commit/1b76119259b8168aeb99cbbec233f7ddaa2d7d2c))
+ - Release git-actor v0.8.0, git-config v0.1.10, git-object v0.17.0, git-diff v0.13.0, git-tempfile v1.0.4, git-chunk v0.3.0, git-traverse v0.12.0, git-pack v0.16.0, git-odb v0.26.0, git-packetline v0.12.3, git-url v0.3.5, git-transport v0.15.0, git-protocol v0.14.0, git-ref v0.11.0, git-repository v0.14.0, cargo-smart-release v0.8.0 ([`8f57c29`](https://github.com/Byron/gitoxide/commit/8f57c297d7d6ed68cf51415ea7ede4bf9263326e))
+ - Release git-features v0.19.1, git-actor v0.8.0, git-config v0.1.10, git-object v0.17.0, git-diff v0.13.0, git-tempfile v1.0.4, git-chunk v0.3.0, git-traverse v0.12.0, git-pack v0.16.0, git-odb v0.26.0, git-packetline v0.12.3, git-url v0.3.5, git-transport v0.15.0, git-protocol v0.14.0, git-ref v0.11.0, git-repository v0.14.0, cargo-smart-release v0.8.0 ([`d78aab7`](https://github.com/Byron/gitoxide/commit/d78aab7b9c4b431d437ac70a0ef96263acb64e46))
+ - Release git-hash v0.9.1, git-features v0.19.1, git-actor v0.8.0, git-config v0.1.10, git-object v0.17.0, git-diff v0.13.0, git-tempfile v1.0.4, git-chunk v0.3.0, git-traverse v0.12.0, git-pack v0.16.0, git-odb v0.26.0, git-packetline v0.12.3, git-url v0.3.5, git-transport v0.15.0, git-protocol v0.14.0, git-ref v0.11.0, git-repository v0.14.0, cargo-smart-release v0.8.0, safety bump 4 crates ([`373cbc8`](https://github.com/Byron/gitoxide/commit/373cbc877f7ad60dac682e57c52a7b90f108ebe3))
+ - Prepare changelogs for release ([`674ec73`](https://github.com/Byron/gitoxide/commit/674ec73b0816baa2c63b4ef1b40b7a41849c5e95))
+ - Prepar changelogs for cargo-smart-release release ([`8900d69`](https://github.com/Byron/gitoxide/commit/8900d699226eb0995be70d66249827ce348261df))
+ - Release git-hash v0.7.0, git-features v0.16.5, git-actor v0.5.3, git-config v0.1.7, git-validate v0.5.3, git-object v0.14.1, git-diff v0.10.0, git-tempfile v1.0.3, git-lock v1.0.1, git-traverse v0.9.0, git-pack v0.12.0, git-odb v0.22.0, git-packetline v0.11.0, git-url v0.3.4, git-transport v0.12.0, git-protocol v0.11.0, git-ref v0.8.0, git-repository v0.10.0, cargo-smart-release v0.4.0 ([`59ffbd9`](https://github.com/Byron/gitoxide/commit/59ffbd9f15583c8248b7f48b3f55ec6faffe7cfe))
+ - Adjusting changelogs prior to release of git-hash v0.7.0, git-features v0.16.5, git-actor v0.5.3, git-validate v0.5.3, git-object v0.14.1, git-diff v0.10.0, git-tempfile v1.0.3, git-lock v1.0.1, git-traverse v0.9.0, git-pack v0.12.0, git-odb v0.22.0, git-packetline v0.11.0, git-url v0.3.4, git-transport v0.12.0, git-protocol v0.11.0, git-ref v0.8.0, git-repository v0.10.0, cargo-smart-release v0.4.0, safety bump 3 crates ([`a474395`](https://github.com/Byron/gitoxide/commit/a47439590e36b1cb8b516b6053fd5cbfc42efed7))
+ - Make fmt, but now it picked up some parts that usually don't get altered… ([`01f7b72`](https://github.com/Byron/gitoxide/commit/01f7b729337bd2c99498321c479a9a13b1858e3e))
+ - Update changelogs just for fun ([`21541b3`](https://github.com/Byron/gitoxide/commit/21541b3301de1e053fc0e84373be60d2162fbaae))
+ - Release git-tempfile v1.0.2 ([`310ea73`](https://github.com/Byron/gitoxide/commit/310ea7336e78fbedb2cefa1ecb773b25e6a77e0a))
+ - Update changelogs once more… ([`d57d279`](https://github.com/Byron/gitoxide/commit/d57d279dc603cf450c151bbb6dc6c6505cc6da10))
+ - Update changelogs retro-actively… ([`78cfe0a`](https://github.com/Byron/gitoxide/commit/78cfe0ac341c6c2257743d913884b50042078e6c))
+ - Release git-tempfile v1.0.1 ([`295eb37`](https://github.com/Byron/gitoxide/commit/295eb374d104ac2775b9f864ef3234e2c5832b54))
+ - [tempfile #195] adapt to Rust 1.55 ([`d9e71ac`](https://github.com/Byron/gitoxide/commit/d9e71acc5d619b5e78673da4fbb5a531c97ad6dd))
+ - Thanks clippy ([`4701296`](https://github.com/Byron/gitoxide/commit/4701296bd5e2c4ad2f80f4e1de498db49f93385a))
+ - Release git-tempfile v1.0.0 ([`1238535`](https://github.com/Byron/gitoxide/commit/123853539dc30ddea2d822ab177ee09b191bdf1b))
+ - [stability #171] prepare git-lock and git-tempfile release ([`3a1cf4d`](https://github.com/Byron/gitoxide/commit/3a1cf4d441b53c880b5c887916302a493ad28b41))
+ - [stability #171] Prime git-tempfile and git-lock for release ([`01278fe`](https://github.com/Byron/gitoxide/commit/01278fe4e28bf97ce6a2b8947198683646e361ee))
+ - Release git-tempfile v0.6.1 ([`eda952f`](https://github.com/Byron/gitoxide/commit/eda952f95e9ece78bbdbe6c26dd78f7ac5365d86))
+ - Apply nightly rustfmt rules. ([`5e0edba`](https://github.com/Byron/gitoxide/commit/5e0edbadb39673d4de640f112fa306349fb11814))
+ - (cargo-release) version 0.6.0 ([`d58f37e`](https://github.com/Byron/gitoxide/commit/d58f37e3b5a000fbe069aa869bd84f66d5c3210b))
+ - [utils #154] refactor: bool.then(||this) - neat ([`1dec1c4`](https://github.com/Byron/gitoxide/commit/1dec1c49032c8acb449e463fde41f403cb640e45))
+ - (cargo-release) version 0.5.0 ([`0e11e98`](https://github.com/Byron/gitoxide/commit/0e11e98f0562c7baa9c90e18db6240731d165217))
+ - [pack #153] implement io traits for tempfiles ([`59d03d6`](https://github.com/Byron/gitoxide/commit/59d03d6133b301a19adfab212cf2c946110fc53b))
+ - Clippy on tests and thanks clippy ([`a77a71c`](https://github.com/Byron/gitoxide/commit/a77a71cf02d328a2a964388928d6b2a235a0aa85))
+ - Thanks clippy ([`e1964e4`](https://github.com/Byron/gitoxide/commit/e1964e43979b3e32a5d4bfbe377a842d2c0b10ea))
+ - Remove unnecessary pub(crate) exports ([`3d2456e`](https://github.com/Byron/gitoxide/commit/3d2456e11709f0461b37c6df55ecc3861ca4cab5))
+ - [lock] support recoverable commits ([`b2217e7`](https://github.com/Byron/gitoxide/commit/b2217e7d25df9801354f702b0625d3168f8d3271))
+ - [ref] support for persistence with recovery ([`d8b2d66`](https://github.com/Byron/gitoxide/commit/d8b2d661b9cf644b52950b9dedf8dbce0d348098))
+ - [ref] refactor ([`a261b82`](https://github.com/Byron/gitoxide/commit/a261b82c1ee7ebdbbc82ce1c8286ca6a0f221cea))
+ - [ref] allow reflogs to be created in place of empty directory trees ([`80a6e0e`](https://github.com/Byron/gitoxide/commit/80a6e0e1ff2321d9162e799d5fc0f457e7de4ade))
+ - [tempfile] a way to delete empty dirs recursively ([`6025aa0`](https://github.com/Byron/gitoxide/commit/6025aa08d93cd5124c8df38c51b795b9c7d1c911))
+ - Bump libc from 0.2.97 to 0.2.98 ([`caf6495`](https://github.com/Byron/gitoxide/commit/caf6495b08f77d7e4eaa058074693fffb5c5644b))
+ - [tempfile] close a tempfile while keeping track of it ([`aa96ed1`](https://github.com/Byron/gitoxide/commit/aa96ed1776a615446b9864b1231f9f33805ab178))
+ - (cargo-release) version 0.4.0 ([`4512798`](https://github.com/Byron/gitoxide/commit/45127986daba0a409f5b405d463fa23f5c4a053b))
+ - [lock] add [must_use = "reason"] attribute where it matters ([`813c46b`](https://github.com/Byron/gitoxide/commit/813c46b1ac9ed5454c7832a6bad5a112f145b565))
+ - [lock] refactor, remaining docs ([`956e69f`](https://github.com/Byron/gitoxide/commit/956e69fcb96085d96124b6c56d829607b36adf9f))
+ - [lock] tests green ([`3706b26`](https://github.com/Byron/gitoxide/commit/3706b2669ebee5cd25a75a42d9b0a4a380707ee1))
+ - [lock] cleanup signal handling even more… ([`9fb13d2`](https://github.com/Byron/gitoxide/commit/9fb13d27ccce5b0742ee9289fca891dbeb8a65de))
+ - [lock] first tests and a lot of refactoring ([`3c34194`](https://github.com/Byron/gitoxide/commit/3c34194b6c0fd5ab22eb91081a563ba3bfa19110))
+ - [lock] refactor; Marker is definitely not necessary… ([`6af84c9`](https://github.com/Byron/gitoxide/commit/6af84c92dbe049068be795ef4870fd830baf5384))
+ - [lock] test what happens if multiple tempfiles are created ([`17942c7`](https://github.com/Byron/gitoxide/commit/17942c7960f25ad1f8f7fb2c94f251d39bb03c6e))
+ - [lock] sketch API ([`f0e1427`](https://github.com/Byron/gitoxide/commit/f0e142734c1b09e6c4175b3c1b232d886449e280))
+ - (cargo-release) version 0.3.0 ([`92f3a83`](https://github.com/Byron/gitoxide/commit/92f3a830457766c88c68f8424828bfd9b5145f86))
+ - [tempfile] refactor ([`f3144a8`](https://github.com/Byron/gitoxide/commit/f3144a897b4e10742fef47fadd350b4e9ddf316a))
+ - [tempfile] remaining tests ([`450db66`](https://github.com/Byron/gitoxide/commit/450db6609eb3dad10deed3f9769a21ae8c4b3be8))
+ - [tempfile] refactor ([`3bafa7b`](https://github.com/Byron/gitoxide/commit/3bafa7b2a3cf8efd0769564026ce7b757cb8c09b))
+ - [tempfile] implement 'closed' version of tempfile ([`d4bb61d`](https://github.com/Byron/gitoxide/commit/d4bb61dbc99b4270464d903978222d31c7e7dc5e))
+ - [tempfile] refactor ([`4788222`](https://github.com/Byron/gitoxide/commit/4788222c28605118c03ce9f3a4dfccc26e7f7b60))
+ - [tempfile] fix docs ([`3cd6712`](https://github.com/Byron/gitoxide/commit/3cd6712c22dae2e804573bca0b7a687c36066c29))
+ - [tempfile] sketch of a closed registration with different types ([`db9bb11`](https://github.com/Byron/gitoxide/commit/db9bb11a3132961029e04f1cf761bfc3c96ec33d))
+ - [tempfile] refactor ([`8a0ce64`](https://github.com/Byron/gitoxide/commit/8a0ce64baf5a3d77a08aa68c3245be8e7964be70))
+ - [tempfile] typesafe diffentiation between writable tempfiles and closed ones ([`3b424b1`](https://github.com/Byron/gitoxide/commit/3b424b1cc071580303d37b7459e80036635eb4aa))
+ - [tempfile] refactor ([`913f301`](https://github.com/Byron/gitoxide/commit/913f3014313fe0c03cd8f0af88944d8d514d89d9))
+ - [tempfile] refactor ([`9384617`](https://github.com/Byron/gitoxide/commit/9384617dbe00dd59726cc418f23fb0a6e6dde415))
+ - [tempfile] implement 'map' on tempfile to realize that 'close()' can't be done… ([`f4a1d33`](https://github.com/Byron/gitoxide/commit/f4a1d33e994e986604d18a85b7f85e1cea063dcf))
+ - (cargo-release) version 0.2.0 ([`7c2eb36`](https://github.com/Byron/gitoxide/commit/7c2eb36274d13646956ac850bee90abbbac91c5b))
+ - [tempfile] improve docs ([`d311b08`](https://github.com/Byron/gitoxide/commit/d311b082cdec323eb76363d986064fe771aa2bfd))
+ - Thanks clippy ([`a0f9803`](https://github.com/Byron/gitoxide/commit/a0f9803533e5684cfed5ab50cd8145d071e978b2))
+ - [tempfile] refactor ([`3a0f1ad`](https://github.com/Byron/gitoxide/commit/3a0f1ad0963c77a07f1984c39b127337463c030b))
+ - [tempfile] refactor ([`9b8abd0`](https://github.com/Byron/gitoxide/commit/9b8abd0336d6ea1d7c088c78fc09fa935408896f))
+ - [tempfile] cleanup control for named and unnamed tempfiles ([`0ef85a2`](https://github.com/Byron/gitoxide/commit/0ef85a247d60332ca232d6d993987c0b89e34466))
+ - [tempfile] all remaining remove_dir tests I can think of ([`3e45e5f`](https://github.com/Byron/gitoxide/commit/3e45e5fef4f0bbd8736ae3f197f15813290fe8dc))
+ - [tempfile] first bunch of tests for error handling and basic function of rmdir ([`ba41a15`](https://github.com/Byron/gitoxide/commit/ba41a15d874a2709ab92a8680d9e168ece7b4676))
+ - [tempfile] quick impl of remove-dir iter without tests ([`bf48913`](https://github.com/Byron/gitoxide/commit/bf48913b3bc1a8c3ebaa230880f573ad01982f08))
+ - [tempfile] refactor ([`9226dbe`](https://github.com/Byron/gitoxide/commit/9226dbe18127d7e85ba2779393cb7263e87cfbf8))
+ - [tempfile] refactor ([`730b733`](https://github.com/Byron/gitoxide/commit/730b733a1a5b2c3911849eef6ffe0833e12daf73))
+ - [tempfile] refactor ([`1da35ce`](https://github.com/Byron/gitoxide/commit/1da35ce045609296c189133ca439a74b550ccc6c))
+ - [tempfile] improve Retries documentation; retries docs for remove_dir ([`e665a5f`](https://github.com/Byron/gitoxide/commit/e665a5fcd38c7002545079c63f0bf35dee11876d))
+ - [tempfile] sketch how tempfile cleanup should be configured… ([`71acede`](https://github.com/Byron/gitoxide/commit/71acede9cba6fc222d0bde1a3fd0c232d3c877ab))
+ - [tempfile] logic fixed, it's working ([`6ad4946`](https://github.com/Byron/gitoxide/commit/6ad4946e2ee603c69dad1da3e1e996cd1d4ca075))
+ - [tempfile] better counting, but… ([`972113f`](https://github.com/Byron/gitoxide/commit/972113f1ea72674db61867b14f0eed0de498b310))
+ - [tempfile] better retry counts ([`c7a35ca`](https://github.com/Byron/gitoxide/commit/c7a35caa295580a1b9d4f8b77eb8ded9d9c88703))
+ - [tempfile] refactor ([`273d722`](https://github.com/Byron/gitoxide/commit/273d72276a73d49a633b9be1c66f1a2357dfcb0f))
+ - [tempfile] a better way to count retries… ([`e110b97`](https://github.com/Byron/gitoxide/commit/e110b97b4925a10fa9a62576daf9f078508b6760))
+ - [tempfile] trying to implement remove_dir really shows that… ([`1319b90`](https://github.com/Byron/gitoxide/commit/1319b908cc42ef5114d22957ebed9ed2ced11391))
+ - [tempfile] docs for create_dir; frame for remove_dir; ([`aa6b6d1`](https://github.com/Byron/gitoxide/commit/aa6b6d14236c817ecc64390b110069c4c1340c03))
+ - [tempfile] tests for automatic directory creation ([`3bd5cee`](https://github.com/Byron/gitoxide/commit/3bd5cee0dc0811ff3b1ab3d1a93e7dca8ae06b69))
+ - [tempfile] refactor ([`d441312`](https://github.com/Byron/gitoxide/commit/d4413125c432da2e7ef809aca61973f5f55dbd5c))
+ - [tempfile] use create_dir::all based on configuration… ([`156c021`](https://github.com/Byron/gitoxide/commit/156c021ac8aaabe8fed60ac4681f365c75e0e165))
+ - [tempfile] remove todo ([`5a14ab6`](https://github.com/Byron/gitoxide/commit/5a14ab63555d6e3a58ce32b68d4b47287869b73f))
+ - [tempfile] more information about error cases, too ([`7415141`](https://github.com/Byron/gitoxide/commit/74151415f0019a32b4759cf01873acb4102f2d1e))
+ - [tempfile] refactor ([`ae0c97a`](https://github.com/Byron/gitoxide/commit/ae0c97a59d9cc56e19d3ce6fcc12b4564a66298a))
+ - [tempfile] refactor ([`7c7658d`](https://github.com/Byron/gitoxide/commit/7c7658d3390fdf1b5348a482c71a9fb20a815cca))
+ - [tempfile] test for racy directory creation… ([`c9073bf`](https://github.com/Byron/gitoxide/commit/c9073bf0d6dff3165cfd43733a602127b8835727))
+ - [tempfile] verify existing files are handled correctly ([`28fee55`](https://github.com/Byron/gitoxide/commit/28fee552718cbbed067b8a16631aaa1080886e00))
+ - [tempfile] a test for directory creation limits ([`584b4b7`](https://github.com/Byron/gitoxide/commit/584b4b7a1e6997594f1234d5feab1bc82a83b859))
+ - [tempfile] limit retries for directory creation… ([`1536c7a`](https://github.com/Byron/gitoxide/commit/1536c7a58f1da4b80e83f1169b3f865f12a3d9a2))
+ - [tempfile] refactor ([`fa7b8e9`](https://github.com/Byron/gitoxide/commit/fa7b8e99d2613297127b044605a2314b878d3ab9))
+ - [tempfile] handle interrupts and assure there is an end to it ([`dc0afbd`](https://github.com/Byron/gitoxide/commit/dc0afbdf08c44237b6749426ebacbded6cf8a647))
+ - [tempfile] first recursive directory creation ([`b01faa9`](https://github.com/Byron/gitoxide/commit/b01faa9fdc371c1226978e32a3c71dbf3be600ec))
+ - [tempfile] refactor ([`7b59392`](https://github.com/Byron/gitoxide/commit/7b59392fec4c80eddd9f82271eb1a5671e44aa5a))
+ - [tempfile] another test ([`9e4834d`](https://github.com/Byron/gitoxide/commit/9e4834df1142fd0ffdbf5ffba1aed63bc67b66b3))
+ - [tempfile] first sketch of iterator based create directory all… ([`314693c`](https://github.com/Byron/gitoxide/commit/314693c6a4577f0b2b00274a55ec99e87c17918f))
+ - [lock] frame for git-lock crate ([`e6bc87d`](https://github.com/Byron/gitoxide/commit/e6bc87d77f9b397b25694f58d347de2fc38bf71d))
+ - [tempfile] add journey test to validate operation on process level ([`2d1efd4`](https://github.com/Byron/gitoxide/commit/2d1efd4915d66890b1132d5b39e08027a83047ba))
+ - [tempfile] more docs ([`d0c5e6b`](https://github.com/Byron/gitoxide/commit/d0c5e6b96f27d7ae708e7182b4cd5dbaceecd3cd))
+ - Refactor ([`e0b7f69`](https://github.com/Byron/gitoxide/commit/e0b7f695ee6bd1032544a29d91906f9b75e12d46))
+ - [tempfile] clean cargo manifest ([`d43f514`](https://github.com/Byron/gitoxide/commit/d43f51438937d5bdd2bb2e02c355dcd4ee2b8680))
+ - [tempfile] fix windows for good ([`3192a47`](https://github.com/Byron/gitoxide/commit/3192a47b730245f2656ccf8cd82394ec31e13126))
+ - [tempfile] fix windows build (hopefully) ([`6c1df66`](https://github.com/Byron/gitoxide/commit/6c1df667031084a9e6fe9676534f80aae9a95789))
+ - [tempfile] refactor ([`4a45df0`](https://github.com/Byron/gitoxide/commit/4a45df02340b55d34534be89934d2201dda261f9))
+ - [tempfile] prepare release ([`c0f7fde`](https://github.com/Byron/gitoxide/commit/c0f7fde70b28526ad52dce9e2314a25af1531689))
+ - [tempfile] an example to show off signal handlers ([`f325e69`](https://github.com/Byron/gitoxide/commit/f325e696c64e3f61f64c0a8d8c4e8af38104a713))
+ - [tempfile] remaining docs ([`d334dc0`](https://github.com/Byron/gitoxide/commit/d334dc004d8b8eea5b586c6ada173d28d380ccce))
+ - [tempfile] restore original signal handler behaviour. ([`9f91dd8`](https://github.com/Byron/gitoxide/commit/9f91dd8e95e1e51a8e0a4f7ba45628b3d93fc5de))
+ - [tempfile] process-id filter on deletion to support forks ([`611056f`](https://github.com/Byron/gitoxide/commit/611056f431dc793684efad668d40b93b1cfec21e))
+ - [tempfile] implement handler correctly, probably. ([`8cb0bbc`](https://github.com/Byron/gitoxide/commit/8cb0bbcf2d022401886071f9c91498977cea185c))
+ - [tempfile] remove tempfiles on shutdown, but… ([`954b760`](https://github.com/Byron/gitoxide/commit/954b76029e4d9e331738137ec2c9804b0e06a890))
+ - [tempfile] switch to dashmap as slab ([`6164719`](https://github.com/Byron/gitoxide/commit/61647195ce8fd0be1b3b63f19e8aaec392f33f19))
+ - [tempfile] a more realistic slab test shows the index can get quite high. ([`915f14c`](https://github.com/Byron/gitoxide/commit/915f14c41145dbd3f63bd798e6d0cc18d51fef6f))
+ - [tempfile] first step towards clearing tempfiles… ([`b0e0cee`](https://github.com/Byron/gitoxide/commit/b0e0cee866b643f9f9e4ebdc495abed5f5c6abf9))
+ - [tempfile] precisely named tempfiles ([`edc74f0`](https://github.com/Byron/gitoxide/commit/edc74f0e8f04f45661d4909bb3e6c62f4ac1b453))
+ - [tempfile] `take()` method ([`d377397`](https://github.com/Byron/gitoxide/commit/d3773976b86ad294528997104b9cfa0c803f9d6a))
+ - [tempfile] basic operation of a tempfile ([`a692950`](https://github.com/Byron/gitoxide/commit/a692950ae7c32ed9dd040c0aebde494ef3029a30))
+ - [tempfile] show that slabs can store a lot actually ([`0cc5b33`](https://github.com/Byron/gitoxide/commit/0cc5b33f0e421ed761e5c350fb4d3ad85ef3e884))
+ - [tempfile] initial docs as there is a lot to consider ([`9dffc2b`](https://github.com/Byron/gitoxide/commit/9dffc2b918178650a3b40adfcc35730e48f46951))
+ - [tempfile] crate frame ([`1b04c39`](https://github.com/Byron/gitoxide/commit/1b04c39030b436fb6850fbfa0c39a4fed7df727c))
+</details>
+
+## 3.0.1 (2023-01-10)
+
+A maintenance release without user-facing changes.
+
+## 3.0.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.
+
+## 2.0.6 (2022-11-06)
+
+A maintenance release without user-facing changes.
+
+## 2.0.5 (2022-09-20)
+
+Maintenance release without observable changes.
+
+## 2.0.4 (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
+
+## 2.0.3 (2022-08-17)
+
+A maintenance release without user facing changes.
+
+## 2.0.2 (2022-07-22)
+
+This is a maintenance release with no functional changes.
+
+## 2.0.1 (2022-04-03)
+
+A maintenance release without any changes on the surface.
+
+## 2.0.0 (2022-02-17)
+
+### Bug Fixes (BREAKING)
+
+ - <csr-id-c863ea5b34fa9ee3dac21c1f85587da16045f8d8/> do not install signal handlers by default.
+
+ The previous behaviour is meant to be convenient for the casual
+ user even though it
+ ends up being surprising when used in applications that install
+ their own signal handlers and need more control over how the program
+ shuts down.
+
+ This is now fixed by **requiring an explicit `setup()`** call before
+ the first tempfile is created, which makes it a breaking change.
+
+## 1.0.6 (2022-02-07)
+
+<csr-id-25209454d3f7e27e12e8ddca92e43b1ff01d58aa/>
+
+Fixes a potential deadlock in in an interrupt handler attempting to cleanup tempfiles.
+
+### Chore
+
+ - <csr-id-25209454d3f7e27e12e8ddca92e43b1ff01d58aa/> upgrade dashmap to 5.1.0 (with security fix)
+
+### Bug Fixes
+
+ - <csr-id-81ed5f5e7a3634f0fab681ca59e40099f0118f75/> Assure interrupt based tempfile cleanup can't deadlock.
+
+ We do this by using the `try_entry()` API provided by the most recent
+ dashmap, at the cost of potentially trying to access a lot of indices
+ that don't exist in the map anymore. The cost of this are expected
+ to be low though especially since interrupts are the uncommmon case.
+
+ A side-effect of this is that tempfiles that are currently being
+ removed for writing to them, for example, won't be cleaned up.
+
+ It will be up to the code running after the interrupt, if the case
+ at all, to deal with the tempfile, which is what it does anyway.
+
+## 1.0.5 (2022-02-01)
+
+### Bug Fixes
+
+ - <csr-id-d9451e8d7fc39c252042f9d2447061262c16ae7a/> downgrade dashmap to 4.0 to avoid unsoundness.
+ See https://github.com/xacrimon/dashmap/issues/167 for tracking
+ progress on resolving the issue.
+
+## 1.0.4 (2022-01-23)
+
+A maintenance release thanks to upgraded dependencies.
+
+## v1.0.3 (2021-10-15)
+
+This release contains no functional changes, but a more useful changelog.
+
+## v1.0.2 (2021-09-10)
+
+- Compatibility with Rust 1.55. It informed about the incorrect usage of `std::io::ErrorKind::Other` which this crate also dependent on in its tests.
+
+## v1.0.1 (2021-09-10)
+
+## v1.0.0 (2021-08-25)
+
+- initial release
+
+## v1.0.0 (2021-08-25)
+
+## v0.6.1 (2021-08-17)
+
+## v0.6.0 (2021-08-11)
+
+## v0.5.0 (2021-08-10)
+
+## v0.4.0 (2021-06-23)
+
+## v0.3.0 (2021-06-20)
+
+## v0.2.0 (2021-06-19)
+
+## v0.1.0 (2021-06-15)
+
diff --git a/vendor/gix-tempfile/Cargo.lock b/vendor/gix-tempfile/Cargo.lock
new file mode 100644
index 000000000..b07efdf9b
--- /dev/null
+++ b/vendor/gix-tempfile/Cargo.lock
@@ -0,0 +1,283 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "dashmap"
+version = "5.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
+dependencies = [
+ "cfg-if",
+ "hashbrown",
+ "lock_api",
+ "once_cell",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "document-features"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e493c573fce17f00dcab13b6ac057994f3ce17d1af4dc39bfd482b83c6eb6157"
+dependencies = [
+ "litrs",
+]
+
+[[package]]
+name = "fastrand"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
+dependencies = [
+ "instant",
+]
+
+[[package]]
+name = "gix-tempfile"
+version = "4.1.1"
+dependencies = [
+ "dashmap",
+ "document-features",
+ "libc",
+ "once_cell",
+ "parking_lot",
+ "signal-hook",
+ "signal-hook-registry",
+ "tempfile",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.139"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
+
+[[package]]
+name = "litrs"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9275e0933cf8bb20f008924c0cb07a0692fe54d8064996520bf998de9eb79aa"
+
+[[package]]
+name = "lock_api"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-sys",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "remove_dir_all"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "signal-hook"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
+dependencies = [
+ "libc",
+ "signal-hook-registry",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
+
+[[package]]
+name = "tempfile"
+version = "3.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "libc",
+ "redox_syscall",
+ "remove_dir_all",
+ "winapi",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
diff --git a/vendor/gix-tempfile/Cargo.toml b/vendor/gix-tempfile/Cargo.toml
new file mode 100644
index 000000000..7dba7fd20
--- /dev/null
+++ b/vendor/gix-tempfile/Cargo.toml
@@ -0,0 +1,97 @@
+# 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-tempfile"
+version = "4.1.1"
+authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"]
+include = [
+ "src/**/*",
+ "LICENSE-*",
+ "README.md",
+ "CHANGELOG.md",
+]
+description = "A tempfile implementation with a global registry to assure cleanup"
+readme = "README.md"
+license = "MIT/Apache-2.0"
+repository = "https://github.com/Byron/gitoxide"
+
+[package.metadata.docs.rs]
+all-features = true
+features = ["document-features"]
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
+[lib]
+test = true
+doctest = false
+
+[[example]]
+name = "delete-tempfiles-on-sigterm"
+path = "examples/delete-tempfiles-on-sigterm.rs"
+required-features = ["signals"]
+
+[[example]]
+name = "delete-tempfiles-on-sigterm-interactive"
+path = "examples/delete-tempfiles-on-sigterm-interactive.rs"
+required-features = ["signals"]
+
+[[example]]
+name = "try-deadlock-on-cleanup"
+path = "examples/try-deadlock-on-cleanup.rs"
+required-features = ["signals"]
+
+[dependencies.dashmap]
+version = "5.1.0"
+optional = true
+
+[dependencies.document-features]
+version = "0.2.0"
+optional = true
+
+[dependencies.once_cell]
+version = "1.8.0"
+features = [
+ "race",
+ "std",
+]
+default-features = false
+
+[dependencies.parking_lot]
+version = "0.12.1"
+
+[dependencies.signal-hook]
+version = "0.3.9"
+optional = true
+default-features = false
+
+[dependencies.signal-hook-registry]
+version = "1.4.0"
+optional = true
+
+[dependencies.tempfile]
+version = "~3.3.0"
+
+[features]
+default = ["hp-hashmap"]
+hp-hashmap = ["dep:dashmap"]
+signals = [
+ "dep:signal-hook",
+ "dep:signal-hook-registry",
+]
+
+[target."cfg(not(windows))".dependencies.libc]
+version = "0.2.98"
+default-features = false
diff --git a/vendor/gix-tempfile/LICENSE-APACHE b/vendor/gix-tempfile/LICENSE-APACHE
new file mode 100644
index 000000000..a51f59a06
--- /dev/null
+++ b/vendor/gix-tempfile/LICENSE-APACHE
@@ -0,0 +1,191 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ Copyright 2018-2021 Sebastian Thiel, and [contributors](https://github.com/byron/gitoxide/contributors)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/gix-tempfile/LICENSE-MIT b/vendor/gix-tempfile/LICENSE-MIT
new file mode 100644
index 000000000..b58e818f1
--- /dev/null
+++ b/vendor/gix-tempfile/LICENSE-MIT
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018-2021 Sebastian Thiel, and [contributors](https://github.com/byron/gitoxide/contributors).
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/gix-tempfile/README.md b/vendor/gix-tempfile/README.md
new file mode 100644
index 000000000..0de38724b
--- /dev/null
+++ b/vendor/gix-tempfile/README.md
@@ -0,0 +1,12 @@
+Use tempfiles to minimize the risk of resource leakage when preparing to overwrite or create a file with new content
+in a signal-safe way, making the change atomic.
+
+Tempfiles can also be used as locks as only one tempfile can exist at a given path at a time.
+
+* [x] registered temporary files which are deleted automatically as the process terminates or on drop
+ * [x] write to temporary file and persist it under new name
+ * [x] close temporary files to convert them into a marker while saving system resources
+ * [x] mark paths with a closed temporary file
+* [x] persist temporary files to prevent them from perishing.
+* [x] signal-handler integration with `gix` to clean lockfiles before the process is aborted.
+* [x] use a temporary file transparently due thanks to implementations of `std::io` traits
diff --git a/vendor/gix-tempfile/src/forksafe.rs b/vendor/gix-tempfile/src/forksafe.rs
new file mode 100644
index 000000000..1da7b2b2c
--- /dev/null
+++ b/vendor/gix-tempfile/src/forksafe.rs
@@ -0,0 +1,107 @@
+use std::path::Path;
+
+use tempfile::{NamedTempFile, TempPath};
+
+use crate::{handle, AutoRemove};
+
+enum TempfileOrTemppath {
+ Tempfile(NamedTempFile),
+ Temppath(TempPath),
+}
+
+pub(crate) struct ForksafeTempfile {
+ inner: TempfileOrTemppath,
+ cleanup: AutoRemove,
+ pub owning_process_id: u32,
+}
+
+impl ForksafeTempfile {
+ pub fn new(tempfile: NamedTempFile, cleanup: AutoRemove, mode: handle::Mode) -> Self {
+ use handle::Mode::*;
+ ForksafeTempfile {
+ inner: match mode {
+ Closed => TempfileOrTemppath::Temppath(tempfile.into_temp_path()),
+ Writable => TempfileOrTemppath::Tempfile(tempfile),
+ },
+ cleanup,
+ owning_process_id: std::process::id(),
+ }
+ }
+}
+
+impl ForksafeTempfile {
+ pub fn as_mut_tempfile(&mut self) -> Option<&mut NamedTempFile> {
+ match &mut self.inner {
+ TempfileOrTemppath::Tempfile(file) => Some(file),
+ TempfileOrTemppath::Temppath(_) => None,
+ }
+ }
+ pub fn close(self) -> Self {
+ if let TempfileOrTemppath::Tempfile(file) = self.inner {
+ ForksafeTempfile {
+ inner: TempfileOrTemppath::Temppath(file.into_temp_path()),
+ cleanup: self.cleanup,
+ owning_process_id: self.owning_process_id,
+ }
+ } else {
+ self
+ }
+ }
+ pub fn persist(mut self, path: impl AsRef<Path>) -> Result<Option<std::fs::File>, (std::io::Error, Self)> {
+ match self.inner {
+ TempfileOrTemppath::Tempfile(file) => match file.persist(path) {
+ Ok(file) => Ok(Some(file)),
+ Err(err) => Err((err.error, {
+ self.inner = TempfileOrTemppath::Tempfile(err.file);
+ self
+ })),
+ },
+ TempfileOrTemppath::Temppath(temppath) => match temppath.persist(path) {
+ Ok(_) => Ok(None),
+ Err(err) => Err((err.error, {
+ self.inner = TempfileOrTemppath::Temppath(err.path);
+ self
+ })),
+ },
+ }
+ }
+
+ pub fn into_temppath(self) -> TempPath {
+ match self.inner {
+ TempfileOrTemppath::Tempfile(file) => file.into_temp_path(),
+ TempfileOrTemppath::Temppath(path) => path,
+ }
+ }
+ pub fn into_tempfile(self) -> Option<NamedTempFile> {
+ match self.inner {
+ TempfileOrTemppath::Tempfile(file) => Some(file),
+ TempfileOrTemppath::Temppath(_) => None,
+ }
+ }
+ pub fn drop_impl(self) {
+ let file_path = match self.inner {
+ TempfileOrTemppath::Tempfile(file) => file.path().to_owned(),
+ TempfileOrTemppath::Temppath(path) => path.to_path_buf(),
+ };
+ let parent_directory = file_path.parent().expect("every tempfile has a parent directory");
+ self.cleanup.execute_best_effort(parent_directory);
+ }
+
+ pub fn drop_without_deallocation(self) {
+ use std::io::Write;
+ let temppath = match self.inner {
+ TempfileOrTemppath::Tempfile(file) => {
+ let (mut file, temppath) = file.into_parts();
+ file.flush().ok();
+ temppath
+ }
+ TempfileOrTemppath::Temppath(path) => path,
+ };
+ std::fs::remove_file(&temppath).ok();
+ std::mem::forget(
+ self.cleanup
+ .execute_best_effort(temppath.parent().expect("every file has a directory")),
+ );
+ std::mem::forget(temppath); // leak memory to prevent deallocation
+ }
+}
diff --git a/vendor/gix-tempfile/src/fs/create_dir.rs b/vendor/gix-tempfile/src/fs/create_dir.rs
new file mode 100644
index 000000000..65efdb2b8
--- /dev/null
+++ b/vendor/gix-tempfile/src/fs/create_dir.rs
@@ -0,0 +1,202 @@
+//!
+use std::path::Path;
+
+/// The amount of retries to do during various aspects of the directory creation.
+#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)]
+pub struct Retries {
+ /// How many times the whole directory can be created in the light of racy interference.
+ /// This count combats racy situations where another process is trying to remove a directory that we want to create,
+ /// and is deliberately higher than those who do deletion. That way, creation usually wins.
+ pub to_create_entire_directory: usize,
+ /// The amount of times we can try to create a directory because we couldn't as the parent didn't exist.
+ /// This amounts to the maximum subdirectory depth we allow to be created. Counts once per attempt to create the entire directory.
+ pub on_create_directory_failure: usize,
+ /// How often to retry to create a single directory if an interrupt happens, as caused by signals.
+ pub on_interrupt: usize,
+}
+
+impl Default for Retries {
+ fn default() -> Self {
+ Retries {
+ on_interrupt: 10,
+ to_create_entire_directory: 5,
+ on_create_directory_failure: 25,
+ }
+ }
+}
+
+mod error {
+ use std::{fmt, path::Path};
+
+ use crate::fs::create_dir::Retries;
+
+ /// The error returned by [all()][super::all()].
+ #[allow(missing_docs)]
+ #[derive(Debug)]
+ pub enum Error<'a> {
+ /// A failure we will probably recover from by trying again.
+ Intermediate { dir: &'a Path, kind: std::io::ErrorKind },
+ /// A failure that ends the operation.
+ Permanent {
+ dir: &'a Path,
+ err: std::io::Error,
+ /// The retries left after running the operation
+ retries_left: Retries,
+ /// The original amount of retries to allow determining how many were actually used
+ retries: Retries,
+ },
+ }
+
+ impl<'a> fmt::Display for Error<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Error::Intermediate { dir, kind } => write!(
+ f,
+ "Intermediae failure creating {:?} with error: {:?}",
+ dir.display(),
+ kind
+ ),
+ Error::Permanent {
+ err: _,
+ dir,
+ retries_left,
+ retries,
+ } => write!(
+ f,
+ "Permanently failing to create directory {dir:?} ({retries_left:?} of {retries:?})",
+ ),
+ }
+ }
+ }
+
+ impl<'a> std::error::Error for Error<'a> {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Error::Permanent { err, .. } => Some(err),
+ _ => None,
+ }
+ }
+ }
+}
+pub use error::Error;
+
+enum State {
+ CurrentlyCreatingDirectories,
+ SearchingUpwardsForExistingDirectory,
+}
+
+/// A special iterator which communicates its operation through results where…
+///
+/// * `Some(Ok(created_directory))` is yielded once or more success, followed by `None`
+/// * `Some(Err(Error::Intermediate))` is yielded zero or more times while trying to create the directory.
+/// * `Some(Err(Error::Permanent))` is yielded exactly once on failure.
+pub struct Iter<'a> {
+ cursors: Vec<&'a Path>,
+ retries: Retries,
+ original_retries: Retries,
+ state: State,
+}
+
+/// Construction
+impl<'a> Iter<'a> {
+ /// Create a new instance that creates `target` when iterated with the default amount of [`Retries`].
+ pub fn new(target: &'a Path) -> Self {
+ Self::new_with_retries(target, Default::default())
+ }
+
+ /// Create a new instance that creates `target` when iterated with the specified amount of `retries`.
+ pub fn new_with_retries(target: &'a Path, retries: Retries) -> Self {
+ Iter {
+ cursors: vec![target],
+ original_retries: retries,
+ retries,
+ state: State::SearchingUpwardsForExistingDirectory,
+ }
+ }
+}
+
+impl<'a> Iter<'a> {
+ fn pernanent_failure(
+ &mut self,
+ dir: &'a Path,
+ err: impl Into<std::io::Error>,
+ ) -> Option<Result<&'a Path, Error<'a>>> {
+ self.cursors.clear();
+ Some(Err(Error::Permanent {
+ err: err.into(),
+ dir,
+ retries_left: self.retries,
+ retries: self.original_retries,
+ }))
+ }
+
+ fn intermediate_failure(&self, dir: &'a Path, err: std::io::Error) -> Option<Result<&'a Path, Error<'a>>> {
+ Some(Err(Error::Intermediate { dir, kind: err.kind() }))
+ }
+}
+
+impl<'a> Iterator for Iter<'a> {
+ type Item = Result<&'a Path, Error<'a>>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ use std::io::ErrorKind::*;
+ match self.cursors.pop() {
+ Some(dir) => match std::fs::create_dir(dir) {
+ Ok(()) => {
+ self.state = State::CurrentlyCreatingDirectories;
+ Some(Ok(dir))
+ }
+ Err(err) => match err.kind() {
+ AlreadyExists if dir.is_dir() => {
+ self.state = State::CurrentlyCreatingDirectories;
+ Some(Ok(dir))
+ }
+ AlreadyExists => self.pernanent_failure(dir, err), // is non-directory
+ NotFound => {
+ self.retries.on_create_directory_failure -= 1;
+ if let State::CurrentlyCreatingDirectories = self.state {
+ self.state = State::SearchingUpwardsForExistingDirectory;
+ self.retries.to_create_entire_directory -= 1;
+ if self.retries.to_create_entire_directory < 1 {
+ return self.pernanent_failure(dir, NotFound);
+ }
+ self.retries.on_create_directory_failure =
+ self.original_retries.on_create_directory_failure;
+ }
+ if self.retries.on_create_directory_failure < 1 {
+ return self.pernanent_failure(dir, NotFound);
+ };
+ self.cursors.push(dir);
+ self.cursors.push(match dir.parent() {
+ None => return self.pernanent_failure(dir, InvalidInput),
+ Some(parent) => parent,
+ });
+ self.intermediate_failure(dir, err)
+ }
+ Interrupted => {
+ self.retries.on_interrupt -= 1;
+ if self.retries.on_interrupt <= 1 {
+ return self.pernanent_failure(dir, Interrupted);
+ };
+ self.cursors.push(dir);
+ self.intermediate_failure(dir, err)
+ }
+ _unexpected_kind => self.pernanent_failure(dir, err),
+ },
+ },
+ None => None,
+ }
+ }
+}
+
+/// Create all directories leading to `dir` including `dir` itself with the specified amount of `retries`.
+/// Returns the input `dir` on success that make it useful in expressions.
+pub fn all(dir: &Path, retries: Retries) -> std::io::Result<&Path> {
+ for res in Iter::new_with_retries(dir, retries) {
+ match res {
+ Err(Error::Permanent { err, .. }) => return Err(err),
+ Err(Error::Intermediate { .. }) | Ok(_) => continue,
+ }
+ }
+ Ok(dir)
+}
diff --git a/vendor/gix-tempfile/src/fs/mod.rs b/vendor/gix-tempfile/src/fs/mod.rs
new file mode 100644
index 000000000..bf26d819b
--- /dev/null
+++ b/vendor/gix-tempfile/src/fs/mod.rs
@@ -0,0 +1,2 @@
+pub mod create_dir;
+pub mod remove_dir;
diff --git a/vendor/gix-tempfile/src/fs/remove_dir.rs b/vendor/gix-tempfile/src/fs/remove_dir.rs
new file mode 100644
index 000000000..ac7b212fa
--- /dev/null
+++ b/vendor/gix-tempfile/src/fs/remove_dir.rs
@@ -0,0 +1,108 @@
+//!
+use std::path::{Path, PathBuf};
+
+/// A special iterator which communicates its operation through results where…
+///
+/// * `Some(Ok(removed_directory))` is yielded once or more success, followed by `None`
+/// * `Some(Err(std::io::Error))` is yielded exactly once on failure.
+pub struct Iter<'a> {
+ cursor: Option<&'a Path>,
+ boundary: &'a Path,
+}
+
+/// Construction
+impl<'a> Iter<'a> {
+ /// Create a new instance that deletes `target` but will stop at `boundary`, without deleting the latter.
+ /// Returns an error if `boundary` doesn't contain `target`
+ ///
+ /// **Note** that we don't canonicalize the path for performance reasons.
+ pub fn new(target: &'a Path, boundary: &'a Path) -> std::io::Result<Self> {
+ if !target.starts_with(boundary) {
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::InvalidInput,
+ format!("Removal target {target:?} must be contained in boundary {boundary:?}"),
+ ));
+ }
+ let cursor = if target == boundary {
+ None
+ } else if target.exists() {
+ Some(target)
+ } else {
+ None
+ };
+ Ok(Iter { cursor, boundary })
+ }
+}
+
+impl<'a> Iterator for Iter<'a> {
+ type Item = std::io::Result<&'a Path>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.cursor.take() {
+ Some(dir) => {
+ let next = match std::fs::remove_dir(dir) {
+ Ok(()) => Some(Ok(dir)),
+ Err(err) => match err.kind() {
+ std::io::ErrorKind::NotFound => Some(Ok(dir)),
+ _other_error_kind => return Some(Err(err)),
+ },
+ };
+ self.cursor = match dir.parent() {
+ Some(parent) => (parent != self.boundary).then_some(parent),
+ None => {
+ unreachable!("directory {:?} ran out of parents, this really shouldn't happen before hitting the boundary {:?}", dir, self.boundary)
+ }
+ };
+ next
+ }
+ None => None,
+ }
+ }
+}
+
+/// Delete all empty directories from `delete_dir` upward and until (not including) the `boundary_dir`.
+///
+/// Note that `boundary_dir` must contain `delete_dir` or an error is returned, otherwise `delete_dir` is returned on success.
+pub fn empty_upward_until_boundary<'a>(delete_dir: &'a Path, boundary_dir: &'a Path) -> std::io::Result<&'a Path> {
+ for item in Iter::new(delete_dir, boundary_dir)? {
+ match item {
+ Ok(_dir) => continue,
+ Err(err) => return Err(err),
+ }
+ }
+ Ok(delete_dir)
+}
+
+/// Delete all empty directories reachable from `delete_dir` from empty leaves moving upward to and including `delete_dir`.
+///
+/// If any encountered directory contains a file the entire operation is aborted.
+/// Please note that this is inherently racy and no attempts are made to counter that, which will allow creators to win
+/// as long as they retry.
+pub fn empty_depth_first(delete_dir: impl Into<PathBuf>) -> std::io::Result<()> {
+ let delete_dir = delete_dir.into();
+ if let Ok(()) = std::fs::remove_dir(&delete_dir) {
+ return Ok(());
+ }
+
+ let mut stack = vec![delete_dir];
+ let mut next_to_push = Vec::new();
+ while let Some(dir_to_delete) = stack.pop() {
+ let mut num_entries = 0;
+ for entry in std::fs::read_dir(&dir_to_delete)? {
+ num_entries += 1;
+ let entry = entry?;
+ if entry.file_type()?.is_dir() {
+ next_to_push.push(entry.path());
+ } else {
+ return Err(std::io::Error::new(std::io::ErrorKind::Other, "Directory not empty"));
+ }
+ }
+ if num_entries == 0 {
+ std::fs::remove_dir(&dir_to_delete)?;
+ } else {
+ stack.push(dir_to_delete);
+ stack.append(&mut next_to_push);
+ }
+ }
+ Ok(())
+}
diff --git a/vendor/gix-tempfile/src/handle.rs b/vendor/gix-tempfile/src/handle.rs
new file mode 100644
index 000000000..f20e237ee
--- /dev/null
+++ b/vendor/gix-tempfile/src/handle.rs
@@ -0,0 +1,319 @@
+//!
+use std::{io, path::Path};
+
+use tempfile::{NamedTempFile, TempPath};
+
+use crate::{AutoRemove, ContainingDirectory, ForksafeTempfile, Handle, NEXT_MAP_INDEX, REGISTRY};
+
+/// Marker to signal the Registration is an open file able to be written to.
+#[derive(Debug)]
+pub struct Writable;
+
+/// Marker to signal the Registration is a closed file that consumes no additional process resources.
+///
+/// It can't ever be written to unless reopened after persisting it.
+#[derive(Debug)]
+pub struct Closed;
+
+pub(crate) enum Mode {
+ Writable,
+ Closed,
+}
+
+/// Utilities
+impl Handle<()> {
+ fn at_path(
+ path: impl AsRef<Path>,
+ directory: ContainingDirectory,
+ cleanup: AutoRemove,
+ mode: Mode,
+ ) -> io::Result<usize> {
+ let path = path.as_ref();
+ let tempfile = {
+ let mut builder = tempfile::Builder::new();
+ let dot_ext_storage;
+ match path.file_stem() {
+ Some(stem) => builder.prefix(stem),
+ None => builder.prefix(""),
+ };
+ if let Some(ext) = path.extension() {
+ dot_ext_storage = format!(".{}", ext.to_string_lossy());
+ builder.suffix(&dot_ext_storage);
+ }
+ let parent_dir = path.parent().expect("parent directory is present");
+ let parent_dir = directory.resolve(parent_dir)?;
+ ForksafeTempfile::new(builder.rand_bytes(0).tempfile_in(parent_dir)?, cleanup, mode)
+ };
+ let id = NEXT_MAP_INDEX.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
+ expect_none(REGISTRY.insert(id, Some(tempfile)));
+ Ok(id)
+ }
+
+ fn new_writable_inner(
+ containing_directory: impl AsRef<Path>,
+ directory: ContainingDirectory,
+ cleanup: AutoRemove,
+ mode: Mode,
+ ) -> io::Result<usize> {
+ let containing_directory = directory.resolve(containing_directory.as_ref())?;
+ let id = NEXT_MAP_INDEX.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
+ expect_none(REGISTRY.insert(
+ id,
+ Some(ForksafeTempfile::new(
+ NamedTempFile::new_in(containing_directory)?,
+ cleanup,
+ mode,
+ )),
+ ));
+ Ok(id)
+ }
+}
+
+/// Creation and ownership transfer
+impl Handle<Closed> {
+ /// Create a registered tempfile at the given `path`, where `path` includes the desired filename and close it immediately.
+ ///
+ /// Depending on the `directory` configuration, intermediate directories will be created, and depending on `cleanup` empty
+ /// intermediate directories will be removed.
+ pub fn at(path: impl AsRef<Path>, directory: ContainingDirectory, cleanup: AutoRemove) -> io::Result<Self> {
+ Ok(Handle {
+ id: Handle::<()>::at_path(path, directory, cleanup, Mode::Closed)?,
+ _marker: Default::default(),
+ })
+ }
+
+ /// Take ownership of the temporary file path, which deletes it when dropped without persisting it beforehand.
+ ///
+ /// It's a theoretical possibility that the file isn't present anymore if signals interfere, hence the `Option`
+ pub fn take(self) -> Option<TempPath> {
+ let res = REGISTRY.remove(&self.id);
+ std::mem::forget(self);
+ res.and_then(|(_k, v)| v.map(|v| v.into_temppath()))
+ }
+}
+
+/// Creation and ownership transfer
+impl Handle<Writable> {
+ /// Create a registered tempfile at the given `path`, where `path` includes the desired filename.
+ ///
+ /// Depending on the `directory` configuration, intermediate directories will be created, and depending on `cleanup` empty
+ /// intermediate directories will be removed.
+ pub fn at(path: impl AsRef<Path>, directory: ContainingDirectory, cleanup: AutoRemove) -> io::Result<Self> {
+ Ok(Handle {
+ id: Handle::<()>::at_path(path, directory, cleanup, Mode::Writable)?,
+ _marker: Default::default(),
+ })
+ }
+
+ /// Create a registered tempfile within `containing_directory` with a name that won't clash, and clean it up as specified with `cleanup`.
+ /// Control how to deal with intermediate directories with `directory`.
+ /// The temporary file is opened and can be written to using the [`with_mut()`][Handle::with_mut()] method.
+ pub fn new(
+ containing_directory: impl AsRef<Path>,
+ directory: ContainingDirectory,
+ cleanup: AutoRemove,
+ ) -> io::Result<Self> {
+ Ok(Handle {
+ id: Handle::<()>::new_writable_inner(containing_directory, directory, cleanup, Mode::Writable)?,
+ _marker: Default::default(),
+ })
+ }
+
+ /// Take ownership of the temporary file.
+ ///
+ /// It's a theoretical possibility that the file isn't present anymore if signals interfere, hence the `Option`
+ pub fn take(self) -> Option<NamedTempFile> {
+ let res = REGISTRY.remove(&self.id);
+ std::mem::forget(self);
+ res.and_then(|(_k, v)| v.map(|v| v.into_tempfile().expect("correct runtime typing")))
+ }
+
+ /// Close the underlying file handle but keep track of the temporary file as before for automatic cleanup.
+ ///
+ /// This saves system resources in situations where one opens a tempfile file at a time, writes a new value, and closes
+ /// it right after to perform more updates of this kind in other tempfiles. When all succeed, they can be renamed one after
+ /// another.
+ pub fn close(self) -> std::io::Result<Handle<Closed>> {
+ match REGISTRY.remove(&self.id) {
+ Some((id, Some(t))) => {
+ std::mem::forget(self);
+ expect_none(REGISTRY.insert(id, Some(t.close())));
+ Ok(Handle::<Closed> {
+ id,
+ _marker: Default::default(),
+ })
+ }
+ None | Some((_, None)) => Err(std::io::Error::new(
+ std::io::ErrorKind::NotFound,
+ format!("The tempfile with id {} wasn't available anymore", self.id),
+ )),
+ }
+ }
+}
+
+/// Mutation
+impl Handle<Writable> {
+ /// Obtain a mutable handler to the underlying named tempfile and call `f(&mut named_tempfile)` on it.
+ ///
+ /// Note that for the duration of the call, a signal interrupting the operation will cause the tempfile not to be cleaned up
+ /// as it is not visible anymore to the signal handler.
+ ///
+ /// # Assumptions
+ /// The caller must assure that the signal handler for cleanup will be followed by an abort call so that
+ /// this code won't run again on a removed instance. An error will occur otherwise.
+ pub fn with_mut<T>(&mut self, once: impl FnOnce(&mut NamedTempFile) -> T) -> std::io::Result<T> {
+ match REGISTRY.remove(&self.id) {
+ Some((id, Some(mut t))) => {
+ let res = once(t.as_mut_tempfile().expect("correct runtime typing"));
+ expect_none(REGISTRY.insert(id, Some(t)));
+ Ok(res)
+ }
+ None | Some((_, None)) => Err(std::io::Error::new(
+ std::io::ErrorKind::NotFound,
+ format!("The tempfile with id {} wasn't available anymore", self.id),
+ )),
+ }
+ }
+}
+
+mod io_impls {
+ use std::{io, io::SeekFrom};
+
+ use super::{Handle, Writable};
+
+ impl io::Write for Handle<Writable> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.with_mut(|f| f.write(buf))?
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.with_mut(|f| f.flush())?
+ }
+ }
+
+ impl io::Seek for Handle<Writable> {
+ fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
+ self.with_mut(|f| f.seek(pos))?
+ }
+ }
+
+ impl io::Read for Handle<Writable> {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ self.with_mut(|f| f.read(buf))?
+ }
+ }
+}
+
+///
+pub mod persist {
+ use std::path::Path;
+
+ use crate::{
+ handle::{expect_none, Closed, Writable},
+ Handle, REGISTRY,
+ };
+
+ mod error {
+ use std::fmt::{self, Debug, Display};
+
+ use crate::Handle;
+
+ /// The error returned by various [`persist(…)`][Handle<crate::handle::Writable>::persist()] methods
+ #[derive(Debug)]
+ pub struct Error<T: Debug> {
+ /// The io error that prevented the attempt to succeed
+ pub error: std::io::Error,
+ /// The registered handle to the tempfile which couldn't be persisted.
+ pub handle: Handle<T>,
+ }
+
+ impl<T: Debug> Display for Error<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ Display::fmt(&self.error, f)
+ }
+ }
+
+ impl<T: Debug> std::error::Error for Error<T> {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ self.error.source()
+ }
+ }
+ }
+ pub use error::Error;
+
+ impl Handle<Writable> {
+ /// Persist this tempfile to replace the file at the given `path` if necessary, in a way that recovers the original instance
+ /// on error or returns the open now persisted former tempfile.
+ /// Note that it might not exist anymore if an interrupt handler managed to steal it and allowed the program to return to
+ /// its normal flow.
+ pub fn persist(self, path: impl AsRef<Path>) -> Result<Option<std::fs::File>, Error<Writable>> {
+ let res = REGISTRY.remove(&self.id);
+
+ match res.and_then(|(_k, v)| v.map(|v| v.persist(path))) {
+ Some(Ok(Some(file))) => {
+ std::mem::forget(self);
+ Ok(Some(file))
+ }
+ None => {
+ std::mem::forget(self);
+ Ok(None)
+ }
+ Some(Err((err, tempfile))) => {
+ expect_none(REGISTRY.insert(self.id, Some(tempfile)));
+ Err(Error::<Writable> {
+ error: err,
+ handle: self,
+ })
+ }
+ Some(Ok(None)) => unreachable!("no open files in an open handle"),
+ }
+ }
+ }
+
+ impl Handle<Closed> {
+ /// Persist this tempfile to replace the file at the given `path` if necessary, in a way that recovers the original instance
+ /// on error.
+ pub fn persist(self, path: impl AsRef<Path>) -> Result<(), Error<Closed>> {
+ let res = REGISTRY.remove(&self.id);
+
+ match res.and_then(|(_k, v)| v.map(|v| v.persist(path))) {
+ None | Some(Ok(None)) => {
+ std::mem::forget(self);
+ Ok(())
+ }
+ Some(Err((err, tempfile))) => {
+ expect_none(REGISTRY.insert(self.id, Some(tempfile)));
+ Err(Error::<Closed> {
+ error: err,
+ handle: self,
+ })
+ }
+ Some(Ok(Some(_file))) => unreachable!("no open files in a closed handle"),
+ }
+ }
+ }
+}
+
+impl ContainingDirectory {
+ fn resolve(self, dir: &Path) -> std::io::Result<&Path> {
+ match self {
+ ContainingDirectory::Exists => Ok(dir),
+ ContainingDirectory::CreateAllRaceProof(retries) => crate::create_dir::all(dir, retries),
+ }
+ }
+}
+
+fn expect_none<T>(v: Option<T>) {
+ assert!(
+ v.is_none(),
+ "there should never be conflicts or old values as ids are never reused."
+ );
+}
+
+impl<T: std::fmt::Debug> Drop for Handle<T> {
+ fn drop(&mut self) {
+ if let Some((_id, Some(tempfile))) = REGISTRY.remove(&self.id) {
+ tempfile.drop_impl();
+ }
+ }
+}
diff --git a/vendor/gix-tempfile/src/lib.rs b/vendor/gix-tempfile/src/lib.rs
new file mode 100644
index 000000000..8585c60b7
--- /dev/null
+++ b/vendor/gix-tempfile/src/lib.rs
@@ -0,0 +1,216 @@
+//! git-style registered tempfiles that are removed upon typical termination signals.
+//!
+//! To register signal handlers in a typical application that doesn't have its own, call
+//! [`gix_tempfile::signal::setup(Default::default())`][signal::setup()] before creating the first tempfile.
+//!
+//! Signal handlers are powered by [`signal-hook`] to get notified when the application is told to shut down
+//! to assure tempfiles are deleted. The deletion is filtered by process id to allow forks to have their own
+//! set of tempfiles that won't get deleted when the parent process exits.
+//!
+//! ### Initial Setup
+//!
+//! As no handlers for `TERMination` are installed, it is required to call [`signal::setup()`] before creating the first tempfile.
+//! This also allows to control how `git-tempfiles` integrates with other handlers under application control.
+//!
+//! As a general rule of thumb, use `Default::default()` as argument to emulate the default behaviour and
+//! abort the process after cleaning temporary files. Read more about options in [signal::handler::Mode].
+//!
+//! # Limitations
+//!
+//! ## Tempfiles might remain on disk
+//!
+//! * Uninterruptible signals are received like `SIGKILL`
+//! * The application is performing a write operation on the tempfile when a signal arrives, preventing this tempfile to be removed,
+//! but not others. Any other operation dealing with the tempfile suffers from the same issue.
+//!
+//! [signal-hook]: https://docs.rs/signal-hook
+//!
+//! ## 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)]
+
+use std::{
+ io,
+ marker::PhantomData,
+ path::{Path, PathBuf},
+ sync::atomic::AtomicUsize,
+};
+
+use once_cell::sync::Lazy;
+
+#[cfg(feature = "hp-hashmap")]
+type HashMap<K, V> = dashmap::DashMap<K, V>;
+
+#[cfg(not(feature = "hp-hashmap"))]
+mod hashmap {
+ use parking_lot::Mutex;
+ use std::collections::HashMap;
+
+ // TODO(performance): use the `gix-hashtable` slot-map once available. It seems quite fast already though, so experiment.
+ pub struct Concurrent<K, V> {
+ inner: Mutex<HashMap<K, V>>,
+ }
+
+ impl<K, V> Default for Concurrent<K, V>
+ where
+ K: Eq + std::hash::Hash,
+ {
+ fn default() -> Self {
+ Concurrent {
+ inner: Default::default(),
+ }
+ }
+ }
+
+ impl<K, V> Concurrent<K, V>
+ where
+ K: Eq + std::hash::Hash + Clone,
+ {
+ pub fn insert(&self, key: K, value: V) -> Option<V> {
+ self.inner.lock().insert(key, value)
+ }
+
+ pub fn remove(&self, key: &K) -> Option<(K, V)> {
+ self.inner.lock().remove(key).map(|v| (key.clone(), v))
+ }
+
+ pub fn for_each<F>(&self, cb: F)
+ where
+ Self: Sized,
+ F: FnMut(&mut V),
+ {
+ if let Some(mut guard) = self.inner.try_lock() {
+ guard.values_mut().for_each(cb);
+ }
+ }
+ }
+}
+
+#[cfg(not(feature = "hp-hashmap"))]
+type HashMap<K, V> = hashmap::Concurrent<K, V>;
+
+mod fs;
+pub use fs::{create_dir, remove_dir};
+
+#[cfg(feature = "signals")]
+/// signal setup and reusable handlers.
+pub mod signal;
+
+mod forksafe;
+use forksafe::ForksafeTempfile;
+
+pub mod handle;
+use crate::handle::{Closed, Writable};
+
+///
+pub mod registry;
+
+static NEXT_MAP_INDEX: AtomicUsize = AtomicUsize::new(0);
+static REGISTRY: Lazy<HashMap<usize, Option<ForksafeTempfile>>> = Lazy::new(|| {
+ #[cfg(feature = "signals")]
+ if signal::handler::MODE.load(std::sync::atomic::Ordering::SeqCst) != signal::handler::Mode::None as usize {
+ for sig in signal_hook::consts::TERM_SIGNALS {
+ // SAFETY: handlers are considered unsafe because a lot can go wrong. See `cleanup_tempfiles()` for details on safety.
+ #[allow(unsafe_code)]
+ unsafe {
+ #[cfg(not(windows))]
+ {
+ signal_hook_registry::register_sigaction(*sig, signal::handler::cleanup_tempfiles_nix)
+ }
+ #[cfg(windows)]
+ {
+ signal_hook::low_level::register(*sig, signal::handler::cleanup_tempfiles_windows)
+ }
+ }
+ .expect("signals can always be installed");
+ }
+ }
+ HashMap::default()
+});
+
+/// A type expressing the ways we can deal with directories containing a tempfile.
+#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)]
+pub enum ContainingDirectory {
+ /// Assume the directory for the tempfile exists and cause failure if it doesn't
+ Exists,
+ /// Create the directory recursively with the given amount of retries in a way that is somewhat race resistant
+ /// depending on the amount of retries.
+ CreateAllRaceProof(create_dir::Retries),
+}
+
+/// A type expressing the ways we cleanup after ourselves to remove resources we created.
+/// Note that cleanup has no effect if the tempfile is persisted.
+#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
+pub enum AutoRemove {
+ /// Remove the temporary file after usage if it wasn't persisted.
+ Tempfile,
+ /// Remove the temporary file as well the containing directories if they are empty until the given `directory`.
+ TempfileAndEmptyParentDirectoriesUntil {
+ /// The directory which shall not be removed even if it is empty.
+ boundary_directory: PathBuf,
+ },
+}
+
+impl AutoRemove {
+ fn execute_best_effort(self, directory_to_potentially_delete: &Path) -> Option<PathBuf> {
+ match self {
+ AutoRemove::Tempfile => None,
+ AutoRemove::TempfileAndEmptyParentDirectoriesUntil { boundary_directory } => {
+ remove_dir::empty_upward_until_boundary(directory_to_potentially_delete, &boundary_directory).ok();
+ Some(boundary_directory)
+ }
+ }
+ }
+}
+
+/// A registered temporary file which will delete itself on drop or if the program is receiving signals that
+/// should cause it to terminate.
+///
+/// # Note
+///
+/// Signals interrupting the calling thread right after taking ownership of the registered tempfile
+/// will cause all but this tempfile to be removed automatically. In the common case it will persist on disk as destructors
+/// were not called or didn't get to remove the file.
+///
+/// In the best case the file is a true temporary with a non-clashing name that 'only' fills up the disk,
+/// in the worst case the temporary file is used as a lock file which may leave the repository in a locked
+/// state forever.
+///
+/// This kind of raciness exists whenever [`take()`][Handle::take()] is used and can't be circumvented.
+#[derive(Debug)]
+#[must_use = "A handle that is immediately dropped doesn't lock a resource meaningfully"]
+pub struct Handle<Marker: std::fmt::Debug> {
+ id: usize,
+ _marker: PhantomData<Marker>,
+}
+
+/// A shortcut to [`Handle::<Writable>::new()`], creating a writable temporary file with non-clashing name in a directory.
+pub fn new(
+ containing_directory: impl AsRef<Path>,
+ directory: ContainingDirectory,
+ cleanup: AutoRemove,
+) -> io::Result<Handle<Writable>> {
+ Handle::<Writable>::new(containing_directory, directory, cleanup)
+}
+
+/// A shortcut to [`Handle::<Writable>::at()`] providing a writable temporary file at the given path.
+pub fn writable_at(
+ path: impl AsRef<Path>,
+ directory: ContainingDirectory,
+ cleanup: AutoRemove,
+) -> io::Result<Handle<Writable>> {
+ Handle::<Writable>::at(path, directory, cleanup)
+}
+
+/// A shortcut to [`Handle::<Closed>::at()`] providing a closed temporary file to mark the presence of something.
+pub fn mark_at(
+ path: impl AsRef<Path>,
+ directory: ContainingDirectory,
+ cleanup: AutoRemove,
+) -> io::Result<Handle<Closed>> {
+ Handle::<Closed>::at(path, directory, cleanup)
+}
diff --git a/vendor/gix-tempfile/src/registry.rs b/vendor/gix-tempfile/src/registry.rs
new file mode 100644
index 000000000..9eaab23a6
--- /dev/null
+++ b/vendor/gix-tempfile/src/registry.rs
@@ -0,0 +1,67 @@
+use crate::REGISTRY;
+
+/// Remove all tempfiles still registered on our global registry, and leak their data to be signal-safe.
+/// This happens on a best-effort basis with all errors being ignored.
+///
+/// # Safety
+/// Note that Mutexes of any kind are not allowed, and so aren't allocation or deallocation of memory.
+/// We are using lock-free datastructures and sprinkle in `std::mem::forget` to avoid deallocating.
+/// Most importantly, we use `try_lock()` which uses an atomic int only without blocking, making our register method safe to use,
+/// at the expense of possibly missing a lock file if another thread wants to obtain it or put it back
+/// (i.e. mutates the registry shard).
+pub fn cleanup_tempfiles_signal_safe() {
+ let current_pid = std::process::id();
+ #[cfg(feature = "hp-hashmap")]
+ {
+ use crate::NEXT_MAP_INDEX;
+ use std::sync::atomic::Ordering;
+
+ let one_past_last_index = NEXT_MAP_INDEX.load(Ordering::SeqCst);
+ for idx in 0..one_past_last_index {
+ if let Some(entry) = REGISTRY.try_entry(idx) {
+ entry.and_modify(|tempfile| {
+ if tempfile
+ .as_ref()
+ .map_or(false, |tf| tf.owning_process_id == current_pid)
+ {
+ if let Some(tempfile) = tempfile.take() {
+ tempfile.drop_without_deallocation();
+ }
+ }
+ });
+ }
+ }
+ }
+ #[cfg(not(feature = "hp-hashmap"))]
+ {
+ REGISTRY.for_each(|tf| {
+ if tf.as_ref().map_or(false, |tf| tf.owning_process_id == current_pid) {
+ if let Some(tf) = tf.take() {
+ tf.drop_without_deallocation();
+ }
+ }
+ });
+ }
+}
+
+/// Remove all tempfiles still registered on our global registry.
+/// This happens on a best-effort basis with all errors being ignored.
+///
+/// # Note
+///
+/// Must not be called from within signal hooks. For that, use [`cleanup_tempfiles_signal_safe()`].
+pub fn cleanup_tempfiles() {
+ let current_pid = std::process::id();
+ #[cfg(feature = "hp-hashmap")]
+ REGISTRY.iter_mut().for_each(|mut tf| {
+ if tf.as_ref().map_or(false, |tf| tf.owning_process_id == current_pid) {
+ tf.take();
+ }
+ });
+ #[cfg(not(feature = "hp-hashmap"))]
+ REGISTRY.for_each(|tf| {
+ if tf.as_ref().map_or(false, |tf| tf.owning_process_id == current_pid) {
+ tf.take();
+ }
+ });
+}
diff --git a/vendor/gix-tempfile/src/signal.rs b/vendor/gix-tempfile/src/signal.rs
new file mode 100644
index 000000000..3e0e7729c
--- /dev/null
+++ b/vendor/gix-tempfile/src/signal.rs
@@ -0,0 +1,100 @@
+use crate::REGISTRY;
+use once_cell::sync::Lazy;
+
+/// Initialize signal handlers and other state to keep track of tempfiles, and **must be called before the first tempfile is created**,
+/// allowing to set the `mode` in which signal handlers are installed.
+///
+/// Only has an effect the first time it is called.
+///
+/// Note that it is possible to not call this function and instead call
+/// [registry::cleanup_tempfiles_signal_safe()][crate::registry::cleanup_tempfiles_signal_safe()]
+/// from a signal handler under the application's control.
+pub fn setup(mode: handler::Mode) {
+ handler::MODE.store(mode as usize, std::sync::atomic::Ordering::SeqCst);
+ Lazy::force(&REGISTRY);
+}
+
+///
+pub mod handler {
+ use std::sync::atomic::AtomicUsize;
+
+ pub(crate) static MODE: AtomicUsize = AtomicUsize::new(Mode::None as usize);
+
+ /// Define how our signal handlers act
+ #[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)]
+ pub enum Mode {
+ /// Do not install a signal handler at all, but have somebody else call our handler directly.
+ None = 0,
+ /// Delete all remaining registered tempfiles on termination.
+ DeleteTempfilesOnTermination = 1,
+ /// Delete all remaining registered tempfiles on termination and emulate the default handler behaviour.
+ ///
+ /// This typically leads to the process being aborted.
+ DeleteTempfilesOnTerminationAndRestoreDefaultBehaviour = 2,
+ }
+
+ impl Default for Mode {
+ /// By default we will emulate the default behaviour and abort the process.
+ ///
+ /// While testing, we will not abort the process.
+ fn default() -> Self {
+ if cfg!(test) {
+ Mode::DeleteTempfilesOnTermination
+ } else {
+ Mode::DeleteTempfilesOnTerminationAndRestoreDefaultBehaviour
+ }
+ }
+ }
+
+ /// On linux we can handle the actual signal as we know it.
+ #[cfg(not(windows))]
+ pub(crate) fn cleanup_tempfiles_nix(sig: &libc::siginfo_t) {
+ crate::registry::cleanup_tempfiles_signal_safe();
+ let restore_original_behaviour = Mode::DeleteTempfilesOnTerminationAndRestoreDefaultBehaviour as usize;
+ if MODE.load(std::sync::atomic::Ordering::SeqCst) == restore_original_behaviour {
+ signal_hook::low_level::emulate_default_handler(sig.si_signo).ok();
+ }
+ }
+
+ /// On windows, assume sig-term and emulate sig-term unconditionally.
+ #[cfg(windows)]
+ pub(crate) fn cleanup_tempfiles_windows() {
+ crate::registry::cleanup_tempfiles_signal_safe();
+ let restore_original_behaviour = Mode::DeleteTempfilesOnTerminationAndRestoreDefaultBehaviour as usize;
+ if MODE.load(std::sync::atomic::Ordering::SeqCst) == restore_original_behaviour {
+ signal_hook::low_level::emulate_default_handler(signal_hook::consts::SIGTERM).ok();
+ }
+ }
+
+ #[cfg(test)]
+ mod tests {
+ use std::path::Path;
+
+ use crate::{AutoRemove, ContainingDirectory};
+
+ fn filecount_in(path: impl AsRef<Path>) -> usize {
+ std::fs::read_dir(path).expect("valid dir").count()
+ }
+
+ #[test]
+ fn various_termination_signals_remove_tempfiles_unconditionally() -> Result<(), Box<dyn std::error::Error>> {
+ crate::signal::setup(Default::default());
+ let dir = tempfile::tempdir()?;
+ for sig in signal_hook::consts::TERM_SIGNALS {
+ let _tempfile = crate::new(dir.path(), ContainingDirectory::Exists, AutoRemove::Tempfile)?;
+ assert_eq!(
+ filecount_in(dir.path()),
+ 1,
+ "only one tempfile exists no matter the iteration"
+ );
+ signal_hook::low_level::raise(*sig)?;
+ assert_eq!(
+ filecount_in(dir.path()),
+ 0,
+ "the signal triggers removal but won't terminate the process (anymore)"
+ );
+ }
+ Ok(())
+ }
+ }
+}