Skip to content

Commit 3d47919

Browse files
committed
Merge branch 'worktree-stack'
2 parents b574a39 + 9237121 commit 3d47919

File tree

101 files changed

+3826
-1796
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+3826
-1796
lines changed

Diff for: Cargo.lock

+288-191
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,11 @@ members = [
173173
"gix-tempfile",
174174
"gix-lock",
175175
"gix-attributes",
176+
"gix-ignore",
176177
"gix-pathspec",
177178
"gix-refspec",
178179
"gix-path",
180+
"gix-utils",
179181
"gix",
180182
"gitoxide-core",
181183
"gix-hashtable",

Diff for: README.md

+2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ is usable to some extent.
7676
* [gix-discover](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-discover)
7777
* [gix-path](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-path)
7878
* [gix-attributes](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-attributes)
79+
* [gix-ignore](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-ignore)
7980
* [gix-pathspec](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-pathspec)
8081
* [gix-index](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-index)
8182
* [gix-revision](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-revision)
@@ -84,6 +85,7 @@ is usable to some extent.
8485
* [gix-refspec](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-refspec)
8586
* `gitoxide-core`
8687
* **very early** _(possibly without any documentation and many rough edges)_
88+
* [gix-utils](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-utils)
8789
* [gix-worktree](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-worktree)
8890
* [gix-bitmap](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-bitmap)
8991
* [gix-date](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-date)

Diff for: crate-status.md

+23-10
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,15 @@ and itself relies on all `git-*` crates. It's not meant for consumption, for app
101101
* [x] write the table of contents
102102

103103
### gix-hashtable
104-
105104
* [x] hashmap
106105
* [x] hashset
107106

107+
### gix-utils
108+
109+
* **filesystem**
110+
* [x] probe capabilities
111+
* [x] symlink creation and removal
112+
* [x] file snapshots
108113

109114
### gix-object
110115
* *decode (zero-copy)* borrowed objects
@@ -323,11 +328,13 @@ Check out the [performance discussion][gix-traverse-performance] as well.
323328
* [ ] Some examples
324329

325330
### gix-attributes
326-
* [x] parse git-ignore files (aka gix-attributes without the attributes or negation)
327-
* [x] parse gix-attributes files
328-
* [ ] create an attributes stack, ideally one that includes 'ignored' status from .gitignore files.
329-
* [ ] support for built-in `binary` macro for `-text -diff -merge`
330-
331+
* [x] parse `.gitattribute` files
332+
* [ ] an attributes stack for matching paths to their attributes, with support for built-in `binary` macro for `-text -diff -merge`
333+
334+
### gix-ignore
335+
* [x] parse `.gitignore` files
336+
* [x] an attributes stack for checking if paths are excluded
337+
331338
### gix-quote
332339
* **ansi-c**
333340
* [x] quote
@@ -440,7 +447,7 @@ Make it the best-performing implementation and the most convenient one.
440447
- [ ] handle submodules
441448
- [ ] handle sparse directories
442449
- [ ] handle sparse index
443-
- [ ] linear scaling with multi-threading up to IO saturation
450+
- [x] linear scaling with multi-threading up to IO saturation
444451
- supported attributes to affect working tree and index contents
445452
- [ ] eol
446453
- [ ] working-tree-encoding
@@ -450,8 +457,10 @@ Make it the best-performing implementation and the most convenient one.
450457
- [ ] `ident`
451458
- [ ] filter processes
452459
- [ ] single-invocation clean/smudge filters
453-
* [x] access to all .gitignore/exclude information
454-
* [ ] access to all attributes information
460+
* manage multiple worktrees
461+
* access to per-path information, like `.gitignore` and `.gitattributes` in a manner well suited for efficient lookups
462+
* [x] _exclude_ information
463+
* [ ] attributes
455464

456465
### gix-revision
457466
* [x] `describe()` (similar to `git name-rev`)
@@ -602,6 +611,8 @@ See its [README.md](https://github.com/Byron/gitoxide/blob/main/gix-lock/README.
602611
* [x] tree with other tree
603612
* [ ] respect case-sensitivity of host filesystem.
604613
* [x] a way to access various diff related settings or use them
614+
* [ ] respect `diff.*.textconv`, `diff.*.cachetextconv` and external diff viewers with `diff.*.command`,
615+
[along with support for reading `diff` gitattributes](https://github.com/git/git/blob/73876f4861cd3d187a4682290ab75c9dccadbc56/Documentation/gitattributes.txt#L699:L699).
605616
* **rewrite tracking**
606617
* **deviation** - git keeps up to four candidates whereas we use the first-found candidate that matches the similarity percentage.
607618
This can lead to different sources being found. As such, we also don't consider the filename at all.
@@ -614,7 +625,7 @@ See its [README.md](https://github.com/Byron/gitoxide/blob/main/gix-lock/README.
614625
* [x] renames
615626
* [x] copies
616627
* [x] 'find-copies-harder' - find copies with the source being the entire tree.
617-
* [ ] tree with working tree
628+
* [ ] tree or index with working tree
618629
* [x] diffs between modified blobs with various algorithms
619630
* [ ] tree with index
620631
* [x] initialize
@@ -673,6 +684,8 @@ See its [README.md](https://github.com/Byron/gitoxide/blob/main/gix-lock/README.
673684
* [ ] obtain 'prunable' information
674685
* [x] proper handling of worktree related refs
675686
* [ ] create, move, remove, and repair
687+
* [x] access exclude information
688+
* [ ] access attribute information
676689
* [x] respect `core.worktree` configuration
677690
- **deviation**
678691
* The delicate interplay between `GIT_COMMON_DIR` and `GIT_WORK_TREE` isn't implemented.

Diff for: gitoxide-core/src/index/checkout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub fn checkout_exclusive(
5656
}
5757

5858
let opts = gix::worktree::index::checkout::Options {
59-
fs: gix::worktree::fs::Capabilities::probe(dest_directory),
59+
fs: gix::utils::FilesystemCapabilities::probe(dest_directory),
6060

6161
destination_is_initially_empty: true,
6262
overwrite_existing: false,

Diff for: gitoxide-core/src/repository/exclude.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ pub fn query(
3535
.worktree()
3636
.with_context(|| "Cannot check excludes without a current worktree")?;
3737
let index = worktree.index()?;
38-
let mut cache = worktree.excludes(
39-
&index,
40-
Some(gix::attrs::MatchGroup::<gix::attrs::Ignore>::from_overrides(overrides)),
41-
)?;
38+
let mut cache = worktree.excludes(&index, Some(gix::ignore::Search::from_overrides(overrides)))?;
4239

4340
let prefix = repo.prefix().expect("worktree - we have an index by now")?;
4441

Diff for: gix-attributes/Cargo.toml

+6-3
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,26 @@ doctest = false
1414

1515
[features]
1616
## Data structures implement `serde::Serialize` and `serde::Deserialize`.
17-
serde1 = ["serde", "bstr/serde", "gix-glob/serde1"]
17+
serde1 = ["serde", "bstr/serde", "gix-glob/serde1", "kstring/serde"]
1818

1919
[dependencies]
20-
gix-features = { version = "^0.28.0", path = "../gix-features" }
21-
gix-path = { version = "^0.7.2", path = "../gix-path" }
20+
gix-path = { version = "^0.7.3", path = "../gix-path" }
2221
gix-quote = { version = "^0.4.3", path = "../gix-quote" }
2322
gix-glob = { version = "^0.5.5", path = "../gix-glob" }
2423

2524
bstr = { version = "1.3.0", default-features = false, features = ["std", "unicode"]}
25+
smallvec = "1.10.0"
26+
kstring = "2.0.0"
2627
unicode-bom = "2.0.2"
2728
thiserror = "1.0.26"
2829
serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"]}
30+
log = "0.4.17"
2931

3032
document-features = { version = "0.2.1", optional = true }
3133

3234
[dev-dependencies]
3335
gix-testtools = { path = "../tests/tools"}
36+
gix-utils = { path = "../gix-utils" }
3437

3538
[package.metadata.docs.rs]
3639
all-features = true

Diff for: gix-attributes/src/lib.rs

+36-47
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
1-
//! Parse `.gitattribute` and `.gitignore` files and provide utilities to match against them.
1+
//! Parse `.gitattribute` files and provide utilities to match against them.
22
//!
33
//! ## Feature Flags
44
#![cfg_attr(
55
feature = "document-features",
66
cfg_attr(doc, doc = ::document_features::document_features!())
77
)]
88
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
9-
#![deny(missing_docs, rust_2018_idioms)]
10-
#![forbid(unsafe_code)]
9+
#![deny(missing_docs, rust_2018_idioms, unsafe_code)]
1110

12-
use std::path::PathBuf;
13-
14-
use bstr::{BStr, BString};
1511
pub use gix_glob as glob;
12+
use kstring::{KString, KStringRef};
1613

1714
mod assignment;
1815
///
1916
pub mod name;
20-
mod state;
17+
///
18+
pub mod state;
2119

22-
mod match_group;
23-
pub use match_group::{Attributes, Ignore, Match, Pattern};
20+
///
21+
pub mod search;
2422

2523
///
2624
pub mod parse;
27-
/// Parse attribute assignments line by line from `bytes`.
25+
26+
/// Parse attribute assignments line by line from `bytes`, and fail the operation on error.
27+
///
28+
/// For leniency, ignore errors using `filter_map(Result::ok)` for example.
2829
pub fn parse(bytes: &[u8]) -> parse::Lines<'_> {
2930
parse::Lines::new(bytes)
3031
}
@@ -42,7 +43,7 @@ pub enum StateRef<'a> {
4243
/// The attribute is set to the given value, which followed the `=` sign.
4344
/// Note that values can be empty.
4445
#[cfg_attr(feature = "serde1", serde(borrow))]
45-
Value(&'a BStr),
46+
Value(state::ValueRef<'a>),
4647
/// The attribute isn't mentioned with a given path or is explicitly set to `Unspecified` using the `!` sign.
4748
Unspecified,
4849
}
@@ -59,19 +60,19 @@ pub enum State {
5960
Unset,
6061
/// The attribute is set to the given value, which followed the `=` sign.
6162
/// Note that values can be empty.
62-
Value(BString), // TODO(performance): Is there a non-utf8 compact_str/KBString crate? See https://github.com/cobalt-org/kstring/issues/37#issuecomment-1446777265 .
63+
Value(state::Value),
6364
/// The attribute isn't mentioned with a given path or is explicitly set to `Unspecified` using the `!` sign.
6465
Unspecified,
6566
}
6667

6768
/// Represents a validated attribute name
6869
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
6970
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
70-
pub struct Name(pub(crate) String); // TODO(performance): See if `KBString` or `compact_string` could be meaningful here.
71+
pub struct Name(pub(crate) KString);
7172

7273
/// Holds a validated attribute name as a reference
73-
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
74-
pub struct NameRef<'a>(&'a str);
74+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
75+
pub struct NameRef<'a>(KStringRef<'a>);
7576

7677
/// Name an attribute and describe it's assigned state.
7778
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
@@ -84,54 +85,42 @@ pub struct Assignment {
8485
}
8586

8687
/// Holds validated attribute data as a reference
87-
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
88+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
8889
pub struct AssignmentRef<'a> {
8990
/// The name of the attribute.
9091
pub name: NameRef<'a>,
9192
/// The state of the attribute.
9293
pub state: StateRef<'a>,
9394
}
9495

95-
/// A grouping of lists of patterns while possibly keeping associated to their base path.
96+
/// A grouping of lists of patterns while possibly keeping associated to their base path in order to find matches.
9697
///
9798
/// Pattern lists with base path are queryable relative to that base, otherwise they are relative to the repository root.
9899
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Default)]
99-
pub struct MatchGroup<T: Pattern = Attributes> {
100+
pub struct Search {
100101
/// A list of pattern lists, each representing a patterns from a file or specified by hand, in the order they were
101102
/// specified in.
102103
///
103-
/// During matching, this order is reversed.
104-
pub patterns: Vec<PatternList<T>>,
104+
/// When matching, this order is reversed.
105+
patterns: Vec<gix_glob::search::pattern::List<search::Attributes>>,
105106
}
106107

107-
/// A list of patterns which optionally know where they were loaded from and what their base is.
108+
/// A list of known global sources for git attribute files in order of ascending precedence.
108109
///
109-
/// Knowing their base which is relative to a source directory, it will ignore all path to match against
110-
/// that don't also start with said base.
111-
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Default)]
112-
pub struct PatternList<T: Pattern> {
113-
/// Patterns and their associated data in the order they were loaded in or specified,
114-
/// the line number in its source file or its sequence number (_`(pattern, value, line_number)`_).
110+
/// This means that values from the first variant will be returned first.
111+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
112+
pub enum Source {
113+
/// The attribute file that the installation itself ships with.
114+
GitInstallation,
115+
/// System-wide attributes file. This is typically defined as
116+
/// `$(prefix)/etc/gitattributes` (where prefix is the git-installation directory).
117+
System,
118+
/// This is `<xdg-config-home>/git/attributes` and is git application configuration per user.
115119
///
116-
/// During matching, this order is reversed.
117-
pub patterns: Vec<PatternMapping<T::Value>>,
118-
119-
/// The path from which the patterns were read, or `None` if the patterns
120-
/// don't originate in a file on disk.
121-
pub source: Option<PathBuf>,
122-
123-
/// The parent directory of source, or `None` if the patterns are _global_ to match against the repository root.
124-
/// It's processed to contain slashes only and to end with a trailing slash, and is relative to the repository root.
125-
pub base: Option<BString>,
120+
/// Note that there is no `~/.gitattributes` file.
121+
Git,
122+
/// The configuration of the repository itself, located in `$GIT_DIR/info/attributes`.
123+
Local,
126124
}
127125

128-
/// An association of a pattern with its value, along with a sequence number providing a sort order in relation to its peers.
129-
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
130-
pub struct PatternMapping<T> {
131-
/// The pattern itself, like `/target/*`
132-
pub pattern: gix_glob::Pattern,
133-
/// The value associated with the pattern.
134-
pub value: T,
135-
/// Typically the line number in the file the pattern was parsed from.
136-
pub sequence_number: usize,
137-
}
126+
mod source;

0 commit comments

Comments
 (0)