Skip to content

Commit 39046e9

Browse files
committed
Merge branch 'worktree-stack'
2 parents 2465381 + e4b57b1 commit 39046e9

File tree

35 files changed

+752
-465
lines changed

35 files changed

+752
-465
lines changed

Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ clippy: ## Run cargo clippy on all crates
6565
cargo clippy --all --no-default-features --features lean-async --tests
6666

6767
check-msrv: ## run cargo msrv to validate the current msrv requirements, similar to what CI does
68-
cd git-repository && cargo msrv verify
68+
cd git-repository && cargo +1.54.0 check --package git-repository --no-default-features --features async-network-client,unstable,local-time-support,max-performance
6969

7070
check-win: ## see that windows compiles, provided the x86_64-pc-windows-msvc target and cargo-xwin are present.
7171
cargo xwin build --target x86_64-pc-windows-msvc --no-default-features --features small
@@ -286,7 +286,7 @@ bench-git-config:
286286
check-msrv-on-ci: ## Check the minimal support rust version for currently installed Rust version
287287
rustc --version
288288
cargo check --package git-repository
289-
cargo check --package git-repository --no-default-features --features async-network-client
289+
cargo check --package git-repository --no-default-features --features async-network-client,unstable,local-time-support,max-performance
290290

291291
##@ Maintenance
292292

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ Crates that seem feature complete and need to see some more use before they can
110110
* [git-traverse](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-traverse)
111111
* [git-config](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-config)
112112
* [git-features](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-features)
113+
* [git-credentials](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-credentials)
114+
* [git-sec](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-sec)
115+
* [git-quote](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-quote)
113116
* [git-ref](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-ref)
114117
* [git-repository](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-repository)
115118
* `gitoxide-core`
@@ -119,10 +122,7 @@ Crates that seem feature complete and need to see some more use before they can
119122
* [git-bitmap](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-bitmap)
120123
* [git-revision](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-revision)
121124
* [git-attributes](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-attributes)
122-
* [git-quote](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-quote)
123125
* **idea**
124-
* [git-credentials](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-credentials)
125-
* [git-sec](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-sec)
126126
* [git-note](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-note)
127127
* [git-filter](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-filter)
128128
* [git-date](https://github.com/Byron/gitoxide/blob/main/crate-status.md#git-date)

etc/check-package-size.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ echo "in root: gitoxide CLI"
3737
(enter git-url && indent cargo diet -n --package-size-limit 15KB)
3838
(enter git-validate && indent cargo diet -n --package-size-limit 5KB)
3939
(enter git-date && indent cargo diet -n --package-size-limit 5KB)
40+
(enter git-filter && indent cargo diet -n --package-size-limit 5KB)
41+
(enter git-lfs && indent cargo diet -n --package-size-limit 5KB)
4042
(enter git-note && indent cargo diet -n --package-size-limit 5KB)
4143
(enter git-sec && indent cargo diet -n --package-size-limit 5KB)
4244
(enter git-tix && indent cargo diet -n --package-size-limit 5KB)

git-attributes/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ serde1 = ["serde", "bstr/serde1", "git-glob/serde1"]
1717
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1818

1919
[dependencies]
20+
git-features = { version = "^0.20.0", path = "../git-features" }
2021
git-quote = { version = "^0.2.0", path = "../git-quote" }
2122
git-glob = { version = "^0.2.0", path = "../git-glob" }
2223

git-attributes/src/lib.rs

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![forbid(unsafe_code)]
22
#![deny(rust_2018_idioms)]
33

4-
use bstr::BStr;
4+
use bstr::{BStr, BString};
55

66
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
77
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
@@ -18,6 +18,88 @@ pub enum State<'a> {
1818
Unspecified,
1919
}
2020

