| @@ -21,6 +21,7 @@ pub struct Options { · 20 unmodified lines |
| 21 | 21 | pub submodules: Submodules, |
| 22 | 22 | pub thread_limit: Option<usize>, |
| 23 | 23 | pub statistics: bool, |
| 24 | + pub allow_write: bool, |
| 24 | 25 | } |
| 25 | 26 | |
| 26 | 27 | pub fn show( |
| @@ -34,6 +35,7 @@ pub fn show( · 7 unmodified lines |
| 34 | 35 | // TODO: implement this |
| 35 | 36 | submodules: _, |
| 36 | 37 | thread_limit, |
| 38 | + allow_write, |
| 37 | 39 | statistics, |
| 38 | 40 | }: Options, |
| 39 | 41 | ) -> anyhow::Result<()> { |
| @@ -67,11 +69,15 @@ pub fn show( · 27 unmodified lines |
| 67 | 69 | _ => unreachable!("state must be attributes stack only"), |
| 68 | 70 | }, |
| 69 | 71 | }; |
| 72 | + let mut printer = Printer { |
| 73 | + out, |
| 74 | + changes: Vec::new(), |
| 75 | + }; |
| 70 | 76 | let outcome = gix_status::index_as_worktree( |
| 71 | 77 | index, |
| 72 | 78 | repo.work_dir() |
| 73 | 79 | .context("This operation cannot be run on a bare repository")?, |
| 74 | | − &mut Printer(out), |
| 80 | + &mut printer, |
| 75 | 81 | FastEq, |
| 76 | 82 | Submodule, |
| 77 | 83 | { |
| @@ -88,6 +94,27 @@ pub fn show( · 10 unmodified lines |
| 88 | 94 | options, |
| 89 | 95 | )?; |
| 90 | 96 | |
| 97 | + if outcome.entries_to_update != 0 && allow_write { |
| 98 | + { |
| 99 | + let entries = index.entries_mut(); |
| 100 | + for (entry_index, change) in printer.changes { |
| 101 | + let entry = &mut entries[entry_index]; |
| 102 | + match change { |
| 103 | + ApplyChange::SetSizeToZero => { |
| 104 | + entry.stat.size = 0; |
| 105 | + } |
| 106 | + ApplyChange::NewStat(new_stat) => { |
| 107 | + entry.stat = new_stat; |
| 108 | + } |
| 109 | + } |
| 110 | + } |
| 111 | + } |
| 112 | + index.write(gix::index::write::Options { |
| 113 | + extensions: Default::default(), |
| 114 | + skip_hash: false, // TODO: make this based on configuration |
| 115 | + })?; |
| 116 | + } |
| 117 | + |
| 91 | 118 | if statistics { |
| 92 | 119 | writeln!(err, "{outcome:#?}").ok(); |
| 93 | 120 | } |
| @@ -109,7 +136,15 @@ impl gix_status::index_as_worktree::traits::SubmoduleStatus for Submodule { · 15 unmodified lines |
| 109 | 136 | } |
| 110 | 137 | } |
| 111 | 138 | |
| 112 | | −struct Printer<W>(W); |
| 139 | +struct Printer<W> { |
| 140 | + out: W, |
| 141 | + changes: Vec<(usize, ApplyChange)>, |
| 142 | +} |
| 143 | + |
| 144 | +enum ApplyChange { |
| 145 | + SetSizeToZero, |
| 146 | + NewStat(gix::index::entry::Stat), |
| 147 | +} |
| 113 | 148 | |
| 114 | 149 | impl<'index, W> gix_status::index_as_worktree::VisitEntry<'index> for Printer<W> |
| 115 | 150 | where |
| @@ -122,28 +157,40 @@ where · 6 unmodified lines |
| 122 | 157 | &mut self, |
| 123 | 158 | _entries: &'index [Entry], |
| 124 | 159 | _entry: &'index Entry, |
| 125 | | − _entry_index: usize, |
| 160 | + entry_index: usize, |
| 126 | 161 | rela_path: &'index BStr, |
| 127 | 162 | status: EntryStatus<Self::ContentChange>, |
| 128 | 163 | ) { |
| 129 | | − self.visit_inner(rela_path, status).ok(); |
| 164 | + self.visit_inner(entry_index, rela_path, status).ok(); |
| 130 | 165 | } |
| 131 | 166 | } |
| 132 | 167 | |
| 133 | 168 | impl<W: std::io::Write> Printer<W> { |
| 134 | | − fn visit_inner(&mut self, rela_path: &BStr, status: EntryStatus<()>) -> std::io::Result<()> { |
| 169 | + fn visit_inner(&mut self, entry_index: usize, rela_path: &BStr, status: EntryStatus<()>) -> std::io::Result<()> { |
| 135 | 170 | let char_storage; |
| 136 | 171 | let status = match status { |
| 137 | 172 | EntryStatus::Conflict(conflict) => as_str(conflict), |
| 138 | 173 | EntryStatus::Change(change) => { |
| 174 | + if matches!( |
| 175 | + change, |
| 176 | + Change::Modification { |
| 177 | + set_entry_stat_size_zero: true, |
| 178 | + .. |
| 179 | + } |
| 180 | + ) { |
| 181 | + self.changes.push((entry_index, ApplyChange::SetSizeToZero)) |
| 182 | + } |
| 139 | 183 | char_storage = change_to_char(&change); |
| 140 | 184 | std::str::from_utf8(std::slice::from_ref(&char_storage)).expect("valid ASCII") |
| 141 | 185 | } |
| 142 | | − EntryStatus::NeedsUpdate(_) => return Ok(()), |
| 186 | + EntryStatus::NeedsUpdate(stat) => { |
| 187 | + self.changes.push((entry_index, ApplyChange::NewStat(stat))); |
| 188 | + return Ok(()); |
| 189 | + } |
| 143 | 190 | EntryStatus::IntentToAdd => "A", |
| 144 | 191 | }; |
| 145 | 192 | |
| 146 | | − writeln!(&mut self.0, "{status: >3} {rela_path}") |
| 193 | + writeln!(&mut self.out, "{status: >3} {rela_path}") |
| 147 | 194 | } |
| 148 | 195 | } |
| 149 | 196 | |