Fixing the stitching in cyclic conflict

pmeunier
Jan 18, 2026, 6:22 PM
FSJBK6CUVMSKZVLD7SWC4L53GMPUKIQESWDBFMV5GLX43WBUZDPQC

Dependencies

  • [2] SXEYMYF7 Fixing the bad changes in history (unfortunately, by rebooting).
  • [3] BD5PC25A Deleting conflict resolution vertices when the sides are deleted
  • [4] 6YMDOZIB Refactoring apply
  • [5] CCLLB7OI Upgrading to Sanakirja 0.15 + version bump
  • [6] I24UEJQL Various post-fire fixes
  • [7] FXEDPLRI Resurrecting tests, and type cleanup (no need for Arc<RwLock<…>> anymore)
  • [8] 55SCQOOH Fixing the tests
  • [9] 43SISRQ4 Formatting
  • [10] ZJWCPRMH Fixing known patches in deleted contexts
  • [11] MQ6ERQ43 Bug fixes when unrecording a patch that introduced zombie files
  • [12] H5DIAL52 Mixed zombie/order conflicts: fixing the bottom vertex
  • [13] HP7CKJIW Fixing a bug in unrecord
  • [14] RRCSHAYZ Formatting
  • [15] QWIYNMI5 Formatting + big-endian Sanakirja
  • [16] U2CGP7OP Record a separate change for Hunk::AddRoot, to avoid #571
  • [17] V3HHWF4Q Commit function in libpijul
  • [18] OXZVZDQZ Simplification of missing context repairs

