diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b645d057175..b819a07b72e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -52,6 +52,9 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v1
+ - run: rustup set auto-self-update disable
+ if: contains(runner.os, 'windows')
+ shell: bash
- uses: actions-rs/toolchain@v1
with:
profile: default
diff --git a/.github/workflows/msrv.yml b/.github/workflows/msrv.yml
index bf86d3b0719..ae0a0a9ed6d 100644
--- a/.github/workflows/msrv.yml
+++ b/.github/workflows/msrv.yml
@@ -22,6 +22,9 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
+ - run: rustup set auto-self-update disable
+ if: contains(runner.os, 'windows')
+ shell: bash
- uses: actions-rs/toolchain@v1
with:
profile: minimal
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 6257e4fdb2c..a44e8299fb8 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -121,6 +121,10 @@ jobs:
run: |
ci/macos-install-packages
+ - run: rustup set auto-self-update disable
+ if: contains(runner.os, 'windows')
+ shell: bash
+
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07256bec33d..c497f0f1085 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,22 +5,28 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-## Unreleased
+## 0.13.0 (2022-07-22)
+
+### New Features
+
+ - `gix config` with section and sub-section filtering.
+ - `gix config` lists all entries of all configuration files git considers.
+ Filters allow to narrow down the output.
### Commit Statistics
- - 12 commits contributed to the release over the course of 61 calendar days.
- - 67 days passed between releases.
- - 0 commits where understood as [conventional](https://www.conventionalcommits.org).
- - 1 unique issue was worked on: [#301](https://github.com/Byron/gitoxide/issues/301)
+ - 37 commits contributed to the release over the course of 101 calendar days.
+ - 107 days passed between releases.
+ - 2 commits where understood as [conventional](https://www.conventionalcommits.org).
+ - 3 unique issues were worked on: [#301](https://github.com/Byron/gitoxide/issues/301), [#331](https://github.com/Byron/gitoxide/issues/331), [#427](https://github.com/Byron/gitoxide/issues/427)
### Thanks Clippy
-[Clippy](https://github.com/rust-lang/rust-clippy) helped 2 times to make code idiomatic.
+[Clippy](https://github.com/rust-lang/rust-clippy) helped 3 times to make code idiomatic.
### Commit Details
@@ -37,7 +43,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- refactor ([`3ff991d`](https://github.com/Byron/gitoxide/commit/3ff991d0ca0d63632fc5710680351840f51c14c3))
- frame for `gix repo exclude query` ([`a331314`](https://github.com/Byron/gitoxide/commit/a331314758629a93ba036245a5dd03cf4109dc52))
- make fmt ([`50ff7aa`](https://github.com/Byron/gitoxide/commit/50ff7aa7fa86e5e2a94fb15aab86470532ac3f51))
+ * **[#331](https://github.com/Byron/gitoxide/issues/331)**
+ - fix journey tests after `gix` restructuring ([`59b95c9`](https://github.com/Byron/gitoxide/commit/59b95c94aacac174e374048b7d11d2c0984a19e0))
+ - `gix config` with section and sub-section filtering. ([`eda39ec`](https://github.com/Byron/gitoxide/commit/eda39ec7d736d49af1ad9e2ad775e4aa12b264b7))
+ - `gix config` lists all entries of all configuration files git considers. ([`d99453e`](https://github.com/Byron/gitoxide/commit/d99453ebeb970ed493be236def299d1e82b01f83))
+ - refactor ([`a437abe`](https://github.com/Byron/gitoxide/commit/a437abe8e77ad07bf25a16f19ca046ebdaef42d6))
+ - move 'exclude' up one level and dissolve 'repo' subcommand ([`8e5b796`](https://github.com/Byron/gitoxide/commit/8e5b796ea3fd760839f3c29a4f65bb42b1f3e893))
+ - move 'mailmap' up one level ([`5cf08ce`](https://github.com/Byron/gitoxide/commit/5cf08ce3d04d635bbfee169cb77ce259efbf6bc3))
+ - move 'odb' up one level ([`0ed65da`](https://github.com/Byron/gitoxide/commit/0ed65da9b66d4cc3c85d3b70fa4bc383c7a0d1a3))
+ - move 'tree' up one level ([`38a8350`](https://github.com/Byron/gitoxide/commit/38a8350d75720a8455e9c55d12f7cdf4b1742e56))
+ - move 'commit' up one level ([`72876f1`](https://github.com/Byron/gitoxide/commit/72876f1fd65efc816b704db6880ab881c89cff01))
+ - move 'verify' up one level ([`ac7d99a`](https://github.com/Byron/gitoxide/commit/ac7d99ac42ff8561e81f476856d0bbe86b5fa627))
+ - move 'revision' one level up ([`c9c78e8`](https://github.com/Byron/gitoxide/commit/c9c78e86c387c09838404c90de420892f41f4356))
+ - move 'remote' to 'free' ([`8967fcd`](https://github.com/Byron/gitoxide/commit/8967fcd009260c2d32881866244ba673894775f2))
+ - move commitgraph to 'free' ([`f99c3b2`](https://github.com/Byron/gitoxide/commit/f99c3b29cea30f1cbbea7e5855abfec3de6ca630))
+ - move index to 'free' ([`83585bd`](https://github.com/Byron/gitoxide/commit/83585bdfccdc42b5307255b2d56d8cb12d4136cb))
+ - move 'pack' to 'free' ([`1cdecbc`](https://github.com/Byron/gitoxide/commit/1cdecbc583ae412e7f25cade73b46e00a182125f))
+ - migrate mailmap to the new 'free' section ([`141c5f1`](https://github.com/Byron/gitoxide/commit/141c5f1145f9d3864e2d879089c66c62f38a2b5d))
+ - first step towards moving all repository-commands one level up. ([`f4e1810`](https://github.com/Byron/gitoxide/commit/f4e1810fb711d57778be79c88f49aa583821abab))
+ - make obvious what plumbing and porcelain really are ([`faaf791`](https://github.com/Byron/gitoxide/commit/faaf791cc960c37b180ddef9792dfabc7d106138))
+ - adjustments due to breaking changes in `git_path` ([`4420ae9`](https://github.com/Byron/gitoxide/commit/4420ae932d5b20a9662a6d36353a27111b5cd672))
+ * **[#427](https://github.com/Byron/gitoxide/issues/427)**
+ - basic infrastructure for delegate implementation ([`d3c0bc6`](https://github.com/Byron/gitoxide/commit/d3c0bc6e8d7764728f4e10500bb895152ccd0b0b))
+ - Hookup explain command ([`1049b00`](https://github.com/Byron/gitoxide/commit/1049b00eaa261a67f060eaca4eb50dcda831eafd))
+ - frame for `gix repo rev explain` ([`12e6277`](https://github.com/Byron/gitoxide/commit/12e6277a65a6572a0e43e8324d2d1dfb23d0bb40))
* **Uncategorized**
+ - thanks clippy ([`48b3f4a`](https://github.com/Byron/gitoxide/commit/48b3f4a5077ba66d47482a80e505feb69e9ac9fc))
+ - make fmt ([`0700b09`](https://github.com/Byron/gitoxide/commit/0700b09d6828849fa2470df89af1f75a67bfb27d))
+ - Use git_path::realpath in all places that allow it right now ([`229dc91`](https://github.com/Byron/gitoxide/commit/229dc917fc7d9241b85e5818260a6fbdd3a5daaa))
- make fmt ([`251b6df`](https://github.com/Byron/gitoxide/commit/251b6df5dbdda24b7bdc452085f808f3acef69d8))
- Merge branch 'git_includeif' of https://github.com/svetli-n/gitoxide into svetli-n-git_includeif ([`0e01da7`](https://github.com/Byron/gitoxide/commit/0e01da74dffedaa46190db6a7b60a2aaff190d81))
- thanks clippy ([`056e8d2`](https://github.com/Byron/gitoxide/commit/056e8d26dc511fe7939ec87c62ef16aafd34fa9c))
diff --git a/Cargo.lock b/Cargo.lock
index 1a5f65bad4a..b6868fd8b7c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -943,6 +943,21 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
+[[package]]
+name = "futures"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
[[package]]
name = "futures-channel"
version = "0.3.21"
@@ -959,6 +974,17 @@ version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
+[[package]]
+name = "futures-executor"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
[[package]]
name = "futures-io"
version = "0.3.21"
@@ -986,6 +1012,29 @@ version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
+[[package]]
+name = "futures-task"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
+
+[[package]]
+name = "futures-util"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
[[package]]
name = "generic-array"
version = "0.14.5"
@@ -1018,7 +1067,7 @@ dependencies = [
[[package]]
name = "git-actor"
-version = "0.10.1"
+version = "0.11.0"
dependencies = [
"bstr",
"btoi",
@@ -1045,8 +1094,8 @@ dependencies = [
"git-path",
"git-quote",
"git-testtools",
- "quick-error",
"serde",
+ "thiserror",
"unicode-bom",
]
@@ -1100,7 +1149,7 @@ dependencies = [
"nom",
"serde",
"serde_derive",
- "serial_test",
+ "serial_test 0.7.0",
"smallvec",
"tempfile",
"thiserror",
@@ -1131,18 +1180,19 @@ dependencies = [
[[package]]
name = "git-date"
-version = "0.0.1"
+version = "0.0.2"
dependencies = [
"bstr",
"document-features",
"git-testtools",
"itoa 1.0.2",
"serde",
+ "time",
]
[[package]]
name = "git-diff"
-version = "0.16.0"
+version = "0.17.0"
dependencies = [
"git-hash",
"git-object",
@@ -1170,7 +1220,7 @@ dependencies = [
[[package]]
name = "git-features"
-version = "0.21.1"
+version = "0.22.0"
dependencies = [
"bstr",
"bytes",
@@ -1183,12 +1233,12 @@ dependencies = [
"jwalk",
"libc",
"num_cpus",
+ "once_cell",
"parking_lot 0.12.1",
"prodash",
"quick-error",
"sha-1",
"sha1_smol",
- "time",
"walkdir",
]
@@ -1198,7 +1248,7 @@ version = "0.0.0"
[[package]]
name = "git-glob"
-version = "0.3.0"
+version = "0.3.1"
dependencies = [
"bitflags",
"bstr",
@@ -1209,7 +1259,7 @@ dependencies = [
[[package]]
name = "git-hash"
-version = "0.9.5"
+version = "0.9.6"
dependencies = [
"document-features",
"git-testtools",
@@ -1220,7 +1270,7 @@ dependencies = [
[[package]]
name = "git-index"
-version = "0.3.0"
+version = "0.4.0"
dependencies = [
"atoi",
"bitflags",
@@ -1254,7 +1304,7 @@ dependencies = [
[[package]]
name = "git-mailmap"
-version = "0.2.0"
+version = "0.3.0"
dependencies = [
"bstr",
"git-actor",
@@ -1269,7 +1319,7 @@ version = "0.0.0"
[[package]]
name = "git-object"
-version = "0.19.0"
+version = "0.20.0"
dependencies = [
"bstr",
"btoi",
@@ -1360,7 +1410,7 @@ dependencies = [
[[package]]
name = "git-path"
-version = "0.3.0"
+version = "0.4.0"
dependencies = [
"bstr",
"tempfile",
@@ -1370,6 +1420,15 @@ dependencies = [
[[package]]
name = "git-pathspec"
version = "0.0.0"
+dependencies = [
+ "bitflags",
+ "bstr",
+ "git-attributes",
+ "git-glob",
+ "git-testtools",
+ "once_cell",
+ "thiserror",
+]
[[package]]
name = "git-protocol"
@@ -1442,6 +1501,7 @@ dependencies = [
"git-attributes",
"git-config",
"git-credentials",
+ "git-date",
"git-diff",
"git-discover",
"git-features",
@@ -1467,6 +1527,7 @@ dependencies = [
"git-worktree",
"is_ci",
"log",
+ "serial_test 0.8.0",
"signal-hook",
"tempfile",
"thiserror",
@@ -1475,7 +1536,7 @@ dependencies = [
[[package]]
name = "git-revision"
-version = "0.2.1"
+version = "0.3.0"
dependencies = [
"bstr",
"document-features",
@@ -1514,7 +1575,7 @@ version = "0.0.0"
[[package]]
name = "git-tempfile"
-version = "2.0.1"
+version = "2.0.2"
dependencies = [
"dashmap",
"libc",
@@ -1526,7 +1587,7 @@ dependencies = [
[[package]]
name = "git-testtools"
-version = "0.7.0"
+version = "0.7.1"
dependencies = [
"bstr",
"crc",
@@ -1578,7 +1639,7 @@ dependencies = [
[[package]]
name = "git-traverse"
-version = "0.15.0"
+version = "0.16.0"
dependencies = [
"git-hash",
"git-object",
@@ -2587,7 +2648,20 @@ dependencies = [
"lazy_static",
"log",
"parking_lot 0.12.1",
- "serial_test_derive",
+ "serial_test_derive 0.7.0",
+]
+
+[[package]]
+name = "serial_test"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7eec42e7232e5ca56aa59d63af3c7f991fe71ee6a3ddd2d3480834cf3902b007"
+dependencies = [
+ "futures",
+ "lazy_static",
+ "log",
+ "parking_lot 0.12.1",
+ "serial_test_derive 0.8.0",
]
[[package]]
@@ -2603,6 +2677,19 @@ dependencies = [
"syn",
]
+[[package]]
+name = "serial_test_derive"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1b95bb2f4f624565e8fe8140c789af7e2082c0e0561b5a82a1b678baa9703dc"
+dependencies = [
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn",
+]
+
[[package]]
name = "sha-1"
version = "0.10.0"
diff --git a/Cargo.toml b/Cargo.toml
index 167ad114203..abbfcd7b70b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,14 +13,14 @@ resolver = "2"
[[bin]]
name = "ein"
-path = "src/porcelain-cli.rs"
+path = "src/ein.rs"
test = false
doctest = false
[[bin]]
name = "gix"
-path = "src/plumbing-cli.rs"
+path = "src/gix.rs"
test = false
doctest = false
@@ -35,7 +35,7 @@ fast = ["git-features/parallel", "git-features/fast-sha1", "git-features/zlib-ng
## Use `clap` 3.0 to build the prettiest, best documented and most user-friendly CLI at the expense of binary size.
## Provides a terminal user interface for detailed and exhaustive progress.
## Provides a line renderer for leaner progress display, without the need for a full-blown TUI.
-pretty-cli = [ "gitoxide-core/serde1", "prodash/progress-tree", "prodash/progress-tree-log", "prodash/local-time", "gitoxide-core/local-time-support", "env_logger/humantime", "env_logger/termcolor", "env_logger/atty" ]
+pretty-cli = [ "gitoxide-core/serde1", "prodash/progress-tree", "prodash/progress-tree-log", "prodash/local-time", "env_logger/humantime", "env_logger/termcolor", "env_logger/atty" ]
## The `--verbose` flag will be powered by an interactive progress mechanism that doubles as log as well as interactive progress
## that appears after a short duration.
@@ -83,7 +83,7 @@ cache-efficiency-debug = ["git-features/cache-efficiency-debug"]
anyhow = "1.0.42"
gitoxide-core = { version = "^0.15.0", path = "gitoxide-core" }
-git-features = { version = "^0.21.1", path = "git-features" }
+git-features = { version = "^0.22.0", path = "git-features" }
git-repository = { version = "^0.20.0", path = "git-repository", default-features = false }
git-transport-for-configuration-only = { package = "git-transport", optional = true, version = "^0.19.0", path = "git-transport" }
@@ -118,7 +118,7 @@ codegen-units = 1
incremental = false
build-override = { opt-level = 0 }
-# It's not quite worth building depencies with more optimizations yet. Let's keep it here for later.
+# It's not quite worth building dependencies with more optimizations yet. Let's keep it here for later.
#[profile.dev.package."*"]
#opt-level = 2
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index e3798d63f34..66b00b0f37a 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -9,6 +9,8 @@
for the mundane things, like unhappy code paths.
* *use git itself* as reference implementation, and use their test-cases and fixtures where
appropriate. At the very least, try to learn from them.
+ * Run the same test against git whenever feasible to assure git agrees with our implementation.
+ See `git-glob` for examples.
* *use libgit2* test fixtures and cases where appropriate, or learn from them.
* **safety first**
* handle all errors, never `unwrap()`. If needed, `expect("why")`.
@@ -106,6 +108,11 @@ A bunch of notes collected to keep track of what's needed to eventually support
* Use `expect(…)` as assertion on Options, providing context on *why* the expectations should hold. Or in other words,
answer "This should work _because_…"
+## `Options` vs `Context`
+
+- Use `Options` whenever there is something to configure in terms of branching behaviour.
+- Use `Context` when potential optional data is required to perform an operation at all. See `git_config::path::Context` as reference.
+
## Examples, Experiments, Porcelain CLI and Plumbing CLI - which does what?
### Plumbing vs Porcelain
@@ -143,7 +150,7 @@ by humans.
* **Experiments**
* quick, potentially one-off programs to learn about an aspect of gitoxide potentially in comparison to other implementations like `libgit2`.
* No need for tests of any kind, but it must compile and be idiomatic Rust and `gitoxide`.
- * Manual commmand-line parsing is OK
+ * Manual command-line parsing is OK
* no polish
* make it compile quickly, so no extras
* **Examples**
diff --git a/Makefile b/Makefile
index a45d05926a9..3987ee4dba4 100644
--- a/Makefile
+++ b/Makefile
@@ -54,7 +54,7 @@ clippy: ## Run cargo clippy on all crates
cargo clippy --all --no-default-features --features lean-async --tests
check-msrv: ## run cargo msrv to validate the current msrv requirements, similar to what CI does
- cd git-repository && cargo check --package git-repository --no-default-features --features async-network-client,unstable,local-time-support,max-performance
+ cd git-repository && cargo check --package git-repository --no-default-features --features async-network-client,unstable,max-performance
check: ## Build all code in suitable configurations
cargo check --all
@@ -63,12 +63,9 @@ check: ## Build all code in suitable configurations
cargo check --no-default-features --features lean
cargo check --no-default-features --features lean-async
cargo check --no-default-features --features max
- cd git-actor && cargo check \
- && cargo check --features local-time-support
cd gitoxide-core && cargo check \
&& cargo check --features blocking-client \
- && cargo check --features async-client \
- && cargo check --features local-time-support
+ && cargo check --features async-client
cd gitoxide-core && if cargo check --all-features 2>/dev/null; then false; else true; fi
cd git-hash && cargo check --all-features \
&& cargo check
@@ -100,7 +97,6 @@ check: ## Build all code in suitable configurations
&& cargo check --features rustsha1 \
&& cargo check --features fast-sha1 \
&& cargo check --features progress \
- && cargo check --features time \
&& cargo check --features io-pipe \
&& cargo check --features crc32 \
&& cargo check --features zlib \
@@ -245,20 +241,20 @@ commit_graphs = \
stress: ## Run various algorithms on big repositories
$(MAKE) -j3 $(linux_repo) $(rust_repo) release-lean
- time ./target/release/gix --verbose pack verify --re-encode $(linux_repo)/objects/pack/*.idx
- time ./target/release/gix --verbose pack multi-index -i $(linux_repo)/objects/pack/multi-pack-index create $(linux_repo)/objects/pack/*.idx
- time ./target/release/gix --verbose pack verify $(linux_repo)/objects/pack/multi-pack-index
- rm -Rf out; mkdir out && time ./target/release/gix --verbose pack index create -p $(linux_repo)/objects/pack/*.pack out/
- time ./target/release/gix --verbose pack verify out/*.idx
-
- time ./target/release/gix --verbose pack verify --statistics $(rust_repo)/objects/pack/*.idx
- time ./target/release/gix --verbose pack verify --algorithm less-memory $(rust_repo)/objects/pack/*.idx
- time ./target/release/gix --verbose pack verify --re-encode $(rust_repo)/objects/pack/*.idx
+ time ./target/release/gix --verbose no-repo pack verify --re-encode $(linux_repo)/objects/pack/*.idx
+ time ./target/release/gix --verbose no-repo pack multi-index -i $(linux_repo)/objects/pack/multi-pack-index create $(linux_repo)/objects/pack/*.idx
+ time ./target/release/gix --verbose no-repo pack verify $(linux_repo)/objects/pack/multi-pack-index
+ rm -Rf out; mkdir out && time ./target/release/gix --verbose no-repo pack index create -p $(linux_repo)/objects/pack/*.pack out/
+ time ./target/release/gix --verbose no-repo pack verify out/*.idx
+
+ time ./target/release/gix --verbose no-repo pack verify --statistics $(rust_repo)/objects/pack/*.idx
+ time ./target/release/gix --verbose no-repo pack verify --algorithm less-memory $(rust_repo)/objects/pack/*.idx
+ time ./target/release/gix --verbose no-repo pack verify --re-encode $(rust_repo)/objects/pack/*.idx
# We must ensure there is exactly one pack file for the pack-explode *.idx globs to work.
git repack -Ad
- time ./target/release/gix --verbose pack explode .git/objects/pack/*.idx
+ time ./target/release/gix --verbose no-repo pack explode .git/objects/pack/*.idx
- rm -Rf delme; mkdir delme && time ./target/release/gix --verbose pack explode .git/objects/pack/*.idx delme/
+ rm -Rf delme; mkdir delme && time ./target/release/gix --verbose no-repo pack explode .git/objects/pack/*.idx delme/
$(MAKE) stress-commitgraph
$(MAKE) bench-git-config
@@ -266,7 +262,7 @@ stress: ## Run various algorithms on big repositories
.PHONY: stress-commitgraph
stress-commitgraph: release-lean $(commit_graphs)
set -x; for path in $(wordlist 2, 999, $^); do \
- time ./target/release/gix --verbose commit-graph verify $$path; \
+ time ./target/release/gix --verbose no-repo commit-graph verify $$path; \
done
.PHONY: bench-git-config
@@ -276,7 +272,7 @@ bench-git-config:
check-msrv-on-ci: ## Check the minimal support rust version for currently installed Rust version
rustc --version
cargo check --package git-repository
- cargo check --package git-repository --no-default-features --features async-network-client,unstable,local-time-support,max-performance
+ cargo check --package git-repository --no-default-features --features async-network-client,unstable,max-performance
##@ Maintenance
diff --git a/README.md b/README.md
index 9b94d1bc376..31b2c33aa8f 100644
--- a/README.md
+++ b/README.md
@@ -27,52 +27,53 @@ Please see _'Development Status'_ for a listing of all crates and their capabili
* Based on the [git-hours] algorithm.
* See the [discussion][git-hours-discussion] for some performance data.
* **the `gix` program** _(plumbing)_ - lower level commands for use in automation
- * **pack**
- * [x] [verify](https://asciinema.org/a/352942)
- * [x] [index verify](https://asciinema.org/a/352945) including each object sha1 and statistics
- * [x] [explode](https://asciinema.org/a/352951), useful for transforming packs into loose objects for inspection or restoration
- * [x] verify written objects (by reading them back from disk)
- * [x] [receive](https://asciinema.org/a/359321) - receive a whole pack produced by **pack-send** or _git-upload-pack_, useful for `clone` like operations.
- * [x] **create** - create a pack from given objects or tips of the commit graph.
- * [ ] **send** - create a pack and send it using the pack protocol to stdout, similar to 'git-upload-pack',
- for consumption by **pack-receive** or _git-receive-pack_
- - **multi-index**
- * [x] **info** - print information about the file
- * [x] **create** - create a multi-index from pack indices
- * [x] **verify** - check the file for consistency
- * [x] **entries** - list all entries of the file
- - **index**
- * [x] [create](https://asciinema.org/a/352941) - create an index file by streaming a pack file as done during clone
- * [x] support for thin packs (as needed for fetch/pull)
- * **commit-graph**
- * [x] **verify** - assure that a commit-graph is consistent
+ * **config** - list the complete git configuration in human-readable form and optionally filter sections by name.
+ * **exclude**
+ * [x] **query** - check if path specs are excluded via gits exclusion rules like `.gitignore`.
+ * **verify** - validate a whole repository, for now only the object database.
+ * **commit**
+ * [x] **describe** - identify a commit by its closest tag in its past
+ * **tree**
+ * [x] **entries** - list tree entries for a single tree or recursively
+ * [x] **info** - display tree statistics
+ * **odb**
+ * [x] **info** - display odb statistics
+ * [x] **entries** - display all object ids in the object database
* **mailmap**
- * [x] **verify** - check entries of a mailmap file for parse errors and display them
- * **repository**
- * **exclude**
- * [x] **query** - check if path specs are excluded via gits exclusion rules like `.gitignore`.
- * **verify** - validate a whole repository, for now only the object database.
- * **commit**
- * [x] **describe** - identify a commit by its closest tag in its past
- * **tree**
- * [x] **entries** - list tree entries for a single tree or recursively
- * [x] **info** - display tree statistics
- * **odb**
- * [x] **info** - display odb statistics
- * [x] **entries** - display all object ids in the object database
- * **mailmap**
- * [x] **entries** - display all entries of the aggregated mailmap git would use for substitution
- * **revision**
- * [ ] **explain** - show what would be done while parsing a revision specification like `HEAD~1`
- * **index**
- * [x] **entries** - show detailed entry information for human or machine consumption (via JSON)
- * [x] **verify** - check the index for consistency
- * [x] **info** - display general information about the index itself, with detailed extension information by default
- * [x] detailed information about the TREE extension
- * [ ] …other extensions details aren't implemented yet
- * [x] **checkout-exclusive** - a predecessor of `git worktree`, providing flexible options to evaluate checkout performance from an index and/or an object database.
- * **remote**
- * [ref-list](https://asciinema.org/a/359320) - list all (or given) references from a remote at the given URL
+ * [x] **entries** - display all entries of the aggregated mailmap git would use for substitution
+ * **revision**
+ * [ ] **explain** - show what would be done while parsing a revision specification like `HEAD~1`
+ * **free** - no git repository necessary
+ * **pack**
+ * [x] [verify](https://asciinema.org/a/352942)
+ * [x] [index verify](https://asciinema.org/a/352945) including each object sha1 and statistics
+ * [x] [explode](https://asciinema.org/a/352951), useful for transforming packs into loose objects for inspection or restoration
+ * [x] verify written objects (by reading them back from disk)
+ * [x] [receive](https://asciinema.org/a/359321) - receive a whole pack produced by **pack-send** or _git-upload-pack_, useful for `clone` like operations.
+ * [x] **create** - create a pack from given objects or tips of the commit graph.
+ * [ ] **send** - create a pack and send it using the pack protocol to stdout, similar to 'git-upload-pack',
+ for consumption by **pack-receive** or _git-receive-pack_
+ - **multi-index**
+ * [x] **info** - print information about the file
+ * [x] **create** - create a multi-index from pack indices
+ * [x] **verify** - check the file for consistency
+ * [x] **entries** - list all entries of the file
+ - **index**
+ * [x] [create](https://asciinema.org/a/352941) - create an index file by streaming a pack file as done during clone
+ * [x] support for thin packs (as needed for fetch/pull)
+ * **commit-graph**
+ * [x] **verify** - assure that a commit-graph is consistent
+ * **mailmap**
+ * [x] **verify** - check entries of a mailmap file for parse errors and display them
+ * **index**
+ * [x] **entries** - show detailed entry information for human or machine consumption (via JSON)
+ * [x] **verify** - check the index for consistency
+ * [x] **info** - display general information about the index itself, with detailed extension information by default
+ * [x] detailed information about the TREE extension
+ * [ ] …other extensions details aren't implemented yet
+ * [x] **checkout-exclusive** - a predecessor of `git worktree`, providing flexible options to evaluate checkout performance from an index and/or an object database.
+ * **remote**
+ * [ref-list](https://asciinema.org/a/359320) - list all (or given) references from a remote at the given URL
[skim]: https://github.com/lotabout/skim
[git-hours]: https://github.com/kimmobrunfeldt/git-hours/blob/8aaeee237cb9d9028e7a2592a25ad8468b1f45e4/index.js#L114-L143
@@ -93,18 +94,25 @@ Follow linked crate name for detailed status. Please note that all crates follow
### Stabilization Candidates
Crates that seem feature complete and need to see some more use before they can be released as 1.0.
+Documentation is complete and was reviewed at least once.
* [git-mailmap](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-mailmap)
* [git-chunk](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-chunk)
+* [git-ref](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-ref)
+* [git-config](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-config)
+* [git-glob](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-glob)
### Initial Development
-* **usable**
+
+These crates may be missing some features and thus are somewhat incomplete, but what's there
+is usable to some extend.
+
+* **usable** _(with rough but complete docs, possibly incomplete functionality)_
* [git-actor](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-actor)
* [git-hash](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-hash)
* [git-object](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-object)
* [git-validate](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-validate)
* [git-url](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-url)
- * [git-glob](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-glob)
* [git-packetline](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-packetline)
* [git-transport](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-transport)
* [git-protocol](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-protocol)
@@ -113,30 +121,28 @@ Crates that seem feature complete and need to see some more use before they can
* [git-commitgraph](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-commitgraph)
* [git-diff](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-diff)
* [git-traverse](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-traverse)
- * [git-config](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-config)
* [git-features](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-features)
* [git-credentials](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-credentials)
* [git-sec](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-sec)
* [git-quote](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-quote)
- * [git-ref](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-ref)
* [git-discover](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-discover)
* [git-path](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-path)
* [git-repository](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-repository)
+ * [git-attributes](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-attributes)
+ * [git-pathspec](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-pathspec)
* `gitoxide-core`
-* **very early**
+* **very early** _(possibly without any documentation and many rough edges)_
* [git-index](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-index)
* [git-worktree](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-worktree)
* [git-bitmap](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-bitmap)
- * [git-attributes](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-attributes)
* [git-revision](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-revision)
* [git-date](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-date)
-* **idea**
+* **idea** _(just a name placeholder)_
* [git-note](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-note)
* [git-filter](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-filter)
* [git-lfs](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-lfs)
* [git-rebase](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-rebase)
* [git-sequencer](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-sequencer)
- * [git-pathspec](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-pathspec)
* [git-submodule](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-submodule)
* [git-tui](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-tui)
* [git-tix](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-tix)
diff --git a/cargo-smart-release/src/context.rs b/cargo-smart-release/src/context.rs
index 9cdf5c1de27..ec5569e64ee 100644
--- a/cargo-smart-release/src/context.rs
+++ b/cargo-smart-release/src/context.rs
@@ -52,7 +52,7 @@ impl Context {
.parent()
.expect("parent of a file is always present")
.strip_prefix(&self.root)
- .expect("workspace members are releative to the root directory");
+ .expect("workspace members are relative to the root directory");
if dir.as_os_str().is_empty() {
None
diff --git a/cargo-smart-release/tests/changelog/parse.rs b/cargo-smart-release/tests/changelog/parse.rs
index a5d5425e049..39c3535a2ba 100644
--- a/cargo-smart-release/tests/changelog/parse.rs
+++ b/cargo-smart-release/tests/changelog/parse.rs
@@ -111,7 +111,7 @@ fn known_and_unknown_sections_are_sorted() {
markdown: "- initial release\n\n".into()
},
Segment::User {
- markdown: "### Something inbetween\n\nintermezzo\n".into()
+ markdown: "### Something in between\n\nintermezzo\n".into()
},
]
},
diff --git a/cargo-smart-release/tests/fixtures/changelog/parse/unknown-known-unknown-known-unsorted.md b/cargo-smart-release/tests/fixtures/changelog/parse/unknown-known-unknown-known-unsorted.md
index 7b8dfa06a3f..f491aa53cc9 100644
--- a/cargo-smart-release/tests/fixtures/changelog/parse/unknown-known-unknown-known-unsorted.md
+++ b/cargo-smart-release/tests/fixtures/changelog/parse/unknown-known-unknown-known-unsorted.md
@@ -4,7 +4,7 @@ Hello, this is a changelog.
- initial release
-### Something inbetween
+### Something in between
intermezzo
diff --git a/crate-status.md b/crate-status.md
index 7b67713a973..fc6e7485ab9 100644
--- a/crate-status.md
+++ b/crate-status.md
@@ -231,7 +231,7 @@ Check out the [performance discussion][git-traverse-performance] as well.
* [ ] check for match
### git-pathspec
-* [ ] parse
+* [x] parse
* [ ] check for match
### git-note
@@ -239,7 +239,7 @@ Check out the [performance discussion][git-traverse-performance] as well.
A mechanism to associate metadata with any object, and keep revisions of it using git itself.
* [ ] CRUD for git notes
-*
+
### git-discover
* [x] check if a git directory is a git repository
@@ -388,26 +388,33 @@ See its [README.md](https://github.com/Byron/gitoxide/blob/main/git-tempfile/REA
See its [README.md](https://github.com/Byron/gitoxide/blob/main/git-lock/README.md).
### git-config
-* [ ] read
- * line-wise parsing with decent error messages
+* [x] read
+ * zero-copy parsing with event emission
* [x] decode value
* [x] boolean
* [x] integer
* [x] color
* [ ] ANSI code output for terminal colors
* [x] path (incl. resolution)
+ * [ ] date
+ * [ ] [permission][https://github.com/git/git/blob/71a8fab31b70c417e8f5b5f716581f89955a7082/setup.c#L1526:L1526]
* [x] include
- * **includeIf**
- * [x] `gitdir`, `gitdir/i`, `onbranch`
- * [ ] `hasconfig`
-* [x] write
+ * **includeIf**
+ * [x] `gitdir`, `gitdir/i`, and `onbranch`
+ * [ ] `hasconfig`
+* [x] access values and sections by name and sub-section
+* [x] edit configuration in memory, non-destructively
+ * cross-platform newline handling
+* [x] write files back for lossless round-trips.
* keep comments and whitespace, and only change lines that are affected by actual changes, to allow truly non-destructive editing
-* [ ] `Config` type which integrates multiple files into one interface to support system, user and repository levels for config files
+* [x] cascaded loading of various configuration files into one
+ * [x] load from environment variables
+ * [ ] load from well-known sources for global configuration
+ * [ ] load repository configuration with all known sources
* [x] API documentation
* [x] Some examples
### git-repository
-
* [x] utilities for applications to make long running operations interruptible gracefully and to support timeouts in servers.
* [ ] handle `core.repositoryFormatVersion` and extensions
* [x] support for unicode-precomposition of command-line arguments (needs explicit use in parent application)
@@ -427,16 +434,15 @@ See its [README.md](https://github.com/Byron/gitoxide/blob/main/git-lock/README.
* [ ] make [git-notes](https://git-scm.com/docs/git-notes) accessible
* [x] tree entries
* **diffs/changes**
- * [x] tree with tree
+ * [x] tree with working tree
* [ ] tree with index
- * [ ] index with working tree
* [x] initialize
- * [ ] Proper configuration depending on platform (e.g. ignorecase, filemode, …)
+ * [x] Proper configuration depending on platform (e.g. ignorecase, filemode, …)
* **Id**
* [x] short hashes with detection of ambiguity.
* **Commit**
* [x] `describe()` like functionality
- * [x] create new commit
+ * [x] create new commit from tree
* **Objects**
* [x] lookup
* [x] peel to object kind
@@ -446,23 +452,32 @@ See its [README.md](https://github.com/Byron/gitoxide/blob/main/git-lock/README.
* **references**
* [x] peel to end
* [x] ref-log access
- * [ ] clone
+ * [ ] clone from remote
* [ ] shallow
- * [ ] namespaces support
- * [ ] sparse checkout support
* [ ] execute hooks
- * [ ] .gitignore handling
- * [ ] checkout/stage conversions clean + smudge as in .gitattributes
* **refs**
* [ ] run transaction hooks and handle special repository states like quarantine
* [ ] support for different backends like `files` and `reftable`
- * **worktrees**
- * [x] open a repository with worktrees
- * [x] read locked state
- * [ ] obtain 'prunable' information
- * [x] proper handling of worktree related refs
- * [ ] create, move, remove, and repair
+ * **main or linked worktree**
+ * [ ] add files with `.gitignore` handling
+ * [ ] checkout with conversions like clean + smudge as in `.gitattributes`
+ * [ ] _diff_ index with working tree
+ * [ ] sparse checkout support
* [ ] read per-worktree config if `extensions.worktreeConfig` is enabled.
+ * **index**
+ * [ ] tree from index
+ * [ ] index from tree
+ * **worktrees**
+ * [x] open a repository with worktrees
+ * [x] read locked state
+ * [ ] obtain 'prunable' information
+ * [x] proper handling of worktree related refs
+ * [ ] create, move, remove, and repair
+ * **config**
+ * [x] read the primitive types `boolean`, `integer`, `string`
+ * [x] read and interpolate trusted paths
+ * [x] low-level API for more elaborate access to all details of `git-config` files
+ * [ ] a way to make changes to individual configuration files
* [ ] remotes with push and pull
* [x] mailmap
* [x] object replacements (`git replace`)
diff --git a/deny.toml b/deny.toml
index 7e1f78a1534..e07e6200dfc 100644
--- a/deny.toml
+++ b/deny.toml
@@ -32,7 +32,7 @@ ignore = [ ]
[licenses]
# The lint level for crates which do not have a detectable license
unlicensed = "deny"
-# List of explictly allowed licenses
+# List of explicitly allowed licenses
# See https://spdx.org/licenses/ for list of possible licenses
# [possible values: any SPDX 3.11 short identifier (+ optional exception)].
allow = [
diff --git a/etc/check-package-size.sh b/etc/check-package-size.sh
index 8a73946e988..0a84a066738 100755
--- a/etc/check-package-size.sh
+++ b/etc/check-package-size.sh
@@ -17,18 +17,18 @@ function indent () {
echo "in root: gitoxide CLI"
(enter cargo-smart-release && indent cargo diet -n --package-size-limit 95KB)
(enter git-actor && indent cargo diet -n --package-size-limit 5KB)
-(enter git-pathspec && indent cargo diet -n --package-size-limit 5KB)
+(enter git-pathspec && indent cargo diet -n --package-size-limit 25KB)
(enter git-path && indent cargo diet -n --package-size-limit 15KB)
(enter git-attributes && indent cargo diet -n --package-size-limit 15KB)
-(enter git-discover && indent cargo diet -n --package-size-limit 15KB)
+(enter git-discover && indent cargo diet -n --package-size-limit 20KB)
(enter git-index && indent cargo diet -n --package-size-limit 30KB)
(enter git-worktree && indent cargo diet -n --package-size-limit 30KB)
(enter git-quote && indent cargo diet -n --package-size-limit 5KB)
-(enter git-revision && indent cargo diet -n --package-size-limit 20KB)
+(enter git-revision && indent cargo diet -n --package-size-limit 25KB)
(enter git-bitmap && indent cargo diet -n --package-size-limit 5KB)
(enter git-tempfile && indent cargo diet -n --package-size-limit 25KB)
(enter git-lock && indent cargo diet -n --package-size-limit 15KB)
-(enter git-config && indent cargo diet -n --package-size-limit 80KB)
+(enter git-config && indent cargo diet -n --package-size-limit 110KB)
(enter git-hash && indent cargo diet -n --package-size-limit 20KB)
(enter git-chunk && indent cargo diet -n --package-size-limit 10KB)
(enter git-rebase && indent cargo diet -n --package-size-limit 5KB)
@@ -45,13 +45,13 @@ echo "in root: gitoxide CLI"
(enter git-note && indent cargo diet -n --package-size-limit 5KB)
(enter git-sec && indent cargo diet -n --package-size-limit 10KB)
(enter git-tix && indent cargo diet -n --package-size-limit 5KB)
-(enter git-credentials && indent cargo diet -n --package-size-limit 5KB)
+(enter git-credentials && indent cargo diet -n --package-size-limit 10KB)
(enter git-object && indent cargo diet -n --package-size-limit 25KB)
(enter git-commitgraph && indent cargo diet -n --package-size-limit 25KB)
(enter git-pack && indent cargo diet -n --package-size-limit 115KB)
(enter git-odb && indent cargo diet -n --package-size-limit 120KB)
(enter git-protocol && indent cargo diet -n --package-size-limit 50KB)
(enter git-packetline && indent cargo diet -n --package-size-limit 35KB)
-(enter git-repository && indent cargo diet -n --package-size-limit 105KB)
+(enter git-repository && indent cargo diet -n --package-size-limit 120KB)
(enter git-transport && indent cargo diet -n --package-size-limit 50KB)
-(enter gitoxide-core && indent cargo diet -n --package-size-limit 70KB)
+(enter gitoxide-core && indent cargo diet -n --package-size-limit 80KB)
diff --git a/etc/discovery/odb.md b/etc/discovery/odb.md
index bab727505f8..bcaaeea9491 100644
--- a/etc/discovery/odb.md
+++ b/etc/discovery/odb.md
@@ -153,7 +153,7 @@ Solutions aren't always mutually exclusive despite the form of presentation sugg
| | | 3. catch error, force a pack refresh, repeat | can work in conjunction with similar shortcomings of loose reference database | needs mutability, burden on the API user; | |
| | | 4. writers force an update of the process-wide pool of packs after creating new packs and before updating references with the new objects | | high implementation complexity; assumes complete control of one process over git repository, excluding running git-maintenance; new readers aren't allowed for a while until the new pack is placed causing some moments of unresponsiveness/waiting | |
| **pack** | ~~5. race when creating/altering more than a pack at a time~~ | 1. ignore | | a chance for occasional object misses | all of them |
-| | | 2. retry more than one time | greatly reduced likelyhood of object misses | | |
+| | | 2. retry more than one time | greatly reduced likelihood of object misses | | |
| **pack** | **6.too many (small) packs (i.e. due to pack-receive) reduce lookup performance** | 1. explode pack into loose objects (and deal with them separately) | can run in parallel (but is typically bound by max IOP/s) | might take a while if many objects are contained in the pack due to file IOP/s; needs recompresssion and looses delta compression; risk of too many small objects | |
| | | 2. combine multiple packs into one | keep all benefits of packs; very fast if pack-to-pack copy is used; can run in parallel (but is typically bound by max IOP/s) | combining with big packs takes has to write a lot of data; can be costly if pack delta compression is used | |
| | | 3. Just-in-time maintenance after writes | tuned to run just at the right time to run just as much as needed | an implementation isn't trivial as there must only be one maintenance operation per repository at a time, so some queue should be made available to not skip maintenance just because one is running already. | |
@@ -238,7 +238,7 @@ for applications that don't need it, like CLIs.
#### Loose References
Writing loose references isn't actually atomic, so readers may observe some references in an old and some in a new state. This isn't always a breaking issue like it is
-the case for packs, the progam can still operate and is likely to produce correct (enough) outcomes.
+the case for packs, the program can still operate and is likely to produce correct (enough) outcomes.
Mitigations are possible with careful programming on the API user's side or by using the `ref-table` database instead.
@@ -273,7 +273,7 @@ refresh to the user in case they fetched or pulled in the meantime, to refresh t
**Drawbacks**
The program could benefit of using 1.2 instead of 1.1 which could cause exhaustion of file handles despite the user having no interest in evaluating all available objects,
-but ideally that is possible without loosing performance during multi-threading.
+but ideally that is possible without losing performance during multi-threading.
### Professional git-hosting mono-repo server with git-maintenance tasks and just-in-time replication
@@ -381,7 +381,7 @@ The default favors speed and using all available cores, but savvy users can run
- not an issue as there isn't enough traffic here
* **9.2** loose object database - too many loose objects reduce overall performance - just-in-time maintenance
* **10** - disk full - display early warnings in the front-end to every user to get it fixed
- - This solution is implemented on application side (and not in `gitoxide`), it's intersting enough to mention though for systems that operate themselves.
+ - This solution is implemented on application side (and not in `gitoxide`), it's interesting enough to mention though for systems that operate themselves.
- One could also imagine that it tries to spend the nights aggressively compression repositories, some low-hanging fruits there.
* **10** - write failure - fail connection
- write failures aren't specifically handled but result in typical Rust error behaviour probably alongside error reporting on the respective channels of the git-transport sideband.
diff --git a/experiments/diffing/Cargo.toml b/experiments/diffing/Cargo.toml
index 477ff1704ae..fede7fca83d 100644
--- a/experiments/diffing/Cargo.toml
+++ b/experiments/diffing/Cargo.toml
@@ -10,6 +10,6 @@ publish = false
[dependencies]
anyhow = "1"
git-repository = { version = "^0.20.0", path = "../../git-repository", features = ["unstable"] }
-git-features-for-config = { package = "git-features", version = "^0.21.0", path = "../../git-features", features = ["cache-efficiency-debug"] }
+git-features-for-config = { package = "git-features", version = "^0.22.0", path = "../../git-features", features = ["cache-efficiency-debug"] }
git2 = "0.14"
rayon = "1.5.0"
diff --git a/git-actor/CHANGELOG.md b/git-actor/CHANGELOG.md
index 04810103cb3..b08ea0cd7ee 100644
--- a/git-actor/CHANGELOG.md
+++ b/git-actor/CHANGELOG.md
@@ -5,6 +5,40 @@ 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.11.0 (2022-07-22)
+
+### Changed (BREAKING)
+
+ - remove local-time-support feature toggle.
+ We treat local time as default feature without a lot of fuzz, and
+ will eventually document that definitive support needs a compile
+ time switch in the compiler (`--cfg unsound_local_offset` or something).
+
+ One day it will perish. Failure is possible anyway and we will write
+ code to deal with it while minimizing the amount of system time
+ fetches when asking for the current local time.
+
+### Commit Statistics
+
+
+
+ - 2 commits contributed to the release.
+ - 39 days passed between releases.
+ - 1 commit where understood as [conventional](https://www.conventionalcommits.org).
+ - 1 unique issue was worked on: [#331](https://github.com/Byron/gitoxide/issues/331)
+
+### Commit Details
+
+
+
+view details
+
+ * **[#331](https://github.com/Byron/gitoxide/issues/331)**
+ - remove local-time-support feature toggle. ([`89a41bf`](https://github.com/Byron/gitoxide/commit/89a41bf2b37db29b9983b4e5492cfd67ed490b23))
+ * **Uncategorized**
+ - prepare changelog prior to release ([`3c50625`](https://github.com/Byron/gitoxide/commit/3c50625fa51350ec885b0f38ec9e92f9444df0f9))
+
+
## 0.10.1 (2022-06-13)
A maintenance release without user-facing changes.
@@ -13,7 +47,7 @@ A maintenance release without user-facing changes.
- - 3 commits contributed to the release over the course of 5 calendar days.
+ - 4 commits contributed to the release over the course of 5 calendar days.
- 25 days passed between releases.
- 0 commits where understood as [conventional](https://www.conventionalcommits.org).
- 1 unique issue was worked on: [#427](https://github.com/Byron/gitoxide/issues/427)
@@ -27,6 +61,7 @@ A maintenance release without user-facing changes.
* **[#427](https://github.com/Byron/gitoxide/issues/427)**
- Replace `Time` with `git-date::Time`. ([`59b3ff8`](https://github.com/Byron/gitoxide/commit/59b3ff8a7e028962917cf3b2930b5b7e5156c302))
* **Uncategorized**
+ - Release git-date v0.0.1, git-hash v0.9.5, git-features v0.21.1, git-actor v0.10.1, git-path v0.2.0, git-attributes v0.2.0, git-ref v0.14.0, git-sec v0.2.0, git-config v0.5.0, git-credentials v0.2.0, git-discover v0.2.0, git-pack v0.20.0, git-odb v0.30.0, git-url v0.6.0, git-transport v0.18.0, git-protocol v0.17.0, git-revision v0.2.1, git-worktree v0.3.0, git-repository v0.19.0, safety bump 13 crates ([`a417177`](https://github.com/Byron/gitoxide/commit/a41717712578f590f04a33d27adaa63171f25267))
- update changelogs prior to release ([`bb424f5`](https://github.com/Byron/gitoxide/commit/bb424f51068b8a8e762696890a55ab48900ab980))
- make fmt ([`c665aef`](https://github.com/Byron/gitoxide/commit/c665aef4270c5ee54da89ee015cc0affd6337608))
diff --git a/git-actor/Cargo.toml b/git-actor/Cargo.toml
index f11a3ff4267..4458f663c36 100644
--- a/git-actor/Cargo.toml
+++ b/git-actor/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "git-actor"
-version = "0.10.1"
+version = "0.11.0"
description = "A way to identify git actors"
authors = ["Sebastian Thiel "]
repository = "https://github.com/Byron/gitoxide"
@@ -15,12 +15,9 @@ doctest = false
## Data structures implement `serde::Serialize` and `serde::Deserialize`.
serde1 = ["serde", "bstr/serde1", "git-date/serde1"]
-## Make `Signature` initializers use the local time (with UTC offset) available.
-local-time-support = ["git-features/time"]
-
[dependencies]
-git-features = { version = "^0.21.1", path = "../git-features", optional = true }
-git-date = { version = "^0.0.1", path = "../git-date" }
+git-features = { version = "^0.22.0", path = "../git-features", optional = true }
+git-date = { version = "^0.0.2", path = "../git-date" }
quick-error = "2.0.0"
btoi = "0.4.2"
diff --git a/git-actor/src/signature/mod.rs b/git-actor/src/signature/mod.rs
index f928da713d9..b8ec635ed9b 100644
--- a/git-actor/src/signature/mod.rs
+++ b/git-actor/src/signature/mod.rs
@@ -124,78 +124,6 @@ mod write {
}
}
-mod init {
- use bstr::BString;
-
- use crate::{Signature, Time};
-
- impl Signature {
- /// Return an actor identified `name` and `email` at the current local time, that is a time with a timezone offset from
- /// UTC based on the hosts configuration.
- #[cfg(feature = "local-time-support")]
- pub fn now_local(
- name: impl Into,
- email: impl Into,
- ) -> Result {
- let offset = git_features::time::tz::current_utc_offset()?;
- Ok(Signature {
- name: name.into(),
- email: email.into(),
- time: Time {
- seconds_since_unix_epoch: std::time::SystemTime::now()
- .duration_since(std::time::UNIX_EPOCH)
- .expect("the system time doesn't run backwards that much")
- .as_secs() as u32,
- offset_in_seconds: offset,
- sign: offset.into(),
- },
- })
- }
-
- /// Return an actor identified `name` and `email` at the current local time, or UTC time if the current time zone could
- /// not be obtained.
- #[cfg(feature = "local-time-support")]
- pub fn now_local_or_utc(name: impl Into, email: impl Into) -> Self {
- let offset = git_features::time::tz::current_utc_offset().unwrap_or(0);
- Signature {
- name: name.into(),
- email: email.into(),
- time: Time {
- seconds_since_unix_epoch: std::time::SystemTime::now()
- .duration_since(std::time::UNIX_EPOCH)
- .expect("the system time doesn't run backwards that much")
- .as_secs() as u32,
- offset_in_seconds: offset,
- sign: offset.into(),
- },
- }
- }
-
- /// Return an actor identified by `name` and `email` at the current time in UTC.
- ///
- /// This would be most useful for bot users, otherwise the [`now_local()`][Signature::now_local()] method should be preferred.
- pub fn now_utc(name: impl Into, email: impl Into) -> Self {
- let utc_offset = 0;
- Signature {
- name: name.into(),
- email: email.into(),
- time: Time {
- seconds_since_unix_epoch: seconds_since_unix_epoch(),
- offset_in_seconds: utc_offset,
- sign: utc_offset.into(),
- },
- }
- }
- }
-
- fn seconds_since_unix_epoch() -> u32 {
- std::time::SystemTime::now()
- .duration_since(std::time::UNIX_EPOCH)
- .expect("the system time doesn't run backwards that much")
- .as_secs() as u32
- }
-}
-
///
mod decode;
pub use decode::decode;
diff --git a/git-attributes/CHANGELOG.md b/git-attributes/CHANGELOG.md
index 64cdb52faf9..3cc3d280df2 100644
--- a/git-attributes/CHANGELOG.md
+++ b/git-attributes/CHANGELOG.md
@@ -5,6 +5,31 @@ 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.3.0 (2022-07-22)
+
+This is a maintenance release with no functional changes.
+
+### Commit Statistics
+
+
+
+ - 3 commits contributed to the release over the course of 33 calendar days.
+ - 39 days passed between releases.
+ - 0 commits where understood as [conventional](https://www.conventionalcommits.org).
+ - 0 issues like '(#ID)' where seen in commit messages
+
+### Commit Details
+
+
+
+view details
+
+ * **Uncategorized**
+ - prepare changelog prior to release ([`3c50625`](https://github.com/Byron/gitoxide/commit/3c50625fa51350ec885b0f38ec9e92f9444df0f9))
+ - assure document-features are available in all 'usable' and 'early' crates ([`238581c`](https://github.com/Byron/gitoxide/commit/238581cc46c7288691eed37dc7de5069e3d86721))
+ - Release git-path v0.3.0, safety bump 14 crates ([`400c9be`](https://github.com/Byron/gitoxide/commit/400c9bec49e4ec5351dc9357b246e7677a63ea35))
+
+
## 0.2.0 (2022-06-13)
A maintenance release without user-facing changes.
@@ -13,7 +38,7 @@ A maintenance release without user-facing changes.
- - 2 commits contributed to the release over the course of 16 calendar days.
+ - 3 commits contributed to the release over the course of 16 calendar days.
- 25 days passed between releases.
- 0 commits where understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' where seen in commit messages
@@ -25,6 +50,7 @@ A maintenance release without user-facing changes.
view details
* **Uncategorized**
+ - Release git-date v0.0.1, git-hash v0.9.5, git-features v0.21.1, git-actor v0.10.1, git-path v0.2.0, git-attributes v0.2.0, git-ref v0.14.0, git-sec v0.2.0, git-config v0.5.0, git-credentials v0.2.0, git-discover v0.2.0, git-pack v0.20.0, git-odb v0.30.0, git-url v0.6.0, git-transport v0.18.0, git-protocol v0.17.0, git-revision v0.2.1, git-worktree v0.3.0, git-repository v0.19.0, safety bump 13 crates ([`a417177`](https://github.com/Byron/gitoxide/commit/a41717712578f590f04a33d27adaa63171f25267))
- update changelogs prior to release ([`bb424f5`](https://github.com/Byron/gitoxide/commit/bb424f51068b8a8e762696890a55ab48900ab980))
- branch start, upgrade to compact_str v0.4 ([`b2f56d5`](https://github.com/Byron/gitoxide/commit/b2f56d5a279dae745d9c2c80ebe599c00e72c0d7))
diff --git a/git-attributes/Cargo.toml b/git-attributes/Cargo.toml
index 4c5c2d64f71..16e22eefc3a 100644
--- a/git-attributes/Cargo.toml
+++ b/git-attributes/Cargo.toml
@@ -18,14 +18,14 @@ serde1 = ["serde", "bstr/serde1", "git-glob/serde1", "compact_str/serde"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-git-features = { version = "^0.21.1", path = "../git-features" }
-git-path = { version = "^0.3.0", path = "../git-path" }
+git-features = { version = "^0.22.0", path = "../git-features" }
+git-path = { version = "^0.4.0", path = "../git-path" }
git-quote = { version = "^0.2.0", path = "../git-quote" }
-git-glob = { version = "^0.3.0", path = "../git-glob" }
+git-glob = { version = "^0.3.1", path = "../git-glob" }
bstr = { version = "0.2.13", default-features = false, features = ["std"]}
unicode-bom = "1.1.4"
-quick-error = "2.0.0"
+thiserror = "1.0.26"
serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"]}
compact_str = "0.4"
diff --git a/git-attributes/src/assignment.rs b/git-attributes/src/assignment.rs
new file mode 100644
index 00000000000..e1d7263f768
--- /dev/null
+++ b/git-attributes/src/assignment.rs
@@ -0,0 +1,28 @@
+use crate::{Assignment, AssignmentRef, NameRef, StateRef};
+
+impl<'a> AssignmentRef<'a> {
+ pub(crate) fn new(name: NameRef<'a>, state: StateRef<'a>) -> AssignmentRef<'a> {
+ AssignmentRef { name, state }
+ }
+
+ /// Turn this reference into its owned counterpart.
+ pub fn to_owned(self) -> Assignment {
+ self.into()
+ }
+}
+
+impl<'a> From> for Assignment {
+ fn from(a: AssignmentRef<'a>) -> Self {
+ Assignment {
+ name: a.name.to_owned(),
+ state: a.state.to_owned(),
+ }
+ }
+}
+
+impl<'a> Assignment {
+ /// Provide a ref type to this owned instance.
+ pub fn as_ref(&'a self) -> AssignmentRef<'a> {
+ AssignmentRef::new(self.name.as_ref(), self.state.as_ref())
+ }
+}
diff --git a/git-attributes/src/lib.rs b/git-attributes/src/lib.rs
index ab396eae4b2..6fb14870f67 100644
--- a/git-attributes/src/lib.rs
+++ b/git-attributes/src/lib.rs
@@ -1,10 +1,12 @@
+//! Parse `.gitattribute` and `.gitignore` files and provide utilities to match against them.
+//!
//! ## Feature Flags
#![cfg_attr(
feature = "document-features",
cfg_attr(doc, doc = ::document_features::document_features!())
)]
#![forbid(unsafe_code)]
-#![deny(rust_2018_idioms)]
+#![deny(rust_2018_idioms, missing_docs)]
use std::path::PathBuf;
@@ -12,10 +14,25 @@ use bstr::{BStr, BString};
use compact_str::CompactString;
pub use git_glob as glob;
+mod assignment;
+///
+pub mod name;
+mod state;
+
+mod match_group;
+pub use match_group::{Attributes, Ignore, Match, Pattern};
+
+///
+pub mod parse;
+/// Parse attribute assignments line by line from `bytes`.
+pub fn parse(bytes: &[u8]) -> parse::Lines<'_> {
+ parse::Lines::new(bytes)
+}
+
/// The state an attribute can be in, referencing the value.
///
/// Note that this doesn't contain the name.
-#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
+#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub enum StateRef<'a> {
/// The attribute is listed, or has the special value 'true'
@@ -42,26 +59,44 @@ pub enum State {
Unset,
/// The attribute is set to the given value, which followed the `=` sign.
/// Note that values can be empty.
- Value(CompactString),
+ Value(CompactString), // TODO: use `kstring`, maybe it gets a binary string soon, needs binary, too, no UTF8 is required for attr values
/// The attribute isn't mentioned with a given path or is explicitly set to `Unspecified` using the `!` sign.
Unspecified,
}
+/// Represents a validated attribute name
+#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
+#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
+pub struct Name(pub(crate) CompactString);
+
+/// Holds a validated attribute name as a reference
+#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
+pub struct NameRef<'a>(&'a str);
+
/// Name an attribute and describe it's assigned state.
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct Assignment {
- /// The name of the attribute.
- pub name: CompactString,
+ /// The validated name of the attribute.
+ pub name: Name,
/// The state of the attribute.
pub state: State,
}
+/// Holds validated attribute data as a reference
+#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
+pub struct AssignmentRef<'a> {
+ /// The name of the attribute.
+ pub name: NameRef<'a>,
+ /// The state of the attribute.
+ pub state: StateRef<'a>,
+}
+
/// A grouping of lists of patterns while possibly keeping associated to their base path.
///
/// Pattern lists with base path are queryable relative to that base, otherwise they are relative to the repository root.
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Default)]
-pub struct MatchGroup {
+pub struct MatchGroup {
/// A list of pattern lists, each representing a patterns from a file or specified by hand, in the order they were
/// specified in.
///
@@ -74,7 +109,7 @@ pub struct MatchGroup {
/// Knowing their base which is relative to a source directory, it will ignore all path to match against
/// that don't also start with said base.
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Default)]
-pub struct PatternList {
+pub struct PatternList {
/// Patterns and their associated data in the order they were loaded in or specified,
/// the line number in its source file or its sequence number (_`(pattern, value, line_number)`_).
///
@@ -90,18 +125,13 @@ pub struct PatternList {
pub base: Option,
}
+/// An association of a pattern with its value, along with a sequence number providing a sort order in relation to its peers.
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
pub struct PatternMapping {
+ /// The pattern itself, like `/target/*`
pub pattern: git_glob::Pattern,
+ /// The value associated with the pattern.
pub value: T,
+ /// Typically the line number in the file the pattern was parsed from.
pub sequence_number: usize,
}
-
-mod match_group;
-pub use match_group::{Attributes, Ignore, Match, Pattern};
-
-pub mod parse;
-
-pub fn parse(buf: &[u8]) -> parse::Lines<'_> {
- parse::Lines::new(buf)
-}
diff --git a/git-attributes/src/match_group.rs b/git-attributes/src/match_group.rs
index de3b6d56880..7732762d0af 100644
--- a/git-attributes/src/match_group.rs
+++ b/git-attributes/src/match_group.rs
@@ -1,38 +1,20 @@
+use crate::{Assignment, MatchGroup, PatternList, PatternMapping};
+use bstr::{BStr, BString, ByteSlice, ByteVec};
use std::{
ffi::OsString,
io::Read,
path::{Path, PathBuf},
};
-use bstr::{BStr, BString, ByteSlice, ByteVec};
-
-use crate::{Assignment, MatchGroup, PatternList, PatternMapping, State, StateRef};
-
-impl<'a> From> for State {
- fn from(s: StateRef<'a>) -> Self {
- match s {
- StateRef::Value(v) => State::Value(v.to_str().expect("no illformed unicode").into()),
- StateRef::Set => State::Set,
- StateRef::Unset => State::Unset,
- StateRef::Unspecified => State::Unspecified,
- }
- }
-}
-
-fn attrs_to_assignments<'a>(
- attrs: impl Iterator), crate::parse::Error>>,
-) -> Result, crate::parse::Error> {
- attrs
- .map(|res| {
- res.map(|(name, state)| Assignment {
- name: name.to_str().expect("no illformed unicode").into(),
- state: state.into(),
- })
- })
- .collect()
+fn into_owned_assignments<'a>(
+ attrs: impl Iterator, crate::name::Error>>,
+) -> Result, crate::name::Error> {
+ attrs.map(|res| res.map(|attr| attr.to_owned())).collect()
}
-/// A marker trait to identify the type of a description.
+/// A trait to convert bytes into patterns and their associated value.
+///
+/// This is used for `gitattributes` which have a value, and `gitignore` which don't.
pub trait Pattern: Clone + PartialEq + Eq + std::fmt::Debug + std::hash::Hash + Ord + PartialOrd + Default {
/// The value associated with a pattern.
type Value: PartialEq + Eq + std::fmt::Debug + std::hash::Hash + Ord + PartialOrd + Clone;
@@ -40,10 +22,11 @@ pub trait Pattern: Clone + PartialEq + Eq + std::fmt::Debug + std::hash::Hash +
/// Parse all patterns in `bytes` line by line, ignoring lines with errors, and collect them.
fn bytes_to_patterns(bytes: &[u8]) -> Vec>;
- fn use_pattern(pattern: &git_glob::Pattern) -> bool;
+ /// Returns true if the given pattern may be used for matching.
+ fn may_use_glob_pattern(pattern: &git_glob::Pattern) -> bool;
}
-/// Identify ignore patterns.
+/// An implementation of the [`Pattern`] trait for ignore patterns.
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Default)]
pub struct Ignore;
@@ -60,7 +43,7 @@ impl Pattern for Ignore {
.collect()
}
- fn use_pattern(_pattern: &git_glob::Pattern) -> bool {
+ fn may_use_glob_pattern(_pattern: &git_glob::Pattern) -> bool {
true
}
}
@@ -69,10 +52,10 @@ impl Pattern for Ignore {
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
pub enum Value {
MacroAttributes(Vec),
- Attributes(Vec),
+ Assignments(Vec),
}
-/// Identify patterns with attributes.
+/// An implementation of the [`Pattern`] trait for attributes.
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Default)]
pub struct Attributes;
@@ -82,19 +65,19 @@ impl Pattern for Attributes {
fn bytes_to_patterns(bytes: &[u8]) -> Vec> {
crate::parse(bytes)
.filter_map(Result::ok)
- .filter_map(|(pattern_kind, attrs, line_number)| {
+ .filter_map(|(pattern_kind, assignments, line_number)| {
let (pattern, value) = match pattern_kind {
crate::parse::Kind::Macro(macro_name) => (
git_glob::Pattern {
- text: macro_name,
+ text: macro_name.as_str().into(),
mode: git_glob::pattern::Mode::all(),
first_wildcard_pos: None,
},
- Value::MacroAttributes(attrs_to_assignments(attrs).ok()?),
+ Value::MacroAttributes(into_owned_assignments(assignments).ok()?),
),
crate::parse::Kind::Pattern(p) => (
(!p.is_negative()).then(|| p)?,
- Value::Attributes(attrs_to_assignments(attrs).ok()?),
+ Value::Assignments(into_owned_assignments(assignments).ok()?),
),
};
PatternMapping {
@@ -107,7 +90,7 @@ impl Pattern for Attributes {
.collect()
}
- fn use_pattern(pattern: &git_glob::Pattern) -> bool {
+ fn may_use_glob_pattern(pattern: &git_glob::Pattern) -> bool {
pattern.mode != git_glob::pattern::Mode::all()
}
}
@@ -115,6 +98,7 @@ impl Pattern for Attributes {
/// Describes a matching value within a [`MatchGroup`].
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
pub struct Match<'a, T> {
+ /// The glob pattern itself, like `/target/*`.
pub pattern: &'a git_glob::Pattern,
/// The value associated with the pattern.
pub value: &'a T,
@@ -199,6 +183,8 @@ impl MatchGroup {
Ok(self.patterns.len() != previous_len)
}
+ /// Add patterns as parsed from `bytes`, providing their `source` path and possibly their `root` path, the path they
+ /// are relative to. This also means that `source` is contained within `root` if `root` is provided.
pub fn add_patterns_buffer(&mut self, bytes: &[u8], source: impl Into, root: Option<&Path>) {
self.patterns
.push(PatternList::::from_bytes(bytes, source.into(), root));
@@ -248,6 +234,9 @@ where
base,
}
}
+
+ /// Create a pattern list from the `source` file, which may be located underneath `root`, while optionally
+ /// following symlinks with `follow_symlinks`, providing `buf` to temporarily store the data contained in the file.
pub fn from_file(
source: impl Into,
root: Option<&Path>,
@@ -263,6 +252,9 @@ impl PatternList
where
T: Pattern,
{
+ /// Return a match if a pattern matches `relative_path`, providing a pre-computed `basename_pos` which is the
+ /// starting position of the basename of `relative_path`. `is_dir` is true if `relative_path` is a directory.
+ /// `case` specifies whether cases should be folded during matching or not.
pub fn pattern_matching_relative_path(
&self,
relative_path: &BStr,
@@ -275,7 +267,7 @@ where
self.patterns
.iter()
.rev()
- .filter(|pm| T::use_pattern(&pm.pattern))
+ .filter(|pm| T::may_use_glob_pattern(&pm.pattern))
.find_map(
|PatternMapping {
pattern,
@@ -294,6 +286,8 @@ where
)
}
+ /// Like [`pattern_matching_relative_path()`][Self::pattern_matching_relative_path()], but returns an index to the pattern
+ /// that matched `relative_path`, instead of the match itself.
pub fn pattern_idx_matching_relative_path(
&self,
relative_path: &BStr,
@@ -307,7 +301,7 @@ where
.iter()
.enumerate()
.rev()
- .filter(|(_, pm)| T::use_pattern(&pm.pattern))
+ .filter(|(_, pm)| T::may_use_glob_pattern(&pm.pattern))
.find_map(|(idx, pm)| {
pm.pattern
.matches_repo_relative_path(relative_path, basename_start_pos, is_dir, case)
diff --git a/git-attributes/src/name.rs b/git-attributes/src/name.rs
new file mode 100644
index 00000000000..bc213f88ed9
--- /dev/null
+++ b/git-attributes/src/name.rs
@@ -0,0 +1,46 @@
+use crate::{Name, NameRef};
+use bstr::BString;
+
+impl<'a> NameRef<'a> {
+ /// Turn this ref into its owned counterpart.
+ pub fn to_owned(self) -> Name {
+ Name(self.0.into())
+ }
+
+ /// Return the inner `str`.
+ pub fn as_str(&self) -> &str {
+ self.0
+ }
+}
+
+impl AsRef for NameRef<'_> {
+ fn as_ref(&self) -> &str {
+ self.0
+ }
+}
+
+impl<'a> Name {
+ /// Provide our ref-type.
+ pub fn as_ref(&'a self) -> NameRef<'a> {
+ NameRef(self.0.as_ref())
+ }
+
+ /// Return the inner `str`.
+ pub fn as_str(&self) -> &str {
+ self.0.as_str()
+ }
+}
+
+impl AsRef for Name {
+ fn as_ref(&self) -> &str {
+ self.0.as_str()
+ }
+}
+
+/// The error returned by [`parse::Iter`][crate::parse::Iter].
+#[derive(Debug, thiserror::Error)]
+#[error("Attribute has non-ascii characters or starts with '-': {attribute}")]
+pub struct Error {
+ /// The attribute that failed to parse.
+ pub attribute: BString,
+}
diff --git a/git-attributes/src/parse/attribute.rs b/git-attributes/src/parse/attribute.rs
index 064e78a4a17..148eb760539 100644
--- a/git-attributes/src/parse/attribute.rs
+++ b/git-attributes/src/parse/attribute.rs
@@ -1,101 +1,89 @@
+use crate::{name, AssignmentRef, Name, NameRef, StateRef};
+use bstr::{BStr, ByteSlice};
use std::borrow::Cow;
-use bstr::{BStr, BString, ByteSlice};
-
+/// The kind of attribute that was parsed.
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub enum Kind {
/// A pattern to match paths against
Pattern(git_glob::Pattern),
/// The name of the macro to define, always a valid attribute name
- // TODO: turn it into its own type for maximum safety
- Macro(BString),
+ Macro(Name),
}
mod error {
use bstr::BString;
- use quick_error::quick_error;
-
- quick_error! {
- #[derive(Debug)]
- pub enum Error {
- PatternNegation { line_number: usize, line: BString } {
- display("Line {} has a negative pattern, for literal characters use \\!: {}", line_number, line)
- }
- AttributeName { line_number: usize, attribute: BString } {
- display("Attribute in line {} has non-ascii characters or starts with '-': {}", line_number, attribute)
- }
- MacroName { line_number: usize, macro_name: BString } {
- display("Macro in line {} has non-ascii characters or starts with '-': {}", line_number, macro_name)
- }
- Unquote(err: git_quote::ansi_c::undo::Error) {
- display("Could not unquote attributes line")
- from()
- source(err)
- }
- }
+ /// The error returned by [`parse::Lines`][crate::parse::Lines].
+ #[derive(thiserror::Error, Debug)]
+ #[allow(missing_docs)]
+ pub enum Error {
+ #[error("Line {line_number} has a negative pattern, for literal characters use \\!: {line}")]
+ PatternNegation { line_number: usize, line: BString },
+ #[error("Attribute in line {line_number} has non-ascii characters or starts with '-': {attribute}")]
+ AttributeName { line_number: usize, attribute: BString },
+ #[error("Macro in line {line_number} has non-ascii characters or starts with '-': {macro_name}")]
+ MacroName { line_number: usize, macro_name: BString },
+ #[error("Could not unquote attributes line")]
+ Unquote(#[from] git_quote::ansi_c::undo::Error),
}
}
pub use error::Error;
+/// An iterator over attribute assignments, parsed line by line.
pub struct Lines<'a> {
lines: bstr::Lines<'a>,
line_no: usize,
}
+/// An iterator over attribute assignments in a single line.
pub struct Iter<'a> {
attrs: bstr::Fields<'a>,
- line_no: usize,
}
impl<'a> Iter<'a> {
- pub fn new(attrs: &'a BStr, line_no: usize) -> Self {
- Iter {
- attrs: attrs.fields(),
- line_no,
- }
+ /// Create a new instance to parse attribute assignments from `input`.
+ pub fn new(input: &'a BStr) -> Self {
+ Iter { attrs: input.fields() }
}
- fn parse_attr(&self, attr: &'a [u8]) -> Result<(&'a BStr, crate::StateRef<'a>), Error> {
+ fn parse_attr(&self, attr: &'a [u8]) -> Result, name::Error> {
let mut tokens = attr.splitn(2, |b| *b == b'=');
let attr = tokens.next().expect("attr itself").as_bstr();
let possibly_value = tokens.next();
let (attr, state) = if attr.first() == Some(&b'-') {
- (&attr[1..], crate::StateRef::Unset)
+ (&attr[1..], StateRef::Unset)
} else if attr.first() == Some(&b'!') {
- (&attr[1..], crate::StateRef::Unspecified)
+ (&attr[1..], StateRef::Unspecified)
} else {
(
attr,
possibly_value
- .map(|v| crate::StateRef::Value(v.as_bstr()))
- .unwrap_or(crate::StateRef::Set),
+ .map(|v| StateRef::Value(v.as_bstr()))
+ .unwrap_or(StateRef::Set),
)
};
- Ok((check_attr(attr, self.line_no)?, state))
+ Ok(AssignmentRef::new(check_attr(attr)?, state))
}
}
-fn check_attr(attr: &BStr, line_number: usize) -> Result<&BStr, Error> {
+fn check_attr(attr: &BStr) -> Result, name::Error> {
fn attr_valid(attr: &BStr) -> bool {
if attr.first() == Some(&b'-') {
return false;
}
- attr.bytes().all(|b| {
- matches!(b,
- b'-' | b'.' | b'_' | b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9')
- })
+ attr.bytes()
+ .all(|b| matches!(b, b'-' | b'.' | b'_' | b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9'))
}
- attr_valid(attr).then(|| attr).ok_or_else(|| Error::AttributeName {
- line_number,
- attribute: attr.into(),
- })
+ attr_valid(attr)
+ .then(|| NameRef(attr.to_str().expect("no illformed utf8")))
+ .ok_or_else(|| name::Error { attribute: attr.into() })
}
impl<'a> Iterator for Iter<'a> {
- type Item = Result<(&'a BStr, crate::StateRef<'a>), Error>;
+ type Item = Result, name::Error>;
fn next(&mut self) -> Option {
let attr = self.attrs.next().filter(|a| !a.is_empty())?;
@@ -104,10 +92,11 @@ impl<'a> Iterator for Iter<'a> {
}
impl<'a> Lines<'a> {
- pub fn new(buf: &'a [u8]) -> Self {
- let bom = unicode_bom::Bom::from(buf);
+ /// Create a new instance to parse all attributes in all lines of the input `bytes`.
+ pub fn new(bytes: &'a [u8]) -> Self {
+ let bom = unicode_bom::Bom::from(bytes);
Lines {
- lines: buf[bom.len()..].lines(),
+ lines: bytes[bom.len()..].lines(),
line_no: 0,
}
}
@@ -153,14 +142,11 @@ fn parse_line(line: &BStr, line_number: usize) -> Option,
};
let kind_res = match line.strip_prefix(b"[attr]") {
- Some(macro_name) => check_attr(macro_name.into(), line_number)
- .map(|m| Kind::Macro(m.into()))
- .map_err(|err| match err {
- Error::AttributeName { line_number, attribute } => Error::MacroName {
- line_number,
- macro_name: attribute,
- },
- _ => unreachable!("BUG: check_attr() must only return attribute errors"),
+ Some(macro_name) => check_attr(macro_name.into())
+ .map(|name| Kind::Macro(name.to_owned()))
+ .map_err(|err| Error::MacroName {
+ line_number,
+ macro_name: err.attribute,
}),
None => {
let pattern = git_glob::Pattern::from_bytes(line.as_ref())?;
@@ -178,7 +164,7 @@ fn parse_line(line: &BStr, line_number: usize) -> Option,
Ok(kind) => kind,
Err(err) => return Some(Err(err)),
};
- Ok((kind, Iter::new(attrs, line_number), line_number)).into()
+ Ok((kind, Iter::new(attrs), line_number)).into()
}
const BLANKS: &[u8] = b" \t\r";
diff --git a/git-attributes/src/parse/ignore.rs b/git-attributes/src/parse/ignore.rs
index 71c29904ba2..d9d9e2038c0 100644
--- a/git-attributes/src/parse/ignore.rs
+++ b/git-attributes/src/parse/ignore.rs
@@ -1,11 +1,13 @@
use bstr::ByteSlice;
+/// An iterator over line-wise ignore patterns parsed from a buffer.
pub struct Lines<'a> {
lines: bstr::Lines<'a>,
line_no: usize,
}
impl<'a> Lines<'a> {
+ /// Create a new instance from `buf` to parse ignore patterns from.
pub fn new(buf: &'a [u8]) -> Self {
let bom = unicode_bom::Bom::from(buf);
Lines {
diff --git a/git-attributes/src/parse/mod.rs b/git-attributes/src/parse/mod.rs
index 5bbd86f5bd4..82cacc8ed02 100644
--- a/git-attributes/src/parse/mod.rs
+++ b/git-attributes/src/parse/mod.rs
@@ -1,8 +1,10 @@
+///
pub mod ignore;
mod attribute;
pub use attribute::{Error, Iter, Kind, Lines};
-pub fn ignore(buf: &[u8]) -> ignore::Lines<'_> {
- ignore::Lines::new(buf)
+/// Parse git ignore patterns, line by line, from `bytes`.
+pub fn ignore(bytes: &[u8]) -> ignore::Lines<'_> {
+ ignore::Lines::new(bytes)
}
diff --git a/git-attributes/src/state.rs b/git-attributes/src/state.rs
new file mode 100644
index 00000000000..3ae275492e6
--- /dev/null
+++ b/git-attributes/src/state.rs
@@ -0,0 +1,32 @@
+use crate::{State, StateRef};
+use bstr::ByteSlice;
+
+impl<'a> StateRef<'a> {
+ /// Turn ourselves into our owned counterpart.
+ pub fn to_owned(self) -> State {
+ self.into()
+ }
+}
+
+impl<'a> State {
+ /// Turn ourselves into our ref-type.
+ pub fn as_ref(&'a self) -> StateRef<'a> {
+ match self {
+ State::Value(v) => StateRef::Value(v.as_bytes().as_bstr()),
+ State::Set => StateRef::Set,
+ State::Unset => StateRef::Unset,
+ State::Unspecified => StateRef::Unspecified,
+ }
+ }
+}
+
+impl<'a> From> for State {
+ fn from(s: StateRef<'a>) -> Self {
+ match s {
+ StateRef::Value(v) => State::Value(v.to_str().expect("no illformed unicode").into()),
+ StateRef::Set => State::Set,
+ StateRef::Unset => State::Unset,
+ StateRef::Unspecified => State::Unspecified,
+ }
+ }
+}
diff --git a/git-attributes/tests/parse/attribute.rs b/git-attributes/tests/parse/attribute.rs
index c4306c70cd0..1c6b9ca90a3 100644
--- a/git-attributes/tests/parse/attribute.rs
+++ b/git-attributes/tests/parse/attribute.rs
@@ -1,4 +1,4 @@
-use bstr::{BStr, ByteSlice};
+use bstr::{BString, ByteSlice};
use git_attributes::{parse, StateRef};
use git_glob::pattern::Mode;
use git_testtools::fixture_bytes;
@@ -119,16 +119,28 @@ fn invalid_escapes_in_quotes_are_an_error() {
#[test]
fn custom_macros_can_be_differentiated() {
- assert_eq!(
- line(r#"[attr]foo bar -baz"#),
- (macro_(r"foo"), vec![set("bar"), unset("baz")], 1)
- );
+ let output = line(r#"[attr]foo bar -baz"#);
+ match output.0 {
+ parse::Kind::Pattern(_) => unreachable!(),
+ parse::Kind::Macro(name) => {
+ assert_eq!(
+ (name.as_str(), output.1, output.2),
+ (r"foo", vec![set("bar"), unset("baz")], 1)
+ );
+ }
+ }
- assert_eq!(
- line(r#""[attr]foo" bar -baz"#),
- (macro_(r"foo"), vec![set("bar"), unset("baz")], 1),
- "it works after unquoting even, making it harder to denote a file name with [attr] prefix"
- );
+ let output = line(r#""[attr]foo" bar -baz"#);
+ match output.0 {
+ parse::Kind::Pattern(_) => unreachable!(),
+ parse::Kind::Macro(name) => {
+ assert_eq!(
+ (name.as_str(), output.1, output.2),
+ (r"foo", vec![set("bar"), unset("baz")], 1),
+ "it works after unquoting even, making it harder to denote a file name with [attr] prefix"
+ );
+ }
+ }
}
#[test]
@@ -249,22 +261,22 @@ fn trailing_whitespace_in_attributes_is_ignored() {
);
}
-type ExpandedAttribute<'a> = (parse::Kind, Vec<(&'a BStr, git_attributes::StateRef<'a>)>, usize);
+type ExpandedAttribute<'a> = (parse::Kind, Vec<(BString, git_attributes::StateRef<'a>)>, usize);
-fn set(attr: &str) -> (&BStr, StateRef) {
- (attr.as_bytes().as_bstr(), StateRef::Set)
+fn set(attr: &str) -> (BString, StateRef) {
+ (attr.into(), StateRef::Set)
}
-fn unset(attr: &str) -> (&BStr, StateRef) {
- (attr.as_bytes().as_bstr(), StateRef::Unset)
+fn unset(attr: &str) -> (BString, StateRef) {
+ (attr.into(), StateRef::Unset)
}
-fn unspecified(attr: &str) -> (&BStr, StateRef) {
- (attr.as_bytes().as_bstr(), StateRef::Unspecified)
+fn unspecified(attr: &str) -> (BString, StateRef) {
+ (attr.into(), StateRef::Unspecified)
}
-fn value<'a, 'b>(attr: &'a str, value: &'b str) -> (&'a BStr, StateRef<'b>) {
- (attr.as_bytes().as_bstr(), StateRef::Value(value.as_bytes().as_bstr()))
+fn value<'a, 'b>(attr: &'a str, value: &'b str) -> (BString, StateRef<'b>) {
+ (attr.into(), StateRef::Value(value.as_bytes().as_bstr()))
}
fn pattern(name: &str, flags: git_glob::pattern::Mode, first_wildcard_pos: Option) -> parse::Kind {
@@ -275,10 +287,6 @@ fn pattern(name: &str, flags: git_glob::pattern::Mode, first_wildcard_pos: Optio
})
}
-fn macro_(name: &str) -> parse::Kind {
- parse::Kind::Macro(name.into())
-}
-
fn try_line(input: &str) -> Result {
let mut lines = git_attributes::parse(input.as_bytes());
let res = expand(lines.next().unwrap())?;
@@ -298,6 +306,12 @@ fn expand(
input: Result<(parse::Kind, parse::Iter<'_>, usize), parse::Error>,
) -> Result, parse::Error> {
let (pattern, attrs, line_no) = input?;
- let attrs = attrs.collect::, _>>()?;
+ let attrs = attrs
+ .map(|r| r.map(|attr| (attr.name.as_str().into(), attr.state)))
+ .collect::, _>>()
+ .map_err(|e| parse::Error::AttributeName {
+ attribute: e.attribute,
+ line_number: line_no,
+ })?;
Ok((pattern, attrs, line_no))
}
diff --git a/git-bitmap/src/ewah.rs b/git-bitmap/src/ewah.rs
index 9b42ffda2c5..3cd4502e4ab 100644
--- a/git-bitmap/src/ewah.rs
+++ b/git-bitmap/src/ewah.rs
@@ -21,7 +21,7 @@ pub fn decode(data: &[u8]) -> Result<(Vec, &[u8]), decode::Error> {
let (len, data) = decode::u32(data).ok_or(Error::Corrupt("eof reading chunk length"))?;
let len = len as usize;
- // NOTE: git does this by copying all bytes first, and then it will change the endianess in a separate loop.
+ // NOTE: git does this by copying all bytes first, and then it will change the endianness in a separate loop.
// Maybe it's faster, but we can't do it without unsafe. Let's leave it to the optimizer and maybe
// one day somebody will find out that it's worth it to use unsafe here.
let (mut bits, data) = decode::split_at_pos(data, len * std::mem::size_of::())
diff --git a/git-commitgraph/CHANGELOG.md b/git-commitgraph/CHANGELOG.md
index f707d9c999b..afc356a7b66 100644
--- a/git-commitgraph/CHANGELOG.md
+++ b/git-commitgraph/CHANGELOG.md
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-## Unreleased
+## 0.8.0 (2022-07-22)
A maintenance release without user-facing changes.
@@ -13,8 +13,8 @@ A maintenance release without user-facing changes.
- - 4 commits contributed to the release over the course of 59 calendar days.
- - 70 days passed between releases.
+ - 10 commits contributed to the release over the course of 99 calendar days.
+ - 110 days passed between releases.
- 0 commits where understood as [conventional](https://www.conventionalcommits.org).
- 1 unique issue was worked on: [#384](https://github.com/Byron/gitoxide/issues/384)
@@ -29,6 +29,12 @@ A maintenance release without user-facing changes.
- add archive files via git-lfs ([`7202a1c`](https://github.com/Byron/gitoxide/commit/7202a1c4734ad904c026ee3e4e2143c0461d51a2))
- auto-set commit.gpgsign=false when executing git ([`c23feb6`](https://github.com/Byron/gitoxide/commit/c23feb64ad157180cfba8a11c882b829733ea8f6))
* **Uncategorized**
+ - Release git-config v0.6.0, git-credentials v0.3.0, git-diff v0.17.0, git-discover v0.3.0, git-index v0.4.0, git-mailmap v0.3.0, git-traverse v0.16.0, git-pack v0.21.0, git-odb v0.31.0, git-url v0.7.0, git-transport v0.19.0, git-protocol v0.18.0, git-revision v0.3.0, git-worktree v0.4.0, git-repository v0.20.0, git-commitgraph v0.8.0, gitoxide-core v0.15.0, gitoxide v0.13.0 ([`aa639d8`](https://github.com/Byron/gitoxide/commit/aa639d8c43f3098cc4a5b50614c5ae94a8156928))
+ - Release git-hash v0.9.6, git-features v0.22.0, git-date v0.0.2, git-actor v0.11.0, git-glob v0.3.1, git-path v0.4.0, git-attributes v0.3.0, git-tempfile v2.0.2, git-object v0.20.0, git-ref v0.15.0, git-sec v0.3.0, git-config v0.6.0, git-credentials v0.3.0, git-diff v0.17.0, git-discover v0.3.0, git-index v0.4.0, git-mailmap v0.3.0, git-traverse v0.16.0, git-pack v0.21.0, git-odb v0.31.0, git-url v0.7.0, git-transport v0.19.0, git-protocol v0.18.0, git-revision v0.3.0, git-worktree v0.4.0, git-repository v0.20.0, git-commitgraph v0.8.0, gitoxide-core v0.15.0, gitoxide v0.13.0, safety bump 22 crates ([`4737b1e`](https://github.com/Byron/gitoxide/commit/4737b1eea1d4c9a8d5a69fb63ecac5aa5d378ae5))
+ - prepare changelog prior to release ([`3c50625`](https://github.com/Byron/gitoxide/commit/3c50625fa51350ec885b0f38ec9e92f9444df0f9))
+ - assure document-features are available in all 'usable' and 'early' crates ([`238581c`](https://github.com/Byron/gitoxide/commit/238581cc46c7288691eed37dc7de5069e3d86721))
+ - Release git-date v0.0.1, git-hash v0.9.5, git-features v0.21.1, git-actor v0.10.1, git-path v0.2.0, git-attributes v0.2.0, git-ref v0.14.0, git-sec v0.2.0, git-config v0.5.0, git-credentials v0.2.0, git-discover v0.2.0, git-pack v0.20.0, git-odb v0.30.0, git-url v0.6.0, git-transport v0.18.0, git-protocol v0.17.0, git-revision v0.2.1, git-worktree v0.3.0, git-repository v0.19.0, safety bump 13 crates ([`a417177`](https://github.com/Byron/gitoxide/commit/a41717712578f590f04a33d27adaa63171f25267))
+ - update changelogs prior to release ([`bb424f5`](https://github.com/Byron/gitoxide/commit/bb424f51068b8a8e762696890a55ab48900ab980))
- Release git-hash v0.9.4, git-features v0.21.0, git-actor v0.10.0, git-glob v0.3.0, git-path v0.1.1, git-attributes v0.1.0, git-sec v0.1.0, git-config v0.3.0, git-credentials v0.1.0, git-validate v0.5.4, git-object v0.19.0, git-diff v0.16.0, git-lock v2.1.0, git-ref v0.13.0, git-discover v0.1.0, git-index v0.3.0, git-mailmap v0.2.0, git-traverse v0.15.0, git-pack v0.19.0, git-odb v0.29.0, git-packetline v0.12.5, git-url v0.5.0, git-transport v0.17.0, git-protocol v0.16.0, git-revision v0.2.0, git-worktree v0.2.0, git-repository v0.17.0, safety bump 20 crates ([`654cf39`](https://github.com/Byron/gitoxide/commit/654cf39c92d5aa4c8d542a6cadf13d4acef6a78e))
diff --git a/git-commitgraph/Cargo.toml b/git-commitgraph/Cargo.toml
index cb7f7d80b43..c457a182d97 100644
--- a/git-commitgraph/Cargo.toml
+++ b/git-commitgraph/Cargo.toml
@@ -17,8 +17,8 @@ doctest = false
serde1 = ["serde", "git-hash/serde1", "bstr/serde1"]
[dependencies]
-git-features = { version = "^0.21.1", path = "../git-features", features = ["rustsha1"] }
-git-hash = { version = "^0.9.5", path = "../git-hash" }
+git-features = { version = "^0.22.0", path = "../git-features", features = ["rustsha1"] }
+git-hash = { version = "^0.9.6", path = "../git-hash" }
git-chunk = { version = "^0.3.0", path = "../git-chunk" }
bstr = { version = "0.2.13", default-features = false, features = ["std"] }
diff --git a/git-config/CHANGELOG.md b/git-config/CHANGELOG.md
index 1bce4477ff0..1fe15e2ddba 100644
--- a/git-config/CHANGELOG.md
+++ b/git-config/CHANGELOG.md
@@ -5,6 +5,565 @@ 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.6.0 (2022-07-22)
+
+
+
+
+
+
+### New Features
+
+ - following includes is now non-fatal by default
+ Otherwise it would be relatively easy to fail gitoxide startup,
+ and we want to be closer to the behaviour in git which ignores
+ most of the errors.
+ - `File::from_git_dir()` as comfortable way to instantiate most complete git configuration.
+ - `File` now compares actual content, ignoring whitespace and comments.
+ - `File::new_environment_overrides()` to easily instantiate overrides from the environment.
+ - `File::new_globals()` can instantiate non-local configuration with zero-configuration.
+ - `Source::storage_location()` to know where files should be located.
+ - `file::ValueMut::(section|into_section_mut)()` to go from value to the owning section.
+ This can be useful if the value was obtained using `raw_value_mut()`.
+ - `Source::is_in_repository()` to find out if a source is in the repository.
+ - `parse::key` to parse a `remote.origin.url`-like key to identify a value
+ - Add `File::detect_newline_style()`, which does at it says.
+ - `File::frontmatter()` and `File::sections_and_postmatter()`.
+ - `parse::Event::to_bstr_lossy()` to get a glimpse at event content.
+ - `File::append()` can append one file to another rather losslessly.
+ The loss happens as we, maybe for the wrong reasons, automatically
+ insert newlines where needed which can only be done while we still know
+ the file boundaries.
+ - `file::Section::meta()` to access a section's metadata.
+ - `File::sections()` to obtain an iterator over all sections, in order.
+ - place spaces around `key = value` pairs, or whatever is used in the source configuration.
+ - proper escaping of value bytes to allow round-tripping after mutation
+ - whitespace in newly pushed keys is derived from first section value.
+ That way, newly added key-value pairs look like they should assuming
+ all keys have the same indentation as the first key in the section.
+
+ If there is no key, then the default whitespace will be double-tabs
+ like what's commmon in git.
+ - `File::from_str()` implementation, to support `let config: File = "[core]".parse()?`
+ - whitespace in mutable sections can be finely controlled, and is derived from existing sections
+ - `parse::Header::new(…)` with sub-section name validation
+ - Add `parse::(Event|section::Header|Comment)::write_to(…)`.
+ Now it's possible to serialize these types in a streaming fashion and
+ without arbitrarily enforcing UTF-8 on it
+ - `serde1` feature to add limited serde support
+
+### Bug Fixes
+
+ - maintain insertion order of includes on per-section basis at least.
+ Note that git inserts values right after the include directive,
+ 'splitting' the section, but we don't do that and insert new values
+ after the section. Probably no issue in practice while keeping
+ our implementation simple.
+ - maintain newline format depending on what's present or use platform default.
+ Previously implicit newlines when adding new sections or keys to
+ sections was always `\n` which isn't correct on windows.
+
+ Now the newline style is detected and used according to what's present,
+ or in the lack of content, defaults to what's correct for the platform.
+ - validate incoming conifguration keys when interpreting envirnoment variables.
+ - `Boolean` can use numbers to indicate true or false, drops support for `one` and `zero`.
+ - `file::MutableSection::remove()` now actually removes keys _and_ values.
+ - `file::MutableMultiValue` escapes input values and maintains key separator specific whitespace.
+ - value normalization (via `value::normalize()` handles escape sequences.
+ The latter ones are `\n`, `\t` and `\b` which are the only supported
+ ones in values of git-config files.
+ - stable sort order for `File::sections_by_name_with_header()`
+ - count newlines (for error display) in multi-line values as well
+ - auto-normalize string values to support quote removal in case of strings.
+ Related to https://github.com/starship/starship/pull/3883 .
+
+### Other
+
+ - :Events::from_bytes()` with `filter` support.
+
+### Changed (BREAKING)
+
+ - add `File::resolve_includes()` and move its error type to `file::includes`.
+ - add `File::from_bytes_owned()` and remove `File::from_path_with_buf()`
+ - remove `File::from_env_paths()`.
+ It's replaced by its more comfortable `new_globals()`.
+ - untangle `file::init::…` `Option` and `Error` types.
+ This moves types to where they belong which is more specific instead
+ of having a catch-all `Error` and `Options` type.
+ - rename `parse::Comment::(comment_tag|comment)` to `::tag|text` and `parse::Section::section_header` to `::header`.
+ - Associate `file::Metadata` with each `File`.
+ This is the first step towards knowing more about the source of each
+ value to filter them based on some properties.
+
+ This breaks various methods handling the instantiation of configuration
+ files as `file::Metadata` typically has to be provided by the caller
+ now or be associated with each path to read configuration from.
+ - rename `file::SectionBody` to `file::section::Body`.
+ - Remove `File::sections_by_name_with_header()` as `::sections_by_name()` now returns entire sections.
+ - create `resolve_includes` options to make space for more options when loading paths.
+ - rename `path::Options` into `path::Context`.
+ It's not an option if it's required context to perform a certain
+ operation.
+ - All accessors in `File` are now using `impl AsRef` where possible for added comfort.
+ - Much more comfortable API `file::*Mut` types thanks to `impl Into/AsRef`.
+ - Rename `Mutable*` into `$1Mut` for consistency.
+ - conform APIs of `file::MutableValue` and `file::MutableMultiValue`.
+ There are more renames and removals than worth mentioning here given the
+ current adoption of the crate.
+ - rename `file::MutableSection::set_leading_space()` to `set_leading_whitespace()`.
+ The corresponding getter was renamed as well to `leading_whitespace()`.
+ - Enforce `parse::section::Header::new()` by making its fields private.
+ - Add `File::write_to()` and `File::to_bstring()`; remove some `TryFrom` impls.
+ Now `File` can be serialized in a streaming fashion and without the
+ possibility for UTF8 conversion issues.
+
+ Note that `Display` is still imlpemented with the usual caveats.
+ - remove `Integer::to_bstring()` as well as some `TryFrom` impls.
+ Note that it can still display itself like before via
+ `std::fmt::Display`.
+ - remove `Boolean::to_bstring()` along with a few `From` impls.
+ These were superfluous and aren't useful in practice.
+ Note that serialization is still implemented via `Display`.
+ - allocation free `File::sections_by_name()` and `File::sections_by_name_with_header()`.
+ - `Path::interpolate()` now takes `path::interpolate::Options` instead of three parameters.
+ - remove `String` type in favor of referring to the `File::string()` method.
+ The wrapper had no effect whatsoever except for adding complexity.
+ - Simplify `Boolean` to be a wrapper around `bool`.
+ Previously it tried hard not to degenerate information, making it a
+ complicated type.
+
+ However, in practice nobody cares about the exact makeup of the boolean,
+ and there is no need to serialize a boolean faithfully either.
+
+ Instead, those who want to set a value just set any value as a string,
+ no need for type safety there, and we take care of escaping values
+ properly on write.
+ - Use bitflags for `color::Attribute` instead of `Vec` of enums.
+ This is less wasteful and sufficient for git, so it should be sufficient
+ for us, especially since attributes are indeed a set and declaring
+ one twice has no effect.
+ - simplify `Color` API.
+ For now we only parse and serialize for display, but more uses are
+ enabled when needed and trivially.
+ - remove `parse::Events::from_path` and `File::at`
+ The latter has been replaced with `File::from_path_with_buf(…)` and
+ is a low-level way to load just a single config file, purposefully
+ uncomfortable as it will not resolve includes.
+
+ The initialization API will need some time to stabilize.
+ - Slim down API surface of `parse::Events`.
+ It's more of a 'dumb' structure now than before, merely present
+ to facilitate typical parsing than something special on its own.
+ - remove `File::new()` method in favor of `File::default()`.
+ - rename `parse::event::List` to `parse::Events`
+ - rename `parse::State` to `parse::event::List`
+ - move `value::*` into the crate root, except for `Error` and `normalize_*()`.
+ - rename `value::parse::Error` to `value::Error`.
+ - rename `value::TrueVariant` to `value::boolean::True`
+ - rename `IntegerSuffix` to `integer::Suffix`
+ - rename `value::Color(Attribute|Value)` to `value::color::Attribute` and `value::color::Name`.
+ - Turn `parse::ParseOrIoError` into `parse::state::from_path::Error`
+ - rename `parse::ParsedComment` into `parse::Comment`
+ - rename `parse::Section*` related types.
+ These are now located in `section::*`.
+ - rename `parse::Parser` to `parse::State`.
+ Furthermore, make `State` the entry point for all parsing, removing
+ all free-standing functions that returned a `State`.
+ - rename `parser` module to `parse`
+ - rename `normalize_cow()` to `normalize()` and move all `normalize*` functions from `values` to the `value` module
+ - move `Path` from `values` to `value` module
+ - Move `Boolean` and `String` from `values` into `value` module
+ - move `values::Integer` into `value` module
+ - move `Color` to own `value` module
+ - remove `values::Bytes` - use `values::String` instead.
+ Note that these values are always normalized and it's only possible
+ to get a raw values using the `raw_value()` API.
+
+### New Features (BREAKING)
+
+ - Support for `lossy` load mode.
+ There is a lot of breaking changes as `file::from_paths::Options` now
+ became `file::init::Options`, and the same goes for the error type.
+ - add `_filter()` versions to most access methods.
+ That way it's possible to filter values by their origin.
+
+ Note that the `remove_section()` methods now return the entire
+ removed section, not just the body, which yields more information
+ than before including section metadata.
+ - section names are now validated.
+ - filtering supportort for `parse::Events`.
+ That way it's possible to construct Files which are not destined to be
+ written back as they only keep events necessary for value access,
+ greatly reducing allocations.
+ - change mostily internal uses of [u8] to BString/BStr
+ - Path-interpolation makes `home-dir` configurable.
+ That way the caller has full control over how the environment is used,
+ which also allows more fine-grained control over which config files
+ can be included.
+
+### Bug Fixes (BREAKING)
+
+ - Simplify specifying keys when mutating config values.
+ - `File::rename_section()` with validation of input arguments.
+ - improve normalization; assure no extra copies are made on query.
+ We now return our own content, rather than the originals with their
+ lifetimes, meaning we bind lifetimes of returned values to our own
+ `File` instance. This allows them to be referenced more often, and
+ smarter normalization assures we don't copy in the simple cases
+ either.
+
+ More tests were added as well.
+ This is breaking as lifetime changes can cause distruptions, and
+ `values?_as()` was removed as well as it's somewhat duplicate
+ to higher-level APIs and it wasn't tested at all.
+ - Remove `git-config` test utilities from `git-path`.
+
+### Other (BREAKING)
+
+ - `File::raw_multi_value()` to `File::raw_values()`
+ - `File::raw_multi_value_mut()` to `File::raw_values_mut()`
+ - `File::multi_value()` to `File::values()`.
+ The latter is better in line with `string()/strings()`
+
+### Commit Statistics
+
+
+
+ - 314 commits contributed to the release over the course of 33 calendar days.
+ - 39 days passed between releases.
+ - 93 commits where understood as [conventional](https://www.conventionalcommits.org).
+ - 1 unique issue was worked on: [#331](https://github.com/Byron/gitoxide/issues/331)
+
+### Thanks Clippy
+
+
+
+[Clippy](https://github.com/rust-lang/rust-clippy) helped 19 times to make code idiomatic.
+
+### Commit Details
+
+
+
+view details
+
+ * **[#331](https://github.com/Byron/gitoxide/issues/331)**
+ - final documentation review + adjustments prior to release candidate ([`06b86e0`](https://github.com/Byron/gitoxide/commit/06b86e05dd9a712d26456b43c8da0a11870f08df))
+ - refactor ([`4dc6594`](https://github.com/Byron/gitoxide/commit/4dc6594686478d9d6cd09e2ba02048624c3577e7))
+ - exclude particular assertion which fails on the linux CI. ([`5e0f889`](https://github.com/Byron/gitoxide/commit/5e0f889c1edb862d698a2d344a61f12ab3b6ade7))
+ - first sketch of using configuration and environment variables for author/committer ([`330d0a1`](https://github.com/Byron/gitoxide/commit/330d0a19d54aabac868b76ef6281fffdbdcde53c))
+ - remove `Permissions` as there is no need for that here. ([`1954ef0`](https://github.com/Byron/gitoxide/commit/1954ef096a58aedb9f568a01e439d5a5cb46c40d))
+ - following includes is now non-fatal by default ([`1bc96bf`](https://github.com/Byron/gitoxide/commit/1bc96bf378d198b012efce9ec9e5b244a91f62bc))
+ - Allow to skip non-existing input paths without error ([`989603e`](https://github.com/Byron/gitoxide/commit/989603efcdf0064e2bb7d48100391cabc810204d))
+ - `File::from_git_dir()` as comfortable way to instantiate most complete git configuration. ([`f9ce1b5`](https://github.com/Byron/gitoxide/commit/f9ce1b5411f1ac788f71060ecf785dda9dfd87bf))
+ - Add a way to load multiple configuration files without allocating a read buffer ([`acb4520`](https://github.com/Byron/gitoxide/commit/acb4520a88ab083640c80a7f23a56a2ca3cda335))
+ - refactor ([`ec21e95`](https://github.com/Byron/gitoxide/commit/ec21e95f4d9ffac771410947923f27187e88321a))
+ - move `Env` test utility into `git-testtools` ([`bd3f4d0`](https://github.com/Byron/gitoxide/commit/bd3f4d014dd7df7a1e25defa8eea7253eec1560a))
+ - refactor ([`b073e29`](https://github.com/Byron/gitoxide/commit/b073e2930bed60ccedadd1709cfaa8889e02ffe3))
+ - another failing tests that can't be fixed without a refactor ([`e4d8fd7`](https://github.com/Byron/gitoxide/commit/e4d8fd72f1f648a29e56e487827f2328bfc08d03))
+ - an attempt to hack newline handling into place for windows newlines ([`dac1463`](https://github.com/Byron/gitoxide/commit/dac146343a0fbe96b6c0990f4fd4e976e0359a7e))
+ - Serialize lossily-read configuration files correctly anyway. ([`cfda0c3`](https://github.com/Byron/gitoxide/commit/cfda0c335d759cae0b23cef51f7b85a5f4b11e82))
+ - multi-path include test ([`3d89a46`](https://github.com/Byron/gitoxide/commit/3d89a46bf88b1fb5b4aa5da9fd12c7e310be3f9d))
+ - refactor ([`8a7fb15`](https://github.com/Byron/gitoxide/commit/8a7fb15f78ce16d5caedd7656e8aa98e72f248a6))
+ - fix windows tests ([`fbcf40e`](https://github.com/Byron/gitoxide/commit/fbcf40e16b8fc1ff97dbed2bc22b64bd44a8b99d))
+ - finally proper whitespace handling in all the right places for perfect roundtripping to/from string ([`97e5ede`](https://github.com/Byron/gitoxide/commit/97e5ededb0390c1b4f296a35903433de9c519821))
+ - serializations maintains some invariants about whitespace where possible. ([`ee10dd5`](https://github.com/Byron/gitoxide/commit/ee10dd5a8ae0dabfee21c1ce146e92c3c9635e8a))
+ - refactor ([`9c248ee`](https://github.com/Byron/gitoxide/commit/9c248eeb015495f910f48ce5df3c8fcce905dba7))
+ - `File` now compares actual content, ignoring whitespace and comments. ([`14a68a6`](https://github.com/Byron/gitoxide/commit/14a68a6a78a09f8ae56e30e3b7501de66ef31fdc))
+ - maintain insertion order of includes on per-section basis at least. ([`6c1588f`](https://github.com/Byron/gitoxide/commit/6c1588fd1a2fa80fd866787cbf4bcc6e5b51abe6))
+ - allow insertion of sections while preserving order ([`f5580a3`](https://github.com/Byron/gitoxide/commit/f5580a3635289d96e662aab00e60d801c4e34e1c))
+ - a test showing that include ordering isn't correct compared to the including config. ([`4e47df5`](https://github.com/Byron/gitoxide/commit/4e47df5332810f6e46ab682a68e870220ba3a6fb))
+ - add `File::resolve_includes()` and move its error type to `file::includes`. ([`17c83d5`](https://github.com/Byron/gitoxide/commit/17c83d55f8942788aac5eb1bea22a48daa045bf4))
+ - add `File::from_bytes_owned()` and remove `File::from_path_with_buf()` ([`5221676`](https://github.com/Byron/gitoxide/commit/5221676e28f2b6cc1a7ef1bdd5654b880965f38c))
+ - make it necessary to deal with the possibility of no-input in `from_paths_metadata()` . ([`612645f`](https://github.com/Byron/gitoxide/commit/612645f74ffc49229ccd783361b4d455e2284ac0))
+ - Don't fail on empty input on the comfort level ([`61ecaca`](https://github.com/Byron/gitoxide/commit/61ecaca43fb871eaff5cf94a8e7f9cc9413a5a77))
+ - `File::new_environment_overrides()` to easily instantiate overrides from the environment. ([`7dadfd8`](https://github.com/Byron/gitoxide/commit/7dadfd82494d47e36d3f570988eaf3c6b628977f))
+ - prepare for supporting comfortable version of environment overrides ([`45c964a`](https://github.com/Byron/gitoxide/commit/45c964a3f581dc7d3090bbbe26f188d553783fb3))
+ - remove `File::from_env_paths()`. ([`98d45c2`](https://github.com/Byron/gitoxide/commit/98d45c2f59863fdee033b38e757cec09593f6892))
+ - `File::new_globals()` can instantiate non-local configuration with zero-configuration. ([`146eeb0`](https://github.com/Byron/gitoxide/commit/146eeb064822839bc46fd37a247a1b9a84f64e40))
+ - Classify `Source` in accordance for what git actually does. ([`97374e4`](https://github.com/Byron/gitoxide/commit/97374e4d867e82d7be04da2eaa6ef553e0d9a7ff))
+ - `Source::storage_location()` to know where files should be located. ([`e701e05`](https://github.com/Byron/gitoxide/commit/e701e053fd05850973930be0cefe73e8f3604d40))
+ - `file::ValueMut::(section|into_section_mut)()` to go from value to the owning section. ([`fff0884`](https://github.com/Byron/gitoxide/commit/fff088485dd5067976cc93d525903b39aafea76a))
+ - `Source::is_in_repository()` to find out if a source is in the repository. ([`f5f2d9b`](https://github.com/Byron/gitoxide/commit/f5f2d9b3fef98d9100d713f9291510fa4aa27867))
+ - `parse::key` to parse a `remote.origin.url`-like key to identify a value ([`91e718f`](https://github.com/Byron/gitoxide/commit/91e718f0e116052b64ca436d7c74cea79529e696))
+ - maintain newline format depending on what's present or use platform default. ([`f7bd2ca`](https://github.com/Byron/gitoxide/commit/f7bd2caceb87a179288030e0771da2e4ed6bd1e4))
+ - prepare for passing through newline ([`3c06f88`](https://github.com/Byron/gitoxide/commit/3c06f8889854860b731735a8ce2bf532366003ef))
+ - Add `File::detect_newline_style()`, which does at it says. ([`26147a7`](https://github.com/Byron/gitoxide/commit/26147a7a61a695eda680808ee4aab44a890b2964))
+ - fix docs ([`78e85d9`](https://github.com/Byron/gitoxide/commit/78e85d9786a541aa43ad7266e85dc1da5e71a412))
+ - a test for lossy File parsing ([`5e8127b`](https://github.com/Byron/gitoxide/commit/5e8127b395bd564129b20a1db2d59d39307a2857))
+ - 'lossy' is now inherited by includes processing ([`88c6b18`](https://github.com/Byron/gitoxide/commit/88c6b185b2e51858b140e4378a5b5730b5cb4075))
+ - untangle `file::init::…` `Option` and `Error` types. ([`230a523`](https://github.com/Byron/gitoxide/commit/230a523593afcfb8720db965ff56265aaceea772))
+ - Support for `lossy` load mode. ([`d003c0f`](https://github.com/Byron/gitoxide/commit/d003c0f139d61e3bd998a0283a9c7af25a60db02))
+ - :Events::from_bytes()` with `filter` support. ([`32d5b3c`](https://github.com/Byron/gitoxide/commit/32d5b3c695d868ba93755123a25b276bfbe55e0a))
+ - try to fix attributes, once more ([`a50a396`](https://github.com/Byron/gitoxide/commit/a50a3964dbf01982b5a2c9a8ccd469332b6f9ca1))
+ - `File::frontmatter()` and `File::sections_and_postmatter()`. ([`0ad1c9a`](https://github.com/Byron/gitoxide/commit/0ad1c9a5280cc172432b5258e0f79898721bac68))
+ - add `_filter()` versions to most access methods. ([`1ea26d8`](https://github.com/Byron/gitoxide/commit/1ea26d80f392114349d25ebf88a7b260ee822aa1))
+ - even better handling of newlines ([`50c1753`](https://github.com/Byron/gitoxide/commit/50c1753c6389f29279d278fbab1afbd9ded34a76))
+ - refactor ([`df94c67`](https://github.com/Byron/gitoxide/commit/df94c6737ba642fff40623f406df0764d5bd3c43))
+ - rename `parse::Comment::(comment_tag|comment)` to `::tag|text` and `parse::Section::section_header` to `::header`. ([`3f3ff11`](https://github.com/Byron/gitoxide/commit/3f3ff11a6ebe9775ee5ae7fc0ec18a94b5b46d61))
+ - `parse::Event::to_bstr_lossy()` to get a glimpse at event content. ([`fc7e311`](https://github.com/Byron/gitoxide/commit/fc7e311b423c5fffb8240d9d0f917ae7139a6133))
+ - finally fix newline behaviour ([`c70e135`](https://github.com/Byron/gitoxide/commit/c70e135ecbbce8c696a6ab542ae20f5b5981dfdf))
+ - Be smarter about which newline style to use by guessing it based onprior events ([`25ed92e`](https://github.com/Byron/gitoxide/commit/25ed92e66bf4345f852e7e84741079c61ae896c8))
+ - `File::append()` can append one file to another rather losslessly. ([`09966a8`](https://github.com/Byron/gitoxide/commit/09966a8ea4eaa3e0805e04188de86dd1bac9f388))
+ - A test to validate frontmatter isn't currently handled correctly when appending ([`4665e87`](https://github.com/Byron/gitoxide/commit/4665e876df4ac6ab9135c10ee69b5408b89b5313))
+ - `file::Section::meta()` to access a section's metadata. ([`56ae574`](https://github.com/Byron/gitoxide/commit/56ae5744e8957e617f3a0ebc4d725846b18d93f8))
+ - refactor ([`d60025e`](https://github.com/Byron/gitoxide/commit/d60025e317d2b5f34f3569f321845bbb557ba2e7))
+ - `File::sections()` to obtain an iterator over all sections, in order. ([`6f97bf0`](https://github.com/Byron/gitoxide/commit/6f97bf0c3e7164855cf5aa53462dbc39c430e03f))
+ - Associate `file::Metadata` with each `File`. ([`6f4eea9`](https://github.com/Byron/gitoxide/commit/6f4eea936d64fb9827277c160f989168e7b1dba2))
+ - rename `file::SectionBody` to `file::section::Body`. ([`b672ed7`](https://github.com/Byron/gitoxide/commit/b672ed7667a334be3d45c59f4727f12797b340da))
+ - Remove `File::sections_by_name_with_header()` as `::sections_by_name()` now returns entire sections. ([`3bea26d`](https://github.com/Byron/gitoxide/commit/3bea26d7d2a9b5751c6c15e1fa9a924b67e0159e))
+ - A way to more easily set interpolation even without following includes. ([`9aa5acd`](https://github.com/Byron/gitoxide/commit/9aa5acdec12a0721543c6bcc39ffe6bd734f9a69))
+ - create `resolve_includes` options to make space for more options when loading paths. ([`41b3e62`](https://github.com/Byron/gitoxide/commit/41b3e622ee71943c285eadc518150fc7b6c92361))
+ - rename `path::Options` into `path::Context`. ([`cabc8ef`](https://github.com/Byron/gitoxide/commit/cabc8ef0e31c954642525e7693009a7fe4b4c465))
+ - try to fix attributes, once more ([`207e483`](https://github.com/Byron/gitoxide/commit/207e483620b29efb029c6ee742c0bb48d54be020))
+ - validate incoming conifguration keys when interpreting envirnoment variables. ([`0d07ef1`](https://github.com/Byron/gitoxide/commit/0d07ef1aa4a9e238c20249d4ae2ed19e6740308a))
+ - try to fix filter settings, but it doesn't seem to work ([`9750b7a`](https://github.com/Byron/gitoxide/commit/9750b7a1f01d6f0690221c6091b16c51784df0a3))
+ - sketch new section and metadata ([`9cb9acb`](https://github.com/Byron/gitoxide/commit/9cb9acb7b7ebada4d6bb3eef199337912ceeaa36))
+ - add `Source` type to allow knowing where a particular value is from. ([`c92d5c6`](https://github.com/Byron/gitoxide/commit/c92d5c6a223e377c10c2ca6b822e7eeb9070e12c))
+ - `Boolean` can use numbers to indicate true or false, drops support for `one` and `zero`. ([`6b90184`](https://github.com/Byron/gitoxide/commit/6b901843cb18b3d31f8b0b84bb9ebbae279aff19))
+ - All accessors in `File` are now using `impl AsRef` where possible for added comfort. ([`3de0cfd`](https://github.com/Byron/gitoxide/commit/3de0cfd81523e4ba7cc362d8625f85ebf8fd9172))
+ - Much more comfortable API `file::*Mut` types thanks to `impl Into/AsRef`. ([`3d25fe6`](https://github.com/Byron/gitoxide/commit/3d25fe6c7a52529488fab19c927d64a1bc75838f))
+ - Rename `Mutable*` into `$1Mut` for consistency. ([`393b392`](https://github.com/Byron/gitoxide/commit/393b392d515661e5c3e60629319fdab771c3d3f0))
+ - `file::MutableSection::remove()` now actually removes keys _and_ values. ([`94dde44`](https://github.com/Byron/gitoxide/commit/94dde44e8dd1a0b8d4e11f2627a3f6b345a15989))
+ - many more tests for MutableSection ([`ac843cb`](https://github.com/Byron/gitoxide/commit/ac843cbef4a6322be706b978e6691bc36c5e458f))
+ - refactor ([`701266e`](https://github.com/Byron/gitoxide/commit/701266e6e52456c0c1938732c260be19ec8029c9))
+ - conform APIs of `file::MutableValue` and `file::MutableMultiValue`. ([`0a7391a`](https://github.com/Byron/gitoxide/commit/0a7391a6575f4035c51a46d34fa20c69e9d078e9))
+ - `file::MutableMultiValue` escapes input values and maintains key separator specific whitespace. ([`048b925`](https://github.com/Byron/gitoxide/commit/048b92531eb877a5a128e702504891bf1e31becf))
+ - place spaces around `key = value` pairs, or whatever is used in the source configuration. ([`5418bc7`](https://github.com/Byron/gitoxide/commit/5418bc70e67476f8778656f2d577f1f9aa65ffbe))
+ - avoid extra copies when setting values and escaping them ([`a7eff01`](https://github.com/Byron/gitoxide/commit/a7eff0166f200a403d4dba320280f20a70e9afc7))
+ - refactor ([`15cd1d2`](https://github.com/Byron/gitoxide/commit/15cd1d2ba447ff27819f6cf398d31e96ff11b213))
+ - more empty-value tests ([`511985a`](https://github.com/Byron/gitoxide/commit/511985a8084f2a00e0550e5f2a85c93779385a1b))
+ - default space is just a single tab, not two ones ([`7e03b83`](https://github.com/Byron/gitoxide/commit/7e03b835bd6f0f5b3f00dbc63e7960ce6364eaef))
+ - proper escaping of value bytes to allow round-tripping after mutation ([`8118644`](https://github.com/Byron/gitoxide/commit/8118644625dc25b616e5f33c85f5100d600766e4))
+ - refactor ([`afa736a`](https://github.com/Byron/gitoxide/commit/afa736aba385bd52e7f11fd89538aea99787ac9d))
+ - a few tests for `MutableValue` showing that it's too buggy right now ([`5e6f9d9`](https://github.com/Byron/gitoxide/commit/5e6f9d909db41926e829e464abc53ef05fbf620b))
+ - rename `file::MutableSection::set_leading_space()` to `set_leading_whitespace()`. ([`83a0922`](https://github.com/Byron/gitoxide/commit/83a0922f06081312b79908835dac2b7f4e849bb3))
+ - whitespace in newly pushed keys is derived from first section value. ([`9f59356`](https://github.com/Byron/gitoxide/commit/9f59356b4f6a1f5f7f35a62c9fbe4859bf8e8e5f))
+ - `File::from_str()` implementation, to support `let config: File = "[core]".parse()?` ([`db1f34d`](https://github.com/Byron/gitoxide/commit/db1f34dfb855058ac08e97d4715876b5db712f61))
+ - whitespace in mutable sections can be finely controlled, and is derived from existing sections ([`9157717`](https://github.com/Byron/gitoxide/commit/9157717c2fb143b5decbdf60d18cc2bd99dde775))
+ - refactor ([`c88eea8`](https://github.com/Byron/gitoxide/commit/c88eea87d7ece807ca5b1753b47ce89d3ad6a502))
+ - refactor ([`a0d6caa`](https://github.com/Byron/gitoxide/commit/a0d6caa243aa293386d4ad164e1604f0e71c2cf3))
+ - auto-compute whitespace for sections, even though it probably needs to be better than that ([`ee9ac95`](https://github.com/Byron/gitoxide/commit/ee9ac953180886cc483e1125b7f4e172af92c3ce))
+ - validation for Keys and header names ([`59ec7f7`](https://github.com/Byron/gitoxide/commit/59ec7f7bf019d269573f8cc69f6d34b9458b1f1a))
+ - Simplify specifying keys when mutating config values. ([`a93a156`](https://github.com/Byron/gitoxide/commit/a93a156655d640ae63ff7c35b0a1f5d67a5ca20f))
+ - `File::rename_section()` with validation of input arguments. ([`895ce40`](https://github.com/Byron/gitoxide/commit/895ce40aabbe6d6af5b681a0d0942303fd6549a2))
+ - re-add newlines after multi-line values ([`9a2f597`](https://github.com/Byron/gitoxide/commit/9a2f59742cf94643c5b9967b76042bcc7a4e1a71))
+ - more header escaping tests ([`12cf005`](https://github.com/Byron/gitoxide/commit/12cf0052d92ee5bee1926f50c879526b5903c175))
+ - Enforce `parse::section::Header::new()` by making its fields private. ([`219cf7a`](https://github.com/Byron/gitoxide/commit/219cf7ae0b35b3ac92f97974be52cd022698e01f))
+ - `parse::Header::new(…)` with sub-section name validation ([`ae3895c`](https://github.com/Byron/gitoxide/commit/ae3895c7882e0a543a44693faee5f760b49b54d7))
+ - section names are now validated. ([`cfd974f`](https://github.com/Byron/gitoxide/commit/cfd974f46d2cbb99e7784a05f5e358fed0d4bcab))
+ - prepare for validation of `parse::section::Header` ([`00592f6`](https://github.com/Byron/gitoxide/commit/00592f6b80abe15a32a890ddc2b1fbf6701798d8))
+ - basic escaping of subsection names during serialization ([`00d1a9b`](https://github.com/Byron/gitoxide/commit/00d1a9b741845b49d8691262bef6e5c21876567e))
+ - refactor ([`9fac8e0`](https://github.com/Byron/gitoxide/commit/9fac8e0066c9b1845d9e06fb30b61ca9e9d64555))
+ - new roundtrip test on file level ([`78bb93c`](https://github.com/Byron/gitoxide/commit/78bb93cf35b6a990bac64bbfc56144799ad36243))
+ - Add `File::write_to()` and `File::to_bstring()`; remove some `TryFrom` impls. ([`4f6cd8c`](https://github.com/Byron/gitoxide/commit/4f6cd8cf65c2d8698bffe327a19031c342b229a6))
+ - remove `Integer::to_bstring()` as well as some `TryFrom` impls. ([`0e392f8`](https://github.com/Byron/gitoxide/commit/0e392f81e99c8c0ff29f41b9b86afd57cd99c245))
+ - remove `Boolean::to_bstring()` along with a few `From` impls. ([`b22732a`](https://github.com/Byron/gitoxide/commit/b22732a2ab17213c4a1020859ec41f25ccabfbfc))
+ - Add `parse::(Event|section::Header|Comment)::write_to(…)`. ([`d087f12`](https://github.com/Byron/gitoxide/commit/d087f12eec73626eb327eaacef8ebb3836b02381))
+ - fix tests on windows ([`3d7fc18`](https://github.com/Byron/gitoxide/commit/3d7fc188914337074775863acc1d6c15f47e913c))
+ - value normalization (via `value::normalize()` handles escape sequences. ([`f911707`](https://github.com/Byron/gitoxide/commit/f911707b455ba6f3800b85f667f91e4d56027b91))
+ - refactor normalization and more tests ([`cf3bf4a`](https://github.com/Byron/gitoxide/commit/cf3bf4a3bde6cdf20c63ffee1a5ae55a1f4e1742))
+ - more escape characters for normalization ([`b92bd58`](https://github.com/Byron/gitoxide/commit/b92bd580de45cb58cd2b3c4af430273e96139c79))
+ - review docs of `file::mutating` ([`2d5703e`](https://github.com/Byron/gitoxide/commit/2d5703e5909946e4327e0372097273facaeca759))
+ - stable sort order for `File::sections_by_name_with_header()` ([`44dfec0`](https://github.com/Byron/gitoxide/commit/44dfec07480cc2ac6fd01674b748cc03af51fed1))
+ - review `file::raw` module ([`6acf4a4`](https://github.com/Byron/gitoxide/commit/6acf4a43fd63c1c5e24b2e21702dc79827e3d11e))
+ - don't over-normalize in comfort layer - all values are normalized now ([`b979a3b`](https://github.com/Byron/gitoxide/commit/b979a3b318faada23a6cf073953b13f7828398af))
+ - docs for comfort level File API ([`eafc6ce`](https://github.com/Byron/gitoxide/commit/eafc6ce14a9f3d3dbc585e34e465609385f07f69))
+ - review and refactor 'File::value' module ([`7aa8a0b`](https://github.com/Byron/gitoxide/commit/7aa8a0b66f3508336e8c20a1a0d2b481e7b9bde8))
+ - allocation free `File::sections_by_name()` and `File::sections_by_name_with_header()`. ([`65c520c`](https://github.com/Byron/gitoxide/commit/65c520c4de8187884f87059adf5cef9cbdcd90a2))
+ - refactor ([`2abffd6`](https://github.com/Byron/gitoxide/commit/2abffd6f2224edd98f806b5dbd4fc0e1c60019c5))
+ - refactor ([`539c2f6`](https://github.com/Byron/gitoxide/commit/539c2f67bede1247478ce75429690c2904915a89))
+ - refactor ([`f1668e9`](https://github.com/Byron/gitoxide/commit/f1668e9d9e94f166fa05164612eab9ee26357d12))
+ - refactor ([`2599680`](https://github.com/Byron/gitoxide/commit/2599680f7479e18612b4379efbe918139dde2345))
+ - refactor ([`879fad5`](https://github.com/Byron/gitoxide/commit/879fad5afdcd90e248934e9c3b973d7bd438d1f9))
+ - fix docs ([`b2b82da`](https://github.com/Byron/gitoxide/commit/b2b82da6c6d3c71b249c9ff2055cd98a58f1d988))
+ - once again zero-allocation for SectionBodyIter ([`ba69124`](https://github.com/Byron/gitoxide/commit/ba691243778b3eb89452fd1277c50dfe83d0075f))
+ - refactor ([`33efef6`](https://github.com/Byron/gitoxide/commit/33efef6de375e399fe33a02e7b6dace1a679ac7e))
+ - docs and refactor ([`700d6aa`](https://github.com/Byron/gitoxide/commit/700d6aa34f2604ee72e619afb15c1bb6ce1697f2))
+ - `Path::interpolate()` now takes `path::interpolate::Options` instead of three parameters. ([`ac57c44`](https://github.com/Byron/gitoxide/commit/ac57c4479e7b6867e8b8e71f7cf76de759dc64a2))
+ - refactor `from_env` ([`c8693f9`](https://github.com/Byron/gitoxide/commit/c8693f9058765671804c93ead1eea1175a94f87c))
+ - make fmt ([`a7d7751`](https://github.com/Byron/gitoxide/commit/a7d7751822a1a8ac89930031707af57ad95d9cbd))
+ - more doc adjustments ([`95fc20a`](https://github.com/Byron/gitoxide/commit/95fc20a377aeb914d6b527c1d1b8e75d8c42c608))
+ - review docs of 'parse' module; refactor ([`a361c7f`](https://github.com/Byron/gitoxide/commit/a361c7ff290cdae071a12351330013ad0043b517))
+ - refactor ([`8e84fda`](https://github.com/Byron/gitoxide/commit/8e84fdadfc49ba61f258286acb0a707bfb2a396b))
+ - `File::raw_multi_value()` to `File::raw_values()` ([`9cd9933`](https://github.com/Byron/gitoxide/commit/9cd99337333f5ef4b30e0ec9461fc087699576e6))
+ - `File::raw_multi_value_mut()` to `File::raw_values_mut()` ([`0076dcf`](https://github.com/Byron/gitoxide/commit/0076dcf9b37f1d633bdad5573b40d34a9fbaba90))
+ - `File::multi_value()` to `File::values()`. ([`a8604a2`](https://github.com/Byron/gitoxide/commit/a8604a237782f8d60a185d4730db57bad81424a6))
+ - remove `String` type in favor of referring to the `File::string()` method. ([`0915051`](https://github.com/Byron/gitoxide/commit/0915051798dd782b40617a1aa16abd71f6db1175))
+ - fix docs ([`8fa7600`](https://github.com/Byron/gitoxide/commit/8fa7600847da6946784466213cea4c32ff9f7f92))
+ - refactor ([`b78e3fa`](https://github.com/Byron/gitoxide/commit/b78e3fa792fad4f3e3f9d5c668afccd75bc551e0))
+ - change! Add `home_for_user` in `Path::interpolate(…)`. ([`f9e0ef3`](https://github.com/Byron/gitoxide/commit/f9e0ef38e97fbc1e123d310dc696270d496438b6))
+ - Simplify `Boolean` to be a wrapper around `bool`. ([`9cadc6f`](https://github.com/Byron/gitoxide/commit/9cadc6f0cbaad0ac23f5469db2f040aecfbfb82c))
+ - Use bitflags for `color::Attribute` instead of `Vec` of enums. ([`703922d`](https://github.com/Byron/gitoxide/commit/703922dd4e1e5b27835298217ff4eb8ef1dc57ce))
+ - A bitflag version of color attributes ([`23ec673`](https://github.com/Byron/gitoxide/commit/23ec673baaf666fc38fda2f3b1ace9a8cf6816b8))
+ - refactor ([`4f21d1e`](https://github.com/Byron/gitoxide/commit/4f21d1ed145bfd0d56d31be73fade25b104bab53))
+ - simplify `Color` API. ([`3fc4ac0`](https://github.com/Byron/gitoxide/commit/3fc4ac04f46f869c6e3a94ce4bb8a5737aa0c524))
+ - deduplicate ([`c1b9cd4`](https://github.com/Byron/gitoxide/commit/c1b9cd443ec103a01daee8b8226a53f560d62498))
+ - first tests for colors specifically; fix space between tokens ([`e2bd055`](https://github.com/Byron/gitoxide/commit/e2bd0557d9ab68a02216c252ab20aaec2e4efd4e))
+ - count newlines (for error display) in multi-line values as well ([`1ea919d`](https://github.com/Byron/gitoxide/commit/1ea919d5ff81ab7b01b8201386ef63c7e081b537))
+ - zero-copy for section names ([`25b9760`](https://github.com/Byron/gitoxide/commit/25b9760f9a6a79c6e28393f032150e37d5ae831e))
+ - prepare for copy-on-write subsections ([`7474997`](https://github.com/Byron/gitoxide/commit/7474997216df2616a034fb9adc0938590f3ab7ed))
+ - another normalization case ([`637fe8f`](https://github.com/Byron/gitoxide/commit/637fe8fca2ce36e07ad671a4454da512b709045c))
+ - allow backspaces in value parser ([`199e546`](https://github.com/Byron/gitoxide/commit/199e5461cb85b11ce0b9a0e727fab40a49b78456))
+ - another failing test pointing at issues with normalization/escaping in parser ([`3c29321`](https://github.com/Byron/gitoxide/commit/3c2932167aa45a89974be79123932bc964fe3ea9))
+ - found failing test with complex multi-line value ([`117401d`](https://github.com/Byron/gitoxide/commit/117401ddb9dea1d78b867ddbafe57c2b37ec10f4))
+ - review `git-config::File` docs and rename some internal symbols ([`5a8b111`](https://github.com/Byron/gitoxide/commit/5a8b111b9a3bba2c01d7d5e32fc58fd8a64b81ad))
+ - more correctness for sub-section parsing ([`910af94`](https://github.com/Byron/gitoxide/commit/910af94fe11bc6e1c270c5512af9124f8a2e0049))
+ - reduce top-level docs ([`cdfb13f`](https://github.com/Byron/gitoxide/commit/cdfb13f5984c92c8e7f234e7751b66930291b461))
+ - refactor; remove unnecessary docs ([`c95e0b9`](https://github.com/Byron/gitoxide/commit/c95e0b9331282e029ef6188880d11a892ed1b4bf))
+ - assure no important docs are missed ([`f5026fb`](https://github.com/Byron/gitoxide/commit/f5026fb3b64bccf26bc8d5a74dbc5e89b98d9959))
+ - filtering supportort for `parse::Events`. ([`6ba2f80`](https://github.com/Byron/gitoxide/commit/6ba2f8060768978ad7204e162fb2253ca8843879))
+ - deduplicate events instantiation ([`ead757c`](https://github.com/Byron/gitoxide/commit/ead757c2a4b737d2f617cf23c370e2ca5c46b08b))
+ - unclutter lifetime declarations ([`e571fdb`](https://github.com/Byron/gitoxide/commit/e571fdb4630ff373ece02efcd963724c05978ede))
+ - remove redundant documentation about errors ([`183c7ae`](https://github.com/Byron/gitoxide/commit/183c7ae0d5f44bb468954a7ad18cc02a01d717bc))
+ - adjust to changes in `git-config` ([`c52cb95`](https://github.com/Byron/gitoxide/commit/c52cb958f85b533e791ec6b38166a9d819f12dd4))
+ - remove `parse::Events::from_path` and `File::at` ([`14149ee`](https://github.com/Byron/gitoxide/commit/14149eea54e2e8a25ac0ccdb2f6efe624f6eaa22))
+ - try to strike a balance between allocations and memory footprint ([`52bd1e7`](https://github.com/Byron/gitoxide/commit/52bd1e7455d2b09811ea0ac5140c3693d3c1e1f7))
+ - allocation-free parsing as callback is passed through ([`ed00e22`](https://github.com/Byron/gitoxide/commit/ed00e22cbdfea1d69d1d4c2b829effc26b493185))
+ - foundation for allocation free (and smallvec free) parsing ([`307c1af`](https://github.com/Byron/gitoxide/commit/307c1afebfba952a4931a69796686b8a998c4cd9))
+ - Slim down API surface of `parse::Events`. ([`73adcee`](https://github.com/Byron/gitoxide/commit/73adceeae12270c0d470d4b7271c1fd6089d5c2d))
+ - remove `File::new()` method in favor of `File::default()`. ([`2e47167`](https://github.com/Byron/gitoxide/commit/2e47167e4a963743494b2df6b0c15800cb876dd0))
+ - a greatly simplified Events->File conversion ([`c5c4398`](https://github.com/Byron/gitoxide/commit/c5c4398a56d4300c83c5be2ba66664bd11f49d5e))
+ - fix docs ([`5022be3`](https://github.com/Byron/gitoxide/commit/5022be3bb7fa54c97e5110f74aaded9e2f1b6ca5))
+ - about 30% faster parsing due to doing no less allocations for section events ([`050d0f0`](https://github.com/Byron/gitoxide/commit/050d0f0dee9a64597855e85417460f6e84672b02))
+ - allocation-free fuzzing, with optimized footprints ([`2e149b9`](https://github.com/Byron/gitoxide/commit/2e149b982ec57689c161924dd1d0b22c4fcb681f))
+ - allocation-free sections ([`d3a0c53`](https://github.com/Byron/gitoxide/commit/d3a0c53864ccc9f8d2851d06f0154b9e8f9bcda7))
+ - allocation-free frontmatter ([`6c3f326`](https://github.com/Byron/gitoxide/commit/6c3f3264911042e88afa0819414eb543a3626d11))
+ - remove last duplicate of top-level parse function ([`cd7a21f`](https://github.com/Byron/gitoxide/commit/cd7a21f8381385833f5353925dc57c05c07e718d))
+ - workaround lack of GAT! ([`4fb327c`](https://github.com/Byron/gitoxide/commit/4fb327c247f1c0260cb3a3443d81063b71e87fe4))
+ - remove duplication of top-level parser ([`0f5c99b`](https://github.com/Byron/gitoxide/commit/0f5c99bffdb61e4665e83472275c5c8b0383650b))
+ - a minimally invasive sketch of a parse Delegate ([`5958ffb`](https://github.com/Byron/gitoxide/commit/5958ffbfec7724c1a47be8db210df03cf54c9374))
+ - fix docs ([`2186456`](https://github.com/Byron/gitoxide/commit/218645618429258e48cb0fdb2bbfba3daa32ee2d))
+ - fix fuzz crash in parser ([`86e1a76`](https://github.com/Byron/gitoxide/commit/86e1a76484be50f83d06d6c8a176107f8cb3dea6))
+ - rename `parse::event::List` to `parse::Events` ([`ea67650`](https://github.com/Byron/gitoxide/commit/ea6765093b5475912ba1aa81d4440cbf5dd49fb6))
+ - rename `parse::State` to `parse::event::List` ([`89f5fca`](https://github.com/Byron/gitoxide/commit/89f5fca843d999c5bea35fb3fe2a03dc3588f74e))
+ - update fuzz instructions and make it work ([`19300d5`](https://github.com/Byron/gitoxide/commit/19300d5f37c201aba921a6bff9760996fec2108e))
+ - improve normalization; assure no extra copies are made on query. ([`4a01d98`](https://github.com/Byron/gitoxide/commit/4a01d983f54a7713dea523f6032cbf5bb2b9dde8))
+ - refactor; assure `normalize` doesn't copy unnecessarily ([`ce069ca`](https://github.com/Byron/gitoxide/commit/ce069ca0b6b44cd734f4d8b4525916d1ddb0de0b))
+ - normalize values in all the right places ([`91ba2dd`](https://github.com/Byron/gitoxide/commit/91ba2ddcd3de63aa22dc6e863b26ce1893a36995))
+ - avoid unnecessary clones ([`e684488`](https://github.com/Byron/gitoxide/commit/e68448831a94574ee3ca2fa36788f603c91d57a0))
+ - adapt to changes in `git-config` ([`363a826`](https://github.com/Byron/gitoxide/commit/363a826144ad59518b5c1a3dbbc82d04e4fc062d))
+ - move `value::*` into the crate root, except for `Error` and `normalize_*()`. ([`3cdb089`](https://github.com/Byron/gitoxide/commit/3cdb0890b71e62cfa92b1ed1760c88cb547ec729))
+ - rename `value::parse::Error` to `value::Error`. ([`748d921`](https://github.com/Byron/gitoxide/commit/748d921efd7469d5c19e40ddcb9099e2462e3bbc))
+ - rename `value::TrueVariant` to `value::boolean::True` ([`7e8a225`](https://github.com/Byron/gitoxide/commit/7e8a22590297f2f4aab76b53be512353637fb651))
+ - rename `IntegerSuffix` to `integer::Suffix` ([`8bcaec0`](https://github.com/Byron/gitoxide/commit/8bcaec0599cf085a73b344f4f53fc023f6e31430))
+ - rename `value::Color(Attribute|Value)` to `value::color::Attribute` and `value::color::Name`. ([`d085037`](https://github.com/Byron/gitoxide/commit/d085037ad9c067af7ce3ba3ab6e5d5ddb45b4057))
+ - refactor ([`a0f7f44`](https://github.com/Byron/gitoxide/commit/a0f7f44c4fca20d3c9b95a3fafe65cef84c760e7))
+ - refactor ([`0845c84`](https://github.com/Byron/gitoxide/commit/0845c84b6f694d97519d5f86a97bca49739df8bf))
+ - keep str in value API ([`ef5b48c`](https://github.com/Byron/gitoxide/commit/ef5b48c71e0e78fa602699a2f8ca8563c10455c4))
+ - Keep BStr even though str could be used. ([`aeca6cc`](https://github.com/Byron/gitoxide/commit/aeca6cce7b4cfe67b18cd80abb600f1271ad6057))
+ - Turn `parse::ParseOrIoError` into `parse::state::from_path::Error` ([`a0f6252`](https://github.com/Byron/gitoxide/commit/a0f6252343a62b0b55eef02888ac00c09100687a))
+ - rename `parse::ParsedComment` into `parse::Comment` ([`b6b31e9`](https://github.com/Byron/gitoxide/commit/b6b31e9c8dd8b3dc4860431069bb1cf5eacd1702))
+ - Allocation-free hashing for section keys and names ([`44d0061`](https://github.com/Byron/gitoxide/commit/44d00611178a4e2f6a080574c41355a50b79b181))
+ - allocation-free case-inequality tests for section keys and names ([`94608db`](https://github.com/Byron/gitoxide/commit/94608db648cd717af43a97785ea842bc75361b7e))
+ - rename `parse::Section*` related types. ([`239cbfb`](https://github.com/Byron/gitoxide/commit/239cbfb450a8cddfc5bec1de21f3dc54fab914ce))
+ - adjustments required due to changed in `git-config` ([`41bfd3b`](https://github.com/Byron/gitoxide/commit/41bfd3b4122e37370d268608b60cb00a671a8879))
+ - rename `parse::Parser` to `parse::State`. ([`60af4c9`](https://github.com/Byron/gitoxide/commit/60af4c9ecb1b99f21df0e8facc33e5f6fc70c424))
+ - rename `parser` module to `parse` ([`3724850`](https://github.com/Byron/gitoxide/commit/3724850e0411f1f76e52c6c767fd8cebe8aea0f6))
+ - fix docs ([`b05aed1`](https://github.com/Byron/gitoxide/commit/b05aed1cfc15a2e29d7796bad4c9a6d4019f4353))
+ - refactor ([`8bd9cd6`](https://github.com/Byron/gitoxide/commit/8bd9cd695d608d05859d8bff4033883e71ce7caa))
+ - refactor ([`90dd2ce`](https://github.com/Byron/gitoxide/commit/90dd2cec8ea88980365bfd08a16614d145e87095))
+ - fix docs ([`0d1be2b`](https://github.com/Byron/gitoxide/commit/0d1be2b893574f2a9d4ba35ac4f2b3da710d4b03))
+ - rename `normalize_cow()` to `normalize()` and move all `normalize*` functions from `values` to the `value` module ([`58b2215`](https://github.com/Byron/gitoxide/commit/58b22152a0295998935abb43563e9096589ef53e))
+ - Documentation for feature flags ([`26e4a9c`](https://github.com/Byron/gitoxide/commit/26e4a9c83af7550eab1acaf0256099774be97965))
+ - `serde1` feature to add limited serde support ([`5a8f242`](https://github.com/Byron/gitoxide/commit/5a8f242ee98793e2467e7bc9806f8780b9d320ce))
+ - remove unused serde feature ([`66a8237`](https://github.com/Byron/gitoxide/commit/66a8237ff284c2cf7f80cc909c7b613b599e1358))
+ - move `Path` from `values` to `value` module ([`767bedc`](https://github.com/Byron/gitoxide/commit/767bedccdae1f3e6faf853d59ecf884a06cc3827))
+ - Move `Boolean` and `String` from `values` into `value` module ([`6033f3f`](https://github.com/Byron/gitoxide/commit/6033f3f93d2356399a661567353a83a044662699))
+ - move `values::Integer` into `value` module ([`d4444e1`](https://github.com/Byron/gitoxide/commit/d4444e18042891b0fe5b9c6e6813fed26df6c560))
+ - move `Color` to own `value` module ([`38f3117`](https://github.com/Byron/gitoxide/commit/38f31174e8c117af675cdfbc21926133b821ec38))
+ - Make symlink tests so that they test real-path conversion ([`d4fbf2e`](https://github.com/Byron/gitoxide/commit/d4fbf2ea71ee1f285c195dd00bfa4e21bf429922))
+ - adjustments due to breaking changes in `git_path` ([`4420ae9`](https://github.com/Byron/gitoxide/commit/4420ae932d5b20a9662a6d36353a27111b5cd672))
+ - a test to validate relative includepaths aren't valid for includeIf ([`7d27dd5`](https://github.com/Byron/gitoxide/commit/7d27dd5e3558a22865e0c9159d269577431097f3))
+ - reuse the initialized environment for a little speed ([`6001613`](https://github.com/Byron/gitoxide/commit/600161324edc370707613841ce9228320c700bf6))
+ - Also test against git baseline ([`adcddb0`](https://github.com/Byron/gitoxide/commit/adcddb0056c14302f0133de251fa07e877b6f509))
+ - refactor ([`0229e25`](https://github.com/Byron/gitoxide/commit/0229e2583ed7beccaf59dc0c82893c5b67c285dd))
+ - prevent race when calling `git` around `GIT_CONFIG_*` env vars ([`53efbf5`](https://github.com/Byron/gitoxide/commit/53efbf54364c373426a7790c28c74c787670877a))
+ - remove duplicate gitdir tests that don't have a baseline ([`5c71394`](https://github.com/Byron/gitoxide/commit/5c713946b1f35675bacb27bd5392addf25010942))
+ - remove unmotivated forward-slash conversion ([`3af09e5`](https://github.com/Byron/gitoxide/commit/3af09e5800648df87cdaf22191dd4d1dc4b278a3))
+ - improved slash/backslash handling on windows ([`a3b7828`](https://github.com/Byron/gitoxide/commit/a3b7828e8bf9d90775f10b0d996fc7ad82f92466))
+ - fix build warnings on windows ([`9d48b2f`](https://github.com/Byron/gitoxide/commit/9d48b2f51777de37cc996ad54261f2d20f417901))
+ - fix windows test ([`a922f0a`](https://github.com/Byron/gitoxide/commit/a922f0a817d290ef4a539bbf99238a4f96d443f9))
+ - refactor ([`d76aee2`](https://github.com/Byron/gitoxide/commit/d76aee22498cb980ab0b53295a2e51af04a8cb7c))
+ - conforming subsection parsing handling backslashes like git ([`6366148`](https://github.com/Byron/gitoxide/commit/6366148f538ee03314dd866e083157de810d4ad4))
+ - Only copy pattern if required ([`b3a752a`](https://github.com/Byron/gitoxide/commit/b3a752a0a873cf9d685e1893c8d35255d7f7323a))
+ * **Uncategorized**
+ - Release git-hash v0.9.6, git-features v0.22.0, git-date v0.0.2, git-actor v0.11.0, git-glob v0.3.1, git-path v0.4.0, git-attributes v0.3.0, git-tempfile v2.0.2, git-object v0.20.0, git-ref v0.15.0, git-sec v0.3.0, git-config v0.6.0, git-credentials v0.3.0, git-diff v0.17.0, git-discover v0.3.0, git-index v0.4.0, git-mailmap v0.3.0, git-traverse v0.16.0, git-pack v0.21.0, git-odb v0.31.0, git-url v0.7.0, git-transport v0.19.0, git-protocol v0.18.0, git-revision v0.3.0, git-worktree v0.4.0, git-repository v0.20.0, git-commitgraph v0.8.0, gitoxide-core v0.15.0, gitoxide v0.13.0, safety bump 22 crates ([`4737b1e`](https://github.com/Byron/gitoxide/commit/4737b1eea1d4c9a8d5a69fb63ecac5aa5d378ae5))
+ - prepare changelog prior to release ([`3c50625`](https://github.com/Byron/gitoxide/commit/3c50625fa51350ec885b0f38ec9e92f9444df0f9))
+ - thanks clippy ([`fddc720`](https://github.com/Byron/gitoxide/commit/fddc7206476423a6964d61acd060305572ecd02b))
+ - thanks fuzzy ([`15a379a`](https://github.com/Byron/gitoxide/commit/15a379a85d59d83f3a0512b9e9fbff1774c9f561))
+ - thanks clippy ([`15fee74`](https://github.com/Byron/gitoxide/commit/15fee74fdfb5fc84349ac103cd5727332f3d2230))
+ - thanks clippy ([`0b05be8`](https://github.com/Byron/gitoxide/commit/0b05be850d629124f027af993e316b9018912337))
+ - thanks clippy ([`693e304`](https://github.com/Byron/gitoxide/commit/693e304a2c38130ed936d5e4544faaa858665872))
+ - fix git-config/tests/.gitattributes ([`a741766`](https://github.com/Byron/gitoxide/commit/a7417664ca1e41936f9de8cf066e13aeaf9b0d75))
+ - Merge branch 'config-metadata' ([`453e9bc`](https://github.com/Byron/gitoxide/commit/453e9bca8f4af12e49222c7e3a46d6222580c7b2))
+ - forced checkin to fix strange crlf issue ([`5d0a5c0`](https://github.com/Byron/gitoxide/commit/5d0a5c0712fbd8fcc00aff54563c83281afc9476))
+ - thanks clippy ([`e5ba0f5`](https://github.com/Byron/gitoxide/commit/e5ba0f532bf9bfee46d2dab24e6a6503df4d239d))
+ - thanks clippy ([`00bfbca`](https://github.com/Byron/gitoxide/commit/00bfbca21e2361008c2e81b54424a9c6f09e76e9))
+ - thanks clippy ([`09e2374`](https://github.com/Byron/gitoxide/commit/09e23743035b9d4463f438378aed54677c03311f))
+ - thanks clippy ([`e842633`](https://github.com/Byron/gitoxide/commit/e84263362fe0631935379a0b4e8d8b1fcf6ac81b))
+ - thanks clippy ([`3ca8027`](https://github.com/Byron/gitoxide/commit/3ca8027e07a835e84a704688778cfb82c956643b))
+ - make fmt ([`aa9fdb0`](https://github.com/Byron/gitoxide/commit/aa9fdb0febfb29f906eb81e4378f07ef01b03e05))
+ - thanks clippy ([`c9a2390`](https://github.com/Byron/gitoxide/commit/c9a239095511ae95fb5efbbc9207293641b623f7))
+ - thanks clippy ([`badd00c`](https://github.com/Byron/gitoxide/commit/badd00c402b59994614e653b28bb3e6c5b70d9d1))
+ - make fmt ([`0700b09`](https://github.com/Byron/gitoxide/commit/0700b09d6828849fa2470df89af1f75a67bfb27d))
+ - thanks clippy ([`b246f0a`](https://github.com/Byron/gitoxide/commit/b246f0ade5aa42413cc387470b35df357b1136bc))
+ - thanks clippy ([`08441de`](https://github.com/Byron/gitoxide/commit/08441def5d1738bbf13b68979f2d1ff7ff3b4153))
+ - thanks clippy ([`8b29dda`](https://github.com/Byron/gitoxide/commit/8b29ddaa627048b9ca130b52221709a575f50d3a))
+ - thanks clippy ([`cff6e01`](https://github.com/Byron/gitoxide/commit/cff6e018a8f0c3b6c78425f99a204d29d72a65aa))
+ - thanks clippy ([`f7be3b0`](https://github.com/Byron/gitoxide/commit/f7be3b0f79bf19faf5a3b68032f764c0b7a12d7e))
+ - thanks clippy ([`7a2a31e`](https://github.com/Byron/gitoxide/commit/7a2a31e5758a2be8434f22cd9401ac00539f2bd9))
+ - Allow backslashes in subsections ([`6f4f325`](https://github.com/Byron/gitoxide/commit/6f4f325a42656800c8c76c8eae075508c31657be))
+ - fix build after changes to `git-url` and `git-config` ([`1f02420`](https://github.com/Byron/gitoxide/commit/1f0242034071ce317743df75cc685e7428b604b0))
+ - thanks clippy ([`9b6a67b`](https://github.com/Byron/gitoxide/commit/9b6a67bf369fcf51c6a3289784c3ef8ab366bee7))
+ - remove `values::Bytes` - use `values::String` instead. ([`aa630ad`](https://github.com/Byron/gitoxide/commit/aa630ad6ec2c6306d3307d5c77e272cb24b00ddd))
+ - change mostily internal uses of [u8] to BString/BStr ([`311d4b4`](https://github.com/Byron/gitoxide/commit/311d4b447daf8d4364670382a20901468748d34d))
+ - Definitely don't unconditionally convert to forward slashes ([`146eb0c`](https://github.com/Byron/gitoxide/commit/146eb0c831ce0a96e215b1ec6499a86bbf5902c9))
+ - avoid panics and provide errors instead of just not matching ([`a0f842c`](https://github.com/Byron/gitoxide/commit/a0f842c7f449a6a7aedc2742f7fc4f74a12fdd17))
+ - try to fix git-config tests on windows even harder ([`16778d4`](https://github.com/Byron/gitoxide/commit/16778d478d6941ab86571de0bd99aaab816ffe67))
+ - try once more to get failing tests under control on windows ([`c26c2e9`](https://github.com/Byron/gitoxide/commit/c26c2e962aa6a93c0e06b900dc719f9cd92f6137))
+ - thanks clippy ([`27b2dde`](https://github.com/Byron/gitoxide/commit/27b2dde9a299aca112347f988fa21d797f64552b))
+ - fix test with brute force; take some notes for later ([`2eda529`](https://github.com/Byron/gitoxide/commit/2eda5296ad9ee58756d564225e98e64a800f46d7))
+ - Merge branch 'main' into cont_include_if ([`daa71c3`](https://github.com/Byron/gitoxide/commit/daa71c3b753c6d76a3d652c29237906b3e28728f))
+ - Take GitEnv by ref. ([`937d7ee`](https://github.com/Byron/gitoxide/commit/937d7eea84e92467fcc8a6a72c78fe6c060dd95d))
+ - remove leftover debug printing ([`7d1cf34`](https://github.com/Byron/gitoxide/commit/7d1cf34e4535721db97f566734f68014ebc7c3e8))
+ - auto-normalize string values to support quote removal in case of strings. ([`1e71e71`](https://github.com/Byron/gitoxide/commit/1e71e71c984289f0d7e0a39379ee6728918b7dc5))
+ - refactor ([`1d6ba9b`](https://github.com/Byron/gitoxide/commit/1d6ba9bd719ad01ce22573cabd8022ddb675c5fc))
+ - avoid unwrap() more as the test code matures ([`c2d7e80`](https://github.com/Byron/gitoxide/commit/c2d7e800abe022f5a2663176f0f6b3ac90eacf0e))
+ - refactor ([`b5c0b30`](https://github.com/Byron/gitoxide/commit/b5c0b3011d2c0e63c933be42753aea65b88ca569))
+ - Merge branch 'main' into cont_include_if ([`0e9df36`](https://github.com/Byron/gitoxide/commit/0e9df364c4cddf006b1de18b8d167319b7cc1186))
+ - make '..' related tests work ([`5f11318`](https://github.com/Byron/gitoxide/commit/5f11318dc55b8dd8da016a4053cc4ad34b13fa97))
+ - find a few cases that aren't according to spec by failing (and ignored) tests ([`f0e6ea9`](https://github.com/Byron/gitoxide/commit/f0e6ea9086ebfa134044568114bb578120eb5da9))
+ - refactor ([`62e5396`](https://github.com/Byron/gitoxide/commit/62e5396ac9221f13437c87f06715c98989981785))
+ - generally avoid using `target_os = "windows"` in favor of `cfg(windows)` and negations ([`91d5402`](https://github.com/Byron/gitoxide/commit/91d54026a61c2aae5e3e1341d271acf16478cd83))
+ - Invoke git only when necessary ([`556c7cf`](https://github.com/Byron/gitoxide/commit/556c7cff5f813e885598b4bd858c6c22cedf688b))
+ - Also use git_path::realpath() in other places that used canonicalize before ([`08af648`](https://github.com/Byron/gitoxide/commit/08af648923c226a0330f0025784c42914d4fea7f))
+ - Our own git_path::realpath doesn't have the questionmark? issue on windows ([`cfe196b`](https://github.com/Byron/gitoxide/commit/cfe196b23051e639cb1332f88f1ec917608fbbe1))
+ - fix windows tests ([`47f10fe`](https://github.com/Byron/gitoxide/commit/47f10feb2b143b9b429237cf6a4a7424c2b9ab13))
+ - more debugging for windows failures ([`e0a72e6`](https://github.com/Byron/gitoxide/commit/e0a72e65e4bbe76755aea1a905d69d74d01f543a))
+ - no need for serial anymore ([`34bb715`](https://github.com/Byron/gitoxide/commit/34bb7152ca5992fc35be5f51016565a568916e7c))
+ - Make a note to be sure we use the home-dir correctly in git-repository; avoid `dirs` crate ([`0e8cf19`](https://github.com/Byron/gitoxide/commit/0e8cf19d7f742f9400afa4863d302ba18a452adc))
+ - finally all tests work without the need for dirs::home_dir() ([`180ce99`](https://github.com/Byron/gitoxide/commit/180ce99a016c17641990eb41b6bbe3b2407ab271))
+ - refactor ([`00ba5d8`](https://github.com/Byron/gitoxide/commit/00ba5d8a53aae1c4adbb379c076651756e1af68d))
+ - refactor ([`0eb7ced`](https://github.com/Byron/gitoxide/commit/0eb7ced6ec49fe6303659bdcab29952c5cea41bd))
+ - Path-interpolation makes `home-dir` configurable. ([`edd2267`](https://github.com/Byron/gitoxide/commit/edd226719cd04a480274cb7d983b6d5d8bfdbb13))
+ - refactor ([`aab9865`](https://github.com/Byron/gitoxide/commit/aab98656ee5c4abf65f79d403c1f0cb36fd0ee88))
+ - Change last test to new simplified symlink setup ([`a40e3c9`](https://github.com/Byron/gitoxide/commit/a40e3c999baf203c92d0e5e53ee61c0032e32e51))
+ - refactor ([`67677b0`](https://github.com/Byron/gitoxide/commit/67677b0edfa1faa0c011a225d41d78dbde3c5f15))
+ - assure the IDE doesn't confuse a module with a test ([`7be0b05`](https://github.com/Byron/gitoxide/commit/7be0b05ff3a5bbea9d9712e4d13ee08cf9979861))
+ - refactor ([`1203a14`](https://github.com/Byron/gitoxide/commit/1203a14eba79d335137c96d4ee573739df30b067))
+ - refactor ([`a721efe`](https://github.com/Byron/gitoxide/commit/a721efecd36984064b4b31c715bbe011df2538ad))
+ - refactor ([`2c8c6e5`](https://github.com/Byron/gitoxide/commit/2c8c6e53fd4681289c9fa2308735c779ed4eace5))
+ - refactor ([`eb0ace1`](https://github.com/Byron/gitoxide/commit/eb0ace14a92899002749d6dbd99dac3a35d73c25))
+ - refactor ([`8f8f873`](https://github.com/Byron/gitoxide/commit/8f8f873ae711eb5ae62f192f6731653f2bb7ff4b))
+ - Merge branch 'main' into cont_include_if ([`41ea8ba`](https://github.com/Byron/gitoxide/commit/41ea8ba78e74f5c988148367386a1f4f304cb951))
+ - Release git-path v0.3.0, safety bump 14 crates ([`400c9be`](https://github.com/Byron/gitoxide/commit/400c9bec49e4ec5351dc9357b246e7677a63ea35))
+ - Remove `git-config` test utilities from `git-path`. ([`c9933c0`](https://github.com/Byron/gitoxide/commit/c9933c0b0f51d21dc8244b2acc33d7dc8a33f6ce))
+ - Add repo_dir to EnvOverwrite. ([`ed5c442`](https://github.com/Byron/gitoxide/commit/ed5c442cc4f0c546834f2e0e9dc553a221b6985d))
+ - Use EnvOverwrite struct. ([`f2e124f`](https://github.com/Byron/gitoxide/commit/f2e124f60f8f9a0d517fddb029d795fa91bcda5a))
+ - tempdir lives long enough for sure. ([`a41002f`](https://github.com/Byron/gitoxide/commit/a41002fe4004485fac429d904bc4e8b6842eaf3c))
+ - Disable symlink tests on windows. ([`8de6b3d`](https://github.com/Byron/gitoxide/commit/8de6b3d42c89c741195e4add273a2d1e7b48fad9))
+
+
## 0.5.0 (2022-06-13)
### New Features (BREAKING)
@@ -16,7 +575,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- - 7 commits contributed to the release over the course of 22 calendar days.
+ - 41 commits contributed to the release over the course of 22 calendar days.
- 22 days passed between releases.
- 1 commit where understood as [conventional](https://www.conventionalcommits.org).
- 1 unique issue was worked on: [#436](https://github.com/Byron/gitoxide/issues/436)
@@ -30,11 +589,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* **[#436](https://github.com/Byron/gitoxide/issues/436)**
- Remove outdated examples ([`cb9529e`](https://github.com/Byron/gitoxide/commit/cb9529e18b222b9fd9f8c1bb0dba8038a6ea1d4b))
* **Uncategorized**
+ - Release git-date v0.0.1, git-hash v0.9.5, git-features v0.21.1, git-actor v0.10.1, git-path v0.2.0, git-attributes v0.2.0, git-ref v0.14.0, git-sec v0.2.0, git-config v0.5.0, git-credentials v0.2.0, git-discover v0.2.0, git-pack v0.20.0, git-odb v0.30.0, git-url v0.6.0, git-transport v0.18.0, git-protocol v0.17.0, git-revision v0.2.1, git-worktree v0.3.0, git-repository v0.19.0, safety bump 13 crates ([`a417177`](https://github.com/Byron/gitoxide/commit/a41717712578f590f04a33d27adaa63171f25267))
- update changelogs prior to release ([`bb424f5`](https://github.com/Byron/gitoxide/commit/bb424f51068b8a8e762696890a55ab48900ab980))
+ - make fmt ([`cd4f727`](https://github.com/Byron/gitoxide/commit/cd4f7279678678fa6f2e55d4e7681a2075f1d6cf))
+ - Temp ignore symlink tests. ([`ec40b94`](https://github.com/Byron/gitoxide/commit/ec40b94bffda14b7b991dd57cd36d893f1f6962b))
+ - fmt. ([`82ea726`](https://github.com/Byron/gitoxide/commit/82ea7261cfb75a01992489aa7631e2e6d807be06))
+ - Use `dirs::home_dir()` ([`5767a50`](https://github.com/Byron/gitoxide/commit/5767a505f2f2cc3515eb604e39da673fa2e09454))
+ - Try fix windows home. ([`393758e`](https://github.com/Byron/gitoxide/commit/393758e14a1b5ff14301f153807fe45623d9f973))
+ - Add more tests. ([`db1204d`](https://github.com/Byron/gitoxide/commit/db1204d74b16ff7e905fb5b2d91d9ecb109bca07))
+ - Add debug output. ([`52db5e8`](https://github.com/Byron/gitoxide/commit/52db5e8894c5033ec3d58894a7cf17b4f29e03f4))
+ - Tests like git: https://github.com/git/git/blob/master/t/t1305-config-include.sh ([`c3a0454`](https://github.com/Byron/gitoxide/commit/c3a04548b08b6972ea0999b0030017d1a6002de2))
+ - Start extracting gitdir tests cont. ([`22e5cbe`](https://github.com/Byron/gitoxide/commit/22e5cbece0206da6cf8890a831fd82847526396a))
- remove `pwd` crate dependency in favor of using libc directly ([`4adfa11`](https://github.com/Byron/gitoxide/commit/4adfa11d70cf78bed541fa59707e8a5082dda245))
- Drop non-existent config paths before parsing ([`475d6fa`](https://github.com/Byron/gitoxide/commit/475d6fab2467ad0499db7df2d4c99f74e43682fc))
+ - Start extracting gitdir tests. ([`5aaf7ba`](https://github.com/Byron/gitoxide/commit/5aaf7ba93857f1e5570f64f4a9539cd3d547b81d))
+ - thanks clippy ([`cfa577f`](https://github.com/Byron/gitoxide/commit/cfa577f84c45c7fbed27e6d59ef361f9ac5c2614))
+ - refactor ([`da23958`](https://github.com/Byron/gitoxide/commit/da239580fca76011f91a45ae502af88c67d429a4))
+ - Finalize onbranch tests; remove mixed ones in favor of specific cases ([`26680c4`](https://github.com/Byron/gitoxide/commit/26680c48951a82d5119f54c57b4e7045d2c20649))
+ - refactor ([`11c417f`](https://github.com/Byron/gitoxide/commit/11c417fdc03331db2c4a778bc3e8038ffd0aff89))
+ - More tests for branch matching prior to making tests clearer ([`31e6db8`](https://github.com/Byron/gitoxide/commit/31e6db8cdc959549a6c2754692d2471103ada64f))
+ - Basic test-setup for more specialized tests ([`b4374d2`](https://github.com/Byron/gitoxide/commit/b4374d21882eca637ddbb80cdde1dac7bc68560e))
+ - refactor ([`04da720`](https://github.com/Byron/gitoxide/commit/04da7207a7e44175dc96e4ea850274b2cc5a6d84))
+ - Fix including .. path. ([`8891fea`](https://github.com/Byron/gitoxide/commit/8891feac0341960a6339ee86c671fc80c3133b4e))
+ - Fix case-insensitive. ([`ca05802`](https://github.com/Byron/gitoxide/commit/ca058024e1e19818261fea39099c893d666928dc))
+ - Fix \\ test. ([`ab555b5`](https://github.com/Byron/gitoxide/commit/ab555b557f4bd68b491a552a14cd4549c6a625bc))
+ - fix tests on windows ([`bb3b4f0`](https://github.com/Byron/gitoxide/commit/bb3b4f013c862a4c017c65075919e1df59cc1986))
+ - refactor ([`e1ba36f`](https://github.com/Byron/gitoxide/commit/e1ba36fab772417d9b60bf89cc49b45fbb7252f9))
+ - Merge branch 'main' into svetli-n-cont_include_if ([`315c87e`](https://github.com/Byron/gitoxide/commit/315c87e18c6cac0fafa7b4e59fdd3c076a58a45a))
+ - refactor ([`e47fb41`](https://github.com/Byron/gitoxide/commit/e47fb412a136d087c79710e7490d3e1c97d1f955))
+ - refactor ([`56eadc8`](https://github.com/Byron/gitoxide/commit/56eadc8b565b2f8a272080bc8814d6665b3f1205))
+ - refactor ([`0ccd8ae`](https://github.com/Byron/gitoxide/commit/0ccd8ae0ab01cdb5ae33dd79f486edfcee2b176a))
+ - Try fix windows test. ([`e2e94db`](https://github.com/Byron/gitoxide/commit/e2e94db2cee237168d5c56db5c5e94a8b4317991))
+ - Refactor include sequence test. ([`b4e657e`](https://github.com/Byron/gitoxide/commit/b4e657ed02cf062b1c2cb1f6c15abdf5d777c177))
+ - Extract include_paths. ([`c078671`](https://github.com/Byron/gitoxide/commit/c0786717c4979810002365a68d31abbf21d90f2d))
- Merge branch 'main' into davidkna-envopen ([`bc0abc6`](https://github.com/Byron/gitoxide/commit/bc0abc643d3329f885f250b6880560dec861150f))
- Make `realpath()` easier to use by introducing `realpath_opt()`. ([`266d437`](https://github.com/Byron/gitoxide/commit/266d4379e9132fd7dd21e6c8fccb36e125069d6e))
+ - Adjust test structure to mirror the new code structure. ([`984b58e`](https://github.com/Byron/gitoxide/commit/984b58ee1dac58fe0dfd0b80f990ca37d323cad7))
+ - Refact. ([`d5d81bc`](https://github.com/Byron/gitoxide/commit/d5d81bc16116b4c58f628e0e5c66d5d0a59b7816))
+ - Read include and incideIf sections in correct order. ([`a4a7ebd`](https://github.com/Byron/gitoxide/commit/a4a7ebdb6fcb5f6183917719d6c93f54eea72e85))
+ - Refact. ([`a342e53`](https://github.com/Byron/gitoxide/commit/a342e53dac58cea1787a94eaa1a9d24fb1389df2))
- Merge branch 'davidkna-discover-x-fs' ([`9abaeda`](https://github.com/Byron/gitoxide/commit/9abaeda2d22e2dbb1db1632c6eb637f1458d06e1))
diff --git a/git-config/Cargo.toml b/git-config/Cargo.toml
index 6a918a43991..8bc71da6630 100644
--- a/git-config/Cargo.toml
+++ b/git-config/Cargo.toml
@@ -15,11 +15,11 @@ include = ["src/**/*", "LICENSE-*", "README.md", "CHANGELOG.md"]
serde1 = ["serde", "bstr/serde1", "git-sec/serde1", "git-ref/serde1", "git-glob/serde1"]
[dependencies]
-git-features = { version = "^0.21.1", path = "../git-features"}
-git-path = { version = "^0.3.0", path = "../git-path" }
+git-features = { version = "^0.22.0", path = "../git-features"}
+git-path = { version = "^0.4.0", path = "../git-path" }
git-sec = { version = "^0.3.0", path = "../git-sec" }
git-ref = { version = "^0.15.0", path = "../git-ref" }
-git-glob = { version = "0.3.0", path = "../git-glob" }
+git-glob = { version = "^0.3.1", path = "../git-glob" }
nom = { version = "7", default_features = false, features = [ "std" ] }
memchr = "2"
diff --git a/git-config/src/file/access/comfort.rs b/git-config/src/file/access/comfort.rs
index af734c7649f..0f15288a724 100644
--- a/git-config/src/file/access/comfort.rs
+++ b/git-config/src/file/access/comfort.rs
@@ -2,11 +2,11 @@ use std::{borrow::Cow, convert::TryFrom};
use bstr::BStr;
-use crate::{value, File};
+use crate::{file::MetadataFilter, value, File};
/// Comfortable API for accessing values
impl<'event> File<'event> {
- /// Like [`value()`][File::value()], but returning an `None` if the string wasn't found.
+ /// Like [`value()`][File::value()], but returning `None` if the string wasn't found.
///
/// As strings perform no conversions, this will never fail.
pub fn string(
@@ -15,25 +15,49 @@ impl<'event> File<'event> {
subsection_name: Option<&str>,
key: impl AsRef,
) -> Option> {
- self.raw_value(section_name, subsection_name, key).ok()
+ self.string_filter(section_name, subsection_name, key, &mut |_| true)
+ }
+
+ /// Like [`string()`][File::string()], but the section containing the returned value must pass `filter` as well.
+ pub fn string_filter(
+ &self,
+ section_name: impl AsRef,
+ subsection_name: Option<&str>,
+ key: impl AsRef,
+ filter: &mut MetadataFilter,
+ ) -> Option> {
+ self.raw_value_filter(section_name, subsection_name, key, filter).ok()
}
/// Like [`value()`][File::value()], but returning `None` if the path wasn't found.
///
/// Note that this path is not vetted and should only point to resources which can't be used
- /// to pose a security risk.
+ /// to pose a security risk. Prefer using [`path_filter()`][File::path_filter()] instead.
///
/// As paths perform no conversions, this will never fail.
- // TODO: add `secure_path()` or similar to make use of our knowledge of the trust associated with each configuration
- // file, maybe even remove the insecure version to force every caller to ask themselves if the resource can
- // be used securely or not.
pub fn path(
&self,
section_name: impl AsRef,
subsection_name: Option<&str>,
key: impl AsRef,
) -> Option> {
- self.raw_value(section_name, subsection_name, key)
+ self.path_filter(section_name, subsection_name, key, &mut |_| true)
+ }
+
+ /// Like [`path()`][File::path()], but the section containing the returned value must pass `filter` as well.
+ ///
+ /// This should be the preferred way of accessing paths as those from untrusted
+ /// locations can be
+ ///
+ /// As paths perform no conversions, this will never fail.
+ pub fn path_filter(
+ &self,
+ section_name: impl AsRef,
+ subsection_name: Option<&str>,
+ key: impl AsRef,
+ filter: &mut MetadataFilter,
+ ) -> Option> {
+ self.raw_value_filter(section_name, subsection_name, key, filter)
.ok()
.map(crate::Path::from)
}
@@ -45,7 +69,18 @@ impl<'event> File<'event> {
subsection_name: Option<&str>,
key: impl AsRef,
) -> Option> {
- self.raw_value(section_name, subsection_name, key)
+ self.boolean_filter(section_name, subsection_name, key, &mut |_| true)
+ }
+
+ /// Like [`boolean()`][File::boolean()], but the section containing the returned value must pass `filter` as well.
+ pub fn boolean_filter(
+ &self,
+ section_name: impl AsRef,
+ subsection_name: Option<&str>,
+ key: impl AsRef,
+ filter: &mut MetadataFilter,
+ ) -> Option> {
+ self.raw_value_filter(section_name, subsection_name, key, filter)
.ok()
.map(|v| crate::Boolean::try_from(v).map(|b| b.into()))
}
@@ -57,7 +92,18 @@ impl<'event> File<'event> {
subsection_name: Option<&str>,
key: impl AsRef,
) -> Option> {
- let int = self.raw_value(section_name, subsection_name, key).ok()?;
+ self.integer_filter(section_name, subsection_name, key, &mut |_| true)
+ }
+
+ /// Like [`integer()`][File::integer()], but the section containing the returned value must pass `filter` as well.
+ pub fn integer_filter(
+ &self,
+ section_name: impl AsRef,
+ subsection_name: Option<&str>,
+ key: impl AsRef,
+ filter: &mut MetadataFilter,
+ ) -> Option> {
+ let int = self.raw_value_filter(section_name, subsection_name, key, filter).ok()?;
Some(crate::Integer::try_from(int.as_ref()).and_then(|b| {
b.to_decimal()
.ok_or_else(|| value::Error::new("Integer overflow", int.into_owned()))
@@ -74,6 +120,17 @@ impl<'event> File<'event> {
self.raw_values(section_name, subsection_name, key).ok()
}
+ /// Similar to [`strings(…)`][File::strings()], but all values are in sections that passed `filter`.
+ pub fn strings_filter(
+ &self,
+ section_name: impl AsRef,
+ subsection_name: Option<&str>,
+ key: impl AsRef,
+ filter: &mut MetadataFilter,
+ ) -> Option>> {
+ self.raw_values_filter(section_name, subsection_name, key, filter).ok()
+ }
+
/// Similar to [`values(…)`][File::values()] but returning integers if at least one of them was found
/// and if none of them overflows.
pub fn integers(
@@ -82,16 +139,30 @@ impl<'event> File<'event> {
subsection_name: Option<&str>,
key: impl AsRef,
) -> Option, value::Error>> {
- self.raw_values(section_name, subsection_name, key).ok().map(|values| {
- values
- .into_iter()
- .map(|v| {
- crate::Integer::try_from(v.as_ref()).and_then(|int| {
- int.to_decimal()
- .ok_or_else(|| value::Error::new("Integer overflow", v.into_owned()))
+ self.integers_filter(section_name, subsection_name, key, &mut |_| true)
+ }
+
+ /// Similar to [`integers(…)`][File::integers()] but all integers are in sections that passed `filter`
+ /// and that are not overflowing.
+ pub fn integers_filter(
+ &self,
+ section_name: impl AsRef,
+ subsection_name: Option<&str>,
+ key: impl AsRef,
+ filter: &mut MetadataFilter,
+ ) -> Option, value::Error>> {
+ self.raw_values_filter(section_name, subsection_name, key, filter)
+ .ok()
+ .map(|values| {
+ values
+ .into_iter()
+ .map(|v| {
+ crate::Integer::try_from(v.as_ref()).and_then(|int| {
+ int.to_decimal()
+ .ok_or_else(|| value::Error::new("Integer overflow", v.into_owned()))
+ })
})
- })
- .collect()
- })
+ .collect()
+ })
}
}
diff --git a/git-config/src/file/access/mod.rs b/git-config/src/file/access/mod.rs
index 1640081a16e..d602b5f8be2 100644
--- a/git-config/src/file/access/mod.rs
+++ b/git-config/src/file/access/mod.rs
@@ -2,4 +2,3 @@ mod comfort;
mod mutate;
mod raw;
mod read_only;
-mod write;
diff --git a/git-config/src/file/access/mutate.rs b/git-config/src/file/access/mutate.rs
index 509e6ca75f3..7810f7c32a3 100644
--- a/git-config/src/file/access/mutate.rs
+++ b/git-config/src/file/access/mutate.rs
@@ -1,30 +1,54 @@
use std::borrow::Cow;
+use git_features::threading::OwnShared;
+
use crate::{
- file::{rename_section, SectionBody, SectionMut},
+ file::{self, rename_section, write::ends_with_newline, MetadataFilter, SectionId, SectionMut},
lookup,
- parse::section,
+ parse::{section, Event, FrontMatterEvents},
File,
};
/// Mutating low-level access methods.
impl<'event> File<'event> {
- /// Returns an mutable section with a given name and optional subsection.
+ /// Returns an mutable section with a given `name` and optional `subsection_name`.
pub fn section_mut<'a>(
&'a mut self,
- section_name: impl AsRef,
+ name: impl AsRef,
subsection_name: Option<&str>,
) -> Result, lookup::existing::Error> {
let id = self
- .section_ids_by_name_and_subname(section_name.as_ref(), subsection_name)?
+ .section_ids_by_name_and_subname(name.as_ref(), subsection_name)?
.rev()
.next()
.expect("BUG: Section lookup vec was empty");
- Ok(SectionMut::new(
- self.sections
- .get_mut(&id)
- .expect("BUG: Section did not have id from lookup"),
- ))
+ let nl = self.detect_newline_style_smallvec();
+ Ok(self
+ .sections
+ .get_mut(&id)
+ .expect("BUG: Section did not have id from lookup")
+ .to_mut(nl))
+ }
+
+ /// Returns the last found mutable section with a given `name` and optional `subsection_name`, that matches `filter`.
+ ///
+ /// If there are sections matching `section_name` and `subsection_name` but the `filter` rejects all of them, `Ok(None)`
+ /// is returned.
+ pub fn section_mut_filter<'a>(
+ &'a mut self,
+ name: impl AsRef,
+ subsection_name: Option<&str>,
+ filter: &mut MetadataFilter,
+ ) -> Result