21+
/// A grouping of lists of patterns while possibly keeping associated to their base path.
22+
///
23+
/// Patterns with base path are queryable relative to that base, otherwise they are relative to the repository root.
24+
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
25+
pub struct MatchGroup<T: match_group::Tag> {
26+
/// A list of pattern lists, each representing a patterns from a file or specified by hand, in the order they were
27+
/// specified in.
28+
///
29+
/// During matching, this order is reversed.
30+
pub patterns: Vec<PatternList<T>>,
31+
}
32+
33+
/// A list of patterns with an optional names, for matching against it.
34+
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
35+
pub struct PatternList<T: match_group::Tag> {
36+
/// Patterns and their associated data in the order they were loaded in or specified.
37+
///
38+
/// During matching, this order is reversed.
39+
pub patterns: Vec<(git_glob::Pattern, T::Value)>,
40+
41+
/// The path at which the patterns are located in a format suitable for matches, or `None` if the patterns
42+
/// are relative to the worktree root.
43+
base: Option<BString>,
44+
}
45+
46+
mod match_group {
47+
use crate::{MatchGroup, PatternList};
48+
use std::ffi::OsString;
49+
use std::path::PathBuf;
50+
51+
/// A marker trait to identify the type of a description.
52+
pub trait Tag: Clone + PartialEq + Eq + std::fmt::Debug + std::hash::Hash + Ord + PartialOrd {
53+
/// The value associated with a pattern.
54+
type Value: PartialEq + Eq + std::fmt::Debug + std::hash::Hash + Ord + PartialOrd + Clone;
55+
}
56+
57+
/// Identify ignore patterns.
58+
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
59+
pub struct Ignore;
60+
impl Tag for Ignore {
61+
type Value = ();
62+
}
63+
64+
/// Identify patterns with attributes.
65+
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
66+
pub struct Attributes;
67+
impl Tag for Attributes {
68+
/// TODO: identify the actual value, should be name/State pairs, but there is the question of storage.
69+
type Value = ();
70+
}
71+
72+
impl MatchGroup<Ignore> {
73+
/// See [PatternList::<Ignore>::from_overrides()] for details.
74+
pub fn from_overrides(patterns: impl IntoIterator<Item = impl Into<OsString>>) -> Self {
75+
MatchGroup {
76+
patterns: vec![PatternList::<Ignore>::from_overrides(patterns)],
77+
}
78+
}
79+
}
80+
81+
impl PatternList<Ignore> {
82+
/// Parse a list of patterns, using slashes as path separators
83+
pub fn from_overrides(patterns: impl IntoIterator<Item = impl Into<OsString>>) -> Self {
84+
PatternList {
85+
patterns: patterns
86+
.into_iter()
87+
.map(Into::into)
88+
.filter_map(|pattern| {
89+
let pattern = git_features::path::into_bytes(PathBuf::from(pattern)).ok()?;
90+
git_glob::parse(pattern.as_ref()).map(|p| (p, ()))
91+
})
92+
.collect(),
93+
base: None,
94+
}
95+
}
96+
}
97+
}
98+
pub use match_group::{Attributes, Ignore, Tag};
99+
100+
pub type Files = MatchGroup<Attributes>;
101+
pub type IgnoreFiles = MatchGroup<Ignore>;
102+
21103
pub mod parse;
22104

23105
pub fn parse(buf: &[u8]) -> parse::Lines<'_> {

git-attributes/tests/attributes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
mod match_group;
12
mod parse;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
mod ignore {
2+
use git_attributes::Ignore;
3+
4+
#[test]
5+
fn init_from_overrides() {
6+
let input = ["simple", "pattern/"];
7+
let patterns = git_attributes::MatchGroup::<Ignore>::from_overrides(input).patterns;
8+
assert_eq!(patterns.len(), 1);
9+
assert_eq!(
10+
git_attributes::PatternList::<Ignore>::from_overrides(input),
11+
patterns.into_iter().next().unwrap()
12+
);
13+
}
14+
}

git-attributes/tests/parse/attribute.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fn line_numbers_are_counted_correctly() {
3030
(pattern(r"!foo.html", Mode::NO_SUB_DIR, None), vec![set("x")], 8),
3131
(pattern(r"#a/path", Mode::empty(), None), vec![unset("a")], 10),
3232
(
33-
pattern(r"*", Mode::ABSOLUTE | Mode::NO_SUB_DIR | Mode::ENDS_WITH, Some(0)),
33+
pattern(r"/*", Mode::ABSOLUTE | Mode::NO_SUB_DIR | Mode::ENDS_WITH, Some(1)),
3434
vec![unspecified("b")],
3535
11
3636
),
@@ -272,7 +272,6 @@ fn pattern(name: &str, flags: git_glob::pattern::Mode, first_wildcard_pos: Optio
272272
text: name.into(),
273273
mode: flags,
274274
first_wildcard_pos,
275-
base_path: None,
276275
})
277276
}
278277

git-attributes/tests/parse/ignore.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ fn line_numbers_are_counted_correctly() {
2020
("*.[oa]".into(), Mode::NO_SUB_DIR, 2),
2121
("*.html".into(), Mode::NO_SUB_DIR | Mode::ENDS_WITH, 5),
2222
("foo.html".into(), Mode::NO_SUB_DIR | Mode::NEGATIVE, 8),
23-
("*".into(), Mode::NO_SUB_DIR | Mode::ENDS_WITH | Mode::ABSOLUTE, 11),
24-
("foo".into(), Mode::NEGATIVE | Mode::NO_SUB_DIR | Mode::ABSOLUTE, 12),
25-
("foo/*".into(), Mode::ABSOLUTE, 13),
26-
("foo/bar".into(), Mode::ABSOLUTE | Mode::NEGATIVE, 14)
23+
("/*".into(), Mode::NO_SUB_DIR | Mode::ENDS_WITH | Mode::ABSOLUTE, 11),
24+
("/foo".into(), Mode::NEGATIVE | Mode::NO_SUB_DIR | Mode::ABSOLUTE, 12),
25+
("/foo/*".into(), Mode::ABSOLUTE, 13),
26+
("/foo/bar".into(), Mode::ABSOLUTE | Mode::NEGATIVE, 14)
2727
]
2828
);
2929
}

