History

adapt to changes in `gix-status`

Sebastian Thiel committed 3 years ago

Commit 54fb7c21 parent 60c948f4 files · +83 −37Browse files

Unified · Split

4 files
  1. crate-status.md +3 −1
  2. gitoxide-core/src/repository/index/entries.rs +4 −3
  3. gitoxide-core/src/repository/status.rs +74 −31
  4. gix/src/filter.rs +2 −2
crate-status.md+3−1
@@ -456,7 +456,9 @@ Make it the best-performing implementation and the most convenient one. · 455 unmodified lines
456456
457457 ### gix-status
458458 * [x] differences between index and worktree to turn index into worktree
459−* [ ] differences between tree and index to turn tree into index
459+ - [ ] rename tracking
460+* [ ] differences between index and index to learn what changed
461+ - [ ] rename tracking
460462 * [ ] untracked files
461463 * [ ] fast answer to 'is it dirty'.
462464 *
gitoxide-core/src/repository/index/entries.rs+4−3
@@ -404,9 +404,10 @@ pub(crate) mod function { · 403 unmodified lines
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+74−31
@@ -5,7 +5,7 @@ use gix::index::Entry; · 4 unmodified lines
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,23 +48,42 @@ pub fn show( · 36 unmodified lines
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")?;
@@ -72,6 +91,18 @@ pub fn show( · 1 unmodified line
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>
@@ -79,42 +110,54 @@ where · 1 unmodified line
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+2−2
@@ -150,8 +150,8 @@ impl<'repo> Pipeline<'repo> { · 149 unmodified lines
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 };