Unified · Split
| @@ -1240,6 +1240,7 @@ dependencies = [ · 1239 unmodified lines | ||
| 1240 | 1240 | "gix-utils 0.1.5", |
| 1241 | 1241 | "gix-validate 0.8.0", |
| 1242 | 1242 | "gix-worktree 0.24.0", |
| 1243 | + "gix-worktree-state", | |
| 1243 | 1244 | "gix-worktree-stream", |
| 1244 | 1245 | "is_ci", |
| 1245 | 1246 | "log", |
| @@ -1497,6 +1498,7 @@ dependencies = [ · 251 unmodified lines | ||
| 1497 | 1498 | name = "gix-diff" |
| 1498 | 1499 | version = "0.34.0" |
| 1499 | 1500 | dependencies = [ |
| 1501 | + "document-features", | |
| 1500 | 1502 | "getrandom", |
| 1501 | 1503 | "gix-hash 0.11.4", |
| 1502 | 1504 | "gix-object 0.34.0", |
| @@ -2215,6 +2217,22 @@ dependencies = [ · 712 unmodified lines | ||
| 2215 | 2217 | name = "gix-sequencer" |
| 2216 | 2218 | version = "0.0.0" |
| 2217 | 2219 | |
| 2220 | +[[package]] | |
| 2221 | +name = "gix-status" | |
| 2222 | +version = "0.1.0" | |
| 2223 | +dependencies = [ | |
| 2224 | + "bstr", | |
| 2225 | + "filetime", | |
| 2226 | + "gix-features 0.32.1", | |
| 2227 | + "gix-fs 0.4.1", | |
| 2228 | + "gix-hash 0.11.4", | |
| 2229 | + "gix-index 0.22.0", | |
| 2230 | + "gix-object 0.34.0", | |
| 2231 | + "gix-path 0.8.4", | |
| 2232 | + "gix-testtools", | |
| 2233 | + "thiserror", | |
| 2234 | +] | |
| 2235 | + | |
| 2218 | 2236 | [[package]] |
| 2219 | 2237 | name = "gix-submodule" |
| 2220 | 2238 | version = "0.1.0" |
| @@ -2449,10 +2467,8 @@ version = "0.24.0" · 228 unmodified lines | ||
| 2449 | 2467 | dependencies = [ |
| 2450 | 2468 | "bstr", |
| 2451 | 2469 | "document-features", |
| 2452 | − "filetime", | |
| 2453 | 2470 | "gix-attributes 0.16.0", |
| 2454 | 2471 | "gix-features 0.32.1", |
| 2455 | − "gix-filter", | |
| 2456 | 2472 | "gix-fs 0.4.1", |
| 2457 | 2473 | "gix-glob 0.10.2", |
| 2458 | 2474 | "gix-hash 0.11.4", |
| @@ -2462,11 +2478,29 @@ dependencies = [ · 3 unmodified lines | ||
| 2462 | 2478 | "gix-odb", |
| 2463 | 2479 | "gix-path 0.8.4", |
| 2464 | 2480 | "gix-testtools", |
| 2481 | + "serde", | |
| 2482 | + "symlink", | |
| 2483 | +] | |
| 2484 | + | |
| 2485 | +[[package]] | |
| 2486 | +name = "gix-worktree-state" | |
| 2487 | +version = "0.1.0" | |
| 2488 | +dependencies = [ | |
| 2489 | + "bstr", | |
| 2490 | + "gix-features 0.32.1", | |
| 2491 | + "gix-filter", | |
| 2492 | + "gix-fs 0.4.1", | |
| 2493 | + "gix-glob 0.10.2", | |
| 2494 | + "gix-hash 0.11.4", | |
| 2495 | + "gix-index 0.22.0", | |
| 2496 | + "gix-object 0.34.0", | |
| 2497 | + "gix-odb", | |
| 2498 | + "gix-path 0.8.4", | |
| 2499 | + "gix-testtools", | |
| 2500 | + "gix-worktree 0.24.0", | |
| 2465 | 2501 | "io-close", |
| 2466 | 2502 | "once_cell", |
| 2467 | − "serde", | |
| 2468 | 2503 | "symlink", |
| 2469 | − "tempfile", | |
| 2470 | 2504 | "thiserror", |
| 2471 | 2505 | "walkdir", |
| 2472 | 2506 | ] |
| @@ -235,6 +235,8 @@ members = [ · 234 unmodified lines | ||
| 235 | 235 | "gix-index", |
| 236 | 236 | "gix-bitmap", |
| 237 | 237 | "gix-worktree", |
| 238 | + "gix-worktree-state", | |
| 239 | + "gix-status", | |
| 238 | 240 | "gix-revision", |
| 239 | 241 | "gix-packetline", |
| 240 | 242 | "gix-packetline-blocking", |
| @@ -95,6 +95,8 @@ is usable to some extent. · 94 unmodified lines | ||
| 95 | 95 | * [gix-worktree-stream](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-worktree-stream) |
| 96 | 96 | * [gix-archive](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-archive) |
| 97 | 97 | * [gix-submodule](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-submodule) |
| 98 | + * [gix-status](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-status) | |
| 99 | + * [gix-worktree-state](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-worktree-state) | |
| 98 | 100 | * `gitoxide-core` |
| 99 | 101 | * **very early** _(possibly without any documentation and many rough edges)_ |
| 100 | 102 | * [gix-date](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-date) |
| @@ -453,28 +453,36 @@ Make it the best-performing implementation and the most convenient one. · 452 unmodified lines | ||
| 453 | 453 | ### gix-glob |
| 454 | 454 | * [x] parse pattern |
| 455 | 455 | * [x] a type for pattern matching of paths and non-paths, optionally case-insensitively. |
| 456 | − | |
| 457 | −### gix-worktree | |
| 456 | + | |
| 457 | +### gix-status | |
| 458 | +* [x] differences between index and worktree to turn index into worktree | |
| 459 | +* [ ] differences between tree and index to turn tree into index | |
| 460 | +* [ ] untracked files | |
| 461 | +* [ ] fast answer to 'is it dirty'. | |
| 462 | +* | |
| 463 | +### gix-worktree-state | |
| 458 | 464 | * handle the working **tree/checkout** |
| 459 | − - [x] checkout an index of files, executables and symlinks just as fast as git | |
| 460 | − - [x] forbid symlinks in directories | |
| 461 | − - [ ] handle submodules | |
| 462 | − - [ ] handle sparse directories | |
| 463 | − - [ ] handle sparse index | |
| 464 | − - [x] linear scaling with multi-threading up to IO saturation | |
| 465 | − - supported attributes to affect working tree and index contents | |
| 466 | − - [ ] eol | |
| 467 | − - [ ] working-tree-encoding | |
| 468 | − - …more | |
| 469 | − - **filtering** | |
| 470 | − - [ ] `text` | |
| 471 | − - [ ] `ident` | |
| 472 | − - [ ] filter processes | |
| 473 | − - [ ] single-invocation clean/smudge filters | |
| 474 | −* manage multiple worktrees | |
| 465 | + - [x] checkout an index of files, executables and symlinks just as fast as git | |
| 466 | + - [x] forbid symlinks in directories | |
| 467 | + - [ ] handle submodules | |
| 468 | + - [ ] handle sparse directories | |
| 469 | + - [ ] handle sparse index | |
| 470 | + - [x] linear scaling with multi-threading up to IO saturation | |
| 471 | + - supported attributes to affect working tree and index contents | |
| 472 | + - [x] eol | |
| 473 | + - [x] working-tree-encoding | |
| 474 | + - …more | |
| 475 | + - **filtering** | |
| 476 | + - [x] `text` | |
| 477 | + - [x] `ident` | |
| 478 | + - [x] filter processes | |
| 479 | + - [x] single-invocation clean/smudge filters | |
| 475 | 480 | * access to per-path information, like `.gitignore` and `.gitattributes` in a manner well suited for efficient lookups |
| 476 | − * [x] _exclude_ information | |
| 477 | − * [ ] attributes | |
| 481 | + * [x] _exclude_ information | |
| 482 | + * [x] attributes | |
| 483 | + | |
| 484 | +### gix-worktree | |
| 485 | +* [x] A stack to to efficiently generate attribute lists for matching paths against. | |
| 478 | 486 | |
| 479 | 487 | ### gix-revision |
| 480 | 488 | * [x] `describe()` (similar to `git name-rev`) |
Binary file not shown.
| @@ -0,0 +1,3 @@ | ||
| 1 | +╔════════════════╗ | |
| 2 | +║ gix-submodule ║ | |
| 3 | +╚════════════════╝ | |
| @@ -101,8 +101,8 @@ pub fn spawn_tree_delta_threads<'scope>( · 100 unmodified lines | ||
| 101 | 101 | repo.index_or_load_from_head().map_err(Into::into).and_then(|index| { |
| 102 | 102 | repo.attributes( |
| 103 | 103 | &index, |
| 104 | − gix::worktree::cache::state::attributes::Source::IdMapping, | |
| 105 | − gix::worktree::cache::state::ignore::Source::IdMapping, | |
| 104 | + gix::worktree::stack::state::attributes::Source::IdMapping, | |
| 105 | + gix::worktree::stack::state::ignore::Source::IdMapping, | |
| 106 | 106 | None, |
| 107 | 107 | ) |
| 108 | 108 | .map_err(Into::into) |
| @@ -4,7 +4,7 @@ use std::{ · 3 unmodified lines | ||
| 4 | 4 | }; |
| 5 | 5 | |
| 6 | 6 | use anyhow::bail; |
| 7 | −use gix::{odb::FindExt, worktree::checkout, Progress}; | |
| 7 | +use gix::{odb::FindExt, worktree::state::checkout, Progress}; | |
| 8 | 8 | |
| 9 | 9 | use crate::{ |
| 10 | 10 | index, |
| @@ -55,7 +55,7 @@ pub fn checkout_exclusive( · 44 unmodified lines | ||
| 55 | 55 | progress.info(format!("Skipping {num_skipped} DIR/SYMLINK/COMMIT entries")); |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | − let opts = gix::worktree::checkout::Options { | |
| 58 | + let opts = gix::worktree::state::checkout::Options { | |
| 59 | 59 | fs: gix::fs::Capabilities::probe(dest_directory), |
| 60 | 60 | |
| 61 | 61 | destination_is_initially_empty: true, |
| @@ -86,7 +86,7 @@ pub fn checkout_exclusive( · 24 unmodified lines | ||
| 86 | 86 | delayed_paths_unknown, |
| 87 | 87 | delayed_paths_unprocessed, |
| 88 | 88 | } = match repo { |
| 89 | − Some(repo) => gix::worktree::checkout( | |
| 89 | + Some(repo) => gix::worktree::state::checkout( | |
| 90 | 90 | &mut index, |
| 91 | 91 | dest_directory, |
| 92 | 92 | { |
| @@ -109,7 +109,7 @@ pub fn checkout_exclusive( · 16 unmodified lines | ||
| 109 | 109 | should_interrupt, |
| 110 | 110 | opts, |
| 111 | 111 | ), |
| 112 | − None => gix::worktree::checkout( | |
| 112 | + None => gix::worktree::state::checkout( | |
| 113 | 113 | &mut index, |
| 114 | 114 | dest_directory, |
| 115 | 115 | |_, buf| { |
| @@ -89,16 +89,16 @@ pub(crate) mod function { · 88 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | pub(crate) fn attributes_cache( |
| 91 | 91 | repo: &gix::Repository, |
| 92 | −) -> anyhow::Result<(gix::worktree::Cache, IndexPersistedOrInMemory)> { | |
| 92 | +) -> anyhow::Result<(gix::worktree::Stack, IndexPersistedOrInMemory)> { | |
| 93 | 93 | let index = repo.index_or_load_from_head()?; |
| 94 | 94 | let cache = repo.attributes( |
| 95 | 95 | &index, |
| 96 | 96 | if repo.is_bare() { |
| 97 | − gix::worktree::cache::state::attributes::Source::IdMapping | |
| 97 | + gix::worktree::stack::state::attributes::Source::IdMapping | |
| 98 | 98 | } else { |
| 99 | − gix::worktree::cache::state::attributes::Source::WorktreeThenIdMapping | |
| 99 | + gix::worktree::stack::state::attributes::Source::WorktreeThenIdMapping | |
| 100 | 100 | }, |
| 101 | − gix::worktree::cache::state::ignore::Source::IdMapping, | |
| 101 | + gix::worktree::stack::state::ignore::Source::IdMapping, | |
| 102 | 102 | None, |
| 103 | 103 | )?; |
| 104 | 104 | Ok((cache, index)) |
| @@ -111,7 +111,7 @@ pub(crate) mod function { · 110 unmodified lines | ||
| 111 | 111 | } |
| 112 | 112 | }; |
| 113 | 113 | |
| 114 | − if let Some(gix::worktree::checkout::Outcome { collisions, errors, .. }) = outcome { | |
| 114 | + if let Some(gix::worktree::state::checkout::Outcome { collisions, errors, .. }) = outcome { | |
| 115 | 115 | if !(collisions.is_empty() && errors.is_empty()) { |
| 116 | 116 | let mut messages = Vec::new(); |
| 117 | 117 | if !errors.is_empty() { |
| @@ -56,22 +56,22 @@ pub(crate) mod function { · 55 unmodified lines | ||
| 56 | 56 | match attrs { |
| 57 | 57 | Attributes::WorktreeAndIndex => { |
| 58 | 58 | if repo.is_bare() { |
| 59 | − gix::worktree::cache::state::attributes::Source::IdMapping | |
| 59 | + gix::worktree::stack::state::attributes::Source::IdMapping | |
| 60 | 60 | } else { |
| 61 | − gix::worktree::cache::state::attributes::Source::WorktreeThenIdMapping | |
| 61 | + gix::worktree::stack::state::attributes::Source::WorktreeThenIdMapping | |
| 62 | 62 | } |
| 63 | 63 | } |
| 64 | − Attributes::Index => gix::worktree::cache::state::attributes::Source::IdMapping, | |
| 64 | + Attributes::Index => gix::worktree::stack::state::attributes::Source::IdMapping, | |
| 65 | 65 | }, |
| 66 | 66 | match attrs { |
| 67 | 67 | Attributes::WorktreeAndIndex => { |
| 68 | 68 | if repo.is_bare() { |
| 69 | − gix::worktree::cache::state::ignore::Source::IdMapping | |
| 69 | + gix::worktree::stack::state::ignore::Source::IdMapping | |
| 70 | 70 | } else { |
| 71 | − gix::worktree::cache::state::ignore::Source::WorktreeThenIdMappingIfNotSkipped | |
| 71 | + gix::worktree::stack::state::ignore::Source::WorktreeThenIdMappingIfNotSkipped | |
| 72 | 72 | } |
| 73 | 73 | } |
| 74 | − Attributes::Index => gix::worktree::cache::state::ignore::Source::IdMapping, | |
| 74 | + Attributes::Index => gix::worktree::stack::state::ignore::Source::IdMapping, | |
| 75 | 75 | }, |
| 76 | 76 | None, |
| 77 | 77 | ) |
| @@ -203,7 +203,7 @@ pub(crate) mod function { · 125 unmodified lines | ||
| 203 | 203 | pub excluded: usize, |
| 204 | 204 | pub with_attributes: usize, |
| 205 | 205 | pub max_attributes_per_path: usize, |
| 206 | − pub cache: Option<gix::worktree::cache::Statistics>, | |
| 206 | + pub cache: Option<gix::worktree::stack::Statistics>, | |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | 209 | #[cfg(feature = "serde")] |
| @@ -11,7 +11,7 @@ mod from_tree { · 10 unmodified lines | ||
| 11 | 11 | use gix_object::tree::EntryMode; |
| 12 | 12 | use gix_odb::FindExt; |
| 13 | 13 | use gix_testtools::bstr::ByteSlice; |
| 14 | − use gix_worktree::cache::state::attributes::Source; | |
| 14 | + use gix_worktree::stack::state::attributes::Source; | |
| 15 | 15 | |
| 16 | 16 | use crate::hex_to_id; |
| 17 | 17 | |
| @@ -284,7 +284,7 @@ mod from_tree { · 266 unmodified lines | ||
| 284 | 284 | Ok(()) |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | − fn basic() -> gix_testtools::Result<(PathBuf, gix_hash::ObjectId, gix_odb::HandleArc, gix_worktree::Cache)> { | |
| 287 | + fn basic() -> gix_testtools::Result<(PathBuf, gix_hash::ObjectId, gix_odb::HandleArc, gix_worktree::Stack)> { | |
| 288 | 288 | let dir = gix_testtools::scripted_fixture_read_only("basic.sh")?; |
| 289 | 289 | |
| 290 | 290 | let head = { |
| @@ -295,14 +295,14 @@ mod from_tree { · 4 unmodified lines | ||
| 295 | 295 | |
| 296 | 296 | let mut collection = Default::default(); |
| 297 | 297 | let mut buf = Default::default(); |
| 298 | − let attributes = gix_worktree::cache::state::Attributes::new( | |
| 298 | + let attributes = gix_worktree::stack::state::Attributes::new( | |
| 299 | 299 | gix_attributes::Search::new_globals(None::<PathBuf>, &mut buf, &mut collection)?, |
| 300 | 300 | None, |
| 301 | 301 | Source::WorktreeThenIdMapping, |
| 302 | 302 | collection, |
| 303 | 303 | ); |
| 304 | − let state = gix_worktree::cache::State::AttributesStack(attributes); | |
| 305 | − let cache = gix_worktree::Cache::new(&dir, state, Case::Sensitive, Default::default(), Default::default()); | |
| 304 | + let state = gix_worktree::stack::State::AttributesStack(attributes); | |
| 305 | + let cache = gix_worktree::Stack::new(&dir, state, Case::Sensitive, Default::default(), Default::default()); | |
| 306 | 306 | Ok((dir, head, odb.into_arc()?, cache)) |
| 307 | 307 | } |
| 308 | 308 | |
| @@ -11,6 +11,9 @@ rust-version = "1.65" · 10 unmodified lines | ||
| 11 | 11 | autotests = false |
| 12 | 12 | |
| 13 | 13 | [features] |
| 14 | +default = ["blob"] | |
| 15 | +## Enable diffing of blobs using imara-diff. | |
| 16 | +blob = ["dep:imara-diff"] | |
| 14 | 17 | ## Data structures implement `serde::Serialize` and `serde::Deserialize`. |
| 15 | 18 | serde = ["dep:serde", "gix-hash/serde", "gix-object/serde"] |
| 16 | 19 | ## Make it possible to compile to the `wasm32-unknown-unknown` target. |
| @@ -23,6 +26,13 @@ doctest = false · 6 unmodified lines | ||
| 23 | 26 | gix-hash = { version = "^0.11.4", path = "../gix-hash" } |
| 24 | 27 | gix-object = { version = "^0.34.0", path = "../gix-object" } |
| 25 | 28 | thiserror = "1.0.32" |
| 26 | −imara-diff = "0.1.3" | |
| 29 | +imara-diff = { version = "0.1.3", optional = true } | |
| 27 | 30 | serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"]} |
| 28 | 31 | getrandom = { version = "0.2.8", optional = true, default-features = false, features = ["js"] } |
| 32 | + | |
| 33 | +document-features = { version = "0.2.0", optional = true } | |
| 34 | + | |
| 35 | +[package.metadata.docs.rs] | |
| 36 | +all-features = true | |
| 37 | +features = ["document-features"] | |
| 38 | +rustdoc-args = ["--cfg", "docsrs"] | |
| @@ -1,4 +1,10 @@ | ||
| 1 | 1 | //! Algorithms for diffing various git object types and for generating patches, highly optimized for performance. |
| 2 | +//! ## Feature Flags | |
| 3 | +#![cfg_attr( | |
| 4 | +feature = "document-features", | |
| 5 | +cfg_attr(doc, doc = ::document_features::document_features!()) | |
| 6 | +)] | |
| 7 | +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] | |
| 2 | 8 | #![deny(missing_docs, rust_2018_idioms)] |
| 3 | 9 | #![forbid(unsafe_code)] |
| 4 | 10 | |
| @@ -6,4 +12,5 @@ · 1 unmodified line | ||
| 6 | 12 | pub mod tree; |
| 7 | 13 | |
| 8 | 14 | /// |
| 15 | +#[cfg(feature = "blob")] | |
| 9 | 16 | pub mod blob; |
| @@ -17,22 +17,22 @@ fn default() -> crate::Result { · 16 unmodified lines | ||
| 17 | 17 | Ok(()) |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | −fn attribute_cache(name: &str) -> gix_testtools::Result<gix_worktree::Cache> { | |
| 20 | +fn attribute_cache(name: &str) -> gix_testtools::Result<gix_worktree::Stack> { | |
| 21 | 21 | let dir = gix_testtools::scripted_fixture_read_only("pipeline_repos.sh")?.join(name); |
| 22 | − Ok(gix_worktree::Cache::new( | |
| 22 | + Ok(gix_worktree::Stack::new( | |
| 23 | 23 | dir, |
| 24 | − gix_worktree::cache::State::for_add( | |
| 25 | − gix_worktree::cache::state::Attributes::new( | |
| 24 | + gix_worktree::stack::State::for_add( | |
| 25 | + gix_worktree::stack::state::Attributes::new( | |
| 26 | 26 | Default::default(), |
| 27 | 27 | None, |
| 28 | − gix_worktree::cache::state::attributes::Source::WorktreeThenIdMapping, | |
| 28 | + gix_worktree::stack::state::attributes::Source::WorktreeThenIdMapping, | |
| 29 | 29 | Default::default(), |
| 30 | 30 | ), |
| 31 | − gix_worktree::cache::state::Ignore::new( | |
| 31 | + gix_worktree::stack::state::Ignore::new( | |
| 32 | 32 | Default::default(), |
| 33 | 33 | Default::default(), |
| 34 | 34 | None, |
| 35 | − gix_worktree::cache::state::ignore::Source::WorktreeThenIdMappingIfNotSkipped, | |
| 35 | + gix_worktree::stack::state::ignore::Source::WorktreeThenIdMappingIfNotSkipped, | |
| 36 | 36 | ), |
| 37 | 37 | ), |
| 38 | 38 | Case::Sensitive, |
| @@ -49,7 +49,7 @@ fn pipeline( · 10 unmodified lines | ||
| 49 | 49 | gix_filter::pipeline::CrlfRoundTripCheck, |
| 50 | 50 | eol::Configuration, |
| 51 | 51 | ), |
| 52 | −) -> gix_testtools::Result<(gix_worktree::Cache, gix_filter::Pipeline)> { | |
| 52 | +) -> gix_testtools::Result<(gix_worktree::Stack, gix_filter::Pipeline)> { | |
| 53 | 53 | let cache = attribute_cache(name)?; |
| 54 | 54 | let (drivers, encodings_with_roundtrip_check, crlf_roundtrip_check, eol_config) = init(); |
| 55 | 55 | let pipe = gix_filter::Pipeline::new( |
File renamed without changes.
| @@ -0,0 +1,37 @@ | ||
| 1 | +[package] | |
| 2 | +name = "gix-status" | |
| 3 | +version = "0.1.0" | |
| 4 | +repository = "https://github.com/Byron/gitoxide" | |
| 5 | +license = "MIT OR Apache-2.0" | |
| 6 | +description = "A crate of the gitoxide project dealing with 'git status'-like functionality" | |
| 7 | +authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>", "Pascal Kuthe <pascal.kuthe@semimod.de>"] | |
| 8 | +edition = "2021" | |
| 9 | +include = ["src/**/*", "LICENSE-*", "CHANGELOG.md"] | |
| 10 | +rust-version = "1.65" | |
| 11 | + | |
| 12 | +[lib] | |
| 13 | +doctest = false | |
| 14 | + | |
| 15 | +[[test]] | |
| 16 | +name = "multi-threaded" | |
| 17 | +path = "tests/status-multi-threaded.rs" | |
| 18 | +required-features = ["internal-testing-gix-features-parallel"] | |
| 19 | + | |
| 20 | +[features] | |
| 21 | +internal-testing-gix-features-parallel = ["gix-features/parallel"] | |
| 22 | + | |
| 23 | +[dependencies] | |
| 24 | +gix-index = { version = "^0.22.0", path = "../gix-index" } | |
| 25 | +gix-fs = { version = "^0.4.1", path = "../gix-fs" } | |
| 26 | +gix-hash = { version = "^0.11.4", path = "../gix-hash" } | |
| 27 | +gix-object = { version = "^0.34.0", path = "../gix-object" } | |
| 28 | +gix-path = { version = "^0.8.4", path = "../gix-path" } | |
| 29 | +gix-features = { version = "^0.32.1", path = "../gix-features" } | |
| 30 | + | |
| 31 | +thiserror = "1.0.26" | |
| 32 | +filetime = "0.2.15" | |
| 33 | +bstr = { version = "1.3.0", default-features = false } | |
| 34 | + | |
| 35 | +[dev-dependencies] | |
| 36 | +gix-testtools = { path = "../tests/tools" } | |
| 37 | + | |
| @@ -0,0 +1 @@ | ||
| 1 | +../LICENSE-APACHE | |
| @@ -0,0 +1 @@ | ||
| 1 | +../LICENSE-MIT | |
File renamed without changes.
| @@ -5,13 +5,13 @@ use filetime::FileTime; · 4 unmodified lines | ||
| 5 | 5 | use gix_features::parallel::{in_parallel_if, Reduce}; |
| 6 | 6 | |
| 7 | 7 | use crate::{ |
| 8 | − read, | |
| 9 | − status::{ | |
| 8 | + index_as_worktree::{ | |
| 10 | 9 | content, |
| 11 | 10 | content::CompareBlobs, |
| 12 | 11 | types::{Error, Options}, |
| 13 | 12 | Change, VisitEntry, |
| 14 | 13 | }, |
| 14 | + read, | |
| 15 | 15 | }; |
| 16 | 16 | |
| 17 | 17 | /// Calculates the changes that need to be applied to an `index` to match the state of the `worktree` and makes them |
| @@ -24,7 +24,7 @@ use crate::{ · 6 unmodified lines | ||
| 24 | 24 | /// Note that this isn't technically quite what this function does as this also provides some additional information, |
| 25 | 25 | /// like whether a file has conflicts, and files that were added with `git add` are shown as a special |
| 26 | 26 | /// changes despite not technically requiring a change to the index since `git add` already added the file to the index. |
| 27 | −pub fn status<'index, T, Find, E>( | |
| 27 | +pub fn index_as_worktree<'index, T, Find, E>( | |
| 28 | 28 | index: &'index mut gix_index::State, |
| 29 | 29 | worktree: &Path, |
| 30 | 30 | collector: &mut impl VisitEntry<'index, ContentChange = T>, |
File renamed without changes.
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | use bstr::BStr; |
| 2 | 2 | use gix_index as index; |
| 3 | 3 | |
| 4 | −use crate::status::{Change, VisitEntry}; | |
| 4 | +use crate::index_as_worktree::{Change, VisitEntry}; | |
| 5 | 5 | |
| 6 | 6 | /// Convenience implementation of [`VisitEntry`] that collects all non-trivial changes into a `Vec`. |
| 7 | 7 | #[derive(Debug, Default)] |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | use bstr::BStr; |
| 2 | 2 | |
| 3 | −/// The error returned by [`status()`][crate::status()]. | |
| 3 | +/// The error returned by [`status()`](crate::index_as_worktree()). | |
| 4 | 4 | #[derive(Debug, thiserror::Error)] |
| 5 | 5 | #[allow(missing_docs)] |
| 6 | 6 | pub enum Error { |
| @@ -40,7 +40,7 @@ pub enum Change<T = ()> { · 33 unmodified lines | ||
| 40 | 40 | /// Indicates that one of the stat changes was an executable bit change |
| 41 | 41 | /// which is a significant change itself. |
| 42 | 42 | executable_bit_changed: bool, |
| 43 | − /// The output of the [`CompareBlobs`][crate::status::content::CompareBlobs] run on this entry. | |
| 43 | + /// The output of the [`CompareBlobs`](crate::index_as_worktree::content::CompareBlobs) run on this entry. | |
| 44 | 44 | /// If there is no content change and only the executable bit |
| 45 | 45 | /// changed than this is `None`. |
| 46 | 46 | content_change: Option<T>, |
| @@ -0,0 +1,15 @@ | ||
| 1 | +//! This crate includes the various diffs `git` can do between different representations | |
| 2 | +//! of the repository state, like comparisons between… | |
| 3 | +//! | |
| 4 | +//! * index and working tree | |
| 5 | +//! * index and tree | |
| 6 | +//! * find untracked files | |
| 7 | +//! | |
| 8 | +//! While also being able to check check if the working tree is dirty, quickly. | |
| 9 | +#![deny(missing_docs, rust_2018_idioms, unsafe_code)] | |
| 10 | + | |
| 11 | +/// | |
| 12 | +pub mod read; | |
| 13 | + | |
| 14 | +pub mod index_as_worktree; | |
| 15 | +pub use index_as_worktree::function::index_as_worktree; | |
| @@ -10,7 +10,6 @@ use std::{ · 9 unmodified lines | ||
| 10 | 10 | }; |
| 11 | 11 | |
| 12 | 12 | use gix_object::Blob; |
| 13 | −use gix_path as path; | |
| 14 | 13 | |
| 15 | 14 | // TODO: tests |
| 16 | 15 | |
| @@ -49,7 +48,7 @@ pub fn data_to_buf_with_meta<'a>( · 32 unmodified lines | ||
| 49 | 48 | if is_symlink && capabilities.symlink { |
| 50 | 49 | // conversion to bstr can never fail because symlinks are only used |
| 51 | 50 | // on unix (by git) so no reason to use the try version here |
| 52 | − let symlink_path = path::into_bstr(read_link(path)?); | |
| 51 | + let symlink_path = gix_path::into_bstr(read_link(path)?); | |
| 53 | 52 | buf.extend_from_slice(&symlink_path); |
| 54 | 53 | // TODO: there is no reason this should be a clone |
| 55 | 54 | // std isn't great about allowing users to avoid allocations but we could |
| @@ -0,0 +1,2 @@ | ||
| 1 | +status_unchanged.tar.xz | |
| 2 | +status_changed.tar.xz | |
| @@ -0,0 +1,3 @@ | ||
| 1 | +version https://git-lfs.github.com/spec/v1 | |
| 2 | +oid sha256:c78c306d8a19ce7f09a4cdf284e761d9c7766a3491bfb83751b9e6f6bc8fc1c9 | |
| 3 | +size 9812 | |
| @@ -0,0 +1,3 @@ | ||
| 1 | +version https://git-lfs.github.com/spec/v1 | |
| 2 | +oid sha256:b64431478ff4ee4613d2e1fe0766b4da8aeac8f4dee2b42726efb6d2e87bc830 | |
| 3 | +size 11012 | |
| @@ -0,0 +1,3 @@ | ||
| 1 | +version https://git-lfs.github.com/spec/v1 | |
| 2 | +oid sha256:d8fa2e8085d464945eade89cfa9dadb89345c584b1d72a535d464859f02950a7 | |
| 3 | +size 9280 | |
| @@ -0,0 +1,3 @@ | ||
| 1 | +version https://git-lfs.github.com/spec/v1 | |
| 2 | +oid sha256:cbc72bb3b08e421928d4402b49100a4ac144b4cdcc84ab70e6b721ec5ce4546c | |
| 3 | +size 10568 | |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -0,0 +1,4 @@ | ||
| 1 | +#[cfg(feature = "internal-testing-gix-features-parallel")] | |
| 2 | +mod status; | |
| 3 | +#[cfg(feature = "internal-testing-gix-features-parallel")] | |
| 4 | +use status::*; | |
| @@ -0,0 +1,4 @@ | ||
| 1 | +#[cfg(not(feature = "internal-testing-gix-features-parallel"))] | |
| 2 | +mod status; | |
| 3 | +#[cfg(not(feature = "internal-testing-gix-features-parallel"))] | |
| 4 | +use status::*; | |
| @@ -7,9 +7,9 @@ use bstr::BStr; · 6 unmodified lines | ||
| 7 | 7 | use filetime::{set_file_mtime, FileTime}; |
| 8 | 8 | use gix_index as index; |
| 9 | 9 | use gix_index::Entry; |
| 10 | −use gix_worktree::{ | |
| 11 | − status, | |
| 12 | − status::{ | |
| 10 | +use gix_status::{ | |
| 11 | + index_as_worktree, | |
| 12 | + index_as_worktree::{ | |
| 13 | 13 | content::{CompareBlobs, FastEq, ReadDataOnce}, |
| 14 | 14 | Change, Options, Recorder, |
| 15 | 15 | }, |
| @@ -33,7 +33,7 @@ fn fixture(name: &str, expected_status: &[(&BStr, Option<Change>, bool)]) { · 17 unmodified lines | ||
| 33 | 33 | let git_dir = worktree.join(".git"); |
| 34 | 34 | let mut index = gix_index::File::at(git_dir.join("index"), gix_hash::Kind::Sha1, Default::default()).unwrap(); |
| 35 | 35 | let mut recorder = Recorder::default(); |
| 36 | − status( | |
| 36 | + index_as_worktree( | |
| 37 | 37 | &mut index, |
| 38 | 38 | &worktree, |
| 39 | 39 | &mut recorder, |
| @@ -172,7 +172,7 @@ fn racy_git() { · 132 unmodified lines | ||
| 172 | 172 | |
| 173 | 173 | let count = Arc::new(AtomicUsize::new(0)); |
| 174 | 174 | let counter = CountCalls(count.clone(), FastEq); |
| 175 | − status( | |
| 175 | + index_as_worktree( | |
| 176 | 176 | &mut index, |
| 177 | 177 | worktree, |
| 178 | 178 | &mut recorder, |
| @@ -193,7 +193,7 @@ fn racy_git() { · 14 unmodified lines | ||
| 193 | 193 | // and cause proper output. |
| 194 | 194 | index.set_timestamp(FileTime::from_unix_time(timestamp as i64, 0)); |
| 195 | 195 | let mut recorder = Recorder::default(); |
| 196 | − status( | |
| 196 | + index_as_worktree( | |
| 197 | 197 | &mut index, |
| 198 | 198 | worktree, |
| 199 | 199 | &mut recorder, |
| @@ -0,0 +1,7 @@ | ||
| 1 | +mod index_as_worktree; | |
| 2 | + | |
| 3 | +pub fn fixture_path(name: &str) -> std::path::PathBuf { | |
| 4 | + let dir = gix_testtools::scripted_fixture_read_only(std::path::Path::new(name).with_extension("sh")) | |
| 5 | + .expect("script works"); | |
| 6 | + dir | |
| 7 | +} | |
| @@ -0,0 +1,44 @@ | ||
| 1 | +[package] | |
| 2 | +name = "gix-worktree-state" | |
| 3 | +version = "0.1.0" | |
| 4 | +repository = "https://github.com/Byron/gitoxide" | |
| 5 | +license = "MIT OR Apache-2.0" | |
| 6 | +description = "A crate of the gitoxide project implementing setting the worktree to a particular state" | |
| 7 | +authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"] | |
| 8 | +edition = "2021" | |
| 9 | +include = ["src/**/*", "LICENSE-*", "CHANGELOG.md"] | |
| 10 | +rust-version = "1.65" | |
| 11 | + | |
| 12 | +[lib] | |
| 13 | +doctest = false | |
| 14 | + | |
| 15 | +[[test]] | |
| 16 | +name = "multi-threaded" | |
| 17 | +path = "tests/state-multi-threaded.rs" | |
| 18 | +required-features = ["internal-testing-gix-features-parallel"] | |
| 19 | + | |
| 20 | +[features] | |
| 21 | +internal-testing-gix-features-parallel = ["gix-features/parallel"] | |
| 22 | + | |
| 23 | +[dependencies] | |
| 24 | +gix-worktree = { version = "^0.24.0", path = "../gix-worktree" } | |
| 25 | +gix-index = { version = "^0.22.0", path = "../gix-index" } | |
| 26 | +gix-fs = { version = "^0.4.1", path = "../gix-fs" } | |
| 27 | +gix-hash = { version = "^0.11.4", path = "../gix-hash" } | |
| 28 | +gix-object = { version = "^0.34.0", path = "../gix-object" } | |
| 29 | +gix-glob = { version = "^0.10.2", path = "../gix-glob" } | |
| 30 | +gix-path = { version = "^0.8.4", path = "../gix-path" } | |
| 31 | +gix-features = { version = "^0.32.1", path = "../gix-features" } | |
| 32 | +gix-filter = { version = "^0.3.0", path = "../gix-filter" } | |
| 33 | + | |
| 34 | +io-close = "0.3.7" | |
| 35 | +thiserror = "1.0.26" | |
| 36 | +bstr = { version = "1.3.0", default-features = false } | |
| 37 | + | |
| 38 | +[dev-dependencies] | |
| 39 | +gix-testtools = { path = "../tests/tools" } | |
| 40 | +gix-odb = { path = "../gix-odb" } | |
| 41 | +symlink = "0.1.0" | |
| 42 | +once_cell = "1.18.0" | |
| 43 | + | |
| 44 | +walkdir = "2.3.2" | |
| @@ -0,0 +1 @@ | ||
| 1 | +../LICENSE-APACHE | |
| @@ -0,0 +1 @@ | ||
| 1 | +../LICENSE-MIT | |
| @@ -6,7 +6,8 @@ use std::{ · 5 unmodified lines | ||
| 6 | 6 | use bstr::{BStr, BString}; |
| 7 | 7 | use gix_hash::oid; |
| 8 | 8 | |
| 9 | −use crate::{checkout, checkout::entry, Cache}; | |
| 9 | +use crate::{checkout, checkout::entry}; | |
| 10 | +use gix_worktree::Stack; | |
| 10 | 11 | |
| 11 | 12 | mod reduce { |
| 12 | 13 | use std::marker::PhantomData; |
| @@ -91,7 +92,7 @@ pub struct Outcome<'a> { · 78 unmodified lines | ||
| 91 | 92 | #[derive(Clone)] |
| 92 | 93 | pub struct Context<Find: Clone> { |
| 93 | 94 | pub find: Find, |
| 94 | − pub path_cache: Cache, | |
| 95 | + pub path_cache: Stack, | |
| 95 | 96 | pub filters: gix_filter::Pipeline, |
| 96 | 97 | pub buf: Vec<u8>, |
| 97 | 98 | pub options: Options, |
| @@ -10,11 +10,11 @@ use gix_hash::oid; · 9 unmodified lines | ||
| 10 | 10 | use gix_index::{entry::Stat, Entry}; |
| 11 | 11 | use io_close::Close; |
| 12 | 12 | |
| 13 | −use crate::Cache; | |
| 13 | +use gix_worktree::Stack; | |
| 14 | 14 | |
| 15 | 15 | pub struct Context<'a, Find> { |
| 16 | 16 | pub find: &'a mut Find, |
| 17 | − pub path_cache: &'a mut Cache, | |
| 17 | + pub path_cache: &'a mut Stack, | |
| 18 | 18 | pub filters: &'a mut gix_filter::Pipeline, |
| 19 | 19 | pub buf: &'a mut Vec<u8>, |
| 20 | 20 | } |
| @@ -3,7 +3,8 @@ use std::sync::atomic::AtomicBool; · 2 unmodified lines | ||
| 3 | 3 | use gix_features::{interrupt, parallel::in_parallel_with_finalize, progress::Progress}; |
| 4 | 4 | use gix_hash::oid; |
| 5 | 5 | |
| 6 | −use crate::{cache, checkout::chunk, Cache}; | |
| 6 | +use crate::checkout::chunk; | |
| 7 | +use gix_worktree::{stack, Stack}; | |
| 7 | 8 | |
| 8 | 9 | /// Checkout the entire `index` into `dir`, and resolve objects found in index entries with `find` to write their content to their |
| 9 | 10 | /// respective path in `dir`. |
| @@ -65,12 +66,12 @@ where · 55 unmodified lines | ||
| 65 | 66 | None, |
| 66 | 67 | ); |
| 67 | 68 | |
| 68 | − let state = cache::State::for_checkout(options.overwrite_existing, std::mem::take(&mut options.attributes)); | |
| 69 | + let state = stack::State::for_checkout(options.overwrite_existing, std::mem::take(&mut options.attributes)); | |
| 69 | 70 | let attribute_files = state.id_mappings_from_index(index, paths, case); |
| 70 | 71 | let mut ctx = chunk::Context { |
| 71 | 72 | buf: Vec::new(), |
| 72 | 73 | options: (&options).into(), |
| 73 | − path_cache: Cache::new(dir, state, case, Vec::with_capacity(512), attribute_files), | |
| 74 | + path_cache: Stack::new(dir, state, case, Vec::with_capacity(512), attribute_files), | |
| 74 | 75 | filters: options.filters, |
| 75 | 76 | find, |
| 76 | 77 | }; |
| @@ -60,7 +60,7 @@ pub struct Options { · 59 unmodified lines | ||
| 60 | 60 | /// Control how stat comparisons are made when checking if a file is fresh. |
| 61 | 61 | pub stat_options: stat::Options, |
| 62 | 62 | /// A stack of attributes to use with the filesystem cache to use as driver for filters. |
| 63 | − pub attributes: crate::cache::state::Attributes, | |
| 63 | + pub attributes: gix_worktree::stack::state::Attributes, | |
| 64 | 64 | /// The filter pipeline to use for applying mandatory filters before writing to the worktree. |
| 65 | 65 | pub filters: gix_filter::Pipeline, |
| 66 | 66 | /// Control how long-running processes may use the 'delay' capability. |
| @@ -0,0 +1,6 @@ | ||
| 1 | +//! A crate to help setting the worktree to a particular state. | |
| 2 | +#![deny(missing_docs, rust_2018_idioms, unsafe_code)] | |
| 3 | + | |
| 4 | +/// | |
| 5 | +pub mod checkout; | |
| 6 | +pub use checkout::function::checkout; | |
| @@ -0,0 +1,5 @@ | ||
| 1 | +make_ignore_and_attributes_setup.tar.xz | |
| 2 | +make_mixed_without_submodules.tar.xz | |
| 3 | +make_mixed_without_submodules_and_symlinks.tar.xz | |
| 4 | +make_attributes_baseline.tar.xz | |
| 5 | +make_dangerous_symlink.tar.xz | |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -0,0 +1,4 @@ | ||
| 1 | +#[cfg(feature = "internal-testing-gix-features-parallel")] | |
| 2 | +mod state; | |
| 3 | +#[cfg(feature = "internal-testing-gix-features-parallel")] | |
| 4 | +use state::*; | |
| @@ -0,0 +1,4 @@ | ||
| 1 | +#[cfg(not(feature = "internal-testing-gix-features-parallel"))] | |
| 2 | +mod state; | |
| 3 | +#[cfg(not(feature = "internal-testing-gix-features-parallel"))] | |
| 4 | +use state::*; | |
| @@ -10,9 +10,9 @@ use std::{ · 9 unmodified lines | ||
| 10 | 10 | use gix_features::progress; |
| 11 | 11 | use gix_object::bstr::ByteSlice; |
| 12 | 12 | use gix_odb::FindExt; |
| 13 | −use gix_worktree::checkout::Collision; | |
| 13 | +use gix_testtools::tempfile::TempDir; | |
| 14 | +use gix_worktree_state::checkout::Collision; | |
| 14 | 15 | use once_cell::sync::Lazy; |
| 15 | −use tempfile::TempDir; | |
| 16 | 16 | |
| 17 | 17 | use crate::fixture_path; |
| 18 | 18 | |
| @@ -454,26 +454,26 @@ pub fn dir_structure<P: AsRef<std::path::Path>>(path: P) -> Vec<std::path::PathB · 435 unmodified lines | ||
| 454 | 454 | } |
| 455 | 455 | |
| 456 | 456 | fn checkout_index_in_tmp_dir( |
| 457 | − opts: gix_worktree::checkout::Options, | |
| 457 | + opts: gix_worktree_state::checkout::Options, | |
| 458 | 458 | name: &str, |
| 459 | −) -> crate::Result<(PathBuf, TempDir, gix_index::File, gix_worktree::checkout::Outcome)> { | |
| 459 | +) -> crate::Result<(PathBuf, TempDir, gix_index::File, gix_worktree_state::checkout::Outcome)> { | |
| 460 | 460 | checkout_index_in_tmp_dir_opts(opts, name, |_d| true, |_| Ok(())) |
| 461 | 461 | } |
| 462 | 462 | |
| 463 | 463 | fn checkout_index_in_tmp_dir_opts( |
| 464 | − opts: gix_worktree::checkout::Options, | |
| 464 | + opts: gix_worktree_state::checkout::Options, | |
| 465 | 465 | name: &str, |
| 466 | 466 | mut allow_return_object: impl FnMut(&gix_hash::oid) -> bool + Send + Clone, |
| 467 | 467 | prep_dest: impl Fn(&Path) -> std::io::Result<()>, |
| 468 | −) -> crate::Result<(PathBuf, TempDir, gix_index::File, gix_worktree::checkout::Outcome)> { | |
| 468 | +) -> crate::Result<(PathBuf, TempDir, gix_index::File, gix_worktree_state::checkout::Outcome)> { | |
| 469 | 469 | let source_tree = fixture_path(name); |
| 470 | 470 | let git_dir = source_tree.join(".git"); |
| 471 | 471 | let mut index = gix_index::File::at(git_dir.join("index"), gix_hash::Kind::Sha1, Default::default())?; |
| 472 | 472 | let odb = gix_odb::at(git_dir.join("objects"))?.into_inner().into_arc()?; |
| 473 | − let destination = tempfile::tempdir_in(std::env::current_dir()?)?; | |
| 473 | + let destination = gix_testtools::tempfile::tempdir_in(std::env::current_dir()?)?; | |
| 474 | 474 | prep_dest(destination.path()).expect("preparation must succeed"); |
| 475 | 475 | |
| 476 | − let outcome = gix_worktree::checkout( | |
| 476 | + let outcome = gix_worktree_state::checkout( | |
| 477 | 477 | &mut index, |
| 478 | 478 | destination.path(), |
| 479 | 479 | move |oid, buf| { |
| @@ -501,8 +501,8 @@ fn probe_gitoxide_dir() -> crate::Result<gix_fs::Capabilities> { · 21 unmodified lines | ||
| 501 | 501 | )) |
| 502 | 502 | } |
| 503 | 503 | |
| 504 | −fn opts_from_probe() -> gix_worktree::checkout::Options { | |
| 505 | − gix_worktree::checkout::Options { | |
| 504 | +fn opts_from_probe() -> gix_worktree_state::checkout::Options { | |
| 505 | + gix_worktree_state::checkout::Options { | |
| 506 | 506 | fs: probe_gitoxide_dir().unwrap(), |
| 507 | 507 | destination_is_initially_empty: true, |
| 508 | 508 | thread_limit: gix_features::parallel::num_threads(None).into(), |
| @@ -0,0 +1,10 @@ | ||
| 1 | +mod checkout; | |
| 2 | + | |
| 3 | +use std::path::{Path, PathBuf}; | |
| 4 | + | |
| 5 | +pub type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error>>; | |
| 6 | + | |
| 7 | +pub fn fixture_path(name: &str) -> PathBuf { | |
| 8 | + let dir = gix_testtools::scripted_fixture_read_only(Path::new(name).with_extension("sh")).expect("script works"); | |
| 9 | + dir | |
| 10 | +} | |
| @@ -15,7 +15,7 @@ mod from_tree { · 14 unmodified lines | ||
| 15 | 15 | use gix_object::{bstr::ByteSlice, tree::EntryMode}; |
| 16 | 16 | use gix_odb::FindExt; |
| 17 | 17 | use gix_testtools::once_cell::sync::Lazy; |
| 18 | − use gix_worktree::cache::state::attributes::Source; | |
| 18 | + use gix_worktree::stack::state::attributes::Source; | |
| 19 | 19 | |
| 20 | 20 | use crate::hex_to_id; |
| 21 | 21 | |
| @@ -231,7 +231,7 @@ mod from_tree { · 209 unmodified lines | ||
| 231 | 231 | Ok(()) |
| 232 | 232 | } |
| 233 | 233 | |
| 234 | − fn basic() -> gix_testtools::Result<(PathBuf, gix_hash::ObjectId, gix_odb::HandleArc, gix_worktree::Cache)> { | |
| 234 | + fn basic() -> gix_testtools::Result<(PathBuf, gix_hash::ObjectId, gix_odb::HandleArc, gix_worktree::Stack)> { | |
| 235 | 235 | let dir = gix_testtools::scripted_fixture_read_only("basic.sh")?; |
| 236 | 236 | |
| 237 | 237 | let head = { |
| @@ -242,14 +242,14 @@ mod from_tree { · 4 unmodified lines | ||
| 242 | 242 | |
| 243 | 243 | let mut collection = Default::default(); |
| 244 | 244 | let mut buf = Default::default(); |
| 245 | − let attributes = gix_worktree::cache::state::Attributes::new( | |
| 245 | + let attributes = gix_worktree::stack::state::Attributes::new( | |
| 246 | 246 | gix_attributes::Search::new_globals(None::<PathBuf>, &mut buf, &mut collection)?, |
| 247 | 247 | None, |
| 248 | 248 | Source::WorktreeThenIdMapping, |
| 249 | 249 | collection, |
| 250 | 250 | ); |
| 251 | − let state = gix_worktree::cache::State::AttributesStack(attributes); | |
| 252 | − let cache = gix_worktree::Cache::new(&dir, state, Case::Sensitive, Default::default(), Default::default()); | |
| 251 | + let state = gix_worktree::stack::State::AttributesStack(attributes); | |
| 252 | + let cache = gix_worktree::Stack::new(&dir, state, Case::Sensitive, Default::default(), Default::default()); | |
| 253 | 253 | Ok((dir, head, odb.into_arc()?, cache)) |
| 254 | 254 | } |
| 255 | 255 | |
| @@ -3,7 +3,7 @@ name = "gix-worktree" · 2 unmodified lines | ||
| 3 | 3 | version = "0.24.0" |
| 4 | 4 | repository = "https://github.com/Byron/gitoxide" |
| 5 | 5 | license = "MIT OR Apache-2.0" |
| 6 | −description = "A crate of the gitoxide project dedicated implementing everything around working trees and git excludes" | |
| 6 | +description = "A crate of the gitoxide project for shared worktree related types and utilities." | |
| 7 | 7 | authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"] |
| 8 | 8 | edition = "2021" |
| 9 | 9 | include = ["src/**/*", "LICENSE-*", "CHANGELOG.md"] |
| @@ -33,25 +33,17 @@ gix-path = { version = "^0.8.4", path = "../gix-path" } · 23 unmodified lines | ||
| 33 | 33 | gix-attributes = { version = "^0.16.0", path = "../gix-attributes" } |
| 34 | 34 | gix-ignore = { version = "^0.5.1", path = "../gix-ignore" } |
| 35 | 35 | gix-features = { version = "^0.32.1", path = "../gix-features" } |
| 36 | −gix-filter = { version = "^0.3.0", path = "../gix-filter" } | |
| 37 | 36 | |
| 38 | 37 | serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"]} |
| 39 | 38 | |
| 40 | −thiserror = "1.0.26" | |
| 41 | −filetime = "0.2.15" | |
| 42 | 39 | bstr = { version = "1.3.0", default-features = false } |
| 43 | 40 | |
| 44 | 41 | document-features = { version = "0.2.0", optional = true } |
| 45 | −io-close = "0.3.7" | |
| 46 | 42 | |
| 47 | 43 | [dev-dependencies] |
| 48 | 44 | gix-testtools = { path = "../tests/tools" } |
| 49 | 45 | gix-odb = { path = "../gix-odb" } |
| 50 | 46 | symlink = "0.1.0" |
| 51 | −once_cell = "1.18.0" | |
| 52 | − | |
| 53 | −walkdir = "2.3.2" | |
| 54 | −tempfile = "3.2.0" | |
| 55 | 47 | |
| 56 | 48 | [package.metadata.docs.rs] |
| 57 | 49 | features = ["document-features", "serde"] |
| @@ -1,4 +1,4 @@ | ||
| 1 | −//! A crate with all index-centric functionality that is interacting with a worktree. | |
| 1 | +//! A crate with utility types for use by other crates that implement specifics. | |
| 2 | 2 | //! |
| 3 | 3 | //! Unless specified differently, all operations need an index file (e.g. `.git/index`) as driver. |
| 4 | 4 | //! |
| @@ -11,9 +11,6 @@ · 6 unmodified lines | ||
| 11 | 11 | #![deny(missing_docs, rust_2018_idioms, unsafe_code)] |
| 12 | 12 | use bstr::BString; |
| 13 | 13 | |
| 14 | −/// | |
| 15 | −pub mod read; | |
| 16 | − | |
| 17 | 14 | /// A cache for efficiently executing operations on directories and files which are encountered in sorted order. |
| 18 | 15 | /// That way, these operations can be re-used for subsequent invocations in the same directory. |
| 19 | 16 | /// |
| @@ -35,26 +32,20 @@ pub mod read; · 15 unmodified lines | ||
| 35 | 32 | /// |
| 36 | 33 | /// The caching is only useful if consecutive calls to create a directory are using a sorted list of entries. |
| 37 | 34 | #[derive(Clone)] |
| 38 | −pub struct Cache { | |
| 35 | +pub struct Stack { | |
| 39 | 36 | stack: gix_fs::Stack, |
| 40 | 37 | /// tells us what to do as we change paths. |
| 41 | − state: cache::State, | |
| 38 | + state: stack::State, | |
| 42 | 39 | /// A buffer used when reading attribute or ignore files or their respective objects from the object database. |
| 43 | 40 | buf: Vec<u8>, |
| 44 | 41 | /// If case folding should happen when looking up attributes or exclusions. |
| 45 | 42 | case: gix_glob::pattern::Case, |
| 46 | 43 | /// A lookup table for object ids to read from in some situations when looking up attributes or exclusions. |
| 47 | 44 | id_mappings: Vec<PathIdMapping>, |
| 48 | − statistics: cache::Statistics, | |
| 45 | + statistics: stack::Statistics, | |
| 49 | 46 | } |
| 50 | 47 | |
| 51 | 48 | pub(crate) type PathIdMapping = (BString, gix_hash::ObjectId); |
| 52 | 49 | |
| 53 | 50 | /// |
| 54 | −pub mod cache; | |
| 55 | −/// | |
| 56 | −pub mod checkout; | |
| 57 | −pub use checkout::function::checkout; | |
| 58 | − | |
| 59 | −pub mod status; | |
| 60 | −pub use status::function::status; | |
| 51 | +pub mod stack; | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | use bstr::{BStr, ByteSlice}; |
| 2 | 2 | |
| 3 | −use crate::{cache::State, PathIdMapping}; | |
| 3 | +use crate::{stack::State, PathIdMapping}; | |
| 4 | 4 | |
| 5 | 5 | /// Various aggregate numbers related to the stack delegate itself. |
| 6 | 6 | #[derive(Default, Clone, Copy, Debug)] |
| @@ -4,10 +4,10 @@ use std::path::{Path, PathBuf}; · 3 unmodified lines | ||
| 4 | 4 | use bstr::{BStr, ByteSlice}; |
| 5 | 5 | use gix_hash::oid; |
| 6 | 6 | |
| 7 | −use super::Cache; | |
| 7 | +use super::Stack; | |
| 8 | 8 | use crate::PathIdMapping; |
| 9 | 9 | |
| 10 | −/// Various aggregate numbers collected from when the corresponding [`Cache`] was instantiated. | |
| 10 | +/// Various aggregate numbers collected from when the corresponding [`Stack`] was instantiated. | |
| 11 | 11 | #[derive(Default, Clone, Copy, Debug)] |
| 12 | 12 | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| 13 | 13 | pub struct Statistics { |
| @@ -45,12 +45,12 @@ pub enum State { · 31 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | #[must_use] |
| 47 | 47 | pub struct Platform<'a> { |
| 48 | − parent: &'a Cache, | |
| 48 | + parent: &'a Stack, | |
| 49 | 49 | is_dir: Option<bool>, |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 52 | /// Initialization |
| 53 | −impl Cache { | |
| 53 | +impl Stack { | |
| 54 | 54 | /// Create a new instance with `worktree_root` being the base for all future paths we match. |
| 55 | 55 | /// `state` defines the capabilities of the cache. |
| 56 | 56 | /// The `case` configures attribute and exclusion case sensitivity at *query time*, which should match the case that |
| @@ -64,7 +64,7 @@ impl Cache { · 7 unmodified lines | ||
| 64 | 64 | id_mappings: Vec<PathIdMapping>, |
| 65 | 65 | ) -> Self { |
| 66 | 66 | let root = worktree_root.into(); |
| 67 | − Cache { | |
| 67 | + Stack { | |
| 68 | 68 | stack: gix_fs::Stack::new(root), |
| 69 | 69 | state, |
| 70 | 70 | case, |
| @@ -76,12 +76,12 @@ impl Cache { · 5 unmodified lines | ||
| 76 | 76 | } |
| 77 | 77 | |
| 78 | 78 | /// Entry points for attribute query |
| 79 | −impl Cache { | |
| 79 | +impl Stack { | |
| 80 | 80 | /// Append the `relative` path to the root directory of the cache and efficiently create leading directories, while assuring that no |
| 81 | 81 | /// symlinks are in that path. |
| 82 | 82 | /// Unless `is_dir` is known with `Some(…)`, then `relative` points to a directory itself in which case the entire resulting |
| 83 | 83 | /// path is created as directory. If it's not known it is assumed to be a file. |
| 84 | − /// `find` maybe used to lookup objects from an [id mapping][crate::cache::State::id_mappings_from_index()], with mappnigs | |
| 84 | + /// `find` maybe used to lookup objects from an [id mapping][crate::stack::State::id_mappings_from_index()], with mappnigs | |
| 85 | 85 | /// |
| 86 | 86 | /// Provide access to cached information for that `relative` path via the returned platform. |
| 87 | 87 | pub fn at_path<Find, E>( |
| @@ -110,7 +110,7 @@ impl Cache { · 22 unmodified lines | ||
| 110 | 110 | |
| 111 | 111 | /// Obtain a platform for lookups from a repo-`relative` path, typically obtained from an index entry. `is_dir` should reflect |
| 112 | 112 | /// whether it's a directory or not, or left at `None` if unknown. |
| 113 | − /// `find` maybe used to lookup objects from an [id mapping][crate::cache::State::id_mappings_from_index()]. | |
| 113 | + /// `find` maybe used to lookup objects from an [id mapping][crate::stack::State::id_mappings_from_index()]. | |
| 114 | 114 | /// All effects are similar to [`at_path()`][Self::at_path()]. |
| 115 | 115 | /// |
| 116 | 116 | /// If `relative` ends with `/` and `is_dir` is `None`, it is automatically assumed to be a directory. |
| @@ -140,7 +140,7 @@ impl Cache { · 23 unmodified lines | ||
| 140 | 140 | } |
| 141 | 141 | |
| 142 | 142 | /// Mutation |
| 143 | −impl Cache { | |
| 143 | +impl Stack { | |
| 144 | 144 | /// Reset the statistics after returning them. |
| 145 | 145 | pub fn take_statistics(&mut self) -> Statistics { |
| 146 | 146 | std::mem::take(&mut self.statistics) |
| @@ -159,7 +159,7 @@ impl Cache { · 12 unmodified lines | ||
| 159 | 159 | } |
| 160 | 160 | |
| 161 | 161 | /// Access |
| 162 | −impl Cache { | |
| 162 | +impl Stack { | |
| 163 | 163 | /// Return the statistics we gathered thus far. |
| 164 | 164 | pub fn statistics(&self) -> &Statistics { |
| 165 | 165 | &self.statistics |
| @@ -2,7 +2,7 @@ use std::path::Path; · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | use bstr::ByteSlice; |
| 4 | 4 | |
| 5 | −use crate::cache::Platform; | |
| 5 | +use crate::stack::Platform; | |
| 6 | 6 | |
| 7 | 7 | /// Access |
| 8 | 8 | impl<'a> Platform<'a> { |
| @@ -4,8 +4,8 @@ use bstr::{BStr, ByteSlice}; · 3 unmodified lines | ||
| 4 | 4 | use gix_glob::pattern::Case; |
| 5 | 5 | |
| 6 | 6 | use crate::{ |
| 7 | − cache::state::{AttributeMatchGroup, Attributes}, | |
| 8 | − Cache, PathIdMapping, | |
| 7 | + stack::state::{AttributeMatchGroup, Attributes}, | |
| 8 | + PathIdMapping, Stack, | |
| 9 | 9 | }; |
| 10 | 10 | |
| 11 | 11 | /// Various aggregate numbers related [`Attributes`]. |
| @@ -23,7 +23,7 @@ pub struct Statistics { · 11 unmodified lines | ||
| 23 | 23 | /// Decide where to read `.gitattributes` files from. |
| 24 | 24 | /// |
| 25 | 25 | /// To Retrieve attribute files from id mappings, see |
| 26 | −/// [State::id_mappings_from_index()][crate::cache::State::id_mappings_from_index()]. | |
| 26 | +/// [State::id_mappings_from_index()][crate::stack::State::id_mappings_from_index()]. | |
| 27 | 27 | /// |
| 28 | 28 | /// These mappings are typically produced from an index. |
| 29 | 29 | /// If a tree should be the source, build an attribute list from a tree instead, or convert a tree to an index. |
| @@ -200,7 +200,7 @@ impl Attributes { · 170 unmodified lines | ||
| 200 | 200 | } |
| 201 | 201 | |
| 202 | 202 | /// Attribute matching specific methods |
| 203 | −impl Cache { | |
| 203 | +impl Stack { | |
| 204 | 204 | /// Creates a new container to store match outcomes for all attribute matches. |
| 205 | 205 | /// |
| 206 | 206 | /// ### Panics |
| @@ -230,7 +230,7 @@ impl Cache { · 23 unmodified lines | ||
| 230 | 230 | } |
| 231 | 231 | |
| 232 | 232 | /// Return the metadata collection that enables initializing attribute match outcomes as done in |
| 233 | − /// [`attribute_matches()`][Cache::attribute_matches()] or [`selected_attribute_matches()`][Cache::selected_attribute_matches()] | |
| 233 | + /// [`attribute_matches()`][Stack::attribute_matches()] or [`selected_attribute_matches()`][Stack::selected_attribute_matches()] | |
| 234 | 234 | /// |
| 235 | 235 | /// ### Panics |
| 236 | 236 | /// |
| @@ -4,7 +4,7 @@ use bstr::{BStr, ByteSlice}; · 3 unmodified lines | ||
| 4 | 4 | use gix_glob::pattern::Case; |
| 5 | 5 | |
| 6 | 6 | use crate::{ |
| 7 | − cache::state::{Ignore, IgnoreMatchGroup}, | |
| 7 | + stack::state::{Ignore, IgnoreMatchGroup}, | |
| 8 | 8 | PathIdMapping, |
| 9 | 9 | }; |
| 10 | 10 | |
| @@ -12,7 +12,7 @@ use crate::{ · 1 unmodified line | ||
| 12 | 12 | #[derive(Default, Debug, Clone, Copy)] |
| 13 | 13 | pub enum Source { |
| 14 | 14 | /// Retrieve ignore files from id mappings, see |
| 15 | − /// [State::id_mappings_from_index()][crate::cache::State::id_mappings_from_index()]. | |
| 15 | + /// [State::id_mappings_from_index()][crate::stack::State::id_mappings_from_index()]. | |
| 16 | 16 | /// |
| 17 | 17 | /// These mappings are typically produced from an index. |
| 18 | 18 | /// If a tree should be the source, build an attribute list from a tree instead, or convert a tree to an index. |
| @@ -3,7 +3,7 @@ use std::path::PathBuf; · 2 unmodified lines | ||
| 3 | 3 | use bstr::{BString, ByteSlice}; |
| 4 | 4 | use gix_glob::pattern::Case; |
| 5 | 5 | |
| 6 | −use crate::{cache::State, PathIdMapping}; | |
| 6 | +use crate::{stack::State, PathIdMapping}; | |
| 7 | 7 | |
| 8 | 8 | type AttributeMatchGroup = gix_attributes::Search; |
| 9 | 9 | type IgnoreMatchGroup = gix_ignore::Search; |
| @@ -1 +0,0 @@ | ||
| 1 | −// TODO: untracked file detection, needs fs::Cache | |
| @@ -1,7 +1,2 @@ | ||
| 1 | 1 | make_ignore_and_attributes_setup.tar.xz |
| 2 | −make_mixed_without_submodules.tar.xz | |
| 3 | −make_mixed_without_submodules_and_symlinks.tar.xz | |
| 4 | 2 | make_attributes_baseline.tar.xz |
| 5 | −make_dangerous_symlink.tar.xz | |
| 6 | −status_unchanged.tar.xz | |
| 7 | −status_changed.tar.xz | |
| @@ -1,3 +1,3 @@ | ||
| 1 | 1 | version https://git-lfs.github.com/spec/v1 |
| 2 | −oid sha256:24f605623efc49819d1b30c52fe22da8f94f2d267e8030ec9bc3b9b845801f76 | |
| 3 | −size 9220 | |
| 2 | +oid sha256:1804dc740055b8a5afe65a2db14f29c8ae4691896e67342a8dcb11530fd448c6 | |
| 3 | +size 9240 | |
| @@ -1,3 +0,0 @@ | ||
| 1 | −version https://git-lfs.github.com/spec/v1 | |
| 2 | −oid sha256:35b728a127f3b6170bac44469ff36d5ad0be2a4247a8926f1aaffb97b5973efc | |
| 3 | −size 1596 | |
| @@ -1,3 +0,0 @@ | ||
| 1 | −version https://git-lfs.github.com/spec/v1 | |
| 2 | −oid sha256:cd6d32ab7a1e372d80a617926cac2463f6620baedf74642d78fe7f8c956fd031 | |
| 3 | −size 11036 | |
| @@ -1,3 +0,0 @@ | ||
| 1 | −version https://git-lfs.github.com/spec/v1 | |
| 2 | −oid sha256:876670d74c01249d361aa73d83ab20d846db7c922a3ca825f778b5f9d746c401 | |
| 3 | −size 9304 | |
| @@ -1,3 +0,0 @@ | ||
| 1 | −version https://git-lfs.github.com/spec/v1 | |
| 2 | −oid sha256:e5fe85a65e3689e9e60598130be60761dc4ea129e04d7d5501320f7ebad1eb2b | |
| 3 | −size 10520 | |
| @@ -1,18 +0,0 @@ | ||
| 1 | −#!/bin/bash | |
| 2 | −set -eu -o pipefail | |
| 3 | − | |
| 4 | −git init -q | |
| 5 | − | |
| 6 | −cat <<EOF >.git/info/exclude | |
| 7 | −# a sample .git/info/exclude | |
| 8 | −file-anywhere | |
| 9 | −/file-from-top | |
| 10 | − | |
| 11 | −dir-anywhere/ | |
| 12 | −/dir-from-top | |
| 13 | − | |
| 14 | −subdir-anywhere/file | |
| 15 | −subdir-anywhere/dir/ | |
| 16 | −EOF | |
| 17 | − | |
| 18 | −git commit --allow-empty -m "init" | |
| @@ -1,17 +1,9 @@ | ||
| 1 | −mod cache; | |
| 2 | −mod checkout; | |
| 3 | −mod status; | |
| 1 | +use gix_hash::ObjectId; | |
| 4 | 2 | |
| 5 | −use std::path::{Path, PathBuf}; | |
| 3 | +mod stack; | |
| 6 | 4 | |
| 7 | −use gix_hash::ObjectId; | |
| 8 | 5 | pub type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error>>; |
| 9 | 6 | |
| 10 | 7 | pub fn hex_to_id(hex: &str) -> ObjectId { |
| 11 | 8 | ObjectId::from_hex(hex.as_bytes()).expect("40 bytes hex") |
| 12 | 9 | } |
| 13 | − | |
| 14 | −pub fn fixture_path(name: &str) -> PathBuf { | |
| 15 | − let dir = gix_testtools::scripted_fixture_read_only(Path::new(name).with_extension("sh")).expect("script works"); | |
| 16 | − dir | |
| 17 | −} | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | use bstr::ByteSlice; |
| 2 | 2 | use gix_attributes::search::Outcome; |
| 3 | 3 | use gix_glob::pattern::Case; |
| 4 | −use gix_worktree::cache::state; | |
| 4 | +use gix_worktree::stack::state; | |
| 5 | 5 | |
| 6 | 6 | #[test] |
| 7 | 7 | fn baseline() -> crate::Result { |
| @@ -19,17 +19,17 @@ fn baseline() -> crate::Result { · 11 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | let mut buf = Vec::new(); |
| 21 | 21 | let mut collection = gix_attributes::search::MetadataCollection::default(); |
| 22 | − let state = gix_worktree::cache::State::for_checkout( | |
| 22 | + let state = gix_worktree::stack::State::for_checkout( | |
| 23 | 23 | false, |
| 24 | 24 | state::Attributes::new( |
| 25 | 25 | gix_attributes::Search::new_globals([base.join("user.attributes")], &mut buf, &mut collection)?, |
| 26 | 26 | Some(git_dir.join("info").join("attributes")), |
| 27 | − gix_worktree::cache::state::attributes::Source::WorktreeThenIdMapping, | |
| 27 | + gix_worktree::stack::state::attributes::Source::WorktreeThenIdMapping, | |
| 28 | 28 | collection, |
| 29 | 29 | ), |
| 30 | 30 | ); |
| 31 | 31 | |
| 32 | − let mut cache = gix_worktree::Cache::new(&base, state, case, buf, vec![]); | |
| 32 | + let mut cache = gix_worktree::Stack::new(&base, state, case, buf, vec![]); | |
| 33 | 33 | |
| 34 | 34 | let mut actual = cache.attribute_matches(); |
| 35 | 35 | let input = std::fs::read(base.join("baseline"))?; |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | use std::path::Path; |
| 2 | 2 | |
| 3 | −use gix_worktree::{cache, Cache}; | |
| 4 | −use tempfile::{tempdir, TempDir}; | |
| 3 | +use gix_testtools::tempfile::{tempdir, TempDir}; | |
| 4 | +use gix_worktree::{stack, Stack}; | |
| 5 | 5 | |
| 6 | 6 | #[allow(clippy::ptr_arg)] |
| 7 | 7 | fn panic_on_find<'buf>(_oid: &gix_hash::oid, _buf: &'buf mut Vec<u8>) -> std::io::Result<gix_object::BlobRef<'buf>> { |
| @@ -11,9 +11,9 @@ fn panic_on_find<'buf>(_oid: &gix_hash::oid, _buf: &'buf mut Vec<u8>) -> std::io · 3 unmodified lines | ||
| 11 | 11 | #[test] |
| 12 | 12 | fn root_is_assumed_to_exist_and_files_in_root_do_not_create_directory() -> crate::Result { |
| 13 | 13 | let dir = tempdir()?; |
| 14 | − let mut cache = Cache::new( | |
| 14 | + let mut cache = Stack::new( | |
| 15 | 15 | dir.path().join("non-existing-root"), |
| 16 | − cache::State::for_checkout(false, Default::default()), | |
| 16 | + stack::State::for_checkout(false, Default::default()), | |
| 17 | 17 | Default::default(), |
| 18 | 18 | Vec::new(), |
| 19 | 19 | Default::default(), |
| @@ -68,7 +68,7 @@ fn symlinks_or_files_in_path_are_forbidden_or_unlinked_when_forced() -> crate::R · 48 unmodified lines | ||
| 68 | 68 | std::fs::write(tmp.path().join("file-in-dir"), [])?; |
| 69 | 69 | |
| 70 | 70 | for dirname in &["file-in-dir", "link-to-dir"] { |
| 71 | − if let cache::State::CreateDirectoryAndAttributesStack { | |
| 71 | + if let stack::State::CreateDirectoryAndAttributesStack { | |
| 72 | 72 | unlink_on_collision, .. |
| 73 | 73 | } = cache.state_mut() |
| 74 | 74 | { |
| @@ -90,7 +90,7 @@ fn symlinks_or_files_in_path_are_forbidden_or_unlinked_when_forced() -> crate::R · 15 unmodified lines | ||
| 90 | 90 | ); |
| 91 | 91 | cache.take_statistics(); |
| 92 | 92 | for dirname in &["link-to-dir", "file-in-dir"] { |
| 93 | − if let cache::State::CreateDirectoryAndAttributesStack { | |
| 93 | + if let stack::State::CreateDirectoryAndAttributesStack { | |
| 94 | 94 | unlink_on_collision, .. |
| 95 | 95 | } = cache.state_mut() |
| 96 | 96 | { |
| @@ -109,11 +109,11 @@ fn symlinks_or_files_in_path_are_forbidden_or_unlinked_when_forced() -> crate::R · 12 unmodified lines | ||
| 109 | 109 | Ok(()) |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | −fn new_cache() -> (Cache, TempDir) { | |
| 112 | +fn new_cache() -> (Stack, TempDir) { | |
| 113 | 113 | let dir = tempdir().unwrap(); |
| 114 | − let cache = Cache::new( | |
| 114 | + let cache = Stack::new( | |
| 115 | 115 | dir.path(), |
| 116 | − cache::State::for_checkout(false, Default::default()), | |
| 116 | + stack::State::for_checkout(false, Default::default()), | |
| 117 | 117 | Default::default(), |
| 118 | 118 | Vec::new(), |
| 119 | 119 | Default::default(), |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | use bstr::{BStr, ByteSlice}; |
| 2 | 2 | use gix_glob::pattern::Case; |
| 3 | 3 | use gix_odb::FindExt; |
| 4 | −use gix_worktree::{cache::state::ignore::Source, Cache}; | |
| 4 | +use gix_worktree::{stack::state::ignore::Source, Stack}; | |
| 5 | 5 | |
| 6 | 6 | use crate::hex_to_id; |
| 7 | 7 | |
| @@ -37,16 +37,16 @@ fn exclude_by_dir_is_handled_just_like_git() { · 29 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | let mut buf = Vec::new(); |
| 39 | 39 | let case = gix_glob::pattern::Case::Sensitive; |
| 40 | − let state = gix_worktree::cache::State::for_add( | |
| 40 | + let state = gix_worktree::stack::State::for_add( | |
| 41 | 41 | Default::default(), |
| 42 | − gix_worktree::cache::state::Ignore::new( | |
| 42 | + gix_worktree::stack::state::Ignore::new( | |
| 43 | 43 | Default::default(), |
| 44 | 44 | gix_ignore::Search::from_git_dir(&git_dir, None, &mut buf).unwrap(), |
| 45 | 45 | None, |
| 46 | 46 | Source::WorktreeThenIdMappingIfNotSkipped, |
| 47 | 47 | ), |
| 48 | 48 | ); |
| 49 | − let mut cache = Cache::new(&dir, state, case, buf, Default::default()); | |
| 49 | + let mut cache = Stack::new(&dir, state, case, buf, Default::default()); | |
| 50 | 50 | let baseline = std::fs::read(git_dir.parent().unwrap().join("git-check-ignore.baseline")).unwrap(); |
| 51 | 51 | let expectations = IgnoreExpectations { |
| 52 | 52 | lines: baseline.lines(), |
| @@ -95,9 +95,9 @@ fn check_against_baseline() -> crate::Result { · 42 unmodified lines | ||
| 95 | 95 | }; |
| 96 | 96 | let mut index = gix_index::File::at(git_dir.join("index"), gix_hash::Kind::Sha1, Default::default())?; |
| 97 | 97 | let odb = gix_odb::at(git_dir.join("objects"))?; |
| 98 | − let state = gix_worktree::cache::State::for_add( | |
| 98 | + let state = gix_worktree::stack::State::for_add( | |
| 99 | 99 | Default::default(), |
| 100 | − gix_worktree::cache::state::Ignore::new( | |
| 100 | + gix_worktree::stack::state::Ignore::new( | |
| 101 | 101 | gix_ignore::Search::from_overrides(vec!["!force-include"]), |
| 102 | 102 | gix_ignore::Search::from_git_dir(&git_dir, Some(user_exclude_path), &mut buf)?, |
| 103 | 103 | None, |
| @@ -113,7 +113,7 @@ fn check_against_baseline() -> crate::Result { · 9 unmodified lines | ||
| 113 | 113 | hex_to_id("5c7e0ed672d3d31d83a3df61f13cc8f7b22d5bfd") |
| 114 | 114 | )] |
| 115 | 115 | ); |
| 116 | − let mut cache = Cache::new(&worktree_dir, state, case, buf, attribute_files_in_index); | |
| 116 | + let mut cache = Stack::new(&worktree_dir, state, case, buf, attribute_files_in_index); | |
| 117 | 117 | |
| 118 | 118 | let baseline = std::fs::read(git_dir.parent().unwrap().join("git-check-ignore.baseline"))?; |
| 119 | 119 | let expectations = IgnoreExpectations { |
File renamed without changes.
| @@ -162,6 +162,7 @@ gix-credentials = { version = "^0.17.1", path = "../gix-credentials" } · 161 unmodified lines | ||
| 162 | 162 | gix-prompt = { version = "^0.5.5", path = "../gix-prompt" } |
| 163 | 163 | gix-index = { version = "^0.22.0", path = "../gix-index" } |
| 164 | 164 | gix-worktree = { version = "^0.24.0", path = "../gix-worktree" } |
| 165 | +gix-worktree-state = { version = "^0.1.0", path = "../gix-worktree-state" } | |
| 165 | 166 | gix-hashtable = { version = "^0.2.4", path = "../gix-hashtable" } |
| 166 | 167 | gix-commitgraph = { version = "^0.18.2", path = "../gix-commitgraph" } |
| 167 | 168 | gix-pathspec = { version = "^0.1.0", path = "../gix-pathspec" } |
| @@ -27,7 +27,8 @@ pub mod main_worktree { · 26 unmodified lines | ||
| 27 | 27 | CheckoutOptions(#[from] crate::config::checkout_options::Error), |
| 28 | 28 | #[error(transparent)] |
| 29 | 29 | IndexCheckout( |
| 30 | − #[from] gix_worktree::checkout::Error<gix_odb::find::existing_object::Error<gix_odb::store::find::Error>>, | |
| 30 | + #[from] | |
| 31 | + gix_worktree_state::checkout::Error<gix_odb::find::existing_object::Error<gix_odb::store::find::Error>>, | |
| 31 | 32 | ), |
| 32 | 33 | #[error("Failed to reopen object database as Arc (only if thread-safety wasn't compiled in)")] |
| 33 | 34 | OpenArcOdb(#[from] std::io::Error), |
| @@ -68,7 +69,7 @@ pub mod main_worktree { · 34 unmodified lines | ||
| 68 | 69 | &mut self, |
| 69 | 70 | mut progress: impl crate::Progress, |
| 70 | 71 | should_interrupt: &AtomicBool, |
| 71 | − ) -> Result<(Repository, gix_worktree::checkout::Outcome), Error> { | |
| 72 | + ) -> Result<(Repository, gix_worktree_state::checkout::Outcome), Error> { | |
| 72 | 73 | let _span = gix_trace::coarse!("gix::clone::PrepareCheckout::main_worktree()"); |
| 73 | 74 | let repo = self |
| 74 | 75 | .repo |
| @@ -82,7 +83,7 @@ pub mod main_worktree { · 7 unmodified lines | ||
| 82 | 83 | None => { |
| 83 | 84 | return Ok(( |
| 84 | 85 | self.repo.take().expect("still present"), |
| 85 | − gix_worktree::checkout::Outcome::default(), | |
| 86 | + gix_worktree_state::checkout::Outcome::default(), | |
| 86 | 87 | )) |
| 87 | 88 | } |
| 88 | 89 | }; |
| @@ -95,7 +96,7 @@ pub mod main_worktree { · 6 unmodified lines | ||
| 95 | 96 | |
| 96 | 97 | let mut opts = repo |
| 97 | 98 | .config |
| 98 | − .checkout_options(repo, gix_worktree::cache::state::attributes::Source::IdMapping)?; | |
| 99 | + .checkout_options(repo, gix_worktree::stack::state::attributes::Source::IdMapping)?; | |
| 99 | 100 | opts.destination_is_initially_empty = true; |
| 100 | 101 | |
| 101 | 102 | let mut files = progress.add_child_with_id("checkout", ProgressId::CheckoutFiles.into()); |
| @@ -105,7 +106,7 @@ pub mod main_worktree { · 3 unmodified lines | ||
| 105 | 106 | bytes.init(None, crate::progress::bytes()); |
| 106 | 107 | |
| 107 | 108 | let start = std::time::Instant::now(); |
| 108 | − let outcome = gix_worktree::checkout( | |
| 109 | + let outcome = gix_worktree_state::checkout( | |
| 109 | 110 | &mut index, |
| 110 | 111 | workdir, |
| 111 | 112 | { |
| @@ -160,8 +160,8 @@ impl Cache { · 159 unmodified lines | ||
| 160 | 160 | pub(crate) fn checkout_options( |
| 161 | 161 | &self, |
| 162 | 162 | repo: &Repository, |
| 163 | − attributes_source: gix_worktree::cache::state::attributes::Source, | |
| 164 | − ) -> Result<gix_worktree::checkout::Options, checkout_options::Error> { | |
| 163 | + attributes_source: gix_worktree::stack::state::attributes::Source, | |
| 164 | + ) -> Result<gix_worktree_state::checkout::Options, checkout_options::Error> { | |
| 165 | 165 | let git_dir = repo.git_dir(); |
| 166 | 166 | let thread_limit = self.apply_leniency( |
| 167 | 167 | self.resolved |
| @@ -189,7 +189,7 @@ impl Cache { · 21 unmodified lines | ||
| 189 | 189 | } else { |
| 190 | 190 | gix_filter::driver::apply::Delay::Forbid |
| 191 | 191 | }; |
| 192 | − Ok(gix_worktree::checkout::Options { | |
| 192 | + Ok(gix_worktree_state::checkout::Options { | |
| 193 | 193 | filter_process_delay, |
| 194 | 194 | filters, |
| 195 | 195 | attributes: self |
| @@ -219,14 +219,14 @@ impl Cache { · 23 unmodified lines | ||
| 219 | 219 | &self, |
| 220 | 220 | git_dir: &std::path::Path, |
| 221 | 221 | overrides: Option<gix_ignore::Search>, |
| 222 | − source: gix_worktree::cache::state::ignore::Source, | |
| 222 | + source: gix_worktree::stack::state::ignore::Source, | |
| 223 | 223 | buf: &mut Vec<u8>, |
| 224 | − ) -> Result<gix_worktree::cache::state::Ignore, config::exclude_stack::Error> { | |
| 224 | + ) -> Result<gix_worktree::stack::state::Ignore, config::exclude_stack::Error> { | |
| 225 | 225 | let excludes_file = match self.excludes_file().transpose()? { |
| 226 | 226 | Some(user_path) => Some(user_path), |
| 227 | 227 | None => self.xdg_config_path("ignore")?, |
| 228 | 228 | }; |
| 229 | − Ok(gix_worktree::cache::state::Ignore::new( | |
| 229 | + Ok(gix_worktree::stack::state::Ignore::new( | |
| 230 | 230 | overrides.unwrap_or_default(), |
| 231 | 231 | gix_ignore::Search::from_git_dir(git_dir, excludes_file, buf)?, |
| 232 | 232 | None, |
| @@ -237,9 +237,9 @@ impl Cache { · 4 unmodified lines | ||
| 237 | 237 | pub(crate) fn assemble_attribute_globals( |
| 238 | 238 | &self, |
| 239 | 239 | git_dir: &std::path::Path, |
| 240 | − source: gix_worktree::cache::state::attributes::Source, | |
| 240 | + source: gix_worktree::stack::state::attributes::Source, | |
| 241 | 241 | attributes: crate::open::permissions::Attributes, |
| 242 | − ) -> Result<(gix_worktree::cache::state::Attributes, Vec<u8>), config::attribute_stack::Error> { | |
| 242 | + ) -> Result<(gix_worktree::stack::state::Attributes, Vec<u8>), config::attribute_stack::Error> { | |
| 243 | 243 | let configured_or_user_attributes = match self |
| 244 | 244 | .trusted_file_path("core", None, Core::ATTRIBUTES_FILE.name) |
| 245 | 245 | .transpose()? |
| @@ -265,7 +265,7 @@ impl Cache { · 19 unmodified lines | ||
| 265 | 265 | let info_attributes_path = git_dir.join("info").join("attributes"); |
| 266 | 266 | let mut buf = Vec::new(); |
| 267 | 267 | let mut collection = gix_attributes::search::MetadataCollection::default(); |
| 268 | − let state = gix_worktree::cache::state::Attributes::new( | |
| 268 | + let state = gix_worktree::stack::state::Attributes::new( | |
| 269 | 269 | gix_attributes::Search::new_globals(attribute_files, &mut buf, &mut collection)?, |
| 270 | 270 | Some(info_attributes_path), |
| 271 | 271 | source, |
| @@ -67,7 +67,7 @@ pub mod pipeline { · 66 unmodified lines | ||
| 67 | 67 | #[derive(Clone)] |
| 68 | 68 | pub struct Pipeline<'repo> { |
| 69 | 69 | inner: gix_filter::Pipeline, |
| 70 | − cache: gix_worktree::Cache, | |
| 70 | + cache: gix_worktree::Stack, | |
| 71 | 71 | repo: &'repo Repository, |
| 72 | 72 | } |
| 73 | 73 | |
| @@ -110,7 +110,7 @@ impl<'repo> Pipeline<'repo> { · 36 unmodified lines | ||
| 110 | 110 | |
| 111 | 111 | /// Create a new instance by extracting all necessary information and configuration from a `repo` along with `cache` for accessing |
| 112 | 112 | /// attributes. The `index` is used for some filters which may access it under very specific circumstances. |
| 113 | − pub fn new(repo: &'repo Repository, cache: gix_worktree::Cache) -> Result<Self, pipeline::options::Error> { | |
| 113 | + pub fn new(repo: &'repo Repository, cache: gix_worktree::Stack) -> Result<Self, pipeline::options::Error> { | |
| 114 | 114 | let pipeline = gix_filter::Pipeline::new(cache.attributes_collection(), Self::options(repo)?); |
| 115 | 115 | Ok(Pipeline { |
| 116 | 116 | inner: pipeline, |
| @@ -120,7 +120,7 @@ impl<'repo> Pipeline<'repo> { · 3 unmodified lines | ||
| 120 | 120 | } |
| 121 | 121 | |
| 122 | 122 | /// Detach the repository and obtain the individual functional parts. |
| 123 | − pub fn into_parts(self) -> (gix_filter::Pipeline, gix_worktree::Cache) { | |
| 123 | + pub fn into_parts(self) -> (gix_filter::Pipeline, gix_worktree::Stack) { | |
| 124 | 124 | (self.inner, self.cache) |
| 125 | 125 | } |
| 126 | 126 | } |
| @@ -43,7 +43,7 @@ impl<'repo> Pathspec<'repo> { · 42 unmodified lines | ||
| 43 | 43 | repo: &'repo Repository, |
| 44 | 44 | patterns: impl IntoIterator<Item = impl AsRef<BStr>>, |
| 45 | 45 | inherit_ignore_case: bool, |
| 46 | − make_attributes: impl FnOnce() -> Result<gix_worktree::Cache, Box<dyn std::error::Error + Send + Sync + 'static>>, | |
| 46 | + make_attributes: impl FnOnce() -> Result<gix_worktree::Stack, Box<dyn std::error::Error + Send + Sync + 'static>>, | |
| 47 | 47 | ) -> Result<Self, init::Error> { |
| 48 | 48 | let mut defaults = repo.pathspec_defaults()?; |
| 49 | 49 | if inherit_ignore_case && repo.config.fs_capabilities()?.ignore_case { |
| @@ -67,9 +67,9 @@ impl<'repo> Pathspec<'repo> { · 17 unmodified lines | ||
| 67 | 67 | Ok(Self { repo, search, cache }) |
| 68 | 68 | } |
| 69 | 69 | /// Turn ourselves into the functional parts for direct usage. |
| 70 | − /// Note that the [`cache`](gix_worktree::Cache) is only set if one of the [`search` patterns](Search) | |
| 70 | + /// Note that the [`cache`](gix_worktree::Stack) is only set if one of the [`search` patterns](Search) | |
| 71 | 71 | /// is specifying attributes to match for. |
| 72 | − pub fn into_parts(self) -> (Search, Option<gix_worktree::Cache>) { | |
| 72 | + pub fn into_parts(self) -> (Search, Option<gix_worktree::Stack>) { | |
| 73 | 73 | (self.search, self.cache) |
| 74 | 74 | } |
| 75 | 75 | } |
| @@ -77,7 +77,7 @@ impl<'repo> Pathspec<'repo> { · 1 unmodified line | ||
| 77 | 77 | /// Access |
| 78 | 78 | impl<'repo> Pathspec<'repo> { |
| 79 | 79 | /// Return the attributes cache which is used when matching attributes in pathspecs, or `None` if none of the pathspecs require that. |
| 80 | − pub fn attributes(&self) -> Option<&gix_worktree::Cache> { | |
| 80 | + pub fn attributes(&self) -> Option<&gix_worktree::Stack> { | |
| 81 | 81 | self.cache.as_ref() |
| 82 | 82 | } |
| 83 | 83 | |
| @@ -29,10 +29,10 @@ impl Repository { · 28 unmodified lines | ||
| 29 | 29 | pub fn attributes( |
| 30 | 30 | &self, |
| 31 | 31 | index: &gix_index::State, |
| 32 | − attributes_source: gix_worktree::cache::state::attributes::Source, | |
| 33 | − ignore_source: gix_worktree::cache::state::ignore::Source, | |
| 32 | + attributes_source: gix_worktree::stack::state::attributes::Source, | |
| 33 | + ignore_source: gix_worktree::stack::state::ignore::Source, | |
| 34 | 34 | exclude_overrides: Option<gix_ignore::Search>, |
| 35 | − ) -> Result<gix_worktree::Cache, Error> { | |
| 35 | + ) -> Result<gix_worktree::Stack, Error> { | |
| 36 | 36 | let case = if self.config.ignore_case { |
| 37 | 37 | gix_glob::pattern::Case::Fold |
| 38 | 38 | } else { |
| @@ -46,9 +46,9 @@ impl Repository { · 7 unmodified lines | ||
| 46 | 46 | let ignore = |
| 47 | 47 | self.config |
| 48 | 48 | .assemble_exclude_globals(self.git_dir(), exclude_overrides, ignore_source, &mut buf)?; |
| 49 | − let state = gix_worktree::cache::State::AttributesAndIgnoreStack { attributes, ignore }; | |
| 49 | + let state = gix_worktree::stack::State::AttributesAndIgnoreStack { attributes, ignore }; | |
| 50 | 50 | let attribute_list = state.id_mappings_from_index(index, index.path_backing(), case); |
| 51 | − Ok(gix_worktree::Cache::new( | |
| 51 | + Ok(gix_worktree::Stack::new( | |
| 52 | 52 | // this is alright as we don't cause mutation of that directory, it's virtual. |
| 53 | 53 | self.work_dir().unwrap_or(self.git_dir()), |
| 54 | 54 | state, |
| @@ -62,8 +62,8 @@ impl Repository { · 7 unmodified lines | ||
| 62 | 62 | pub fn attributes_only( |
| 63 | 63 | &self, |
| 64 | 64 | index: &gix_index::State, |
| 65 | − attributes_source: gix_worktree::cache::state::attributes::Source, | |
| 66 | − ) -> Result<gix_worktree::Cache, config::attribute_stack::Error> { | |
| 65 | + attributes_source: gix_worktree::stack::state::attributes::Source, | |
| 66 | + ) -> Result<gix_worktree::Stack, config::attribute_stack::Error> { | |
| 67 | 67 | let case = if self.config.ignore_case { |
| 68 | 68 | gix_glob::pattern::Case::Fold |
| 69 | 69 | } else { |
| @@ -74,9 +74,9 @@ impl Repository { · 4 unmodified lines | ||
| 74 | 74 | attributes_source, |
| 75 | 75 | self.options.permissions.attributes, |
| 76 | 76 | )?; |
| 77 | − let state = gix_worktree::cache::State::AttributesStack(attributes); | |
| 77 | + let state = gix_worktree::stack::State::AttributesStack(attributes); | |
| 78 | 78 | let attribute_list = state.id_mappings_from_index(index, index.path_backing(), case); |
| 79 | − Ok(gix_worktree::Cache::new( | |
| 79 | + Ok(gix_worktree::Stack::new( | |
| 80 | 80 | // this is alright as we don't cause mutation of that directory, it's virtual. |
| 81 | 81 | self.work_dir().unwrap_or(self.git_dir()), |
| 82 | 82 | state, |
| @@ -105,8 +105,8 @@ impl Repository { · 22 unmodified lines | ||
| 105 | 105 | &self, |
| 106 | 106 | index: &gix_index::State, |
| 107 | 107 | overrides: Option<gix_ignore::Search>, |
| 108 | − source: gix_worktree::cache::state::ignore::Source, | |
| 109 | − ) -> Result<gix_worktree::Cache, config::exclude_stack::Error> { | |
| 108 | + source: gix_worktree::stack::state::ignore::Source, | |
| 109 | + ) -> Result<gix_worktree::Stack, config::exclude_stack::Error> { | |
| 110 | 110 | let case = if self.config.ignore_case { |
| 111 | 111 | gix_glob::pattern::Case::Fold |
| 112 | 112 | } else { |
| @@ -116,9 +116,9 @@ impl Repository { · 3 unmodified lines | ||
| 116 | 116 | let ignore = self |
| 117 | 117 | .config |
| 118 | 118 | .assemble_exclude_globals(self.git_dir(), overrides, source, &mut buf)?; |
| 119 | − let state = gix_worktree::cache::State::IgnoreStack(ignore); | |
| 119 | + let state = gix_worktree::stack::State::IgnoreStack(ignore); | |
| 120 | 120 | let attribute_list = state.id_mappings_from_index(index, index.path_backing(), case); |
| 121 | − Ok(gix_worktree::Cache::new( | |
| 121 | + Ok(gix_worktree::Stack::new( | |
| 122 | 122 | // this is alright as we don't cause mutation of that directory, it's virtual. |
| 123 | 123 | self.work_dir().unwrap_or(self.git_dir()), |
| 124 | 124 | state, |
| @@ -49,13 +49,13 @@ impl Repository { · 48 unmodified lines | ||
| 49 | 49 | }, |
| 50 | 50 | Ok, |
| 51 | 51 | )?)?; |
| 52 | − let cache = self.attributes_only(&index, gix_worktree::cache::state::attributes::Source::IdMapping)?; | |
| 52 | + let cache = self.attributes_only(&index, gix_worktree::stack::state::attributes::Source::IdMapping)?; | |
| 53 | 53 | (cache, IndexPersistedOrInMemory::InMemory(index)) |
| 54 | 54 | } else { |
| 55 | 55 | let index = self.index()?; |
| 56 | 56 | let cache = self.attributes_only( |
| 57 | 57 | &index, |
| 58 | − gix_worktree::cache::state::attributes::Source::WorktreeThenIdMapping, | |
| 58 | + gix_worktree::stack::state::attributes::Source::WorktreeThenIdMapping, | |
| 59 | 59 | )?; |
| 60 | 60 | (cache, IndexPersistedOrInMemory::Persisted(index)) |
| 61 | 61 | }; |
| @@ -17,7 +17,7 @@ impl Repository { · 16 unmodified lines | ||
| 17 | 17 | Pathspec::new(self, patterns, inherit_ignore_case, || { |
| 18 | 18 | self.attributes_only( |
| 19 | 19 | index, |
| 20 | − gix_worktree::cache::state::attributes::Source::WorktreeThenIdMapping, | |
| 20 | + gix_worktree::stack::state::attributes::Source::WorktreeThenIdMapping, | |
| 21 | 21 | ) |
| 22 | 22 | .map_err(Into::into) |
| 23 | 23 | }) |
| @@ -74,7 +74,7 @@ impl crate::Repository { · 73 unmodified lines | ||
| 74 | 74 | // TODO(perf): when loading a non-HEAD tree, we effectively traverse the tree twice. This is usually fast though, and sharing |
| 75 | 75 | // an object cache between the copies of the ODB handles isn't trivial and needs a lock. |
| 76 | 76 | let index = self.index_from_tree(&id)?; |
| 77 | − let mut cache = self.attributes_only(&index, gix_worktree::cache::state::attributes::Source::IdMapping)?; | |
| 77 | + let mut cache = self.attributes_only(&index, gix_worktree::stack::state::attributes::Source::IdMapping)?; | |
| 78 | 78 | let pipeline = |
| 79 | 79 | gix_filter::Pipeline::new(cache.attributes_collection(), crate::filter::Pipeline::options(self)?); |
| 80 | 80 | let objects = self.objects.clone().into_arc().expect("TBD error handling"); |
| @@ -202,7 +202,7 @@ pub struct Remote<'repo> { · 201 unmodified lines | ||
| 202 | 202 | pub struct Pathspec<'repo> { |
| 203 | 203 | pub(crate) repo: &'repo Repository, |
| 204 | 204 | /// The cache to power attribute access. It's only initialized if we have a pattern with attributes. |
| 205 | − pub(crate) cache: Option<gix_worktree::Cache>, | |
| 205 | + pub(crate) cache: Option<gix_worktree::Stack>, | |
| 206 | 206 | /// The prepared search to use for checking matches. |
| 207 | 207 | pub(crate) search: gix_pathspec::Search, |
| 208 | 208 | } |
| @@ -3,6 +3,7 @@ use std::path::PathBuf; · 2 unmodified lines | ||
| 3 | 3 | #[cfg(feature = "worktree-archive")] |
| 4 | 4 | pub use gix_archive as archive; |
| 5 | 5 | pub use gix_worktree::*; |
| 6 | +pub use gix_worktree_state as state; | |
| 6 | 7 | #[cfg(feature = "worktree-stream")] |
| 7 | 8 | pub use gix_worktree_stream as stream; |
| 8 | 9 | |
| @@ -120,12 +121,12 @@ pub mod excludes { · 111 unmodified lines | ||
| 120 | 121 | /// |
| 121 | 122 | /// When only excludes are desired, this is the most efficient way to obtain them. Otherwise use |
| 122 | 123 | /// [`Worktree::attributes()`][crate::Worktree::attributes()] for accessing both attributes and excludes. |
| 123 | − pub fn excludes(&self, overrides: Option<gix_ignore::Search>) -> Result<gix_worktree::Cache, Error> { | |
| 124 | + pub fn excludes(&self, overrides: Option<gix_ignore::Search>) -> Result<gix_worktree::Stack, Error> { | |
| 124 | 125 | let index = self.index()?; |
| 125 | 126 | Ok(self.parent.excludes( |
| 126 | 127 | &index, |
| 127 | 128 | overrides, |
| 128 | − gix_worktree::cache::state::ignore::Source::WorktreeThenIdMappingIfNotSkipped, | |
| 129 | + gix_worktree::stack::state::ignore::Source::WorktreeThenIdMappingIfNotSkipped, | |
| 129 | 130 | )?) |
| 130 | 131 | } |
| 131 | 132 | } |
| @@ -150,23 +151,23 @@ pub mod attributes { · 18 unmodified lines | ||
| 150 | 151 | /// |
| 151 | 152 | /// * `$XDG_CONFIG_HOME/…/ignore|attributes` if `core.excludesFile|attributesFile` is *not* set, otherwise use the configured file. |
| 152 | 153 | /// * `$GIT_DIR/info/exclude|attributes` if present. |
| 153 | − pub fn attributes(&self, overrides: Option<gix_ignore::Search>) -> Result<gix_worktree::Cache, Error> { | |
| 154 | + pub fn attributes(&self, overrides: Option<gix_ignore::Search>) -> Result<gix_worktree::Stack, Error> { | |
| 154 | 155 | let index = self.index()?; |
| 155 | 156 | Ok(self.parent.attributes( |
| 156 | 157 | &index, |
| 157 | − gix_worktree::cache::state::attributes::Source::WorktreeThenIdMapping, | |
| 158 | − gix_worktree::cache::state::ignore::Source::WorktreeThenIdMappingIfNotSkipped, | |
| 158 | + gix_worktree::stack::state::attributes::Source::WorktreeThenIdMapping, | |
| 159 | + gix_worktree::stack::state::ignore::Source::WorktreeThenIdMappingIfNotSkipped, | |
| 159 | 160 | overrides, |
| 160 | 161 | )?) |
| 161 | 162 | } |
| 162 | 163 | |
| 163 | 164 | /// Like [attributes()][Self::attributes()], but without access to exclude/ignore information. |
| 164 | − pub fn attributes_only(&self) -> Result<gix_worktree::Cache, Error> { | |
| 165 | + pub fn attributes_only(&self) -> Result<gix_worktree::Stack, Error> { | |
| 165 | 166 | let index = self.index()?; |
| 166 | 167 | self.parent |
| 167 | 168 | .attributes_only( |
| 168 | 169 | &index, |
| 169 | − gix_worktree::cache::state::attributes::Source::WorktreeThenIdMapping, | |
| 170 | + gix_worktree::stack::state::attributes::Source::WorktreeThenIdMapping, | |
| 170 | 171 | ) |
| 171 | 172 | .map_err(|err| Error::CreateCache(err.into())) |
| 172 | 173 | } |
| @@ -99,6 +99,7 @@ check: · 98 unmodified lines | ||
| 99 | 99 | cargo check -p gix-config-value |
| 100 | 100 | cargo check -p gix-config --all-features |
| 101 | 101 | cargo check -p gix-config |
| 102 | + cargo check -p gix-diff --no-default-features | |
| 102 | 103 | cargo check -p gix-transport |
| 103 | 104 | cargo check -p gix-transport --features blocking-client |
| 104 | 105 | cargo check -p gix-transport --features async-client |
| @@ -134,14 +135,18 @@ unit-tests: · 29 unmodified lines | ||
| 134 | 135 | cargo test -p gix-archive --features tar |
| 135 | 136 | cargo test -p gix-archive --features tar_gz |
| 136 | 137 | cargo test -p gix-archive --features zip |
| 137 | − cd gix-object; \ | |
| 138 | + cd gix-status; \ | |
| 138 | 139 | set -ex; \ |
| 139 | 140 | cargo test; \ |
| 140 | − cargo test --features verbose-object-parsing-errors | |
| 141 | − cd gix-worktree; \ | |
| 141 | + cargo test --features "internal-testing-gix-features-parallel" | |
| 142 | + cd gix-worktree-state; \ | |
| 142 | 143 | set -ex; \ |
| 143 | 144 | cargo test; \ |
| 144 | 145 | cargo test --features "internal-testing-gix-features-parallel" |
| 146 | + cd gix-object; \ | |
| 147 | + set -ex; \ | |
| 148 | + cargo test; \ | |
| 149 | + cargo test --features verbose-object-parsing-errors | |
| 145 | 150 | cargo test -p gix-tempfile --features signals |
| 146 | 151 | cargo test -p gix-tempfile |
| 147 | 152 | cargo test -p gix-features |