Skip to content

Commit 45edd2e

Browse files
committed
Merge branch 'status'
2 parents 52efa90 + 2e06a00 commit 45edd2e

File tree

20 files changed

+136
-58
lines changed

20 files changed

+136
-58
lines changed

gitoxide-core/src/index/information.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub struct Options {
66

77
#[cfg(feature = "serde")]
88
mod serde_only {
9+
use gix::index::entry::Stage;
910

1011
mod ext {
1112
#[derive(serde::Serialize)]
@@ -115,11 +116,10 @@ mod serde_only {
115116
let (mut intent_to_add, mut skip_worktree) = (0, 0);
116117
for entry in f.entries() {
117118
match entry.flags.stage() {
118-
0 => stage_0_merged += 1,
119-
1 => stage_1_base += 1,
120-
2 => stage_2_ours += 1,
121-
3 => stage_3_theirs += 1,
122-
invalid => anyhow::bail!("Invalid stage {} encountered", invalid),
119+
Stage::Unconflicted => stage_0_merged += 1,
120+
Stage::Base => stage_1_base += 1,
121+
Stage::Ours => stage_2_ours += 1,
122+
Stage::Theirs => stage_3_theirs += 1,
123123
}
124124
match entry.mode {
125125
gix::index::entry::Mode::DIR => dir += 1,

gitoxide-core/src/repository/attributes/validate_baseline.rs

+7
Original file line numberDiff line numberDiff line change
@@ -262,13 +262,18 @@ pub(crate) mod function {
262262
}
263263

264264
#[derive(Debug)]
265+
// See note on `Mismatch`
266+
#[allow(dead_code)]
265267
pub struct ExcludeLocation {
266268
pub line: usize,
267269
pub rela_source_file: String,
268270
pub pattern: String,
269271
}
270272

271273
#[derive(Debug)]
274+
// We debug-print this structure, which makes all fields 'used', but it doesn't count.
275+
// TODO: find a way to not have to do more work, but make the warning go away.
276+
#[allow(dead_code)]
272277
pub enum Mismatch {
273278
Attributes {
274279
actual: Vec<gix::attrs::Assignment>,
@@ -281,6 +286,8 @@ pub(crate) mod function {
281286
}
282287

283288
#[derive(Debug)]
289+
// See note on `Mismatch`
290+
#[allow(dead_code)]
284291
pub struct ExcludeMatch {
285292
pub pattern: gix::glob::Pattern,
286293
pub source: Option<PathBuf>,

gitoxide-core/src/repository/index/entries.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub(crate) mod function {
2323
io::{BufWriter, Write},
2424
};
2525

26+
use gix::index::entry::Stage;
2627
use gix::{
2728
bstr::{BStr, BString},
2829
worktree::IndexPersistedOrInMemory,
@@ -392,11 +393,10 @@ pub(crate) mod function {
392393
out,
393394
"{} {}{:?} {} {}{}{}",
394395
match entry.flags.stage() {
395-
0 => " ",
396-
1 => "BASE ",
397-
2 => "OURS ",
398-
3 => "THEIRS ",
399-
_ => "UNKNOWN",
396+
Stage::Unconflicted => " ",
397+
Stage::Base => "BASE ",
398+
Stage::Ours => "OURS ",
399+
Stage::Theirs => "THEIRS ",
400400
},
401401
if entry.flags.is_empty() {
402402
"".to_string()

gix-config/src/file/includes/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,14 @@ fn append_followed_includes_recursively(
9999
}
100100

101101
buf.clear();
102-
std::io::copy(&mut std::fs::File::open(&config_path)?, buf)?;
102+
std::io::copy(
103+
&mut std::fs::File::open(&config_path).map_err(|err| Error::Io {
104+
source: err,
105+
path: config_path.to_owned(),
106+
})?,
107+
buf,
108+
)
109+
.map_err(Error::CopyBuffer)?;
103110
let config_meta = Metadata {
104111
path: Some(config_path),
105112
trust: meta.trust,

gix-config/src/file/includes/types.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
use crate::{parse, path::interpolate};
2+
use std::path::PathBuf;
23

34
/// The error returned when following includes.
45
#[derive(Debug, thiserror::Error)]
56
#[allow(missing_docs)]
67
pub enum Error {
7-
#[error(transparent)]
8-
Io(#[from] std::io::Error),
8+
#[error("Failed to copy configuration file into buffer")]
9+
CopyBuffer(#[source] std::io::Error),
10+
#[error("Could not read included configuration file at '{}'", path.display())]
11+
Io { path: PathBuf, source: std::io::Error },
912
#[error(transparent)]
1013
Parse(#[from] parse::Error),
1114
#[error(transparent)]

gix-index/src/access/mod.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{cmp::Ordering, ops::Range};
33
use bstr::{BStr, ByteSlice, ByteVec};
44
use filetime::FileTime;
55

6+
use crate::entry::{Stage, StageRaw};
67
use crate::{entry, extension, AccelerateLookup, Entry, PathStorage, PathStorageRef, State, Version};
78

89
// TODO: integrate this somehow, somewhere, depending on later usage.
@@ -81,7 +82,7 @@ impl State {
8182
res
8283
})
8384
.ok()?;
84-
self.entry_index_by_idx_and_stage(path, idx, stage, stage_cmp)
85+
self.entry_index_by_idx_and_stage(path, idx, stage as StageRaw, stage_cmp)
8586
}
8687

8788
/// Walk as far in `direction` as possible, with [`Ordering::Greater`] towards higher stages, and [`Ordering::Less`]
@@ -112,7 +113,7 @@ impl State {
112113
&self,
113114
path: &BStr,
114115
idx: usize,
115-
wanted_stage: entry::Stage,
116+
wanted_stage: entry::StageRaw,
116117
stage_cmp: Ordering,
117118
) -> Option<usize> {
118119
match stage_cmp {
@@ -121,15 +122,15 @@ impl State {
121122
.enumerate()
122123
.rev()
123124
.take_while(|(_, e)| e.path(self) == path)
124-
.find_map(|(idx, e)| (e.stage() == wanted_stage).then_some(idx)),
125+
.find_map(|(idx, e)| (e.stage_raw() == wanted_stage).then_some(idx)),
125126
Ordering::Equal => Some(idx),
126127
Ordering::Less => self
127128
.entries
128129
.get(idx + 1..)?
129130
.iter()
130131
.enumerate()
131132
.take_while(|(_, e)| e.path(self) == path)
132-
.find_map(|(ofs, e)| (e.stage() == wanted_stage).then_some(idx + ofs + 1)),
133+
.find_map(|(ofs, e)| (e.stage_raw() == wanted_stage).then_some(idx + ofs + 1)),
133134
}
134135
}
135136

@@ -291,15 +292,15 @@ impl State {
291292
.binary_search_by(|e| {
292293
let res = e.path(self).cmp(path);
293294
if res.is_eq() {
294-
stage_at_index = e.stage();
295+
stage_at_index = e.stage_raw();
295296
}
296297
res
297298
})
298299
.ok()?;
299300
let idx = if stage_at_index == 0 || stage_at_index == 2 {
300301
idx
301302
} else {
302-
self.entry_index_by_idx_and_stage(path, idx, 2, stage_at_index.cmp(&2))?
303+
self.entry_index_by_idx_and_stage(path, idx, Stage::Ours as StageRaw, stage_at_index.cmp(&2))?
303304
};
304305
Some(&self.entries[idx])
305306
}
@@ -334,13 +335,13 @@ impl State {
334335
+ self.entries[low..].partition_point(|e| e.path(self).get(..prefix_len).map_or(false, |p| p <= prefix));
335336

336337
let low_entry = &self.entries.get(low)?;
337-
if low_entry.stage() != 0 {
338+
if low_entry.stage_raw() != 0 {
338339
low = self
339340
.walk_entry_stages(low_entry.path(self), low, Ordering::Less)
340341
.unwrap_or(low);
341342
}
342343
if let Some(high_entry) = self.entries.get(high) {
343-
if high_entry.stage() != 0 {
344+
if high_entry.stage_raw() != 0 {
344345
high = self
345346
.walk_entry_stages(high_entry.path(self), high, Ordering::Less)
346347
.unwrap_or(high);
@@ -374,7 +375,7 @@ impl State {
374375
.binary_search_by(|e| {
375376
let res = e.path(self).cmp(path);
376377
if res.is_eq() {
377-
stage_at_index = e.stage();
378+
stage_at_index = e.stage_raw();
378379
}
379380
res
380381
})

gix-index/src/entry/flags.rs

+17
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,23 @@ bitflags! {
6262
impl Flags {
6363
/// Return the stage as extracted from the bits of this instance.
6464
pub fn stage(&self) -> Stage {
65+
match self.stage_raw() {
66+
0 => Stage::Unconflicted,
67+
1 => Stage::Base,
68+
2 => Stage::Ours,
69+
3 => Stage::Theirs,
70+
_ => unreachable!("BUG: Flags::STAGE_MASK is two bits, whose 4 possible values we have covered"),
71+
}
72+
}
73+
74+
/// Return an entry's stage as raw number between 0 and 4.
75+
/// Possible values are:
76+
///
77+
/// * 0 = no conflict,
78+
/// * 1 = base,
79+
/// * 2 = ours,
80+
/// * 3 = theirs
81+
pub fn stage_raw(&self) -> u32 {
6582
(*self & Flags::STAGE_MASK).bits() >> 12
6683
}
6784

gix-index/src/entry/mod.rs

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
1-
/// The stage of an entry, one of…
1+
/// The stage of an entry.
2+
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
3+
pub enum Stage {
4+
/// This is the default, and most entries are in this stage.
5+
#[default]
6+
Unconflicted = 0,
7+
/// The entry is the common base between 'our' change and 'their' change, for comparison.
8+
Base = 1,
9+
/// The entry represents our change.
10+
Ours = 2,
11+
/// The entry represents their change.
12+
Theirs = 3,
13+
}
14+
15+
// The stage of an entry, one of…
216
/// * 0 = no conflict,
317
/// * 1 = base,
418
/// * 2 = ours,
519
/// * 3 = theirs
6-
pub type Stage = u32;
20+
pub type StageRaw = u32;
721

822
///
923
#[allow(clippy::empty_docs)]
@@ -78,6 +92,17 @@ mod access {
7892
pub fn stage(&self) -> entry::Stage {
7993
self.flags.stage()
8094
}
95+
96+
/// Return an entry's stage as raw number between 0 and 4.
97+
/// Possible values are:
98+
///
99+
/// * 0 = no conflict,
100+
/// * 1 = base,
101+
/// * 2 = ours,
102+
/// * 3 = theirs
103+
pub fn stage_raw(&self) -> u32 {
104+
self.flags.stage_raw()
105+
}
81106
}
82107
}
83108

gix-index/src/extension/fs_monitor.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{
66
};
77

88
#[derive(Clone)]
9+
#[allow(dead_code)]
910
pub enum Token {
1011
V1 { nanos_since_1970: u64 },
1112
V2 { token: BString },

gix-index/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ pub struct State {
144144
}
145145

146146
mod impls {
147+
use crate::entry::Stage;
147148
use std::fmt::{Debug, Formatter};
148149

149150
use crate::State;
@@ -155,11 +156,10 @@ mod impls {
155156
f,
156157
"{} {}{:?} {} {}",
157158
match entry.flags.stage() {
158-
0 => " ",
159-
1 => "BASE ",
160-
2 => "OURS ",
161-
3 => "THEIRS ",
162-
_ => "UNKNOWN",
159+
Stage::Unconflicted => " ",
160+
Stage::Base => "BASE ",
161+
Stage::Ours => "OURS ",
162+
Stage::Theirs => "THEIRS ",
163163
},
164164
if entry.flags.is_empty() {
165165
"".to_string()

gix-index/tests/index/access.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::index::Fixture;
22
use bstr::{BString, ByteSlice};
3+
use gix_index::entry::Stage;
34

45
fn icase_fixture() -> gix_index::File {
56
Fixture::Generated("v2_icase_name_clashes").open()
@@ -11,7 +12,7 @@ fn entry_by_path() {
1112
for entry in file.entries() {
1213
let path = entry.path(&file);
1314
assert_eq!(file.entry_by_path(path), Some(entry));
14-
assert_eq!(file.entry_by_path_and_stage(path, 0), Some(entry));
15+
assert_eq!(file.entry_by_path_and_stage(path, Stage::Unconflicted), Some(entry));
1516
}
1617
}
1718

@@ -140,27 +141,27 @@ fn entry_by_path_and_stage() {
140141
for entry in file.entries() {
141142
let path = entry.path(&file);
142143
assert_eq!(
143-
file.entry_index_by_path_and_stage(path, 0)
144+
file.entry_index_by_path_and_stage(path, Stage::Unconflicted)
144145
.map(|idx| &file.entries()[idx]),
145146
Some(entry)
146147
);
147-
assert_eq!(file.entry_by_path_and_stage(path, 0), Some(entry));
148+
assert_eq!(file.entry_by_path_and_stage(path, Stage::Unconflicted), Some(entry));
148149
}
149150
}
150151

151152
#[test]
152153
fn entry_by_path_with_conflicting_file() {
153154
let file = Fixture::Loose("conflicting-file").open();
154-
for expected_stage in [1 /* common ancestor */, 2 /* ours */, 3 /* theirs */] {
155+
for expected_stage in [Stage::Base, Stage::Ours, Stage::Theirs] {
155156
assert!(
156157
file.entry_by_path_and_stage("file".into(), expected_stage).is_some(),
157-
"we have no stage 0 during a conflict, but all other ones. Missed {expected_stage}"
158+
"we have no stage 0 during a conflict, but all other ones. Missed {expected_stage:?}"
158159
);
159160
}
160161

161162
assert_eq!(
162163
file.entry_by_path("file".into()).expect("found").stage(),
163-
2,
164+
Stage::Ours,
164165
"we always find our stage while in a merge"
165166
);
166167
}
@@ -226,13 +227,13 @@ fn sort_entries() {
226227

227228
for (idx, entry) in file.entries()[..valid_entries].iter().enumerate() {
228229
assert_eq!(
229-
file.entry_index_by_path_and_stage_bounded(entry.path(&file), 0, valid_entries),
230+
file.entry_index_by_path_and_stage_bounded(entry.path(&file), Stage::Unconflicted, valid_entries),
230231
Some(idx),
231232
"we can still find entries in the correctly sorted region"
232233
);
233234
}
234235
assert_eq!(
235-
file.entry_by_path_and_stage(new_entry_path, 0),
236+
file.entry_by_path_and_stage(new_entry_path, Stage::Unconflicted),
236237
None,
237238
"new entry can't be found due to incorrect order"
238239
);
@@ -241,7 +242,7 @@ fn sort_entries() {
241242
assert!(file.verify_entries().is_ok(), "sorting of entries restores invariants");
242243

243244
assert_eq!(
244-
file.entry_by_path_and_stage(new_entry_path, 0)
245+
file.entry_by_path_and_stage(new_entry_path, Stage::Unconflicted)
245246
.expect("can be found")
246247
.path(&file),
247248
new_entry_path,

0 commit comments

Comments
 (0)