git-config/tests/values/boolean.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
use crate::values::b;
2-
use git_config::values::{Boolean, TrueVariant};
31
use std::convert::TryFrom;
42

3+
use git_config::values::{Boolean, TrueVariant};
4+
5+
use crate::values::b;
6+
57
#[test]
68
fn from_str_false() {
79
assert_eq!(Boolean::try_from(b("no")), Ok(Boolean::False("no".into())));

git-config/tests/values/color_attribute.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use git_config::values::ColorAttribute;
21
use std::str::FromStr;
32

3+
use git_config::values::ColorAttribute;
4+
45
#[test]
56
fn non_inverted() {
67
assert_eq!(ColorAttribute::from_str("bold"), Ok(ColorAttribute::Bold));

git-config/tests/values/color_value.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use git_config::values::ColorValue;
21
use std::str::FromStr;
32

3+
use git_config::values::ColorValue;
4+
45
#[test]
56
fn non_bright() {
67
assert_eq!(ColorValue::from_str("normal"), Ok(ColorValue::Normal));

git-config/tests/values/integer.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
use crate::values::b;
2-
use git_config::values::{Integer, IntegerSuffix};
31
use std::convert::TryFrom;
42

3+
use git_config::values::{Integer, IntegerSuffix};
4+
5+
use crate::values::b;
6+
57
#[test]
68
fn from_str_no_suffix() {
79
assert_eq!(Integer::try_from(b("1")).unwrap(), Integer { value: 1, suffix: None });

git-config/tests/values/normalize.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use git_config::values::normalize_str;
21
use std::borrow::Cow;
32

3+
use git_config::values::normalize_str;
4+
45
#[test]
56
fn not_modified_is_borrowed() {
67
assert_eq!(normalize_str("hello world"), Cow::Borrowed(b"hello world"));

git-config/tests/values/path.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
use crate::values::b;
2-
use git_config::values::path::interpolate;
3-
use git_config::values::Path;
41
use std::borrow::Cow;
52

3+
use git_config::values::{path::interpolate, Path};
4+
5+
use crate::values::b;
6+
67
#[test]
78
fn no_interpolation_for_paths_without_tilde_or_prefix() {
89
let path = &b"/foo/bar"[..];

git-glob/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ pub struct Pattern {
1616
pub mode: pattern::Mode,
1717
/// The position in `text` with the first wildcard character, or `None` if there is no wildcard at all.
1818
pub first_wildcard_pos: Option<usize>,
19-
/// The relative base at which this pattern resides, with trailing slash, using slashes as path separator.
20-
/// If `None`, the pattern is considered to be at the root of the repository.
21-
pub base_path: Option<BString>,
2219
}
2320

2421
///

git-glob/src/parse.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,23 @@ pub fn pattern(mut pat: &[u8]) -> Option<(BString, pattern::Mode, Option<usize>)
2626
}
2727
if pat.first() == Some(&b'/') {
2828
mode |= Mode::ABSOLUTE;
29-
pat = &pat[1..];
3029
}
31-
let mut line = truncate_non_escaped_trailing_spaces(pat);
32-
if line.last() == Some(&b'/') {
30+
let mut pat = truncate_non_escaped_trailing_spaces(pat);
31+
if pat.last() == Some(&b'/') {
3332
mode |= Mode::MUST_BE_DIR;
34-
line.pop();
33+
pat.pop();
3534
}
36-
if !line.contains(&b'/') {
35+
36+
let relative_pattern = mode.contains(Mode::ABSOLUTE).then(|| &pat[1..]).unwrap_or(&pat);
37+
if !relative_pattern.contains(&b'/') {
3738
mode |= Mode::NO_SUB_DIR;
3839
}
39-
let pos_of_first_wildcard = first_wildcard_pos(&line);
40-
if line.first() == Some(&b'*') && first_wildcard_pos(&line[1..]).is_none() {
40+
if relative_pattern.first() == Some(&b'*') && first_wildcard_pos(&relative_pattern[1..]).is_none() {
4141
mode |= Mode::ENDS_WITH;
4242
}
43-
Some((line, mode, pos_of_first_wildcard))
43+
44+
let pos_of_first_wildcard = first_wildcard_pos(&pat);
45+
Some((pat, mode, pos_of_first_wildcard))
4446
}
4547

4648
fn first_wildcard_pos(pat: &[u8]) -> Option<usize> {

0 commit comments

Comments
 (0)