diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:35 +0000 |
commit | 7e5d7eea9c580ef4b41a765bde624af431942b96 (patch) | |
tree | 2c0d9ca12878fc4525650aa4e54d77a81a07cc09 /vendor/gix-refspec | |
parent | Adding debian version 1.70.0+dfsg1-9. (diff) | |
download | rustc-7e5d7eea9c580ef4b41a765bde624af431942b96.tar.xz rustc-7e5d7eea9c580ef4b41a765bde624af431942b96.zip |
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-refspec')
-rw-r--r-- | vendor/gix-refspec/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | vendor/gix-refspec/CHANGELOG.md | 511 | ||||
-rw-r--r-- | vendor/gix-refspec/Cargo.toml | 51 | ||||
-rw-r--r-- | vendor/gix-refspec/README.md | 11 | ||||
-rw-r--r-- | vendor/gix-refspec/src/instruction.rs | 68 | ||||
-rw-r--r-- | vendor/gix-refspec/src/lib.rs | 39 | ||||
-rw-r--r-- | vendor/gix-refspec/src/match_group/mod.rs | 112 | ||||
-rw-r--r-- | vendor/gix-refspec/src/match_group/types.rs | 104 | ||||
-rw-r--r-- | vendor/gix-refspec/src/match_group/util.rs | 162 | ||||
-rw-r--r-- | vendor/gix-refspec/src/match_group/validate.rs | 141 | ||||
-rw-r--r-- | vendor/gix-refspec/src/parse.rs | 255 | ||||
-rw-r--r-- | vendor/gix-refspec/src/spec.rs | 257 | ||||
-rw-r--r-- | vendor/gix-refspec/src/types.rs | 21 | ||||
-rw-r--r-- | vendor/gix-refspec/src/write.rs | 74 |
14 files changed, 1807 insertions, 0 deletions
diff --git a/vendor/gix-refspec/.cargo-checksum.json b/vendor/gix-refspec/.cargo-checksum.json new file mode 100644 index 000000000..9024c8d9e --- /dev/null +++ b/vendor/gix-refspec/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"b0693420b49e9c32ee14d249c7d1b434e14b137d59b3517a585881799b7e30e1","Cargo.toml":"8581b00d978480f6bfef66106a7aeba52ee50c83f9261242ccf26180b674a30c","README.md":"1b08787d12bb32a8b5a3a48c3198435d9691d15c3b623727a6ff6188b4106d65","src/instruction.rs":"a1f989da75ad1cb774171c905241f541ca2a68f2b365f54dd3cf3f247615caa4","src/lib.rs":"493fe85e248c19665667a44d445314c4536fe197eafac92c65e12d2a9ded44f6","src/match_group/mod.rs":"256a496434ab4d1723611fd19f3b4f81d780e0a1b92ee6878450cba73068737c","src/match_group/types.rs":"a3e0bb1d555955e9415c26b011cc0e84f8b07166479ae09861dc988d453476e5","src/match_group/util.rs":"4b325f879883244c0692cdc2c43674cc1e69574b542bcccaba93dea3e4c62e64","src/match_group/validate.rs":"1203deb9a0d2e81ba6eb6f28f5d2249bac8f88482e7db42d824331b679083254","src/parse.rs":"956f2894ad2ff345f1e55e80e67eb552eda2dc61b7e7f1f72ecf4ed15a2c9da3","src/spec.rs":"99c52b4c52074555a9932beb1f992d540e640375bdc36cf2cb84fdb048aa4b6f","src/types.rs":"af5efab6fc8179262d0a368f72624efe68f48dec7afb74f2e7ef932f140d42ff","src/write.rs":"1871ac43652b6ae6b5b453f7d79d88f4652294937d005e20227be8660d2e551f"},"package":"aba332462bda2e8efeae4302b39a6ed01ad56ef772fd5b7ef197cf2798294d65"}
\ No newline at end of file diff --git a/vendor/gix-refspec/CHANGELOG.md b/vendor/gix-refspec/CHANGELOG.md new file mode 100644 index 000000000..e7e8b57db --- /dev/null +++ b/vendor/gix-refspec/CHANGELOG.md @@ -0,0 +1,511 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.9.0 (2023-03-04) + +A maintenance release without user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 2 commits contributed to the release. + - 3 days passed between releases. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Prepare changelogs prior to release ([`895e482`](https://github.com/Byron/gitoxide/commit/895e482badf01e953bb9144001eebd5e1b1c4d84)) + - Release gix-features v0.28.0, gix-actor v0.19.0, gix-object v0.28.0, gix-diff v0.28.0, gix-traverse v0.24.0, gix-pack v0.32.0, safety bump 20 crates ([`0f411e9`](https://github.com/Byron/gitoxide/commit/0f411e93ec812592bb9d3a52b751399dd86f76f7)) +</details> + +## 0.8.0 (2023-03-01) + +A maintenance release without user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 4 commits contributed to the release. + - 8 days passed between releases. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-tempfile v4.1.0, gix-lock v4.0.0, gix-ref v0.25.0, gix-config v0.17.0, gix-url v0.14.0, gix-credentials v0.10.0, gix-diff v0.27.0, gix-discover v0.14.0, gix-hashtable v0.1.2, gix-bitmap v0.2.2, gix-traverse v0.23.0, gix-index v0.13.0, gix-mailmap v0.10.0, gix-pack v0.31.0, gix-odb v0.41.0, gix-transport v0.26.0, gix-protocol v0.27.0, gix-revision v0.11.0, gix-refspec v0.8.0, gix-worktree v0.13.0, gix v0.38.0, safety bump 6 crates ([`ea9fd1d`](https://github.com/Byron/gitoxide/commit/ea9fd1d9b60e1e9e17042e9e37c06525823c40a5)) + - Release gix-features v0.27.0, gix-actor v0.18.0, gix-quote v0.4.3, gix-attributes v0.9.0, gix-object v0.27.0, gix-ref v0.25.0, gix-config v0.17.0, gix-url v0.14.0, gix-credentials v0.10.0, gix-diff v0.27.0, gix-discover v0.14.0, gix-hashtable v0.1.2, gix-bitmap v0.2.2, gix-traverse v0.23.0, gix-index v0.13.0, gix-mailmap v0.10.0, gix-pack v0.31.0, gix-odb v0.41.0, gix-transport v0.26.0, gix-protocol v0.27.0, gix-revision v0.11.0, gix-refspec v0.8.0, gix-worktree v0.13.0, gix v0.38.0 ([`e6cc618`](https://github.com/Byron/gitoxide/commit/e6cc6184a7a49dbc2503c1c1bdd3688ca5cec5fe)) + - Adjust manifests prior to release ([`addd789`](https://github.com/Byron/gitoxide/commit/addd78958fdd1e54eb702854e96079539d01965a)) + - Prepare changelogs prior to release ([`94c99c7`](https://github.com/Byron/gitoxide/commit/94c99c71520f33269cc8dbc26f82a74747cc7e16)) +</details> + +## 0.7.3 (2023-02-20) + +### Bug Fixes + + - <csr-id-135d317065aae87af302beb6c26bb6ca8e30b6aa/> compatibility with `bstr` v1.3, use `*.as_bytes()` instead of `.as_ref()`. + `as_ref()` relies on a known target type which isn't always present. However, once + there is only one implementation, that's no problem, but when that changes compilation + fails due to ambiguity. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 2 commits contributed to the release. + - 3 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-date v0.4.3, gix-hash v0.10.3, gix-features v0.26.5, gix-actor v0.17.2, gix-glob v0.5.5, gix-path v0.7.2, gix-quote v0.4.2, gix-attributes v0.8.3, gix-validate v0.7.3, gix-object v0.26.2, gix-ref v0.24.1, gix-config v0.16.2, gix-command v0.2.4, gix-url v0.13.3, gix-credentials v0.9.2, gix-discover v0.13.1, gix-index v0.12.4, gix-mailmap v0.9.3, gix-pack v0.30.3, gix-packetline v0.14.3, gix-transport v0.25.6, gix-protocol v0.26.4, gix-revision v0.10.4, gix-refspec v0.7.3, gix-worktree v0.12.3, gix v0.36.1 ([`9604783`](https://github.com/Byron/gitoxide/commit/96047839a20a657a559376b0b14c65aeab96acbd)) + - Compatibility with `bstr` v1.3, use `*.as_bytes()` instead of `.as_ref()`. ([`135d317`](https://github.com/Byron/gitoxide/commit/135d317065aae87af302beb6c26bb6ca8e30b6aa)) +</details> + +## 0.7.2 (2023-02-17) + +<csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> +<csr-id-533e887e80c5f7ede8392884562e1c5ba56fb9a8/> + +### New Features (BREAKING) + + - <csr-id-3d8fa8fef9800b1576beab8a5bc39b821157a5ed/> upgrade edition to 2021 in most crates. + MSRV for this is 1.56, and we are now at 1.60 so should be compatible. + This isn't more than a patch release as it should break nobody + who is adhering to the MSRV, but let's be careful and mark it + breaking. + + Note that `git-features` and `git-pack` are still on edition 2018 + as they make use of a workaround to support (safe) mutable access + to non-overlapping entries in a slice which doesn't work anymore + in edition 2021. + +### Changed (BREAKING) + + - <csr-id-2a0a87a04e7b4d6ed3be3d8adc89917576727686/> remove lifetime of `match_group::Fix`, keeping `RefSpec` instances instead + That lifetime unnecessarily complicated things and wasn't worth keeping + due to being a premature optimization. + - <csr-id-4c4f82170d08b910a7f64482431c99956b1a04c3/> reject all invalid negative refspec patterns. + Git is more lenient, but will then fail to match against such patterns + which seems like avoidable surprising behaviour. + - <csr-id-99905bacace8aed42b16d43f0f04cae996cb971c/> upgrade `bstr` to `1.0.1` + +### New Features + + - <csr-id-21b21b6c25e1d8d1da9464b7bef06a795f679210/> add `RefSpecRef::expand_prefix()` method to avoid missing prefixes. + The current implementation might cause refspecs to end up ignored as + they don't have a prefix, and in protocol V2 it would then fail + to add a ref-spec filter which causes them to be missed. + + With `expand_prefix()`, we assure that there are all possible prefixes + that can contain partial names, similar to what git does. + - <csr-id-d7f63a6c60a826dc862bd13adbef041e4ac6d8ab/> `RefSpec::allow_non_fast_forward()` to get information about 'force' quickly. + - <csr-id-6df179b5cf831402444cc78429a57f835358376e/> `RefSpecRef::prefix()` to return the two-component prefix of a refspec's source. #(450) + - <csr-id-abdf83f494e2a9fba4a8d9fcb776f2c84baebd3e/> Simple serialization for `Instruction` and `RefSpecRef` type. + It's also a way to normalize input strings as there is only one way + to serialize instructions, which themselves are already normalized + towards what's possible. + +### Chore + + - <csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> uniformize deny attributes + - <csr-id-533e887e80c5f7ede8392884562e1c5ba56fb9a8/> remove default link to cargo doc everywhere + +### Documentation + + - <csr-id-39ed9eda62b7718d5109135e5ad406fb1fe2978c/> fix typos + +### Bug Fixes + + - <csr-id-d34292294a0c41991aebd5af46e7bd7e3ad7324d/> Fixes build for parsing fuzz harness + - <csr-id-d53ddcde948cfbd7773eb830cbb636626b32debb/> `HEAD` may now return itself as prefix in `RefSpecRef::prefix()` and `expanded_prefix()`. + Previously, the expanded prefix would be a list of possibilities, even + though it's such a common case that we really want to avoid spamming the + remote about it when asking for HEAD during clone for instance. + - <csr-id-278ff7a6ee084ea864193a5ca25b6cd0f18e19a0/> `RefSpecRef` instruction uses the correct lifetime. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 234 commits contributed to the release over the course of 196 calendar days. + - 14 commits were understood as [conventional](https://www.conventionalcommits.org). + - 5 unique issues were worked on: [#450](https://github.com/Byron/gitoxide/issues/450), [#470](https://github.com/Byron/gitoxide/issues/470), [#571](https://github.com/Byron/gitoxide/issues/571), [#691](https://github.com/Byron/gitoxide/issues/691), [#XXX](https://github.com/Byron/gitoxide/issues/XXX) + +### Thanks Clippy + +<csr-read-only-do-not-edit/> + +[Clippy](https://github.com/rust-lang/rust-clippy) helped 10 times to make code idiomatic. + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **[#450](https://github.com/Byron/gitoxide/issues/450)** + - Improve docs for `Instruction` ([`911f68f`](https://github.com/Byron/gitoxide/commit/911f68fe099e3eac7dd4a0f15fcd682657564389)) + - `HEAD` may now return itself as prefix in `RefSpecRef::prefix()` and `expanded_prefix()`. ([`d53ddcd`](https://github.com/Byron/gitoxide/commit/d53ddcde948cfbd7773eb830cbb636626b32debb)) + - Fix docs ([`9d0f31e`](https://github.com/Byron/gitoxide/commit/9d0f31e4bea4b47f1a91fa4dc38f592bdbf976a8)) + - Add `RefSpecRef::expand_prefix()` method to avoid missing prefixes. ([`21b21b6`](https://github.com/Byron/gitoxide/commit/21b21b6c25e1d8d1da9464b7bef06a795f679210)) + - `RefSpec::allow_non_fast_forward()` to get information about 'force' quickly. ([`d7f63a6`](https://github.com/Byron/gitoxide/commit/d7f63a6c60a826dc862bd13adbef041e4ac6d8ab)) + - `RefSpecRef` instruction uses the correct lifetime. ([`278ff7a`](https://github.com/Byron/gitoxide/commit/278ff7a6ee084ea864193a5ca25b6cd0f18e19a0)) + - A more efficient representation for `validate::Fix` ([`e819fc6`](https://github.com/Byron/gitoxide/commit/e819fc68531e2d2de3d7df782f63f84941eeef57)) + - Make `specs` in `MatchGroup` public to reduce API surface. ([`2a7df32`](https://github.com/Byron/gitoxide/commit/2a7df323b15678aee3e61a41908aceb644873b11)) + - Allow `match_group::Fix` to be cloned. ([`85c49ec`](https://github.com/Byron/gitoxide/commit/85c49ec16ac7eeb2175fa43545c72b81da693ab1)) + - Fix `match_group::Item` to make it uniform with how we typically name refs ([`21420da`](https://github.com/Byron/gitoxide/commit/21420dacb485795e80baabf2a300ff900036ba7b)) + - Remote todo with note about our current understanding ([`9dc7a3f`](https://github.com/Byron/gitoxide/commit/9dc7a3f40dbf3d4802ed095fc21dfb3da67acfea)) + - Actually assure we don't try to write into the HEAD ref, which git avoids as well ([`1335618`](https://github.com/Byron/gitoxide/commit/13356184c735d72edb891d64b3de1bb5c981a6ad)) + - Allow 'HEAD' based refspecs to match correctly ([`7432a2b`](https://github.com/Byron/gitoxide/commit/7432a2bb5d11e9991ed5f9d1b29ecf79b10c676a)) + - Tests to show that empty remotes actually work ([`2fdec73`](https://github.com/Byron/gitoxide/commit/2fdec7315a65117095f909b4d7d57a91ba666a43)) + - Another test which doesn't manage to trigger a certain message from git. ([`4f48095`](https://github.com/Byron/gitoxide/commit/4f48095566fc1e2b440d542ef2c5118c3e37fddd)) + - Fully drop 'funny' names ([`f137d60`](https://github.com/Byron/gitoxide/commit/f137d6010610d98de32edb4501053d7786181217)) + - A first version of the 'funny name' sanitization ([`c81e418`](https://github.com/Byron/gitoxide/commit/c81e418ae7f90b674ad005e4b42816c35332a417)) + - Frame for testing of fixes ([`9148102`](https://github.com/Byron/gitoxide/commit/91481020c87cfa0cae9dd497fb87e7fb9dd33c8a)) + - Refactor ([`d37fd04`](https://github.com/Byron/gitoxide/commit/d37fd044df2cc5355735121e63fcc3c54b8ea4cb)) + - All baseline specs are tested and pass ([`afc0a3d`](https://github.com/Byron/gitoxide/commit/afc0a3da864362ec7a0ab243f72daba4713db569)) + - The first test to validate conflict reporting ([`aef0a46`](https://github.com/Byron/gitoxide/commit/aef0a464811ce98e81d44d1417098c9adef035f5)) + - Sketch of validation API along with test suite integration ([`70a765e`](https://github.com/Byron/gitoxide/commit/70a765e295295f87f8550453452d2ffe95b177be)) + - Refactor ([`547129e`](https://github.com/Byron/gitoxide/commit/547129e98dfcac32ebc83e743f9aee05d038629b)) + - Sketch `Outcome` type which can be used for later sanitization and validation. ([`53e17c1`](https://github.com/Byron/gitoxide/commit/53e17c10f663bc3c389a13cdfec3716da34dd311)) + - Prepare first test for conflicts and validation ([`508a33a`](https://github.com/Byron/gitoxide/commit/508a33a5f279c9a6f29e98f560fcd54cea1ed77d)) + - Just-in-time deduplication of mappings ([`8ed5d01`](https://github.com/Byron/gitoxide/commit/8ed5d01a75ceb03083b2bddc58b1e9dc26a66cd0)) + - Adjust expectations to make first exclusion tests work ([`6e1b19b`](https://github.com/Byron/gitoxide/commit/6e1b19b7f07050c3fcb70187a4d6a4e4210d3343)) + - Reject all invalid negative refspec patterns. ([`4c4f821`](https://github.com/Byron/gitoxide/commit/4c4f82170d08b910a7f64482431c99956b1a04c3)) + - Basic negation implementation along with first failure. ([`e4931d0`](https://github.com/Byron/gitoxide/commit/e4931d0205c9b8e8e859e8ea940b67483e62a07e)) + - First tests for multiple refspecs ([`77db112`](https://github.com/Byron/gitoxide/commit/77db1127a8ccd71c75670b5d803cabcf93cbcedc)) + - Refactor ([`4c73a19`](https://github.com/Byron/gitoxide/commit/4c73a19ae4b044df816e95a4fc19dc6481222a4c)) + - Refactor ([`00401be`](https://github.com/Byron/gitoxide/commit/00401bef4279d4b8152ea4c149a00ddf50f518e3)) + - Improved glob matching ([`eaf36e7`](https://github.com/Byron/gitoxide/commit/eaf36e7d0336be8398d0b1d9414d3ad73afbb393)) + - Basic glob matching. ([`a93628c`](https://github.com/Byron/gitoxide/commit/a93628cb404987c498779b35994db0a05b3dbc0a)) + - Type-system supprots glob matching ([`4b73d11`](https://github.com/Byron/gitoxide/commit/4b73d11a4f0bef8db374cde567547a9ba7097719)) + - More tests for simple 1:1 fetch and update specs ([`74de83c`](https://github.com/Byron/gitoxide/commit/74de83cbea30b84136bfa191f471e137ae7af5c3)) + - Make it easy to obtain the local and remote sides of RefSpecs ([`67506b1`](https://github.com/Byron/gitoxide/commit/67506b1b1997c2b5951f0e1320b0459eac1366e2)) + - Don't reject object-id like heads on the receiving side. ([`6668c3f`](https://github.com/Byron/gitoxide/commit/6668c3f418663ed6f2ed56efd3d7e78d27124296)) + - Make object-ids in the source position type-safe ([`413051d`](https://github.com/Byron/gitoxide/commit/413051d03c843c9c99dbc67f4a5f48d6f2b1aeb2)) + - Prepare for dual-sided ref mapping to realize that it needs a special case. ([`7368fe4`](https://github.com/Byron/gitoxide/commit/7368fe4ee38bbd34bd811310afa8eeb78c475fda)) + - Refactor ([`579e891`](https://github.com/Byron/gitoxide/commit/579e89188679942508f9da107d856ab782a512a1)) + - Support testing source-only object names ([`bb61c49`](https://github.com/Byron/gitoxide/commit/bb61c49a9b6a3a109d7af3ddde43fc98bb712ec7)) + - Preliminary matching of refs by name ([`426107f`](https://github.com/Byron/gitoxide/commit/426107fea911a2f75d3b624a1c7279cac4edc12e)) + - Handle partial names as well ([`dc7f162`](https://github.com/Byron/gitoxide/commit/dc7f1620cb6d00af60cf78e02b4c2949a3e260e4)) + - Generalize baseline assertion to support multiple input specs ([`b752e48`](https://github.com/Byron/gitoxide/commit/b752e48b4201c1f26401af39de0a7312b158607b)) + - First successful test ([`3625d5a`](https://github.com/Byron/gitoxide/commit/3625d5a0abb109270b046e2dc206d6f870164306)) + - Top-level match-group loop without negation ([`c915a5f`](https://github.com/Byron/gitoxide/commit/c915a5f5f0d771e704b108b9442a605d62f0945e)) + - Refactor to use a match-group instead. ([`4ba31c5`](https://github.com/Byron/gitoxide/commit/4ba31c55b57f644361e18e5d31d5df514cddd58a)) + - Not using a matchgroup right away seems like the wrong approach ([`7f3bc30`](https://github.com/Byron/gitoxide/commit/7f3bc300dfb980d6e6aa72f8c22edd58fa9351fb)) + - Actual expectation for first simple test ([`cec6905`](https://github.com/Byron/gitoxide/commit/cec69057585796ec7bc69f5a6295b97cddb8cb4f)) + - Get to the point where the matcher is invoked ([`cbbdf59`](https://github.com/Byron/gitoxide/commit/cbbdf59290d6c3fb4936b31e3b7836becb126ce4)) + - Simple serialization for `Instruction` and `RefSpecRef` type. ([`abdf83f`](https://github.com/Byron/gitoxide/commit/abdf83f494e2a9fba4a8d9fcb776f2c84baebd3e)) + - Ground work for matcher tests ([`509764c`](https://github.com/Byron/gitoxide/commit/509764c95978115da129b8bb9baeb304634fa10c)) + - Tag specific tests ([`4f35485`](https://github.com/Byron/gitoxide/commit/4f354852e15b469260bd3553e4f615f9612fabcc)) + - More tests to investigate conflict handling ([`192d4f7`](https://github.com/Byron/gitoxide/commit/192d4f78ba611f090dafda7ef5014efb900d2115)) + - A more realistic sketch for `Matcher`, which will need a surrounding `MatchGroup` ([`dd1d824`](https://github.com/Byron/gitoxide/commit/dd1d8244c8708bbc3583cc0f3f42ad967d5ad524)) + - More robust baseline tests on windows ([`54ca267`](https://github.com/Byron/gitoxide/commit/54ca267138a5116aa2215109b4abe00a64518feb)) + - Pares FETCH_HEAD (as specs without local sides); sketch `Match` type ([`44228a0`](https://github.com/Byron/gitoxide/commit/44228a0b9c057bcc915bc0ade43b4ccb3cb916f2)) + - Restore full ref names for baseline ([`f6124db`](https://github.com/Byron/gitoxide/commit/f6124db39dc0e828801a59310265d95a755ea46a)) + - Parse basline mapping ([`3000a14`](https://github.com/Byron/gitoxide/commit/3000a14c1eed4a543fdef2fd8bcbacba2742aece)) + - Parse baseline reflist which serves as input to the matcher ([`fce877f`](https://github.com/Byron/gitoxide/commit/fce877f8d2112fafdb71208784104a66b2313a40)) + - Frame for baseline for fetch-matching ([`2569da5`](https://github.com/Byron/gitoxide/commit/2569da5988a055372a1b85660f93185603900dbe)) + - Upgrade `bstr` to `1.0.1` ([`99905ba`](https://github.com/Byron/gitoxide/commit/99905bacace8aed42b16d43f0f04cae996cb971c)) + - Prefer to represent instructions with Matchers ([`0887e2e`](https://github.com/Byron/gitoxide/commit/0887e2e0b7ebdcad30606a2633794ac8ff586091)) + - More examples using fully spelled out object names as fetch destination ([`095a099`](https://github.com/Byron/gitoxide/commit/095a09918dc080ba7794c6ff13db0ef0ead20d0d)) + - Get more clarity about `git ls-remote` and `git fetch` ([`1b15fe8`](https://github.com/Byron/gitoxide/commit/1b15fe80817d600f39090848c7d144ff94ac398c)) + - A tiny sketch of a possible matching API ([`39d5ff3`](https://github.com/Byron/gitoxide/commit/39d5ff39ac58ec2abf2b55ee69df9905a4f303c2)) + - Assure ref-specs handle equality, ordering and hashing according to their instruction ([`b4bf7d0`](https://github.com/Byron/gitoxide/commit/b4bf7d015a5d0d48bf7d0509d2fd930a1cb6f398)) + - Cleanup crate structure ([`f0163c9`](https://github.com/Byron/gitoxide/commit/f0163c99bccfb7d6719217a8fa773667cabe95fd)) + - Don't expose mode() as it's kind of messy and should be left as implementation detail ([`6278966`](https://github.com/Byron/gitoxide/commit/627896655ce04e1a306c5bf3970ebd6e73bb1a5d)) + - Improve docs ([`c695a7e`](https://github.com/Byron/gitoxide/commit/c695a7e9716262d885c3ccfde68eb2077650b8ce)) + - Add fuzz target and basic docs on how to run it ([`febf070`](https://github.com/Byron/gitoxide/commit/febf0706b83b36a71efbe669ee760c2d4ef14b72)) + - Add fuzz target ([`62d721a`](https://github.com/Byron/gitoxide/commit/62d721a5a7260adb408415810899bcf11d524d0c)) + - More push-spec restrictions ([`bb992ac`](https://github.com/Byron/gitoxide/commit/bb992acc13fc2a63ec5098e9fa8954909ef486ca)) + - More detailed tests of what's allowed and where ([`57a6e69`](https://github.com/Byron/gitoxide/commit/57a6e695697744459149dd6400c54b9c4c88a365)) + - Disallow excludes in push mode ([`9c280b2`](https://github.com/Byron/gitoxide/commit/9c280b2de59773c6d13134e3257cf1da5731e35d)) + - Don't allow object hashes in excludes ([`b889953`](https://github.com/Byron/gitoxide/commit/b8899532b461ebcdc0ecd33e54a8721e69136c22)) + - Negative must not be empty ([`79e0eaf`](https://github.com/Byron/gitoxide/commit/79e0eaf4c754da47731f8c5ed3635339586b3d00)) + - Support for `@` shortcut. ([`32d98e9`](https://github.com/Byron/gitoxide/commit/32d98e9c5db402bbfc04394218c0de30bfa64808)) + - And the entire test-suite passes ([`3fa52f8`](https://github.com/Byron/gitoxide/commit/3fa52f8ffd04721e1367706318542cf6d4e71f3b)) + - Handle ref-name validation mostly correctly ([`d7c2789`](https://github.com/Byron/gitoxide/commit/d7c27899c76092bdc8e86f2784aaf67666f117dd)) + - Refactor ([`e8c072e`](https://github.com/Byron/gitoxide/commit/e8c072e99e845ed1b4a0cc0a0ec7146c53561dcd)) + - Tests causing all instrucitons ([`c23a21d`](https://github.com/Byron/gitoxide/commit/c23a21d3e50e62d29bef4e638049b0398d3fb20e)) + - Tests for handling exclusions ([`c4499ce`](https://github.com/Byron/gitoxide/commit/c4499ce13aa9e71c7b0024ad8658bdbcbccf5c14)) + - Better handling of special cases ([`c99f575`](https://github.com/Byron/gitoxide/commit/c99f5750967a835afd9a99211b3520b441ae1881)) + - Basic validation and detection of patterns ([`e4227d6`](https://github.com/Byron/gitoxide/commit/e4227d6ddd4cd021245bf6f352a0798457c37aae)) + - Handle colon and empty on the right side ([`7afebb7`](https://github.com/Byron/gitoxide/commit/7afebb778b93611d924843c95acfd6b36f284fb2)) + - Support for deletion ([`966a9e9`](https://github.com/Byron/gitoxide/commit/966a9e93b3afdcdc15af95c9fa3037d71af6e0ee)) + - Add include directive ([`701d46f`](https://github.com/Byron/gitoxide/commit/701d46f020db5c5f86a0184ff345f30d077be8ed)) + - First successful test for returning a refspec. ([`6e5bd5c`](https://github.com/Byron/gitoxide/commit/6e5bd5c152403d76ba1cf3da2b984689cb6fe8c5)) + - Sort out how expectations can be expressed in test suite ([`3f264af`](https://github.com/Byron/gitoxide/commit/3f264afda02235dbcdf712d957e37c71ce749f01)) + - Refactor ([`6713793`](https://github.com/Byron/gitoxide/commit/6713793dca4054a7f8717e70c8e9e4b7e625e9b4)) + - Sketch all possible instructions of fetch and push refspecs ([`0ba1b73`](https://github.com/Byron/gitoxide/commit/0ba1b73bf988357f4b27753b87432618edec697a)) + - Run the baseline test and gather some information ([`5e4ee9b`](https://github.com/Byron/gitoxide/commit/5e4ee9ba422cac9eef2b558746f3a3aa4b67a5e4)) + - First few bits of error handling in parser ([`9c5fed2`](https://github.com/Byron/gitoxide/commit/9c5fed2e2a6ea388acde73be32f8b7f8687c415b)) + - Frame for basic parsing ([`b9a4bdc`](https://github.com/Byron/gitoxide/commit/b9a4bdca41c074364b7bc26523784c35ac3196ce)) + - Sketch data structure that should do the trick ([`5c823dc`](https://github.com/Byron/gitoxide/commit/5c823dcbfd3aca0a8846300629e01aed8d7b7e66)) + - All baseline test cases from git's test-suite ([`362bd46`](https://github.com/Byron/gitoxide/commit/362bd4651751960b3062fd1c65d58b986b46cc97)) + - Prepare git-refspec changelog prior to release ([`3383408`](https://github.com/Byron/gitoxide/commit/3383408ce22ca9c7502ad2d1fab51cf12dc5ee72)) + - Empty `git-refspec` crate for name reservation prior to implementation ([`871a3c0`](https://github.com/Byron/gitoxide/commit/871a3c054d4fe6c1e92b6f2e260b19463404509f)) + * **[#470](https://github.com/Byron/gitoxide/issues/470)** + - Update changelogs prior to release ([`caa7a1b`](https://github.com/Byron/gitoxide/commit/caa7a1bdef74d7d3166a7e38127a59f5ab3cfbdd)) + * **[#571](https://github.com/Byron/gitoxide/issues/571)** + - Refactor ([`ef7467c`](https://github.com/Byron/gitoxide/commit/ef7467cd61762dc4206fa82e66adc287ba2f7f52)) + - Assure sub-branches can be matched correctly ([`c9383c6`](https://github.com/Byron/gitoxide/commit/c9383c693e0b3c506c9b1c42f339f40c1145f998)) + * **[#691](https://github.com/Byron/gitoxide/issues/691)** + - Set `rust-version` to 1.64 ([`55066ce`](https://github.com/Byron/gitoxide/commit/55066ce5fd71209abb5d84da2998b903504584bb)) + * **[#XXX](https://github.com/Byron/gitoxide/issues/XXX)** + - Prepare changelogs prior to release ([`8c0bca3`](https://github.com/Byron/gitoxide/commit/8c0bca37ff9fbaadbe55561fb2b0d649980c95b1)) + * **Uncategorized** + - Release gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`7fc00f8`](https://github.com/Byron/gitoxide/commit/7fc00f87d74aedf631ce4032be1cdfe1804c7e7d)) + - Release gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`59e9fac`](https://github.com/Byron/gitoxide/commit/59e9fac67d1b353e124300435b55f6b5468d7deb)) + - Release gix-index v0.12.3, gix-mailmap v0.9.2, gix-chunk v0.4.1, gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`48f5bd2`](https://github.com/Byron/gitoxide/commit/48f5bd2014fa3dda6fbd60d091065c5537f69453)) + - Release gix-credentials v0.9.1, gix-diff v0.26.1, gix-discover v0.13.0, gix-hashtable v0.1.1, gix-bitmap v0.2.1, gix-traverse v0.22.1, gix-index v0.12.3, gix-mailmap v0.9.2, gix-chunk v0.4.1, gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`a5869e0`](https://github.com/Byron/gitoxide/commit/a5869e0b223406820bca836e3e3a7fae2bfd9b04)) + - Release gix-config v0.16.1, gix-command v0.2.3, gix-prompt v0.3.2, gix-url v0.13.2, gix-credentials v0.9.1, gix-diff v0.26.1, gix-discover v0.13.0, gix-hashtable v0.1.1, gix-bitmap v0.2.1, gix-traverse v0.22.1, gix-index v0.12.3, gix-mailmap v0.9.2, gix-chunk v0.4.1, gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`41d57b9`](https://github.com/Byron/gitoxide/commit/41d57b98964094fc1528adb09f69ca824229bf25)) + - Release gix-attributes v0.8.2, gix-config-value v0.10.1, gix-tempfile v3.0.2, gix-lock v3.0.2, gix-validate v0.7.2, gix-object v0.26.1, gix-ref v0.24.0, gix-sec v0.6.2, gix-config v0.16.1, gix-command v0.2.3, gix-prompt v0.3.2, gix-url v0.13.2, gix-credentials v0.9.1, gix-diff v0.26.1, gix-discover v0.13.0, gix-hashtable v0.1.1, gix-bitmap v0.2.1, gix-traverse v0.22.1, gix-index v0.12.3, gix-mailmap v0.9.2, gix-chunk v0.4.1, gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`e313112`](https://github.com/Byron/gitoxide/commit/e31311257bd138b52042dea5fc40c3abab7f269b)) + - Release gix-features v0.26.4, gix-actor v0.17.1, gix-glob v0.5.3, gix-path v0.7.1, gix-quote v0.4.1, gix-attributes v0.8.2, gix-config-value v0.10.1, gix-tempfile v3.0.2, gix-lock v3.0.2, gix-validate v0.7.2, gix-object v0.26.1, gix-ref v0.24.0, gix-sec v0.6.2, gix-config v0.16.1, gix-command v0.2.3, gix-prompt v0.3.2, gix-url v0.13.2, gix-credentials v0.9.1, gix-diff v0.26.1, gix-discover v0.13.0, gix-hashtable v0.1.1, gix-bitmap v0.2.1, gix-traverse v0.22.1, gix-index v0.12.3, gix-mailmap v0.9.2, gix-chunk v0.4.1, gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`6efd0d3`](https://github.com/Byron/gitoxide/commit/6efd0d31fbeca31ab7319aa2ac97bb31dc4ce055)) + - Release gix-date v0.4.2, gix-hash v0.10.2, gix-features v0.26.4, gix-actor v0.17.1, gix-glob v0.5.3, gix-path v0.7.1, gix-quote v0.4.1, gix-attributes v0.8.2, gix-config-value v0.10.1, gix-tempfile v3.0.2, gix-lock v3.0.2, gix-validate v0.7.2, gix-object v0.26.1, gix-ref v0.24.0, gix-sec v0.6.2, gix-config v0.16.1, gix-command v0.2.3, gix-prompt v0.3.2, gix-url v0.13.2, gix-credentials v0.9.1, gix-diff v0.26.1, gix-discover v0.13.0, gix-hashtable v0.1.1, gix-bitmap v0.2.1, gix-traverse v0.22.1, gix-index v0.12.3, gix-mailmap v0.9.2, gix-chunk v0.4.1, gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`6ccc88a`](https://github.com/Byron/gitoxide/commit/6ccc88a8e4a56973b1a358cf72dc012ee3c75d56)) + - Merge branch 'rename-crates' into inform-about-gix-rename ([`c9275b9`](https://github.com/Byron/gitoxide/commit/c9275b99ea43949306d93775d9d78c98fb86cfb1)) + - Rename `git-testtools` to `gix-testtools` ([`b65c33d`](https://github.com/Byron/gitoxide/commit/b65c33d256cfed65d11adeff41132e3e58754089)) + - Adjust to renaming of `git-pack` to `gix-pack` ([`1ee81ad`](https://github.com/Byron/gitoxide/commit/1ee81ad310285ee4aa118118a2be3810dbace574)) + - Adjust to renaming of `git-odb` to `gix-odb` ([`476e2ad`](https://github.com/Byron/gitoxide/commit/476e2ad1a64e9e3f0d7c8651d5bcbee36cd78241)) + - Adjust to renaming of `git-index` to `gix-index` ([`86db5e0`](https://github.com/Byron/gitoxide/commit/86db5e09fc58ce66b252dc13b8d7e2c48e4d5062)) + - Adjust to renaming of `git-diff` to `gix-diff` ([`49a163e`](https://github.com/Byron/gitoxide/commit/49a163ec8b18f0e5fcd05a315de16d5d8be7650e)) + - Adjust to renaming of `git-commitgraph` to `gix-commitgraph` ([`f1dd0a3`](https://github.com/Byron/gitoxide/commit/f1dd0a3366e31259af029da73228e8af2f414244)) + - Adjust to renaming of `git-mailmap` to `gix-mailmap` ([`2e28c56`](https://github.com/Byron/gitoxide/commit/2e28c56bb9f70de6f97439818118d3a25859698f)) + - Adjust to renaming of `git-discover` to `gix-discover` ([`53adfe1`](https://github.com/Byron/gitoxide/commit/53adfe1c34e9ea3b27067a97b5e7ac80b351c441)) + - Adjust to renaming of `git-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)) + - Rename `git-refspec` to `gix-refspec` ([`3c56012`](https://github.com/Byron/gitoxide/commit/3c56012d7ba0e82ca566c0de9ad9dc2966f3a34f)) + - Adjust to renaming of `git-revision` to `gix-revision` ([`ee0ee84`](https://github.com/Byron/gitoxide/commit/ee0ee84607c2ffe11ee75f27a31903db68afed02)) + - Adjust to renaming of `git-transport` to `gix-transport` ([`b2ccf71`](https://github.com/Byron/gitoxide/commit/b2ccf716dc4425bb96651d4d58806a3cc2da219e)) + - Adjust to renaming of `git-credentials` to `gix-credentials` ([`6b18abc`](https://github.com/Byron/gitoxide/commit/6b18abcf2856f02ab938d535a65e51ac282bf94a)) + - Adjust to renaming of `git-prompt` to `gix-prompt` ([`6a4654e`](https://github.com/Byron/gitoxide/commit/6a4654e0d10ab773dd219cb4b731c0fc1471c36d)) + - Adjust to renaming of `git-command` to `gix-command` ([`d26b8e0`](https://github.com/Byron/gitoxide/commit/d26b8e046496894ae06b0bbfdba77196976cd975)) + - Adjust to renaming of `git-packetline` to `gix-packetline` ([`5cbd22c`](https://github.com/Byron/gitoxide/commit/5cbd22cf42efb760058561c6c3bbcd4dab8c8be1)) + - Adjust to renaming of `git-worktree` to `gix-worktree` ([`73a1282`](https://github.com/Byron/gitoxide/commit/73a12821b3d9b66ec1714d07dd27eb7a73e3a544)) + - Adjust to renamining of `git-hashtable` to `gix-hashtable` ([`26a0c98`](https://github.com/Byron/gitoxide/commit/26a0c98d0a389b03e3dc7bfc758b37155e285244)) + - Adjust to renamining of `git-worktree` to `gix-worktree` ([`108bb1a`](https://github.com/Byron/gitoxide/commit/108bb1a634f4828853fb590e9fc125f79441dd38)) + - Adjust to renaming of `git-url` to `gix-url` ([`b50817a`](https://github.com/Byron/gitoxide/commit/b50817aadb143e19f61f64e19b19ec1107d980c6)) + - Adjust to renaming of `git-date` to `gix-date` ([`9a79ff2`](https://github.com/Byron/gitoxide/commit/9a79ff2d5cc74c1efad9f41e21095ae498cce00b)) + - Adjust to renamining of `git-attributes` to `gix-attributes` ([`4a8b3b8`](https://github.com/Byron/gitoxide/commit/4a8b3b812ac26f2a2aee8ce8ca81591273383c84)) + - Adjust to renaminig of `git-quote` to `gix-quote` ([`648025b`](https://github.com/Byron/gitoxide/commit/648025b7ca94411fdd0d90c53e5faede5fde6c8d)) + - Adjust to renaming of `git-config` to `gix-config` ([`3a861c8`](https://github.com/Byron/gitoxide/commit/3a861c8f049f6502d3bcbdac752659aa1aeda46a)) + - Adjust to renaming of `git-ref` to `gix-ref` ([`1f5f695`](https://github.com/Byron/gitoxide/commit/1f5f695407b034377d94b172465ff573562b3fc3)) + - Adjust to renaming of `git-lock` to `gix-lock` ([`2028e78`](https://github.com/Byron/gitoxide/commit/2028e7884ae1821edeec81612f501e88e4722b17)) + - Adjust to renaming of `git-tempfile` to `gix-tempfile` ([`b6cc3eb`](https://github.com/Byron/gitoxide/commit/b6cc3ebb5137084a6327af16a7d9364d8f092cc9)) + - Adjust to renaming of `git-object` to `gix-object` ([`fc86a1e`](https://github.com/Byron/gitoxide/commit/fc86a1e710ad7bf076c25cc6f028ddcf1a5a4311)) + - Adjust to renaming of `git-actor` to `gix-actor` ([`4dc9b44`](https://github.com/Byron/gitoxide/commit/4dc9b44dc52f2486ffa2040585c6897c1bf55df4)) + - Adjust to renaming of `git-validate` to `gix-validate` ([`5e40ad0`](https://github.com/Byron/gitoxide/commit/5e40ad078af3d08cbc2ca81ce755c0ed8a065b4f)) + - Adjust to renaming of `git-hash` to `gix-hash` ([`4a9d025`](https://github.com/Byron/gitoxide/commit/4a9d0257110c3efa61d08c8457c4545b200226d1)) + - Adjust to renaming of `git-features` to `gix-features` ([`e2dd68a`](https://github.com/Byron/gitoxide/commit/e2dd68a417aad229e194ff20dbbfd77668096ec6)) + - Adjust to renaming of `git-glob` to `gix-glob` ([`35b2a3a`](https://github.com/Byron/gitoxide/commit/35b2a3acbc8f2a03f151bc0a3863163844e0ca86)) + - Adjust to renaming of `git-sec` to `gix-sec` ([`eabbb92`](https://github.com/Byron/gitoxide/commit/eabbb923bd5a32fc80fa80f96cfdc2ab7bb2ed17)) + - Adapt to renaming of `git-path` to `gix-path` ([`d3bbcfc`](https://github.com/Byron/gitoxide/commit/d3bbcfccad80fc44ea8e7bf819f23adaca06ba2d)) + - Adjust to rename of `git-config-value` to `gix-config-value` ([`622b3e1`](https://github.com/Byron/gitoxide/commit/622b3e1d0bffa0f8db73697960f9712024fac430)) + - Release git-refspec v0.7.2, git-repository v0.34.0 ([`1210c19`](https://github.com/Byron/gitoxide/commit/1210c1926851495df5d6fd3f6906602a7e423548)) + - 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)) + - Merge remote-tracking branch 'origin/main' ([`f5fbcfb`](https://github.com/Byron/gitoxide/commit/f5fbcfbcf281429d56c46f815ca86da848410083)) + - Fixes build for parsing fuzz harness ([`d342922`](https://github.com/Byron/gitoxide/commit/d34292294a0c41991aebd5af46e7bd7e3ad7324d)) + - Release git-date v0.4.1, git-features v0.26.1, git-glob v0.5.2, git-attributes v0.8.1, git-tempfile v3.0.1, git-ref v0.23.1, git-sec v0.6.1, git-config v0.15.1, git-prompt v0.3.1, git-url v0.13.1, git-discover v0.12.1, git-index v0.12.2, git-mailmap v0.9.1, git-pack v0.30.1, git-odb v0.40.1, git-transport v0.25.3, git-protocol v0.26.2, git-revision v0.10.1, git-refspec v0.7.1, git-worktree v0.12.1, git-repository v0.33.0 ([`5b5b380`](https://github.com/Byron/gitoxide/commit/5b5b3809faa71c658db38b40dfc410224d08a367)) + - Prepare changelogs prior to release ([`93bef97`](https://github.com/Byron/gitoxide/commit/93bef97b3c0c75d4bf7119fdd787516e1efc77bf)) + - Merge branch 'patch-1' ([`b93f0c4`](https://github.com/Byron/gitoxide/commit/b93f0c49fc677b6c19aea332cbfc1445ce475375)) + - Thanks clippy ([`9e04685`](https://github.com/Byron/gitoxide/commit/9e04685dd3f109bfb27663f9dc7c04102e660bf2)) + - Release git-ref v0.23.0, git-config v0.15.0, git-command v0.2.2, git-diff v0.26.0, git-discover v0.12.0, git-mailmap v0.9.0, git-pack v0.30.0, git-odb v0.40.0, git-transport v0.25.2, git-protocol v0.26.1, git-revision v0.10.0, git-refspec v0.7.0, git-worktree v0.12.0, git-repository v0.32.0 ([`ffb5b6a`](https://github.com/Byron/gitoxide/commit/ffb5b6a21cb415315db6fd5294940c7c6deb4538)) + - Prepare changelogs prior to release ([`4381a03`](https://github.com/Byron/gitoxide/commit/4381a03a34c305f31713cce234c2afbf8ac60f01)) + - Release git-date v0.4.0, git-actor v0.17.0, git-object v0.26.0, git-traverse v0.22.0, git-index v0.12.0, safety bump 15 crates ([`0e3d0a5`](https://github.com/Byron/gitoxide/commit/0e3d0a56d7e6a60c6578138f2690b4fa54a2072d)) + - Release git-features v0.26.0, git-actor v0.16.0, git-attributes v0.8.0, git-object v0.25.0, git-ref v0.22.0, git-config v0.14.0, git-command v0.2.1, git-url v0.13.0, git-credentials v0.9.0, git-diff v0.25.0, git-discover v0.11.0, git-traverse v0.21.0, git-index v0.11.0, git-mailmap v0.8.0, git-pack v0.29.0, git-odb v0.39.0, git-transport v0.25.0, git-protocol v0.26.0, git-revision v0.9.0, git-refspec v0.6.0, git-worktree v0.11.0, git-repository v0.31.0, safety bump 24 crates ([`5ac9fbe`](https://github.com/Byron/gitoxide/commit/5ac9fbe265a5b61c533a2a6b3abfed2bdf7f89ad)) + - Prepare changelogs prior to release ([`30d8ca1`](https://github.com/Byron/gitoxide/commit/30d8ca19284049dcfbb0de2698cafae1d1a16b0c)) + - Release git-date v0.3.1, git-features v0.25.0, git-actor v0.15.0, git-glob v0.5.1, git-path v0.7.0, git-attributes v0.7.0, git-config-value v0.10.0, git-lock v3.0.1, git-validate v0.7.1, git-object v0.24.0, git-ref v0.21.0, git-sec v0.6.0, git-config v0.13.0, git-prompt v0.3.0, git-url v0.12.0, git-credentials v0.8.0, git-diff v0.24.0, git-discover v0.10.0, git-traverse v0.20.0, git-index v0.10.0, git-mailmap v0.7.0, git-pack v0.28.0, git-odb v0.38.0, git-packetline v0.14.1, git-transport v0.24.0, git-protocol v0.25.0, git-revision v0.8.0, git-refspec v0.5.0, git-worktree v0.10.0, git-repository v0.30.0, safety bump 26 crates ([`e6b9906`](https://github.com/Byron/gitoxide/commit/e6b9906c486b11057936da16ed6e0ec450a0fb83)) + - Prepare chnagelogs prior to git-repository release ([`7114bbb`](https://github.com/Byron/gitoxide/commit/7114bbb6732aa8571d4ab74f28ed3e26e9fbe4d0)) + - Merge branch 'main' into read-split-index ([`c57bdde`](https://github.com/Byron/gitoxide/commit/c57bdde6de37eca9672ea715962bbd02aa3eb055)) + - Merge branch 'adjustments-for-cargo' ([`083909b`](https://github.com/Byron/gitoxide/commit/083909bc7eb902eeee2002034fdb6ed88280dc5c)) + - Adjust to changes in `git-testtools` ([`4eb842c`](https://github.com/Byron/gitoxide/commit/4eb842c7150b980e1c2637217e1f9657a671cea7)) + - Release git-hash v0.10.1, git-hashtable v0.1.0 ([`7717170`](https://github.com/Byron/gitoxide/commit/771717095d9a67b0625021eb0928828ab686e772)) + - Merge branch 'main' into http-config ([`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 ([`c4e6849`](https://github.com/Byron/gitoxide/commit/c4e68496c368611ebe17c6693d06c8147c28c717)) + - Merge branch 'gix-clone' ([`def53b3`](https://github.com/Byron/gitoxide/commit/def53b36c3dec26fa78939ab0584fe4ff930909c)) + - Merge branch 'main' into gix-clone ([`91bf67a`](https://github.com/Byron/gitoxide/commit/91bf67af9751d1e6beb78fb77b40f05352b98215)) + - Merge branch 'fix-571' ([`2514334`](https://github.com/Byron/gitoxide/commit/2514334c17f543e3e18ac43261990ad412b7c7ae)) + - Release git-hash v0.9.11, git-features v0.23.0, git-actor v0.13.0, git-attributes v0.5.0, git-object v0.22.0, git-ref v0.17.0, git-sec v0.4.1, git-config v0.9.0, git-url v0.10.0, git-credentials v0.6.0, git-diff v0.20.0, git-discover v0.6.0, git-traverse v0.18.0, git-index v0.6.0, git-mailmap v0.5.0, git-pack v0.24.0, git-odb v0.34.0, git-packetline v0.13.1, git-transport v0.21.0, git-protocol v0.21.0, git-revision v0.6.0, git-refspec v0.3.0, git-worktree v0.6.0, git-repository v0.25.0, safety bump 24 crates ([`104d922`](https://github.com/Byron/gitoxide/commit/104d922add61ab21c534c24ce8ed37cddf3e275a)) + - Prepare changelogs for release ([`d232567`](https://github.com/Byron/gitoxide/commit/d23256701a95284857dc8d1cb37c7c94cada973c)) + - Merge branch 'clone' ([`507dc7e`](https://github.com/Byron/gitoxide/commit/507dc7e706cb3c9d89d048b3aff5df239a9b6788)) + - Remove lifetime of `match_group::Fix`, keeping `RefSpec` instances instead ([`2a0a87a`](https://github.com/Byron/gitoxide/commit/2a0a87a04e7b4d6ed3be3d8adc89917576727686)) + - Another test to validate components must not be empty ([`b2c9af1`](https://github.com/Byron/gitoxide/commit/b2c9af1cf7eedfb618c47d0598cfcef636e793ff)) + - Merge branch 'main' into new-http-impl ([`702a161`](https://github.com/Byron/gitoxide/commit/702a161ef11fc959611bf44b70e9ffe04561c7ad)) + - Make fmt ([`53acf25`](https://github.com/Byron/gitoxide/commit/53acf2565743eff7cead7a42011107b2fc8d7e0e)) + - Merge branch 'fetch-pack' ([`3c49400`](https://github.com/Byron/gitoxide/commit/3c49400809c7c2120f4ce704c19a0421545b5acd)) + - `RefSpecRef::prefix()` to return the two-component prefix of a refspec's source. #(450) ([`6df179b`](https://github.com/Byron/gitoxide/commit/6df179b5cf831402444cc78429a57f835358376e)) + - Merge branch 'diff' ([`25a7726`](https://github.com/Byron/gitoxide/commit/25a7726377fbe400ea3c4927d04e9dec99802b7b)) + - Release 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 ([`f5c36d8`](https://github.com/Byron/gitoxide/commit/f5c36d85755d1f0f503b77d9a565fad6aecf6728)) + - 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)) + - Make fmt ([`429cccc`](https://github.com/Byron/gitoxide/commit/429cccc5831c25a7205a12dc7a0443ac48616e2c)) + - Merge branch 'filter-refs' ([`3773b92`](https://github.com/Byron/gitoxide/commit/3773b92b8372c9a40a74d281149ca65b057a7da9)) + - Merge branch 'filter-refs' ([`fd14489`](https://github.com/Byron/gitoxide/commit/fd14489f729172d615d0fa1e8dbd605e9eacf69d)) + - Thanks clippy ([`74a5f22`](https://github.com/Byron/gitoxide/commit/74a5f2262154c5cb5434c1ef2854c4ec3d839f89)) + - Thanks clippy ([`016cd1f`](https://github.com/Byron/gitoxide/commit/016cd1f70a536ac95eaa8b80958110caa096d875)) + - Thanks clippy ([`b8ac13e`](https://github.com/Byron/gitoxide/commit/b8ac13e5074fa08111fcef1092432ed3a2326c6e)) + - Thanks clippy ([`73b405f`](https://github.com/Byron/gitoxide/commit/73b405fe70cf7d53e5e011cf69ea654f4bd96dd2)) + - Make fmt ([`535e967`](https://github.com/Byron/gitoxide/commit/535e967666c6da657ff1b7eff7c64ab27cafb182)) + - Merge branch 'main' into filter-refs-by-spec ([`1f6e5ab`](https://github.com/Byron/gitoxide/commit/1f6e5ab15f5fd8d23719b13e6aea59cd231ac0fe)) + - Merge branch 'fix-522' ([`5869e9f`](https://github.com/Byron/gitoxide/commit/5869e9ff2508d5a93c07635277af8764fcb57713)) + - Release git-hash v0.9.9 ([`da0716f`](https://github.com/Byron/gitoxide/commit/da0716f8c27b4f29cfff0e5ce7fcb3d7240f4aeb)) + - Merge branch 'main' into index-from-tree ([`bc64b96`](https://github.com/Byron/gitoxide/commit/bc64b96a2ec781c72d1d4daad38aa7fb8b74f99b)) + - Merge branch 'main' into filter-refs-by-spec ([`cef0b51`](https://github.com/Byron/gitoxide/commit/cef0b51ade2a3301fa09ede7a425aa1fe3527e78)) + - Release git-object v0.20.3, git-ref v0.15.4, git-config v0.7.1, git-diff v0.18.0, git-traverse v0.16.3, git-pack v0.22.0, git-odb v0.32.0, git-url v0.7.3, git-transport v0.19.3, git-protocol v0.19.1, git-refspec v0.1.1, git-repository v0.23.0, safety bump 6 crates ([`85a3bed`](https://github.com/Byron/gitoxide/commit/85a3bedd68d2e5f36592a2f691c977dc55298279)) + - Release git-features v0.22.3, git-revision v0.4.4 ([`c2660e2`](https://github.com/Byron/gitoxide/commit/c2660e2503323531ba02519eaa51124ee22fec51)) + - Merge branch 'main' into filter-refs-by-spec ([`cfa1440`](https://github.com/Byron/gitoxide/commit/cfa144031dbcac2707ab0cec012bc35e78f9c475)) + - Release git-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 'remote-ls-refs' ([`39d585d`](https://github.com/Byron/gitoxide/commit/39d585d9f9ac6f3ecf51359c8e37f0a50e21ed45)) + - 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 ([`c82bbfa`](https://github.com/Byron/gitoxide/commit/c82bbfaddc45bf9b5b55f056613046d977d9ef09)) + - Prepare for release of git-repository ([`8aa5389`](https://github.com/Byron/gitoxide/commit/8aa5389d5a1bdd3a07f1caa1c2f55c8af4f9844a)) + - 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)) + - Release git-hash v0.9.7, git-features v0.22.1 ([`232784a`](https://github.com/Byron/gitoxide/commit/232784a59ded3e8016e4257c7e146ad385cdd64a)) + - Merge branch 'main' into write-index-v2 ([`a938986`](https://github.com/Byron/gitoxide/commit/a938986877302c197d1aed087594c5605416fe5f)) + - Merge branch 'main' into remote-ls-refs ([`de61c4d`](https://github.com/Byron/gitoxide/commit/de61c4db7855d6925d66961f62ae3d12cc4acf78)) + - Thanks clippy ([`4bd747c`](https://github.com/Byron/gitoxide/commit/4bd747cb3e126fe5b1d540270cfbd731cffd42ef)) + - Thanks clippy ([`b9e1cdb`](https://github.com/Byron/gitoxide/commit/b9e1cdbf19045816387d922abd9c886419ff6bf2)) + - Merge branch 'parse-refspec' ([`2ba338e`](https://github.com/Byron/gitoxide/commit/2ba338e28eb45d4d3215dd6ff9882611880d4cd9)) + - Thanks clippy ([`6c963b0`](https://github.com/Byron/gitoxide/commit/6c963b022e48854001353f8909c3e8314c2e5861)) + - Thanks clippy ([`b62ee56`](https://github.com/Byron/gitoxide/commit/b62ee56b5bf468b9673b01034ec284faf1a7c7c2)) + - Release git-refspec v0.0.0 ([`d406689`](https://github.com/Byron/gitoxide/commit/d406689f01c8fa7cc81b52d6500a44303e719ec2)) +</details> + +## 0.7.1 (2023-01-10) + +A maintenance release without user-facing changes. + +## 0.7.0 (2023-01-09) + +A maintenance release without user-facing changes. + +## 0.6.0 (2022-12-30) + +A maintenance release without user-facing changes. + +## 0.5.0 (2022-12-19) + +A maintenance release without user-facing changes. + +## 0.4.0 (2022-11-21) + +### New Features (BREAKING) + + - <csr-id-3d8fa8fef9800b1576beab8a5bc39b821157a5ed/> upgrade edition to 2021 in most crates. + MSRV for this is 1.56, and we are now at 1.60 so should be compatible. + This isn't more than a patch release as it should break nobody + who is adhering to the MSRV, but let's be careful and mark it + breaking. + + Note that `gix-features` and `gix-pack` are still on edition 2018 + as they make use of a workaround to support (safe) mutable access + to non-overlapping entries in a slice which doesn't work anymore + in edition 2021. + +## 0.3.1 (2022-11-06) + +### New Features + + - <csr-id-21b21b6c25e1d8d1da9464b7bef06a795f679210/> add `RefSpecRef::expand_prefix()` method to avoid missing prefixes. + The current implementation might cause refspecs to end up ignored as + they don't have a prefix, and in protocol V2 it would then fail + to add a ref-spec filter which causes them to be missed. + + With `expand_prefix()`, we assure that there are all possible prefixes + that can contain partial names, similar to what git does. + +### Bug Fixes + + - <csr-id-d53ddcde948cfbd7773eb830cbb636626b32debb/> `HEAD` may now return itself as prefix in `RefSpecRef::prefix()` and `expanded_prefix()`. + Previously, the expanded prefix would be a list of possibilities, even + though it's such a common case that we really want to avoid spamming the + remote about it when asking for HEAD during clone for instance. + +## 0.3.0 (2022-10-10) + +### New Features + + - <csr-id-d7f63a6c60a826dc862bd13adbef041e4ac6d8ab/> `RefSpec::allow_non_fast_forward()` to get information about 'force' quickly. + - <csr-id-6df179b5cf831402444cc78429a57f835358376e/> `RefSpecRef::prefix()` to return the two-component prefix of a refspec's source. #(450) + +### Bug Fixes + + - <csr-id-278ff7a6ee084ea864193a5ca25b6cd0f18e19a0/> `RefSpecRef` instruction uses the correct lifetime. + +### Changed (BREAKING) + + - <csr-id-2a0a87a04e7b4d6ed3be3d8adc89917576727686/> remove lifetime of `match_group::Fix`, keeping `RefSpec` instances instead + That lifetime unnecessarily complicated things and wasn't worth keeping + due to being a premature optimization. + +## 0.2.0 (2022-09-20) + +### New Features + + - <csr-id-abdf83f494e2a9fba4a8d9fcb776f2c84baebd3e/> Simple serialization for `Instruction` and `RefSpecRef` type. + It's also a way to normalize input strings as there is only one way + to serialize instructions, which themselves are already normalized + towards what's possible. + +### Changed (BREAKING) + + - <csr-id-4c4f82170d08b910a7f64482431c99956b1a04c3/> reject all invalid negative refspec patterns. + Git is more lenient, but will then fail to match against such patterns + which seems like avoidable surprising behaviour. + - <csr-id-99905bacace8aed42b16d43f0f04cae996cb971c/> upgrade `bstr` to `1.0.1` + +## 0.1.1 (2022-08-28) + +Maintenance release without user-facing changes. + +## 0.1.0 (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 + +## 0.0.0 (2022-08-05) + +Initial release for name reservation. + diff --git a/vendor/gix-refspec/Cargo.toml b/vendor/gix-refspec/Cargo.toml new file mode 100644 index 000000000..acc79c110 --- /dev/null +++ b/vendor/gix-refspec/Cargo.toml @@ -0,0 +1,51 @@ +# 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-refspec" +version = "0.9.0" +authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"] +include = [ + "src/**/*", + "CHANGELOG.md", + "README.md", +] +description = "A WIP crate of the gitoxide project for parsing and representing refspecs" +readme = "README.md" +license = "MIT/Apache-2.0" +repository = "https://github.com/Byron/gitoxide" + +[lib] +doctest = false + +[dependencies.bstr] +version = "1.3.0" +features = ["std"] +default-features = false + +[dependencies.gix-hash] +version = "^0.10.3" + +[dependencies.gix-revision] +version = "^0.12.0" + +[dependencies.gix-validate] +version = "^0.7.3" + +[dependencies.smallvec] +version = "1.9.0" + +[dependencies.thiserror] +version = "1.0.26" + +[dev-dependencies] diff --git a/vendor/gix-refspec/README.md b/vendor/gix-refspec/README.md new file mode 100644 index 000000000..371337b98 --- /dev/null +++ b/vendor/gix-refspec/README.md @@ -0,0 +1,11 @@ +# `gix-refspec` + +### Testing + +#### Fuzzing + +`cargo fuzz` is used for fuzzing, installable with `cargo install cargo-fuzz`. + +Targets can be listed with `cargo fuzz list` and executed via `cargo +nightly fuzz run <target>`, +where `<target>` can be `parse` for example. + diff --git a/vendor/gix-refspec/src/instruction.rs b/vendor/gix-refspec/src/instruction.rs new file mode 100644 index 000000000..990d0debc --- /dev/null +++ b/vendor/gix-refspec/src/instruction.rs @@ -0,0 +1,68 @@ +use bstr::BStr; + +use crate::{parse::Operation, Instruction}; + +impl Instruction<'_> { + /// Derive the mode of operation from this instruction. + pub fn operation(&self) -> Operation { + match self { + Instruction::Push(_) => Operation::Push, + Instruction::Fetch(_) => Operation::Fetch, + } + } +} + +/// Note that all sources can either be a ref-name, partial or full, or a rev-spec, unless specified otherwise, on the local side. +/// Destinations can only be a partial or full ref names on the remote side. +#[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, Hash, Debug)] +pub enum Push<'a> { + /// Push all local branches to the matching destination on the remote, which has to exist to be updated. + AllMatchingBranches { + /// If true, allow non-fast-forward updates of the matched destination branch. + allow_non_fast_forward: bool, + }, + /// Delete the destination ref or glob pattern, with only a single `*` allowed. + Delete { + /// The reference or pattern to delete on the remote. + ref_or_pattern: &'a BStr, + }, + /// Push a single ref or refspec to a known destination ref. + Matching { + /// The source ref or refspec to push. If pattern, it contains a single `*`. + /// Examples are refnames like `HEAD` or `refs/heads/main`, or patterns like `refs/heads/*`. + src: &'a BStr, + /// The ref to update with the object from `src`. If `src` is a pattern, this is a pattern too. + /// Examples are refnames like `HEAD` or `refs/heads/main`, or patterns like `refs/heads/*`. + dst: &'a BStr, + /// If true, allow non-fast-forward updates of `dest`. + allow_non_fast_forward: bool, + }, +} + +/// Any source can either be a ref name (full or partial) or a fully spelled out hex-sha for an object, on the remote side. +/// +/// Destinations can only be a partial or full ref-names on the local side. +#[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, Hash, Debug)] +pub enum Fetch<'a> { + /// Fetch a ref or refs, without updating local branches. + Only { + /// The partial or full ref name to fetch on the remote side or the full object hex-name, without updating the local side. + /// Note that this may not be a glob pattern, as those need to be matched by a destination which isn't present here. + src: &'a BStr, + }, + /// Exclude a single ref. + Exclude { + /// A single partial or full ref name to exclude on the remote, or a pattern with a single `*`. It cannot be a spelled out object hash. + src: &'a BStr, + }, + /// Fetch from `src` and update the corresponding destination branches in `dst` accordingly. + AndUpdate { + /// The ref name to fetch on the remote side, or a pattern with a single `*` to match against. + src: &'a BStr, + /// The local destination to update with what was fetched, or a pattern whose single `*` will be replaced with the matching portion + /// of the `*` from `src`. + dst: &'a BStr, + /// If true, allow non-fast-forward updates of `dest`. + allow_non_fast_forward: bool, + }, +} diff --git a/vendor/gix-refspec/src/lib.rs b/vendor/gix-refspec/src/lib.rs new file mode 100644 index 000000000..54d5f3057 --- /dev/null +++ b/vendor/gix-refspec/src/lib.rs @@ -0,0 +1,39 @@ +//! Parse git ref-specs and represent them. +#![deny(missing_docs, rust_2018_idioms)] +#![forbid(unsafe_code)] + +/// +pub mod parse; +pub use parse::function::parse; + +/// +pub mod instruction; + +/// A refspec with references to the memory it was parsed from. +#[derive(Eq, Copy, Clone, Debug)] +pub struct RefSpecRef<'a> { + mode: types::Mode, + op: parse::Operation, + src: Option<&'a bstr::BStr>, + dst: Option<&'a bstr::BStr>, +} + +/// An owned refspec. +#[derive(Eq, Clone, Debug)] +pub struct RefSpec { + mode: types::Mode, + op: parse::Operation, + src: Option<bstr::BString>, + dst: Option<bstr::BString>, +} + +mod spec; + +mod write; + +/// +pub mod match_group; +pub use match_group::types::MatchGroup; + +mod types; +pub use types::Instruction; diff --git a/vendor/gix-refspec/src/match_group/mod.rs b/vendor/gix-refspec/src/match_group/mod.rs new file mode 100644 index 000000000..c53b5b531 --- /dev/null +++ b/vendor/gix-refspec/src/match_group/mod.rs @@ -0,0 +1,112 @@ +use std::collections::BTreeSet; + +use crate::{parse::Operation, types::Mode, MatchGroup, RefSpecRef}; + +pub(crate) mod types; +pub use types::{Item, Mapping, Outcome, Source, SourceRef}; + +/// +pub mod validate; + +/// Initialization +impl<'a> MatchGroup<'a> { + /// Take all the fetch ref specs from `specs` get a match group ready. + pub fn from_fetch_specs(specs: impl IntoIterator<Item = RefSpecRef<'a>>) -> Self { + MatchGroup { + specs: specs.into_iter().filter(|s| s.op == Operation::Fetch).collect(), + } + } +} + +/// Matching +impl<'a> MatchGroup<'a> { + /// Match all `items` against all fetch specs present in this group, returning deduplicated mappings from source to destination. + /// Note that this method only makes sense if the specs are indeed fetch specs and may panic otherwise. + /// + /// Note that negative matches are not part of the return value, so they are not observable but will be used to remove mappings. + pub fn match_remotes<'item>(self, mut items: impl Iterator<Item = Item<'item>> + Clone) -> Outcome<'a, 'item> { + let mut out = Vec::new(); + let mut seen = BTreeSet::default(); + let mut push_unique = |mapping| { + if seen.insert(calculate_hash(&mapping)) { + out.push(mapping); + } + }; + let mut matchers: Vec<Option<Matcher<'_>>> = self + .specs + .iter() + .copied() + .map(Matcher::from) + .enumerate() + .map(|(idx, m)| match m.lhs { + Some(Needle::Object(id)) => { + push_unique(Mapping { + item_index: None, + lhs: SourceRef::ObjectId(id), + rhs: m.rhs.map(|n| n.to_bstr()), + spec_index: idx, + }); + None + } + _ => Some(m), + }) + .collect(); + + let mut has_negation = false; + for (spec_index, (spec, matcher)) in self.specs.iter().zip(matchers.iter_mut()).enumerate() { + for (item_index, item) in items.clone().enumerate() { + if spec.mode == Mode::Negative { + has_negation = true; + continue; + } + if let Some(matcher) = matcher { + let (matched, rhs) = matcher.matches_lhs(item); + if matched { + push_unique(Mapping { + item_index: Some(item_index), + lhs: SourceRef::FullName(item.full_ref_name), + rhs, + spec_index, + }) + } + } + } + } + + if let Some(id) = has_negation.then(|| items.next().map(|i| i.target)).flatten() { + let null_id = gix_hash::ObjectId::null(id.kind()); + for matcher in matchers + .into_iter() + .zip(self.specs.iter()) + .filter_map(|(m, spec)| m.and_then(|m| (spec.mode == Mode::Negative).then_some(m))) + { + out.retain(|m| match m.lhs { + SourceRef::ObjectId(_) => true, + SourceRef::FullName(name) => { + !matcher + .matches_lhs(Item { + full_ref_name: name, + target: &null_id, + object: None, + }) + .0 + } + }); + } + } + Outcome { + group: self, + mappings: out, + } + } +} + +fn calculate_hash<T: std::hash::Hash>(t: &T) -> u64 { + use std::hash::Hasher; + let mut s = std::collections::hash_map::DefaultHasher::new(); + t.hash(&mut s); + s.finish() +} + +mod util; +use util::{Matcher, Needle}; diff --git a/vendor/gix-refspec/src/match_group/types.rs b/vendor/gix-refspec/src/match_group/types.rs new file mode 100644 index 000000000..6be601dd5 --- /dev/null +++ b/vendor/gix-refspec/src/match_group/types.rs @@ -0,0 +1,104 @@ +use std::borrow::Cow; + +use bstr::{BStr, BString}; +use gix_hash::oid; + +use crate::RefSpecRef; + +/// A match group is able to match a list of ref specs in order while handling negation, conflicts and one to many mappings. +#[derive(Default, Debug, Clone)] +pub struct MatchGroup<'a> { + /// The specs that take part in item matching. + pub specs: Vec<RefSpecRef<'a>>, +} + +/// The outcome of any matching operation of a [`MatchGroup`]. +/// +/// It's used to validate and process the contained [mappings][Mapping]. +#[derive(Debug, Clone)] +pub struct Outcome<'spec, 'item> { + /// The match group that produced this outcome. + pub group: MatchGroup<'spec>, + /// The mappings derived from matching [items][Item]. + pub mappings: Vec<Mapping<'item, 'spec>>, +} + +/// An item to match, input to various matching operations. +#[derive(Debug, Copy, Clone)] +pub struct Item<'a> { + /// The full name of the references, like `refs/heads/main` + pub full_ref_name: &'a BStr, + /// The id that `full_ref_name` points to, which typically is a commit, but can also be a tag object (or anything else). + pub target: &'a oid, + /// The object an annotated tag is pointing to, if `target` is an annotated tag. + pub object: Option<&'a oid>, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +/// The source (or left-hand) side of a mapping, which references its name. +pub enum SourceRef<'a> { + /// A full reference name, which is expected to be valid. + /// + /// Validity, however, is not enforced here. + FullName(&'a BStr), + /// The name of an object that is expected to exist on the remote side. + /// Note that it might not be advertised by the remote but part of the object graph, + /// and thus gets sent in the pack. The server is expected to fail unless the desired + /// object is present but at some time it is merely a request by the user. + ObjectId(gix_hash::ObjectId), +} + +impl SourceRef<'_> { + /// Create a fully owned instance from this one. + pub fn to_owned(&self) -> Source { + match self { + SourceRef::ObjectId(id) => Source::ObjectId(*id), + SourceRef::FullName(name) => Source::FullName((*name).to_owned()), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +/// The source (or left-hand) side of a mapping, which owns its name. +pub enum Source { + /// A full reference name, which is expected to be valid. + /// + /// Validity, however, is not enforced here. + FullName(BString), + /// The name of an object that is expected to exist on the remote side. + /// Note that it might not be advertised by the remote but part of the object graph, + /// and thus gets sent in the pack. The server is expected to fail unless the desired + /// object is present but at some time it is merely a request by the user. + ObjectId(gix_hash::ObjectId), +} + +impl std::fmt::Display for Source { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Source::FullName(name) => name.fmt(f), + Source::ObjectId(id) => id.fmt(f), + } + } +} + +/// A mapping from a remote to a local refs for fetches or local to remote refs for pushes. +/// +/// Mappings are like edges in a graph, initially without any constraints. +#[derive(Debug, Clone)] +pub struct Mapping<'a, 'b> { + /// The index into the initial `items` list that matched against a spec. + pub item_index: Option<usize>, + /// The name of the remote side for fetches or the local one for pushes that matched. + pub lhs: SourceRef<'a>, + /// The name of the local side for fetches or the remote one for pushes that corresponds to `lhs`, if available. + pub rhs: Option<Cow<'b, BStr>>, + /// The index of the matched ref-spec as seen from the match group. + pub spec_index: usize, +} + +impl std::hash::Hash for Mapping<'_, '_> { + fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + self.lhs.hash(state); + self.rhs.hash(state); + } +} diff --git a/vendor/gix-refspec/src/match_group/util.rs b/vendor/gix-refspec/src/match_group/util.rs new file mode 100644 index 000000000..5339aef32 --- /dev/null +++ b/vendor/gix-refspec/src/match_group/util.rs @@ -0,0 +1,162 @@ +use std::{borrow::Cow, ops::Range}; + +use bstr::{BStr, BString, ByteSlice, ByteVec}; +use gix_hash::ObjectId; + +use crate::{match_group::Item, RefSpecRef}; + +/// A type keeping enough information about a ref-spec to be able to efficiently match it against multiple matcher items. +pub struct Matcher<'a> { + pub(crate) lhs: Option<Needle<'a>>, + pub(crate) rhs: Option<Needle<'a>>, +} + +impl<'a> Matcher<'a> { + /// Match `item` against this spec and return `(true, Some<rhs>)` to gain the other side of the match as configured, or `(true, None)` + /// if there was no `rhs`. + /// + /// This may involve resolving a glob with an allocation, as the destination is built using the matching portion of a glob. + pub fn matches_lhs(&self, item: Item<'_>) -> (bool, Option<Cow<'a, BStr>>) { + match (self.lhs, self.rhs) { + (Some(lhs), None) => (lhs.matches(item).is_match(), None), + (Some(lhs), Some(rhs)) => lhs.matches(item).into_match_outcome(rhs, item), + (None, None) | (None, Some(_)) => { + unreachable!("For all we know, the lefthand side is never empty. Push specs might change that.") + } + } + } +} + +#[derive(Debug, Copy, Clone)] +pub(crate) enum Needle<'a> { + FullName(&'a BStr), + PartialName(&'a BStr), + Glob { name: &'a BStr, asterisk_pos: usize }, + Object(ObjectId), +} + +enum Match { + /// There was no match. + None, + /// No additional data is provided as part of the match. + Normal, + /// The range of text to copy from the originating item name + GlobRange(Range<usize>), +} + +impl Match { + fn is_match(&self) -> bool { + !matches!(self, Match::None) + } + fn into_match_outcome<'a>(self, destination: Needle<'a>, item: Item<'_>) -> (bool, Option<Cow<'a, BStr>>) { + let arg = match self { + Match::None => return (false, None), + Match::Normal => None, + Match::GlobRange(range) => Some((range, item)), + }; + (true, destination.to_bstr_replace(arg).into()) + } +} + +impl<'a> Needle<'a> { + #[inline] + fn matches(&self, item: Item<'_>) -> Match { + match self { + Needle::FullName(name) => { + if *name == item.full_ref_name { + Match::Normal + } else { + Match::None + } + } + Needle::PartialName(name) => crate::spec::expand_partial_name(name, |expanded| { + (expanded == item.full_ref_name).then_some(Match::Normal) + }) + .unwrap_or(Match::None), + Needle::Glob { name, asterisk_pos } => { + match item.full_ref_name.get(..*asterisk_pos) { + Some(full_name_portion) if full_name_portion != name[..*asterisk_pos] => { + return Match::None; + } + None => return Match::None, + _ => {} + }; + let tail = &name[*asterisk_pos + 1..]; + if !item.full_ref_name.ends_with(tail) { + return Match::None; + } + let end = item.full_ref_name.len() - tail.len(); + Match::GlobRange(*asterisk_pos..end) + } + Needle::Object(id) => { + if *id == item.target { + return Match::Normal; + } + match item.object { + Some(object) if object == *id => Match::Normal, + _ => Match::None, + } + } + } + } + + fn to_bstr_replace(self, range: Option<(Range<usize>, Item<'_>)>) -> Cow<'a, BStr> { + match (self, range) { + (Needle::FullName(name), None) => Cow::Borrowed(name), + (Needle::PartialName(name), None) => Cow::Owned({ + let mut base: BString = "refs/".into(); + if !(name.starts_with(b"tags/") || name.starts_with(b"remotes/")) { + base.push_str("heads/"); + } + base.push_str(name); + base + }), + (Needle::Glob { name, asterisk_pos }, Some((range, item))) => { + let mut buf = Vec::with_capacity(name.len() + range.len() - 1); + buf.push_str(&name[..asterisk_pos]); + buf.push_str(&item.full_ref_name[range]); + buf.push_str(&name[asterisk_pos + 1..]); + Cow::Owned(buf.into()) + } + (Needle::Object(id), None) => { + let mut name = id.to_string(); + name.insert_str(0, "refs/heads/"); + Cow::Owned(name.into()) + } + (Needle::Glob { .. }, None) => unreachable!("BUG: no range provided for glob pattern"), + (_, Some(_)) => { + unreachable!("BUG: range provided even though needle wasn't a glob. Globs are symmetric.") + } + } + } + + pub fn to_bstr(self) -> Cow<'a, BStr> { + self.to_bstr_replace(None) + } +} + +impl<'a> From<&'a BStr> for Needle<'a> { + fn from(v: &'a BStr) -> Self { + if let Some(pos) = v.find_byte(b'*') { + Needle::Glob { + name: v, + asterisk_pos: pos, + } + } else if v.starts_with(b"refs/") { + Needle::FullName(v) + } else if let Ok(id) = gix_hash::ObjectId::from_hex(v) { + Needle::Object(id) + } else { + Needle::PartialName(v) + } + } +} + +impl<'a> From<RefSpecRef<'a>> for Matcher<'a> { + fn from(v: RefSpecRef<'a>) -> Self { + Matcher { + lhs: v.src.map(Into::into), + rhs: v.dst.map(Into::into), + } + } +} diff --git a/vendor/gix-refspec/src/match_group/validate.rs b/vendor/gix-refspec/src/match_group/validate.rs new file mode 100644 index 000000000..097a64587 --- /dev/null +++ b/vendor/gix-refspec/src/match_group/validate.rs @@ -0,0 +1,141 @@ +use std::collections::BTreeMap; + +use bstr::BString; + +use crate::{ + match_group::{Outcome, Source}, + RefSpec, +}; + +/// All possible issues found while validating matched mappings. +#[derive(Debug, PartialEq, Eq)] +pub enum Issue { + /// Multiple sources try to write the same destination. + /// + /// Note that this issue doesn't take into consideration that these sources might contain the same object behind a reference. + Conflict { + /// The unenforced full name of the reference to be written. + destination_full_ref_name: BString, + /// The list of sources that map to this destination. + sources: Vec<Source>, + /// The list of specs that caused the mapping conflict, each matching the respective one in `sources` to allow both + /// `sources` and `specs` to be zipped together. + specs: Vec<BString>, + }, +} + +impl std::fmt::Display for Issue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Issue::Conflict { + destination_full_ref_name, + sources, + specs, + } => { + write!( + f, + "Conflicting destination {destination_full_ref_name:?} would be written by {}", + sources + .iter() + .zip(specs.iter()) + .map(|(src, spec)| format!("{src} ({spec:?})")) + .collect::<Vec<_>>() + .join(", ") + ) + } + } + } +} + +/// All possible fixes corrected while validating matched mappings. +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum Fix { + /// Removed a mapping that contained a partial destination entirely. + MappingWithPartialDestinationRemoved { + /// The destination ref name that was ignored. + name: BString, + /// The spec that defined the mapping + spec: RefSpec, + }, +} + +/// The error returned [outcome validation][Outcome::validated()]. +#[derive(Debug)] +pub struct Error { + /// All issues discovered during validation. + pub issues: Vec<Issue>, +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Found {} {} the refspec mapping to be used: \n\t{}", + self.issues.len(), + if self.issues.len() == 1 { + "issue that prevents" + } else { + "issues that prevent" + }, + self.issues + .iter() + .map(|issue| issue.to_string()) + .collect::<Vec<_>>() + .join("\n\t") + ) + } +} + +impl std::error::Error for Error {} + +impl<'spec, 'item> Outcome<'spec, 'item> { + /// Validate all mappings or dissolve them into an error stating the discovered issues. + /// Return `(modified self, issues)` providing a fixed-up set of mappings in `self` with the fixed `issues` + /// provided as part of it. + /// Terminal issues are communicated using the [`Error`] type accordingly. + pub fn validated(mut self) -> Result<(Self, Vec<Fix>), Error> { + let mut sources_by_destinations = BTreeMap::new(); + for (dst, (spec_index, src)) in self + .mappings + .iter() + .filter_map(|m| m.rhs.as_ref().map(|dst| (dst.as_ref(), (m.spec_index, &m.lhs)))) + { + let sources = sources_by_destinations.entry(dst).or_insert_with(Vec::new); + if !sources.iter().any(|(_, lhs)| lhs == &src) { + sources.push((spec_index, src)) + } + } + let mut issues = Vec::new(); + for (dst, conflicting_sources) in sources_by_destinations.into_iter().filter(|(_, v)| v.len() > 1) { + issues.push(Issue::Conflict { + destination_full_ref_name: dst.to_owned(), + specs: conflicting_sources + .iter() + .map(|(spec_idx, _)| self.group.specs[*spec_idx].to_bstring()) + .collect(), + sources: conflicting_sources.into_iter().map(|(_, src)| src.to_owned()).collect(), + }) + } + if !issues.is_empty() { + Err(Error { issues }) + } else { + let mut fixed = Vec::new(); + let group = &self.group; + self.mappings.retain(|m| match m.rhs.as_ref() { + Some(dst) => { + if dst.starts_with(b"refs/") || dst.as_ref() == "HEAD" { + true + } else { + fixed.push(Fix::MappingWithPartialDestinationRemoved { + name: dst.as_ref().to_owned(), + spec: group.specs[m.spec_index].to_owned(), + }); + false + } + } + None => true, + }); + Ok((self, fixed)) + } + } +} diff --git a/vendor/gix-refspec/src/parse.rs b/vendor/gix-refspec/src/parse.rs new file mode 100644 index 000000000..390db13fa --- /dev/null +++ b/vendor/gix-refspec/src/parse.rs @@ -0,0 +1,255 @@ +/// The error returned by the [`parse()`][crate::parse()] function. +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum Error { + #[error("Empty refspecs are invalid")] + Empty, + #[error("Negative refspecs cannot have destinations as they exclude sources")] + NegativeWithDestination, + #[error("Negative specs must not be empty")] + NegativeEmpty, + #[error("Negative specs are only supported when fetching")] + NegativeUnsupported, + #[error("Negative specs must be object hashes")] + NegativeObjectHash, + #[error("Negative specs must be full ref names, starting with \"refs/\"")] + NegativePartialName, + #[error("Negative glob patterns are not allowed")] + NegativeGlobPattern, + #[error("Fetch destinations must be ref-names, like 'HEAD:refs/heads/branch'")] + InvalidFetchDestination, + #[error("Cannot push into an empty destination")] + PushToEmpty, + #[error("glob patterns may only involved a single '*' character, found {pattern:?}")] + PatternUnsupported { pattern: bstr::BString }, + #[error("Both sides of the specification need a pattern, like 'a/*:b/*'")] + PatternUnbalanced, + #[error(transparent)] + ReferenceName(#[from] gix_validate::refname::Error), + #[error(transparent)] + RevSpec(#[from] gix_revision::spec::parse::Error), +} + +/// Define how the parsed refspec should be used. +#[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, Hash, Debug)] +pub enum Operation { + /// The `src` side is local and the `dst` side is remote. + Push, + /// The `src` side is remote and the `dst` side is local. + Fetch, +} + +pub(crate) mod function { + use bstr::{BStr, ByteSlice}; + + use crate::{ + parse::{Error, Operation}, + types::Mode, + RefSpecRef, + }; + + /// Parse `spec` for use in `operation` and return it if it is valid. + pub fn parse(mut spec: &BStr, operation: Operation) -> Result<RefSpecRef<'_>, Error> { + fn fetch_head_only(mode: Mode) -> RefSpecRef<'static> { + RefSpecRef { + mode, + op: Operation::Fetch, + src: Some("HEAD".into()), + dst: None, + } + } + + let mode = match spec.first() { + Some(&b'^') => { + spec = &spec[1..]; + if operation == Operation::Push { + return Err(Error::NegativeUnsupported); + } + Mode::Negative + } + Some(&b'+') => { + spec = &spec[1..]; + Mode::Force + } + Some(_) => Mode::Normal, + None => { + return match operation { + Operation::Push => Err(Error::Empty), + Operation::Fetch => Ok(fetch_head_only(Mode::Normal)), + } + } + }; + + let (mut src, dst) = match spec.find_byte(b':') { + Some(pos) => { + if mode == Mode::Negative { + return Err(Error::NegativeWithDestination); + } + + let (src, dst) = spec.split_at(pos); + let dst = &dst[1..]; + let src = (!src.is_empty()).then(|| src.as_bstr()); + let dst = (!dst.is_empty()).then(|| dst.as_bstr()); + match (src, dst) { + (None, None) => match operation { + Operation::Push => (None, None), + Operation::Fetch => (Some("HEAD".into()), None), + }, + (None, Some(dst)) => match operation { + Operation::Push => (None, Some(dst)), + Operation::Fetch => (Some("HEAD".into()), Some(dst)), + }, + (Some(src), None) => match operation { + Operation::Push => return Err(Error::PushToEmpty), + Operation::Fetch => (Some(src), None), + }, + (Some(src), Some(dst)) => (Some(src), Some(dst)), + } + } + None => { + let src = (!spec.is_empty()).then_some(spec); + if Operation::Fetch == operation && mode != Mode::Negative && src.is_none() { + return Ok(fetch_head_only(mode)); + } else { + (src, None) + } + } + }; + + if let Some(spec) = src.as_mut() { + if *spec == "@" { + *spec = "HEAD".into(); + } + } + let (src, src_had_pattern) = validated(src, operation == Operation::Push && dst.is_some())?; + let (dst, dst_had_pattern) = validated(dst, false)?; + if mode != Mode::Negative && src_had_pattern != dst_had_pattern { + return Err(Error::PatternUnbalanced); + } + + if mode == Mode::Negative { + match src { + Some(spec) => { + if src_had_pattern { + return Err(Error::NegativeGlobPattern); + } else if looks_like_object_hash(spec) { + return Err(Error::NegativeObjectHash); + } else if !spec.starts_with(b"refs/") && spec != "HEAD" { + return Err(Error::NegativePartialName); + } + } + None => return Err(Error::NegativeEmpty), + } + } + + Ok(RefSpecRef { + op: operation, + mode, + src, + dst, + }) + } + + fn looks_like_object_hash(spec: &BStr) -> bool { + spec.len() >= gix_hash::Kind::shortest().len_in_hex() && spec.iter().all(|b| b.is_ascii_hexdigit()) + } + + fn validated(spec: Option<&BStr>, allow_revspecs: bool) -> Result<(Option<&BStr>, bool), Error> { + match spec { + Some(spec) => { + let glob_count = spec.iter().filter(|b| **b == b'*').take(2).count(); + if glob_count > 1 { + return Err(Error::PatternUnsupported { pattern: spec.into() }); + } + let has_globs = glob_count == 1; + if has_globs { + let mut buf = smallvec::SmallVec::<[u8; 256]>::with_capacity(spec.len()); + buf.extend_from_slice(spec); + let glob_pos = buf.find_byte(b'*').expect("glob present"); + buf[glob_pos] = b'a'; + gix_validate::reference::name_partial(buf.as_bstr())?; + } else { + gix_validate::reference::name_partial(spec) + .map_err(Error::from) + .or_else(|err| { + if allow_revspecs { + match gix_revision::spec::parse(spec, &mut super::revparse::Noop) { + Ok(_) => { + if spec.iter().any(|b| b.is_ascii_whitespace()) { + Err(err) + } else { + Ok(spec) + } + } + Err(err) => Err(err.into()), + } + } else { + Err(err) + } + })?; + } + Ok((Some(spec), has_globs)) + } + None => Ok((None, false)), + } + } +} + +mod revparse { + use bstr::BStr; + use gix_revision::spec::parse::delegate::{ + Kind, Navigate, PeelTo, PrefixHint, ReflogLookup, Revision, SiblingBranch, Traversal, + }; + + pub(crate) struct Noop; + + impl Revision for Noop { + fn find_ref(&mut self, _name: &BStr) -> Option<()> { + Some(()) + } + + fn disambiguate_prefix(&mut self, _prefix: gix_hash::Prefix, _hint: Option<PrefixHint<'_>>) -> Option<()> { + Some(()) + } + + fn reflog(&mut self, _query: ReflogLookup) -> Option<()> { + Some(()) + } + + fn nth_checked_out_branch(&mut self, _branch_no: usize) -> Option<()> { + Some(()) + } + + fn sibling_branch(&mut self, _kind: SiblingBranch) -> Option<()> { + Some(()) + } + } + + impl Navigate for Noop { + fn traverse(&mut self, _kind: Traversal) -> Option<()> { + Some(()) + } + + fn peel_until(&mut self, _kind: PeelTo<'_>) -> Option<()> { + Some(()) + } + + fn find(&mut self, _regex: &BStr, _negated: bool) -> Option<()> { + Some(()) + } + + fn index_lookup(&mut self, _path: &BStr, _stage: u8) -> Option<()> { + Some(()) + } + } + + impl Kind for Noop { + fn kind(&mut self, _kind: gix_revision::spec::Kind) -> Option<()> { + Some(()) + } + } + + impl gix_revision::spec::parse::Delegate for Noop { + fn done(&mut self) {} + } +} diff --git a/vendor/gix-refspec/src/spec.rs b/vendor/gix-refspec/src/spec.rs new file mode 100644 index 000000000..9361ae682 --- /dev/null +++ b/vendor/gix-refspec/src/spec.rs @@ -0,0 +1,257 @@ +use bstr::{BStr, BString, ByteSlice}; + +use crate::{ + instruction::{Fetch, Push}, + parse::Operation, + types::Mode, + Instruction, RefSpec, RefSpecRef, +}; + +/// Conversion. Use the [RefSpecRef][RefSpec::to_ref()] type for more usage options. +impl RefSpec { + /// Return ourselves as reference type. + pub fn to_ref(&self) -> RefSpecRef<'_> { + RefSpecRef { + mode: self.mode, + op: self.op, + src: self.src.as_ref().map(|b| b.as_ref()), + dst: self.dst.as_ref().map(|b| b.as_ref()), + } + } + + /// Return true if the spec stats with a `+` and thus forces setting the reference. + pub fn allow_non_fast_forward(&self) -> bool { + matches!(self.mode, Mode::Force) + } +} + +mod impls { + use std::{ + cmp::Ordering, + hash::{Hash, Hasher}, + }; + + use crate::{RefSpec, RefSpecRef}; + + impl From<RefSpecRef<'_>> for RefSpec { + fn from(v: RefSpecRef<'_>) -> Self { + v.to_owned() + } + } + + impl Hash for RefSpec { + fn hash<H: Hasher>(&self, state: &mut H) { + self.to_ref().hash(state) + } + } + + impl Hash for RefSpecRef<'_> { + fn hash<H: Hasher>(&self, state: &mut H) { + self.instruction().hash(state) + } + } + + impl PartialEq for RefSpec { + fn eq(&self, other: &Self) -> bool { + self.to_ref().eq(&other.to_ref()) + } + } + + impl PartialEq for RefSpecRef<'_> { + fn eq(&self, other: &Self) -> bool { + self.instruction().eq(&other.instruction()) + } + } + + impl PartialOrd for RefSpecRef<'_> { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + self.instruction().partial_cmp(&other.instruction()) + } + } + + impl PartialOrd for RefSpec { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + self.to_ref().partial_cmp(&other.to_ref()) + } + } + + impl Ord for RefSpecRef<'_> { + fn cmp(&self, other: &Self) -> Ordering { + self.instruction().cmp(&other.instruction()) + } + } + + impl Ord for RefSpec { + fn cmp(&self, other: &Self) -> Ordering { + self.to_ref().cmp(&other.to_ref()) + } + } +} + +/// Access +impl<'a> RefSpecRef<'a> { + /// Return the left-hand side of the spec, typically the source. + /// It takes many different forms so don't rely on this being a ref name. + /// + /// It's not present in case of deletions. + pub fn source(&self) -> Option<&BStr> { + self.src + } + + /// Return the right-hand side of the spec, typically the destination. + /// It takes many different forms so don't rely on this being a ref name. + /// + /// It's not present in case of source-only specs. + pub fn destination(&self) -> Option<&BStr> { + self.dst + } + + /// Always returns the remote side, whose actual side in the refspec depends on how it was parsed. + pub fn remote(&self) -> Option<&BStr> { + match self.op { + Operation::Push => self.dst, + Operation::Fetch => self.src, + } + } + + /// Always returns the local side, whose actual side in the refspec depends on how it was parsed. + pub fn local(&self) -> Option<&BStr> { + match self.op { + Operation::Push => self.src, + Operation::Fetch => self.dst, + } + } + + /// Derive the prefix from the [`source`][Self::source()] side of this spec if this is a fetch spec, + /// or the [`destination`][Self::destination()] side if it is a push spec, if it is possible to do so without ambiguity. + /// + /// This means it starts with `refs/`. Note that it won't contain more than two components, like `refs/heads/` + pub fn prefix(&self) -> Option<&BStr> { + if self.mode == Mode::Negative { + return None; + } + let source = match self.op { + Operation::Fetch => self.source(), + Operation::Push => self.destination(), + }?; + if source == "HEAD" { + return source.into(); + } + let suffix = source.strip_prefix(b"refs/")?; + let slash_pos = suffix.find_byte(b'/')?; + let prefix = source[..="refs/".len() + slash_pos].as_bstr(); + (!prefix.contains(&b'*')).then_some(prefix) + } + + /// As opposed to [`prefix()`][Self::prefix], if the latter is `None` it will expand to all possible prefixes and place them in `out`. + /// + /// Note that only the `source` side is considered. + pub fn expand_prefixes(&self, out: &mut Vec<BString>) { + match self.prefix() { + Some(prefix) => out.push(prefix.into()), + None => { + let source = match match self.op { + Operation::Fetch => self.source(), + Operation::Push => self.destination(), + } { + Some(source) => source, + None => return, + }; + if let Some(rest) = source.strip_prefix(b"refs/") { + if !rest.contains(&b'/') { + out.push(source.into()); + } + return; + } else if gix_hash::ObjectId::from_hex(source).is_ok() { + return; + } + expand_partial_name(source, |expanded| { + out.push(expanded.into()); + None::<()> + }); + } + } + } + + /// Transform the state of the refspec into an instruction making clear what to do with it. + pub fn instruction(&self) -> Instruction<'a> { + match self.op { + Operation::Fetch => match (self.mode, self.src, self.dst) { + (Mode::Normal | Mode::Force, Some(src), None) => Instruction::Fetch(Fetch::Only { src }), + (Mode::Normal | Mode::Force, Some(src), Some(dst)) => Instruction::Fetch(Fetch::AndUpdate { + src, + dst, + allow_non_fast_forward: matches!(self.mode, Mode::Force), + }), + (Mode::Negative, Some(src), None) => Instruction::Fetch(Fetch::Exclude { src }), + (mode, src, dest) => { + unreachable!( + "BUG: fetch instructions with {:?} {:?} {:?} are not possible", + mode, src, dest + ) + } + }, + Operation::Push => match (self.mode, self.src, self.dst) { + (Mode::Normal | Mode::Force, Some(src), None) => Instruction::Push(Push::Matching { + src, + dst: src, + allow_non_fast_forward: matches!(self.mode, Mode::Force), + }), + (Mode::Normal | Mode::Force, None, Some(dst)) => { + Instruction::Push(Push::Delete { ref_or_pattern: dst }) + } + (Mode::Normal | Mode::Force, None, None) => Instruction::Push(Push::AllMatchingBranches { + allow_non_fast_forward: matches!(self.mode, Mode::Force), + }), + (Mode::Normal | Mode::Force, Some(src), Some(dst)) => Instruction::Push(Push::Matching { + src, + dst, + allow_non_fast_forward: matches!(self.mode, Mode::Force), + }), + (mode, src, dest) => { + unreachable!( + "BUG: push instructions with {:?} {:?} {:?} are not possible", + mode, src, dest + ) + } + }, + } + } +} + +/// Conversion +impl RefSpecRef<'_> { + /// Convert this ref into a standalone, owned copy. + pub fn to_owned(&self) -> RefSpec { + RefSpec { + mode: self.mode, + op: self.op, + src: self.src.map(ToOwned::to_owned), + dst: self.dst.map(ToOwned::to_owned), + } + } +} + +pub(crate) fn expand_partial_name<T>(name: &BStr, mut cb: impl FnMut(&BStr) -> Option<T>) -> Option<T> { + use bstr::ByteVec; + let mut buf = BString::from(Vec::with_capacity(128)); + for (base, append_head) in [ + ("", false), + ("refs/", false), + ("refs/tags/", false), + ("refs/heads/", false), + ("refs/remotes/", false), + ("refs/remotes/", true), + ] { + buf.clear(); + buf.push_str(base); + buf.push_str(name); + if append_head { + buf.push_str("/HEAD"); + } + if let Some(res) = cb(buf.as_ref()) { + return Some(res); + } + } + None +} diff --git a/vendor/gix-refspec/src/types.rs b/vendor/gix-refspec/src/types.rs new file mode 100644 index 000000000..0a0e24e36 --- /dev/null +++ b/vendor/gix-refspec/src/types.rs @@ -0,0 +1,21 @@ +use crate::instruction; + +/// The way to interpret a refspec. +#[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, Hash, Debug)] +pub(crate) enum Mode { + /// Apply standard rules for refspecs which are including refs with specific rules related to allowing fast forwards of destinations. + Normal, + /// Even though according to normal rules a non-fastforward would be denied, override this and reset a ref forcefully in the destination. + Force, + /// Instead of considering matching refs included, we consider them excluded. This applies only to the source side of a refspec. + Negative, +} + +/// Tells what to do and is derived from a [`RefSpec`][crate::RefSpecRef]. +#[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, Hash, Debug)] +pub enum Instruction<'a> { + /// An instruction for pushing. + Push(instruction::Push<'a>), + /// An instruction for fetching. + Fetch(instruction::Fetch<'a>), +} diff --git a/vendor/gix-refspec/src/write.rs b/vendor/gix-refspec/src/write.rs new file mode 100644 index 000000000..74c71c6e1 --- /dev/null +++ b/vendor/gix-refspec/src/write.rs @@ -0,0 +1,74 @@ +use bstr::BString; + +use crate::{ + instruction::{Fetch, Push}, + Instruction, RefSpecRef, +}; + +impl RefSpecRef<'_> { + /// Reproduce ourselves in parseable form. + pub fn to_bstring(&self) -> BString { + let mut buf = Vec::with_capacity(128); + self.write_to(&mut buf).expect("no io error"); + buf.into() + } + + /// Serialize ourselves in a parseable format to `out`. + pub fn write_to(&self, out: impl std::io::Write) -> std::io::Result<()> { + self.instruction().write_to(out) + } +} + +impl Instruction<'_> { + /// Reproduce ourselves in parseable form. + pub fn to_bstring(&self) -> BString { + let mut buf = Vec::with_capacity(128); + self.write_to(&mut buf).expect("no io error"); + buf.into() + } + + /// Serialize ourselves in a parseable format to `out`. + pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { + match self { + Instruction::Push(Push::Matching { + src, + dst, + allow_non_fast_forward, + }) => { + if *allow_non_fast_forward { + out.write_all(&[b'+'])?; + } + out.write_all(src)?; + out.write_all(&[b':'])?; + out.write_all(dst) + } + Instruction::Push(Push::AllMatchingBranches { allow_non_fast_forward }) => { + if *allow_non_fast_forward { + out.write_all(&[b'+'])?; + } + out.write_all(&[b':']) + } + Instruction::Push(Push::Delete { ref_or_pattern }) => { + out.write_all(&[b':'])?; + out.write_all(ref_or_pattern) + } + Instruction::Fetch(Fetch::Only { src }) => out.write_all(src), + Instruction::Fetch(Fetch::Exclude { src }) => { + out.write_all(&[b'^'])?; + out.write_all(src) + } + Instruction::Fetch(Fetch::AndUpdate { + src, + dst, + allow_non_fast_forward, + }) => { + if *allow_non_fast_forward { + out.write_all(&[b'+'])?; + } + out.write_all(src)?; + out.write_all(&[b':'])?; + out.write_all(dst) + } + } + } +} |