Record a separate change for Hunk::AddRoot, to avoid #571

pmeunier
Dec 6, 2021, 11:39 AM
U2CGP7OPHQZNAAPWCRSFVZQWXFRVCB2NC3APRA7ACQJZBIVBE6IQC

Dependencies

  • [2] EEBKW7VT Keys and identities
  • [*] SXEYMYF7 Fixing the bad changes in history (unfortunately, by rebooting).

Change contents

  • edit in pijul/src/commands/record.rs at line 144
    [2.1911]
    [4.104054]
    txn.write()
    .apply_root_change_if_needed(&repo.changes, &channel, rand::thread_rng())?;
  • edit in libpijul/src/lib.rs at line 104
    [4.720579]
    [4.720579]
    fn apply_root_change_if_needed<C: changestore::ChangeStore, R: rand::Rng>(
    &mut self,
    changes: &C,
    channel: &ChannelRef<Self>,
    rng: R,
    ) -> Result<Option<(pristine::Hash, u64, pristine::Merkle)>, crate::apply::ApplyError<C::Error, Self::GraphError>> {
    crate::apply::apply_root_change(self, channel, changes, rng)
    }
  • edit in libpijul/src/apply.rs at line 827
    [4.982240]
    pub fn apply_root_change<R: rand::Rng, T: MutTxnT, P: ChangeStore>(
    txn: &mut T,
    channel: &ChannelRef<T>,
    store: &P,
    rng: R,
    ) -> Result<Option<(Hash, u64, Merkle)>, ApplyError<P::Error, T::GraphError>> {
    let mut change = {
    // If the graph already has a root.
    {
    let channel = channel.read();
    let gr = txn.graph(&*channel);
    for v in iter_adjacent(&*txn, gr, Vertex::ROOT, EdgeFlags::FOLDER, EdgeFlags::FOLDER|EdgeFlags::BLOCK)? {
    let v = txn.find_block(gr, v?.dest()).map_err(LocalApplyError::from)?;
    if v.start == v.end {
    // Already has a root
    return Ok(None)
    } else {
    // Non-empty channel without a root
    break
    }
    }
    // If we are here, either the channel is empty, or it
    // isn't and doesn't have a root.
    }
    let root = Position {
    change: Some(Hash::None),
    pos: ChangePosition(0u64.into()),
    };
    let contents = rng.sample_iter(rand::distributions::Standard).take(32).collect();
    crate::change::LocalChange::make_change(
    txn,
    channel,
    vec![crate::change::Hunk::AddRoot {
    name: Atom::NewVertex(NewVertex {
    up_context: vec![root],
    down_context: Vec::new(),
    start: ChangePosition(0u64.into()),
    end: ChangePosition(0u64.into()),
    flag: EdgeFlags::FOLDER|EdgeFlags::BLOCK,
    inode: root,
    }),
    inode: Atom::NewVertex(NewVertex {
    up_context: vec![Position {
    change: None,
    pos: ChangePosition(0u64.into()),
    }],
    down_context: Vec::new(),
    start: ChangePosition(1u64.into()),
    end: ChangePosition(1u64.into()),
    flag: EdgeFlags::FOLDER|EdgeFlags::BLOCK,
    inode: root,
    }),
    }],
    contents,
    crate::change::ChangeHeader::default(),
    Vec::new(),
    )?
    };
    let h = store.save_change(&mut change, |_, _| Ok(())).map_err(ApplyError::Changestore)?;
    let (n, merkle) = apply_change(store, txn, &mut channel.write(), &h)?;
    Ok(Some((h, n, merkle)))
    }