Skip to content

Commit b2ce073

Browse files
committed
adapt to changes in gix-status
1 parent eea1294 commit b2ce073

File tree

3 files changed

+80
-36
lines changed

3 files changed

+80
-36
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,10 @@ pub(crate) mod function {
404404
out,
405405
"{} {}{:?} {} {}{}{}",
406406
match entry.flags.stage() {
407-
0 => "BASE ",
408-
1 => "OURS ",
409-
2 => "THEIRS ",
407+
0 => " ",
408+
1 => "BASE ",
409+
2 => "OURS ",
410+
3 => "THEIRS ",
410411
_ => "UNKNOWN",
411412
},
412413
if entry.flags.is_empty() {

gitoxide-core/src/repository/status.rs

Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use gix::index::Entry;
55
use gix::prelude::FindExt;
66
use gix::Progress;
77
use gix_status::index_as_worktree::traits::FastEq;
8-
use gix_status::index_as_worktree::Change;
8+
use gix_status::index_as_worktree::{Change, Conflict, EntryStatus};
99

1010
pub enum Submodules {
1111
/// display all information about submodules, including ref changes, modifications and untracked files.
@@ -48,73 +48,116 @@ pub fn show(
4848
)?;
4949
let mut progress = progress.add_child("traverse index");
5050
let start = std::time::Instant::now();
51+
let options = gix_status::index_as_worktree::Options {
52+
fs: repo.filesystem_options()?,
53+
thread_limit,
54+
stat: repo.stat_options()?,
55+
attributes: match repo
56+
.attributes_only(
57+
index,
58+
gix::worktree::stack::state::attributes::Source::WorktreeThenIdMapping,
59+
)?
60+
.detach()
61+
.state_mut()
62+
{
63+
gix::worktree::stack::State::AttributesStack(attrs) => std::mem::take(attrs),
64+
// TODO: this should be nicer by creating attributes directly, but it's a private API
65+
_ => unreachable!("state must be attributes stack only"),
66+
},
67+
};
5168
gix_status::index_as_worktree(
5269
index,
5370
repo.work_dir()
5471
.context("This operation cannot be run on a bare repository")?,
5572
&mut Printer(out),
5673
FastEq,
74+
Submodule,
5775
{
5876
let odb = repo.objects.clone().into_arc()?;
5977
move |id, buf| odb.find_blob(id, buf)
6078
},
6179
&mut progress,
6280
pathspec.detach()?,
63-
gix_status::index_as_worktree::Options {
64-
fs: repo.filesystem_options()?,
65-
thread_limit,
66-
stat: repo.stat_options()?,
67-
},
81+
repo.filter_pipeline(Some(gix::hash::ObjectId::empty_tree(repo.object_hash())))?
82+
.0
83+
.into_parts()
84+
.0,
85+
&gix::interrupt::IS_INTERRUPTED,
86+
options,
6887
)?;
6988

7089
writeln!(err, "\nhead -> index and untracked files aren't implemented yet")?;
7190
progress.show_throughput(start);
7291
Ok(())
7392
}
7493

94+
#[derive(Clone)]
95+
struct Submodule;
96+
97+
impl gix_status::index_as_worktree::traits::SubmoduleStatus for Submodule {
98+
type Output = ();
99+
type Error = std::convert::Infallible;
100+
101+
fn status(&mut self, _entry: &Entry, _rela_path: &BStr) -> Result<Option<Self::Output>, Self::Error> {
102+
Ok(None)
103+
}
104+
}
105+
75106
struct Printer<W>(W);
76107

77108
impl<'index, W> gix_status::index_as_worktree::VisitEntry<'index> for Printer<W>
78109
where
79110
W: std::io::Write,
80111
{
81112
type ContentChange = ();
113+
type SubmoduleStatus = ();
82114

83115
fn visit_entry(
84116
&mut self,
85-
entry: &'index Entry,
117+
_entries: &'index [Entry],
118+
_entry: &'index Entry,
119+
_entry_index: usize,
86120
rela_path: &'index BStr,
87-
change: Option<Change<Self::ContentChange>>,
88-
conflict: bool,
121+
status: EntryStatus<Self::ContentChange>,
89122
) {
90-
self.visit_inner(entry, rela_path, change, conflict).ok();
123+
self.visit_inner(rela_path, status).ok();
91124
}
92125
}
93126

94127
impl<W: std::io::Write> Printer<W> {
95-
fn visit_inner(
96-
&mut self,
97-
_entry: &Entry,
98-
rela_path: &BStr,
99-
change: Option<Change<()>>,
100-
conflict: bool,
101-
) -> anyhow::Result<()> {
102-
if let Some(change) = conflict
103-
.then_some('U')
104-
.or_else(|| change.as_ref().and_then(change_to_char))
105-
{
106-
writeln!(&mut self.0, "{change} {rela_path}")?;
107-
}
108-
Ok(())
128+
fn visit_inner(&mut self, rela_path: &BStr, status: EntryStatus<()>) -> std::io::Result<()> {
129+
let char_storage;
130+
let status = match status {
131+
EntryStatus::Conflict(conflict) => as_str(conflict),
132+
EntryStatus::Change(change) => {
133+
char_storage = change_to_char(&change);
134+
std::str::from_utf8(std::slice::from_ref(&char_storage)).expect("valid ASCII")
135+
}
136+
EntryStatus::NeedsUpdate(_) => return Ok(()),
137+
EntryStatus::IntentToAdd => "A",
138+
};
139+
140+
writeln!(&mut self.0, "{status: >3} {rela_path}")
109141
}
110142
}
111143

112-
fn change_to_char(change: &Change<()>) -> Option<char> {
144+
fn as_str(c: Conflict) -> &'static str {
145+
match c {
146+
Conflict::BothDeleted => "DD",
147+
Conflict::AddedByUs => "AU",
148+
Conflict::DeletedByThem => "UD",
149+
Conflict::AddedByThem => "UA",
150+
Conflict::DeletedByUs => "DU",
151+
Conflict::BothAdded => "AA",
152+
Conflict::BothModified => "UU",
153+
}
154+
}
155+
156+
fn change_to_char(change: &Change<()>) -> u8 {
113157
// Known status letters: https://github.com/git/git/blob/6807fcfedab84bc8cd0fbf721bc13c4e68cda9ae/diff.h#L613
114-
Some(match change {
115-
Change::Removed => 'D',
116-
Change::Type => 'T',
117-
Change::Modification { .. } => 'M',
118-
Change::IntentToAdd => return None,
119-
})
158+
match change {
159+
Change::Removed => b'D',
160+
Change::Type => b'T',
161+
Change::SubmoduleModification(_) | Change::Modification { .. } => b'M',
162+
}
120163
}

gix/src/filter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ impl<'repo> Pipeline<'repo> {
150150
&mut |_, attrs| {
151151
entry.matching_attributes(attrs);
152152
},
153-
&mut |rela_path, buf| -> Result<_, gix_odb::find::Error> {
154-
let entry = match index.entry_by_path(rela_path) {
153+
&mut |buf| -> Result<_, gix_odb::find::Error> {
154+
let entry = match index.entry_by_path(gix_path::into_bstr(rela_path).as_ref()) {
155155
None => return Ok(None),
156156
Some(entry) => entry,
157157
};

0 commit comments

Comments
 (0)