More detailed display of conflicts

pmeunier
Oct 11, 2022, 12:13 PM
3QXUJMZDPH2EDJY6UXIRA5ZQK3GRS2R422S7CKN56I36O4POAQXQC

Dependencies

  • [2] 7GQSGIV5 Fixing conflict identifiers (some nested conflicts were wrong)
  • [3] YXAVFTPP Allowing vertex buffer to use references to the transaction, by changing `output::output` to take an ArcTxn<T> instead of a simple T
  • [4] HBUMCAFV Avoid printing multiple names conflicts more than once
  • [5] GA3P7FOM Nicer conflict markers
  • [6] GHO6DWPI Refactoring iterators
  • [7] E7UUQQCC Apply changes with prefixes in .pijul/changes
  • [8] G55Y75FU Avoiding deadlocks when using output.rs with a non-filesystem output
  • [9] CCLLB7OI Upgrading to Sanakirja 0.15 + version bump
  • [10] VYHHOEYH Versions and formatting
  • [11] ZDK3GNDB Tag transactions (including a massive refactoring of errors)
  • [12] 3AMEP2Y5 More convenient interface for channels
  • [13] LPM4PBYJ More precise API for working copy in record and output
  • [14] VO5OQW4W Removing anyhow in libpijul
  • [15] C4MJ7D7Q Verbose printing of conflicts to stderr
  • [16] SXEYMYF7 Fixing the bad changes in history (unfortunately, by rebooting).
  • [17] RMDMAYRX Adding a root inode (aka supporting submodules)
  • [18] Z6FWHKCA Improving the UI around zombie conflicts