Change contents

  • edit in libpijul/src/tests/conflict.rs at line 2538
    [2.433351]
    [7.78092]
    {
    let txn = txn.read();
    let graph = channel_bob.read();
    let mut f = std::fs::File::create("bob0").unwrap();
    crate::pristine::debug(&*txn, &txn.graph(&*graph), &mut f).unwrap();
    }
  • edit in libpijul/src/tests/conflict.rs at line 2546
    [7.78172]
    [8.10475]
    {
    let txn = txn.read();
    let graph = channel_bob.read();
    let mut f = std::fs::File::create("bob1").unwrap();
    crate::pristine::debug(&*txn, &txn.graph(&*graph), &mut f).unwrap();
    }
  • replacement in libpijul/src/lib.rs at line 84
    [2.720384][2.720384:720536]()
    impl MutTxnTExt for pristine::sanakirja::MutTxn<()> {}
    impl TxnTExt for pristine::sanakirja::MutTxn<()> {}
    impl TxnTExt for pristine::sanakirja::Txn {}
    [2.720384]
    [2.720536]
    impl<
    T: ::sanakirja::LoadPage<Error = ::sanakirja::Error>
    + ::sanakirja::RootPageMut
    + ::sanakirja::Commit
    + ::sanakirja::AllocPage<Error = ::sanakirja::Error>,
    > MutTxnTExt for pristine::sanakirja::GenericTxn<T>
    {
    }
    impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage> TxnTExt
    for pristine::sanakirja::GenericTxn<T>
    {
    }
  • replacement in libpijul/src/diff/delete.rs at line 133
    [2.809674][5.116879:116894]()
    )?
    [2.809674]
    [3.1308]
    )?;
  • replacement in libpijul/src/apply.rs at line 602
    [12.821][13.7152:7199](),[13.7199][12.821:1066](),[12.821][12.821:1066]()
    debug!("descendant {:#?}", r);
    put_graph_with_rev(
    txn,
    channel,
    EdgeFlags::PSEUDO,
    elt.last_alive,
    *r,
    ChangeId::ROOT,
    )?;
    [12.821]
    [12.1066]
    debug!("put_pseudo, descendant {:?} {:?}", elt.last_alive, r);
    // If we aren't in a direct cycle, reconnect.
    if elt.last_alive != *r {
    put_graph_with_rev(
    txn,
    channel,
    EdgeFlags::PSEUDO,
    elt.last_alive,
    *r,
    ChangeId::ROOT,
    )?;
    }
    }
    if !elt.is_alive() {
    continue;
  • replacement in libpijul/src/apply.rs at line 626
    [13.7529][13.7529:8249]()
    // We need to reconnect, and we can do it now
    // since we won't have a chance to visit that
    // edge (because non-PARENT edge we are
    // inserting now starts from a vertex that is
    // on the path, which means we've already
    // pushed all its children onto the stack.).
    put_graph_with_rev(
    txn,
    channel,
    EdgeFlags::PSEUDO,
    v.vertex,
    elt.vertex,
    ChangeId::ROOT,
    )?;
    [13.7529]
    [13.8249]
    if v.vertex != elt.vertex {
    // We need to reconnect, and we can do it now
    // since we won't have a chance to visit that
    // edge (because non-PARENT edge we are
    // inserting now starts from a vertex that is
    // on the path, which means we've already
    // pushed all its children onto the stack.).
    debug!("alive, put_pseudo {:?} {:?}", v.vertex, elt.vertex);
    put_graph_with_rev(
    txn,
    channel,
    EdgeFlags::PSEUDO,
    v.vertex,
    elt.vertex,
    ChangeId::ROOT,
    )?;
    }
  • replacement in libpijul/src/apply.rs at line 712
    [12.2810][12.2810:2971]()
    put_graph_with_rev(
    txn,
    channel,
    EdgeFlags::PSEUDO,
    [12.2810]
    [13.8605]
    debug!(
    "put_pseudo, alive 2, {:?} {:?}",
  • replacement in libpijul/src/apply.rs at line 715
    [13.8647][12.3015:3138](),[12.3015][12.3015:3138]()
    stack[len - 1].vertex,
    ChangeId::ROOT,
    )?;
    [13.8647]
    [12.3138]
    stack[len - 1].vertex
    );
    debug!("{:?}", stack);
    let edge = Edge {
    dest: stack[len - 1].vertex.start_pos(),
    flag: EdgeFlags::empty(),
    introduced_by: ChangeId::ROOT,
    };
    match txn.get_graph(channel, &v.last_alive, Some(&edge.into()))? {
    Some(e) if e.dest() == edge.dest && e.flag() == EdgeFlags::BLOCK => {}
    _ => {
    put_graph_with_rev(
    txn,
    channel,
    EdgeFlags::PSEUDO,
    v.last_alive,
    stack[len - 1].vertex,
    ChangeId::ROOT,
    )?;
    }
    }
  • replacement in libpijul/src/apply.rs at line 776
    [11.7127][11.7127:7137]()
    {
    [11.7127]
    [11.7137]
    if log_enabled!(log::Level::Debug) {
  • edit in libpijul/src/apply.rs at line 1125
    [4.27459]
    [4.27459]
    debug!("put_pseudo {:?} {:?}", next, current);
  • replacement in libpijul/src/apply.rs at line 1250
    [9.583][9.583:639]()
    .sample_iter(rand::distributions::Standard)
    [9.583]
    [9.639]
    .sample_iter(rand::distr::StandardUniform)
  • edit in libpijul/src/apply/vertex.rs at line 37
    [6.91421]
    [10.2117]
    // Collect the vertices in the up context (we only have their
    // end positions at this point), also collecting the deleted
    // ones (they're part of a conflict if they're unknown to the
    // patch we're applying).
  • edit in libpijul/src/apply/vertex.rs at line 50
    [6.91778]
    [6.91778]
    // Not the same here, we're only collecting down contexts.
  • edit in libpijul/src/apply/vertex.rs at line 61
    [6.92181]
    [6.92181]
    // Mark the delete/insert conflict, if any.
  • edit in libpijul/src/apply/vertex.rs at line 66
    [6.92333]
    [6.92333]
    // And put the edge into the graph.