Change contents

  • replacement in pijul/src/commands/mod.rs at line 368
    [4.2085][4.2085:2230]()
    Conflict::Name { ref path } => writeln!(w, " - Name conflict on \"{}\"", path)?,
    Conflict::ZombieFile { ref path } => {
    [4.2085]
    [4.2230]
    Conflict::Name { ref path, .. } => writeln!(w, " - Name conflict on \"{}\"", path)?,
    Conflict::ZombieFile { ref path, .. } => {
  • replacement in pijul/src/commands/mod.rs at line 375
    [4.2462][4.2462:2527]()
    Conflict::Zombie { ref path, ref line } => writeln!(
    [4.2462]
    [4.2527]
    Conflict::Zombie {
    ref path, ref line, ..
    } => writeln!(
  • replacement in pijul/src/commands/mod.rs at line 382
    [4.2660][4.2660:2725]()
    Conflict::Cyclic { ref path, ref line } => writeln!(
    [4.2660]
    [4.2725]
    Conflict::Cyclic {
    ref path, ref line, ..
    } => writeln!(
  • replacement in pijul/src/commands/mod.rs at line 389
    [4.2855][4.2855:2919]()
    Conflict::Order { ref path, ref line } => writeln!(
    [4.2855]
    [4.2919]
    Conflict::Order {
    ref path, ref line, ..
    } => writeln!(
  • edit in libpijul/src/vertex_buffer.rs at line 57
    [4.218994]
    [4.218994]
    pub inode_vertex: Position<ChangeId>,
  • replacement in libpijul/src/vertex_buffer.rs at line 63
    [4.219137][4.219137:219232]()
    pub fn new(w: W, path: &'b str, conflicts: &'a mut Vec<crate::output::Conflict>) -> Self {
    [4.219137]
    [4.219232]
    pub fn new(
    w: W,
    path: &'b str,
    inode_vertex: Position<ChangeId>,
    conflicts: &'a mut Vec<crate::output::Conflict>,
    ) -> Self {
  • edit in libpijul/src/vertex_buffer.rs at line 70
    [4.219258]
    [4.219258]
    inode_vertex,
  • edit in libpijul/src/vertex_buffer.rs at line 141
    [4.221061]
    [4.221061]
    inode_vertex: [self.inode_vertex],
  • edit in libpijul/src/vertex_buffer.rs at line 143
    [4.221091]
    [4.221091]
    changes: side.iter().cloned().cloned().collect(),
    id,
  • edit in libpijul/src/vertex_buffer.rs at line 155
    [4.221333]
    [4.221333]
    inode_vertex: [self.inode_vertex],
  • edit in libpijul/src/vertex_buffer.rs at line 157
    [4.221363]
    [4.221363]
    changes: add_del.iter().cloned().cloned().collect(),
    id,
  • edit in libpijul/src/vertex_buffer.rs at line 165
    [4.221605]
    [4.221605]
    inode_vertex: [self.inode_vertex],
  • edit in libpijul/src/vertex_buffer.rs at line 167
    [4.221635]
    [4.221635]
    changes: Vec::new(),
    id,
  • edit in libpijul/src/vertex_buffer.rs at line 172
    [4.221703]
    [4.221703]
    fn conflict_next(&mut self, id_: usize, side: &[&Hash]) -> Result<(), std::io::Error> {
    for conflict in self.conflicts.iter_mut().rev() {
    match conflict {
    crate::output::Conflict::Order { id, changes, .. } if *id == id_ => {
    changes.extend(side.into_iter().cloned())
    }
    crate::output::Conflict::Zombie { id, changes, .. } if *id == id_ => {
    changes.extend(side.into_iter().cloned())
    }
    crate::output::Conflict::Cyclic { id, changes, .. } if *id == id_ => {
    changes.extend(side.into_iter().cloned())
    }
    _ => break,
    }
    }
    self.output_conflict_marker(SEPARATOR, id_, side)
    }
  • edit in libpijul/src/output/output.rs at line 22
    [4.4222]
    [4.4222]
    inodes: Vec<Position<ChangeId>>,
    changes: Vec<Hash>,
  • edit in libpijul/src/output/output.rs at line 27
    [4.4268]
    [4.4268]
    inode: [Position<ChangeId>; 1],
    changes: Vec<Hash>,
  • edit in libpijul/src/output/output.rs at line 31
    [4.4295][4.4295:4328]()
    pos: Position<ChangeId>,
  • edit in libpijul/src/output/output.rs at line 32
    [4.4350]
    [4.4350]
    pos: [Position<ChangeId>; 1],
    names: Vec<Vertex<ChangeId>>,
    changes: Vec<Hash>,
  • edit in libpijul/src/output/output.rs at line 38
    [4.4392]
    [4.4392]
    inode_vertex: [Position<ChangeId>; 1],
  • edit in libpijul/src/output/output.rs at line 40
    [4.4413]
    [4.4413]
    changes: Vec<Hash>,
    id: usize,
  • edit in libpijul/src/output/output.rs at line 45
    [4.4455]
    [4.4455]
    inode_vertex: [Position<ChangeId>; 1],
  • edit in libpijul/src/output/output.rs at line 47
    [4.4476]
    [4.4476]
    changes: Vec<Hash>,
    id: usize,
  • edit in libpijul/src/output/output.rs at line 52
    [4.4517]
    [4.4517]
    inode_vertex: [Position<ChangeId>; 1],
  • edit in libpijul/src/output/output.rs at line 54
    [4.4538]
    [4.4538]
    changes: Vec<Hash>,
    id: usize,
  • edit in libpijul/src/output/output.rs at line 57
    [4.4545]
    [4.672753]
    }
    impl Conflict {
    pub fn changes(&self) -> &[Hash] {
    match self {
    Conflict::Name { ref changes, .. } => changes,
    Conflict::ZombieFile { ref changes, .. } => changes,
    Conflict::MultipleNames { ref changes, .. } => changes,
    Conflict::Zombie { ref changes, .. } => changes,
    Conflict::Cyclic { ref changes, .. } => changes,
    Conflict::Order { ref changes, .. } => changes,
    }
    }
    pub fn inodes(&self) -> &[Position<ChangeId>] {
    match self {
    Conflict::Name { ref inodes, .. } => inodes,
    Conflict::ZombieFile { ref inode, .. } => inode,
    Conflict::MultipleNames { ref pos, .. } => pos,
    Conflict::Zombie {
    ref inode_vertex, ..
    } => inode_vertex,
    Conflict::Cyclic {
    ref inode_vertex, ..
    } => inode_vertex,
    Conflict::Order {
    ref inode_vertex, ..
    } => inode_vertex,
    }
    }
  • edit in libpijul/src/output/output.rs at line 125
    [4.24169]
    [4.24169]
  • edit in libpijul/src/output/output.rs at line 258
    [4.13191]
    [4.263]
  • edit in libpijul/src/output/output.rs at line 260
    [4.299]
    [4.13222]
  • replacement in libpijul/src/output/output.rs at line 304
    [4.13906][4.13906:13975]()
    let o = output_loop(repo, changes, txn, channel, work, stop, 0);
    [4.13906]
    [4.13975]
    let o = output_loop(repo, changes, txn.clone(), channel, work, stop, 0);
  • edit in libpijul/src/output/output.rs at line 324
    [4.14225]
    [4.25353]
    let txn_ = txn.read();
    for (pos, (_, path, names)) in state.done_vertices {
    if !names.is_empty() {
    state.conflicts.insert(Conflict::MultipleNames {
    changes: names
    .iter()
    .map(|v| txn_.get_external(&v.change).unwrap().unwrap().into())
    .collect(),
    pos: [pos],
    names,
    path,
    });
    }
    }
  • replacement in libpijul/src/output/output.rs at line 364
    [4.14869][4.14869:14945]()
    done_vertices: HashMap<Position<ChangeId>, (Vertex<ChangeId>, String)>,
    [4.14869]
    [4.472]
    done_vertices: HashMap<Position<ChangeId>, (Vertex<ChangeId>, String, Vec<Vertex<ChangeId>>)>,
  • edit in libpijul/src/output/output.rs at line 367
    [4.507]
    [4.492]
  • replacement in libpijul/src/output/output.rs at line 411
    [4.16489][4.16489:16523]()
    is_first_name: &mut bool,
    [4.16489]
    [4.16523]
    is_first_name: &mut Option<Position<ChangeId>>,
    name_conflict: &mut Vec<Position<ChangeId>>,
  • replacement in libpijul/src/output/output.rs at line 415
    [4.16619][4.16619:16655]()
    Entry::Occupied(e) => {
    [4.16619]
    [4.16655]
    Entry::Occupied(mut e) => {
  • replacement in libpijul/src/output/output.rs at line 423
    [4.16880][4.16880:16923]()
    if e.get().0 != name_key {
    [4.16880]
    [4.16923]
    let e = e.get_mut();
    if e.0 != name_key {
    if e.2.is_empty() {
    e.2.push(e.0)
    }
  • replacement in libpijul/src/output/output.rs at line 429
    [4.16985][4.508:576](),[4.576][4.17051:17170](),[4.17051][4.17051:17170]()
    self.conflicts.insert(Conflict::MultipleNames {
    pos: output_item.pos,
    path: e.get().1.clone(),
    });
    [4.16985]
    [4.17170]
    e.2.push(name_key)
  • replacement in libpijul/src/output/output.rs at line 438
    [4.17397][4.17397:17437]()
    let name = if !*is_first_name {
    [4.17397]
    [4.17437]
    let name = if let Some(ref inode) = is_first_name {
    if name_conflict.is_empty() {
    name_conflict.push(*inode)
    }
    name_conflict.push(output_item.pos);
  • edit in libpijul/src/output/output.rs at line 447
    [4.17597][4.577:655]()
    self.conflicts.insert(Conflict::Name { path: name.clone() });
  • edit in libpijul/src/output/output.rs at line 449
    [4.17715][4.17715:17780](),[4.17780][4.656:711](),[4.711][4.17833:17894](),[4.17833][4.17833:17894]()
    debug!("not outputting {:?} {:?}", a, name_key);
    self.conflicts.insert(Conflict::Name {
    path: a.to_string(),
    });
  • replacement in libpijul/src/output/output.rs at line 452
    [4.17973][4.17973:18009]()
    *is_first_name = false;
    [4.17973]
    [4.18009]
    *is_first_name = Some(output_item.pos);
  • replacement in libpijul/src/output/output.rs at line 458
    [4.18209][4.18209:18274]()
    name_entry.insert((name_key, output_item.path.clone()));
    [4.18209]
    [4.18274]
    name_entry.insert((name_key, output_item.path.clone(), Vec::new()));
  • replacement in libpijul/src/output/output.rs at line 476
    [4.25796][4.18953:18991](),[4.18953][4.18953:18991]()
    let mut is_first_name = true;
    [4.25796]
    [4.18991]
    let mut is_first_name = None;
    let mut name_conflict = Vec::new();
  • replacement in libpijul/src/output/output.rs at line 480
    [4.19105][4.19105:19204]()
    let name = match self.make_inode(&a, name_key, &mut output_item, &mut is_first_name) {
    [4.19105]
    [4.19204]
    let name = match self.make_inode(
    &a,
    name_key,
    &mut output_item,
    &mut is_first_name,
    &mut name_conflict,
    ) {
  • replacement in libpijul/src/output/output.rs at line 552
    [4.21266][4.21266:21305]()
    if output_item.is_zombie {
    [4.21266]
    [4.712]
    if let Some(id) = output_item.is_zombie.take() {
  • replacement in libpijul/src/output/output.rs at line 554
    [4.773][4.21364:21408](),[4.21364][4.21364:21408]()
    path: name.to_string(),
    [4.773]
    [4.774]
    path: path.clone(),
    changes: id,
    inode: [output_item.pos],
  • edit in libpijul/src/output/output.rs at line 560
    [4.679083]
    [4.21428]
    if !name_conflict.is_empty() {
    let txn = txn.read();
    self.conflicts.insert(Conflict::Name {
    changes: name_conflict
    .iter()
    .map(|v| txn.get_external(&v.change).unwrap().unwrap().into())
    .collect(),
    path: a.clone(),
    inodes: name_conflict,
    });
    }
  • replacement in libpijul/src/output/output.rs at line 729
    [4.18][4.18:48]()
    let txn = txn.read();
    [4.18]
    [4.48]
    debug!("write");
    let txn = txn.write();
    debug!("/write");
  • replacement in libpijul/src/output/output.rs at line 738
    [4.26328][4.26328:26402]()
    let mut f = vertex_buffer::ConflictsWriter::new(w, &path, conflicts);
    [4.26328]
    [3.4033]
    debug!("vertex_buffer");
    let mut f = vertex_buffer::ConflictsWriter::new(w, &path, output_item.pos, conflicts);
    debug!("outputting graph");
  • replacement in libpijul/src/output/mod.rs at line 137
    [4.686542][4.686542:686563]()
    is_zombie: bool,
    [4.686494]
    [4.686563]
    is_zombie: Option<Vec<Hash>>,
  • replacement in libpijul/src/output/mod.rs at line 298
    [4.87230][4.87230:87273]()
    ) -> Result<bool, TxnErr<T::GraphError>> {
    [4.87230]
    [4.689844]
    ) -> Result<Option<Vec<Hash>>, TxnErr<T::GraphError>> {
  • replacement in libpijul/src/output/mod.rs at line 304
    [4.87402][4.87402:87419]()
    Ok(true)
    [4.87402]
    [4.87419]
    let mut id = Vec::new();
    let f = EdgeFlags::FOLDER | EdgeFlags::PARENT;
    for e in iter_adjacent(txn, channel, pos.inode_vertex(), f, EdgeFlags::all())? {
    let e = e?;
    if e.flag().contains(f) {
    id.push(txn.get_external(&e.introduced_by())?.unwrap().into())
    }
    }
    Ok(Some(id))
  • replacement in libpijul/src/output/mod.rs at line 314
    [4.87432][4.87432:87450]()
    Ok(false)
    [4.87432]
    [4.87450]
    Ok(None)
  • replacement in libpijul/src/output/archive.rs at line 196
    [3.5317][4.693414:693456](),[4.693414][4.693414:693456]()
    let mut is_first_name = true;
    [3.5317]
    [4.693456]
    let mut is_first_name = None;
  • replacement in libpijul/src/output/archive.rs at line 205
    [4.693808][4.693808:693862]()
    pos: output_item.pos,
    [4.693808]
    [4.5165]
    changes: Vec::new(),
    pos: [output_item.pos],
  • edit in libpijul/src/output/archive.rs at line 208
    [4.5222]
    [4.693862]
    names: Vec::new(),
  • replacement in libpijul/src/output/archive.rs at line 219
    [4.694368][4.694368:694415]()
    let name = if !is_first_name {
    [4.694368]
    [4.694415]
    let name = if let Some(inode) = is_first_name {
    let inodes = vec![inode, output_item.pos];
    let txn = txn.read();
  • edit in libpijul/src/output/archive.rs at line 224
    [4.694512]
    [4.694512]
    changes: inodes
    .iter()
    .map(|i| txn.get_external(&i.change).unwrap().unwrap().into())
    .collect(),
    inodes,
  • replacement in libpijul/src/output/archive.rs at line 232
    [4.694588][4.694588:694631]()
    is_first_name = false;
    [4.694588]
    [4.694631]
    is_first_name = Some(output_item.pos);
  • edit in libpijul/src/output/archive.rs at line 279
    [4.695688]
    [4.695688]
    output_item.pos,
  • replacement in libpijul/src/output/archive.rs at line 295
    [4.696145][4.696145:696188]()
    if output_item.is_zombie {
    [4.696145]
    [4.696188]
    if let Some(id) = output_item.is_zombie {
  • edit in libpijul/src/output/archive.rs at line 298
    [4.696294]
    [4.696294]
    changes: id,
    inode: [output_item.pos],
  • replacement in libpijul/src/alive/output.rs at line 63
    [4.5871][4.5871:6022]()
    let ext = txn.get_external(&graph[vid].vertex.change)?.unwrap();
    line_buf.begin_conflict(id, &[&ext.into()])?;
    [4.5871]
    [4.6022]
    let ext = txn.get_external(&graph[vid].vertex.change)?.unwrap().into();
    std::mem::drop(channel);
    std::mem::drop(txn);
    line_buf.begin_conflict(id, &[&ext])?;
  • edit in libpijul/src/alive/output.rs at line 69
    [4.6063]
    [4.6063]
    std::mem::drop(channel);
    std::mem::drop(txn);
  • replacement in libpijul/src/alive/output.rs at line 86
    [3.9886][4.6440:6529](),[4.6440][4.6440:6529](),[4.6529][2.32:105]()
    let ext = txn.get_external(&graph[vid].vertex.change)?.unwrap();
    line_buf.conflict_next(elt.id, &[&ext.into()])?;
    [3.9886]
    [4.6599]
    let ext = txn.get_external(&graph[vid].vertex.change)?.unwrap().into();
    std::mem::drop(txn);
    line_buf.conflict_next(elt.id, &[&ext])?;