Removing anyhow in libpijul
[?]
Dec 6, 2020, 11:09 AM
VO5OQW4W2656DIYYRNZ3PO7TQ4JOKQ3GVWE5ALUTYVMX3WMXJOYQCDependencies
- [2]
Q45QHPO4Feedback on network stuff - [3]
62XVBWPYremove redundant Clap attributes - [4]
5DVRL6MFHard-unrecord - [5]
LCERQSWMCleanup - [6]
GVQ7YSEDChecking for dependencies even for a local change - [7]
ZXTHL45Oaddress clippy lints - [8]
DNQHXWRZaddress clippy hard errors - [9]
3YDPHBANaddress non-controversial clippy lints - [10]
V2MDXX62Channel rename: do not leave the old name behind - [11]
JP3BYVXXFixing file paths on Windows - [12]
6T5ULULMFixing conflicts with the changes from discussion #143 - [13]
4OCC6D42Recursive add - [14]
7A2TSC4PConflict solving code (FOLDER edges) - [15]
FYVZZNRQParsing UTF-8 in changes (bytes vs chars) - [16]
QNJBR73Kdon't return Result for infallible functions - [17]
UNZXTNSJChange text format: order dependencies in the order they were on the channel at record time - [18]
L4JXJHWXpijul/*: reorganize imports and remove extern crate - [19]
O4DNWMPDCleaunp and proofreading of libpijul::record - [20]
7PM25EXLRecursive apply was written a little too fast… - [21]
RJMQSZERExternal commands - [22]
OCBM7IFENew release: pijul-1.0.0-alpha.8 - [23]
NLGQAH4HCredit and reset relative to current directory instead of the root - [24]
GURIBVW6Fixing the pager - [25]
WZVCLZKYaddress clippy lints - [26]
NX5I5H53New published versions - [27]
WIORLB47Version bump - [28]
SNZ3OAMCuse native external subcommand support instead of hand-rolled one - [29]
KWAMD2KRA few fixes in the documentation comments - [30]
ERV3644QAdding the block module - [31]
BZSC7VMYaddress clippy lints - [32]
74HX2XZDCleanup and debugging - [33]
KVBLRDOUConcatenating edits with order conflict resolutions (if relevant), and parsing the text format of the result - [34]
KDF6FJRVbigger clippy refactors - [35]
JWTT77WJAdd help on subcommands - [36]
4H2XTVJ2Fix some mistakes in the docs - [37]
R3H7D42UDebugging `pijul git`: proper error reporting - [38]
5BRU2RRWCleanup (debugging a crash related to trees/inodes) - [39]
43AJ37IXGetting rid of edge validation, which does not work for zombie conflicts - [40]
BXD3IQYNFixing --features git - [41]
2K7JLB4ZNo pager on Windows - [42]
SAGSYAPXVarious version bumps - [43]
CVAT6LN3Fixing git import, and adding more useful feedback (with `RUST_LOG="pijul=info"`) - [44]
OXMYGLW2Printing the actual lines rather than str::lines + \n - [45]
N35L72XVVersions in Cargo.lock - [46]
ISQJRA3OFixing the parsing of zombie resurrection in the change text format - [47]
PJ7T2VFLDo not hang on locked repositories - [48]
G6YZ7U65Version bump - [49]
OUWD436AVersion bump - [50]
AEPEFS7OWrite help for each argument - [51]
UBCBQ5FGRemoving pijul/src/commands/checkout.rs (unused file), as well as litorg comments - [52]
H23LO7U7a few more clippy lints addressed - [53]
I52XSRUHMassive cleanup, and simplification - [54]
SXEYMYF7Fixing the bad changes in history (unfortunately, by rebooting). - [55]
7UPL3Y2AUnrecord: don't restore the same unrecorded file deletion twice in the inodes and tree tables
Change contents
- replacement in pijul-macros/src/lib.rs at line 511
) -> Result<bool, anyhow::Error>;) -> Result<bool, Self::Error>; - replacement in pijul-macros/src/lib.rs at line 517
) -> Result<bool, anyhow::Error>;) -> Result<bool, Self::Error>; - replacement in pijul-macros/src/lib.rs at line 546
) -> Result<bool, anyhow::Error> {) -> Result<bool, Self::Error> { - replacement in pijul-macros/src/lib.rs at line 554
) -> Result<bool, anyhow::Error> {) -> Result<bool, Self::Error> { - replacement in pijul-macros/src/lib.rs at line 565
) -> Result<bool, anyhow::Error> {) -> Result<bool, Self::Error> { - replacement in pijul-macros/src/lib.rs at line 575
) -> Result<bool, anyhow::Error> {) -> Result<bool, Self::Error> { - edit in pijul/src/main.rs at line 108[17.85778]→[3.159:203](∅→∅),[3.203]→[17.85845:85867](∅→∅),[17.866]→[17.85845:85867](∅→∅),[17.85845]→[17.85845:85867](∅→∅)
#[clap(setting = AppSettings::Hidden)]Upgrade(Upgrade), - edit in pijul/src/main.rs at line 241
SubCommand::Upgrade(upgrade) => upgrade.run(), - file deletion: upgrade.rs
use std::collections::{HashMap, HashSet};use std::path::PathBuf;use clap::Clap;use libpijul::changestore::ChangeStore;use libpijul::{Hash, MutTxnT, MutTxnTExt, TxnT, TxnTExt};use crate::repository::Repository;#[derive(Clap, Debug)]pub struct Upgrade {#[clap(long = "repository")]repo_path: Option<PathBuf>,}impl Upgrade {pub fn run(self) -> Result<(), anyhow::Error> {let mut channels = HashMap::new();{let repo = Repository::find_root(self.repo_path.clone())?;let txn = repo.pristine.txn_begin()?;let mut hashes = HashSet::new();for channel in txn.iter_channels("") {let channel = channel.borrow();let name = channel.name();let e = channels.entry(name.to_string()).or_insert_with(Vec::new);hashes.clear();for (_, (h, _)) in txn.reverse_log(&channel, None) {if !hashes.insert(h) {continue;}let path = repo.changes.filename(&h);let change = libpijul::change::v3::LocalChange3::deserialize(path.to_str().unwrap(),Some(&h),).unwrap();e.push((h, change))}}std::fs::rename(repo.path.join(".pijul"), repo.path.join(".pijul.old"))?;}let repo2 = Repository::init(self.repo_path)?;let mut txn2 = repo2.pristine.mut_txn_begin();let mut translations = HashMap::new();translations.insert(None, None);translations.insert(Some(Hash::None), Some(Hash::None));for (channel_name, mut changes) in channels {let mut channel = txn2.open_or_create_channel(&channel_name)?;while let Some((old_h, c)) = changes.pop() {let h = repo2.changes.save_change(&c.to_v4(&translations))?;translations.insert(Some(old_h), Some(h));txn2.apply_change(&repo2.changes, &mut channel, h)?;}}txn2.commit()?;Ok(())}}/// Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a `.pijul` directory. - edit in pijul/src/commands/mod.rs at line 59
mod upgrade;pub use upgrade::*; - replacement in pijul/src/commands/git.rs at line 648
Err(e) => match e.downcast() {Ok(libpijul::Error::ChangeAlreadyOnChannel { hash }) => {error!("change already on channel: {:?}", hash);return Ok(txn.current_state(&channel.borrow()).unwrap());}Ok(e) => return Err(e.into()),Err(e) => return Err(e),},Err(libpijul::LocalApplyError::ChangeAlreadyOnChannel { hash }) => {error!("change already on channel: {:?}", hash);return Ok(txn.current_state(&channel.borrow()).unwrap());}Err(e) => return Err(e.into()), - replacement in pijul/src/commands/git.rs at line 692
) -> Result<(usize, Option<libpijul::Hash>, Option<libpijul::Merkle>), anyhow::Error> {) -> Result<(usize, Option<libpijul::Hash>, Option<libpijul::Merkle>),libpijul::LocalApplyError<T::Error>,> { - replacement in pijul/src/commands/git.rs at line 699
if let Err(e) = result {match e.downcast() {Ok(libpijul::Error::FileNotInRepo { .. }) => {}Ok(e) => return Err(e.into()),Err(e) => return Err(e),use libpijul::working_copy::filesystem::*;match result {Ok(_) => {}Err(Error::Add(AddError::Fs(FsError::NotFound(_)))) => {}Err(Error::Add(AddError::Fs(FsError::AlreadyInRepo(_)))) => {}Err(e) => {error!("While adding {:?}: {}", p, e); - replacement in pijul/src/commands/credit.rs at line 88
fn output_line<C: FnOnce(&mut Vec<u8>) -> Result<(), anyhow::Error>>(fn output_line<E, C: FnOnce(&mut Vec<u8>) -> Result<(), E>>( - replacement in pijul/src/commands/credit.rs at line 92
) -> Result<(), anyhow::Error> {) -> Result<(), E>whereE: From<std::io::Error>,{ - replacement in pijul/src/commands/credit.rs at line 142
fn output_conflict_marker(&mut self, s: &str) -> Result<(), anyhow::Error> {fn output_conflict_marker(&mut self, s: &str) -> Result<(), std::io::Error> { - edit in libpijul/src/working_copy/mod.rs at line 11
#[derive(Debug, Error)]pub enum WriteError<E: std::error::Error + 'static> {#[error(transparent)]E(E),#[error(transparent)]Io(#[from] std::io::Error),} - replacement in libpijul/src/working_copy/mod.rs at line 21
fn create_dir_all(&mut self, path: &str) -> Result<(), anyhow::Error>;fn file_metadata(&self, file: &str) -> Result<InodeMetadata, anyhow::Error>;fn read_file(&self, file: &str, buffer: &mut Vec<u8>) -> Result<(), anyhow::Error>;fn modified_time(&self, file: &str) -> Result<std::time::SystemTime, anyhow::Error>;fn remove_path(&mut self, name: &str) -> Result<(), anyhow::Error>;fn rename(&mut self, former: &str, new: &str) -> Result<(), anyhow::Error>;fn set_permissions(&mut self, name: &str, permissions: u16) -> Result<(), anyhow::Error>;fn write_file<A, F: FnOnce(&mut dyn std::io::Write) -> Result<A, anyhow::Error>>(type Error: std::error::Error;fn create_dir_all(&mut self, path: &str) -> Result<(), Self::Error>;fn file_metadata(&self, file: &str) -> Result<InodeMetadata, Self::Error>;fn read_file(&self, file: &str, buffer: &mut Vec<u8>) -> Result<(), Self::Error>;fn modified_time(&self, file: &str) -> Result<std::time::SystemTime, Self::Error>;fn remove_path(&mut self, name: &str) -> Result<(), Self::Error>;fn rename(&mut self, former: &str, new: &str) -> Result<(), Self::Error>;fn set_permissions(&mut self, name: &str, permissions: u16) -> Result<(), Self::Error>;fn write_file<A, E: std::error::Error, F: FnOnce(&mut dyn std::io::Write) -> Result<A, E>>( - replacement in libpijul/src/working_copy/mod.rs at line 33
) -> Result<A, anyhow::Error>;) -> Result<A, WriteError<E>>; - edit in libpijul/src/working_copy/memory.rs at line 197
}#[derive(Debug, Error)]pub enum Error {#[error("Path not found: {path}")]NotFound { path: String }, - replacement in libpijul/src/working_copy/memory.rs at line 206
fn create_dir_all(&mut self, file: &str) -> Result<(), anyhow::Error> {type Error = Error;fn create_dir_all(&mut self, file: &str) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/memory.rs at line 223
fn file_metadata(&self, file: &str) -> Result<InodeMetadata, anyhow::Error> {fn file_metadata(&self, file: &str) -> Result<InodeMetadata, Self::Error> { - replacement in libpijul/src/working_copy/memory.rs at line 227
None => Err((crate::Error::FileNotFound {None => Err(Error::NotFound { - replacement in libpijul/src/working_copy/memory.rs at line 229
}).into()),}), - replacement in libpijul/src/working_copy/memory.rs at line 232
fn read_file(&self, file: &str, buffer: &mut Vec<u8>) -> Result<(), anyhow::Error> {fn read_file(&self, file: &str, buffer: &mut Vec<u8>) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/memory.rs at line 239
None => Err((crate::Error::FileNotFound {None => Err(Error::NotFound { - replacement in libpijul/src/working_copy/memory.rs at line 241
}).into()),}), - replacement in libpijul/src/working_copy/memory.rs at line 244
fn modified_time(&self, _file: &str) -> Result<std::time::SystemTime, anyhow::Error> {fn modified_time(&self, _file: &str) -> Result<std::time::SystemTime, Self::Error> { - replacement in libpijul/src/working_copy/memory.rs at line 248
fn remove_path(&mut self, path: &str) -> Result<(), anyhow::Error> {fn remove_path(&mut self, path: &str) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/memory.rs at line 253
fn rename(&mut self, old: &str, new: &str) -> Result<(), anyhow::Error> {fn rename(&mut self, old: &str, new: &str) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/memory.rs at line 260
fn set_permissions(&mut self, file: &str, permissions: u16) -> Result<(), anyhow::Error> {fn set_permissions(&mut self, file: &str, permissions: u16) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/memory.rs at line 273
fn write_file<A, F: FnOnce(&mut dyn std::io::Write) -> Result<A, anyhow::Error>>(fn write_file<A, E: std::error::Error, F: FnOnce(&mut dyn std::io::Write) -> Result<A, E>>( - replacement in libpijul/src/working_copy/memory.rs at line 277
) -> Result<A, anyhow::Error> {) -> Result<A, WriteError<E>> { - replacement in libpijul/src/working_copy/memory.rs at line 283
writer(contents)writer(contents).map_err(WriteError::E) - replacement in libpijul/src/working_copy/memory.rs at line 288
let a = writer(&mut contents)?;let a = writer(&mut contents).map_err(WriteError::E)?; - replacement in libpijul/src/working_copy/filesystem.rs at line 32
) -> Result<(PathBuf, String), anyhow::Error> {) -> Result<(PathBuf, String), std::io::Error> { - edit in libpijul/src/working_copy/filesystem.rs at line 56
}#[derive(Debug, Error)]pub enum AddError<T: std::error::Error + 'static> {#[error(transparent)]Ignore(#[from] ignore::Error),#[error(transparent)]Io(#[from] std::io::Error),#[error(transparent)]Fs(#[from] crate::fs::FsError<T>), - edit in libpijul/src/working_copy/filesystem.rs at line 68
#[derive(Debug, Error)]pub enum Error<C: std::error::Error + 'static, T: std::error::Error + 'static> {#[error(transparent)]Add(#[from] AddError<T>),#[error(transparent)]Record(#[from] crate::record::RecordError<C, std::io::Error, T>),} - replacement in libpijul/src/working_copy/filesystem.rs at line 95
) -> Result<(), anyhow::Error> {) -> Result<(), Error<C::Error, T::Error>> { - replacement in libpijul/src/working_copy/filesystem.rs at line 111
) -> Result<(), anyhow::Error> {) -> Result<(), AddError<T::Error>> { - replacement in libpijul/src/working_copy/filesystem.rs at line 168
) -> Result<(), anyhow::Error> {) -> Result<(), Error<C::Error, T::Error>> { - replacement in libpijul/src/working_copy/filesystem.rs at line 193
fn create_dir_all(&mut self, file: &str) -> Result<(), anyhow::Error> {type Error = std::io::Error;fn create_dir_all(&mut self, file: &str) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/filesystem.rs at line 197
fn file_metadata(&self, file: &str) -> Result<InodeMetadata, anyhow::Error> {fn file_metadata(&self, file: &str) -> Result<InodeMetadata, Self::Error> { - replacement in libpijul/src/working_copy/filesystem.rs at line 203
fn read_file(&self, file: &str, buffer: &mut Vec<u8>) -> Result<(), anyhow::Error> {fn read_file(&self, file: &str, buffer: &mut Vec<u8>) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/filesystem.rs at line 209
fn modified_time(&self, file: &str) -> Result<std::time::SystemTime, anyhow::Error> {fn modified_time(&self, file: &str) -> Result<std::time::SystemTime, Self::Error> { - replacement in libpijul/src/working_copy/filesystem.rs at line 214
fn remove_path(&mut self, path: &str) -> Result<(), anyhow::Error> {fn remove_path(&mut self, path: &str) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/filesystem.rs at line 227
fn rename(&mut self, former: &str, new: &str) -> Result<(), anyhow::Error> {fn rename(&mut self, former: &str, new: &str) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/filesystem.rs at line 239
fn set_permissions(&mut self, name: &str, permissions: u16) -> Result<(), anyhow::Error> {fn set_permissions(&mut self, name: &str, permissions: u16) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/filesystem.rs at line 254
fn set_permissions(&mut self, _name: &str, _permissions: u16) -> Result<(), anyhow::Error> {fn set_permissions(&mut self, _name: &str, _permissions: u16) -> Result<(), Self::Error> { - replacement in libpijul/src/working_copy/filesystem.rs at line 257
fn write_file<A, F: FnOnce(&mut dyn std::io::Write) -> Result<A, anyhow::Error>>(fn write_file<A, E: std::error::Error, F: FnOnce(&mut dyn std::io::Write) -> Result<A, E>>( - replacement in libpijul/src/working_copy/filesystem.rs at line 261
) -> Result<A, anyhow::Error> {) -> Result<A, WriteError<E>> { - replacement in libpijul/src/working_copy/filesystem.rs at line 264
std::fs::create_dir_all(p)?std::fs::create_dir_all(p).map_err(WriteError::Io)? - replacement in libpijul/src/working_copy/filesystem.rs at line 267
let mut file = std::io::BufWriter::new(std::fs::File::create(&path)?);writer(&mut file)let mut file =std::io::BufWriter::new(std::fs::File::create(&path).map_err(WriteError::Io)?);writer(&mut file).map_err(WriteError::E) - replacement in libpijul/src/vertex_buffer.rs at line 15
fn output_line<F: FnOnce(&mut Vec<u8>) -> Result<(), anyhow::Error>>(&mut self,key: Vertex<ChangeId>,contents: F,) -> Result<(), anyhow::Error>;fn output_line<E, F>(&mut self, key: Vertex<ChangeId>, contents: F) -> Result<(), E>whereE: From<std::io::Error>,F: FnOnce(&mut Vec<u8>) -> Result<(), E>; - replacement in libpijul/src/vertex_buffer.rs at line 20
fn output_conflict_marker(&mut self, s: &str) -> Result<(), anyhow::Error>;fn begin_conflict(&mut self) -> Result<(), anyhow::Error> {fn output_conflict_marker(&mut self, s: &str) -> Result<(), std::io::Error>;fn begin_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 24
fn begin_zombie_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_zombie_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 27
fn begin_cyclic_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_cyclic_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 30
fn conflict_next(&mut self) -> Result<(), anyhow::Error> {fn conflict_next(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 33
fn end_conflict(&mut self) -> Result<(), anyhow::Error> {fn end_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 36
fn end_zombie_conflict(&mut self) -> Result<(), anyhow::Error> {fn end_zombie_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 39
fn end_cyclic_conflict(&mut self) -> Result<(), anyhow::Error> {fn end_cyclic_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 80
fn output_line<C: FnOnce(&mut Vec<u8>) -> Result<(), anyhow::Error>>(&mut self,_: Vertex<ChangeId>,c: C,) -> Result<(), anyhow::Error> {fn output_line<E, C>(&mut self, _: Vertex<ChangeId>, c: C) -> Result<(), E>whereE: From<std::io::Error>,C: FnOnce(&mut Vec<u8>) -> Result<(), E>,{ - replacement in libpijul/src/vertex_buffer.rs at line 98
fn output_conflict_marker(&mut self, s: &str) -> Result<(), anyhow::Error> {fn output_conflict_marker(&mut self, s: &str) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 112
fn begin_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 119
fn begin_zombie_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_zombie_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 126
fn begin_cyclic_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_cyclic_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 168
fn output_line<C: FnOnce(&mut Vec<u8>) -> Result<(), anyhow::Error>>(&mut self,_: Vertex<ChangeId>,c: C,) -> Result<(), anyhow::Error> {fn output_line<E, C>(&mut self, _: Vertex<ChangeId>, c: C) -> Result<(), E>whereE: From<std::io::Error>,C: FnOnce(&mut Vec<u8>) -> Result<(), E>,{ - replacement in libpijul/src/vertex_buffer.rs at line 185
fn output_conflict_marker(&mut self, s: &str) -> Result<(), anyhow::Error> {fn output_conflict_marker(&mut self, s: &str) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 196
fn begin_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 199
fn begin_zombie_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_zombie_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/vertex_buffer.rs at line 202
fn begin_cyclic_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_cyclic_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/unrecord/working_copy.rs at line 10
) -> Result<(), anyhow::Error> {) -> Result<(), T::Error> { - replacement in libpijul/src/unrecord/working_copy.rs at line 29
) -> Result<(), anyhow::Error> {) -> Result<(), super::UnrecordError<P::Error, T::Error>> { - replacement in libpijul/src/unrecord/working_copy.rs at line 47
) -> Result<(), anyhow::Error> {) -> Result<(), super::UnrecordError<P::Error, T::Error>> { - replacement in libpijul/src/unrecord/working_copy.rs at line 67
return_value = Some(restore_inode(txn, changes, source, dest, Inode::ROOT)?)return_value = Some(restore_inode(txn, changes, source, dest, Inode::ROOT)?); - replacement in libpijul/src/unrecord/working_copy.rs at line 69
return_value = Some(restore_inode(txn, changes, source, dest, inode)?)return_value = Some(restore_inode(txn, changes, source, dest, inode)?); - replacement in libpijul/src/unrecord/working_copy.rs at line 85
) -> Result<Inode, anyhow::Error> {) -> Result<Inode, super::UnrecordError<P::Error, T::Error>> { - replacement in libpijul/src/unrecord/working_copy.rs at line 87
let (_, basename) = changes.get_file_name(|h| txn.get_external(h), source, &mut name)?;let (_, basename) = changes.get_file_name(|h| txn.get_external(h), source, &mut name).map_err(super::UnrecordError::Changestore)?; - replacement in libpijul/src/unrecord/working_copy.rs at line 99
put_tree_with_rev(txn, file_id.as_file_id(), inode)?;put_inodes_with_rev(txn, inode, dest)?;put_tree_with_rev(txn, file_id.as_file_id(), inode).map_err(super::UnrecordError::Txn)?;put_inodes_with_rev(txn, inode, dest).map_err(super::UnrecordError::Txn)?; - replacement in libpijul/src/unrecord/working_copy.rs at line 109
) -> Result<Vertex<ChangeId>, crate::Error> {) -> Result<Vertex<ChangeId>, BlockError> { - replacement in libpijul/src/unrecord/working_copy.rs at line 140
pub fn undo_file_reinsertion<T: MutTxnT>(pub fn undo_file_reinsertion<P: ChangeStore, T: MutTxnT>( - replacement in libpijul/src/unrecord/working_copy.rs at line 144
) -> Result<(), anyhow::Error> {) -> Result<(), super::UnrecordError<P::Error, T::Error>> { - replacement in libpijul/src/unrecord/working_copy.rs at line 150
del_inodes_with_rev(txn, inode, position)?;del_inodes_with_rev(txn, inode, position).map_err(super::UnrecordError::Txn)?; - edit in libpijul/src/unrecord/mod.rs at line 1
// org id IuiCX9taX7EZv/Aqz/UZc5r7v/fH7MJn3/QIj46oHwc= - edit in libpijul/src/unrecord/mod.rs at line 6
use crate::Error; - edit in libpijul/src/unrecord/mod.rs at line 11
#[derive(Debug, Error)]pub enum UnrecordError<ChangestoreError: std::error::Error + 'static,TxnError: std::error::Error + 'static,> {#[error("Changestore error: {0}")]Changestore(ChangestoreError),#[error(transparent)]Txn(TxnError),#[error(transparent)]Block(#[from] crate::pristine::BlockError),#[error(transparent)]InconsistentChange(#[from] crate::pristine::InconsistentChange),#[error("Change not in channel: {}", hash.to_base32())]ChangeNotInChannel { hash: ChangeId },#[error("Change not in channel: {}", change_id.to_base32())]ChangeIsDependedUpon { change_id: ChangeId },#[error(transparent)]Missing(#[from] crate::missing_context::MissingError<TxnError>),#[error(transparent)]LocalApply(#[from] crate::apply::LocalApplyError<TxnError>),#[error(transparent)]Apply(#[from] crate::apply::ApplyError<ChangestoreError, TxnError>),} - replacement in libpijul/src/unrecord/mod.rs at line 41
) -> Result<bool, anyhow::Error> {let change = changes.get_change(hash)?;) -> Result<bool, UnrecordError<P::Error, T::Error>> {let change = changes.get_change(hash).map_err(UnrecordError::Changestore)?; - replacement in libpijul/src/unrecord/mod.rs at line 53
del_channel_changes(txn, &mut channel, change_id)?;del_channel_changes::<T, P>(txn, &mut channel, change_id)?; - replacement in libpijul/src/unrecord/mod.rs at line 59
while txn.del_dep(change_id, None)? {}txn.del_external(change_id, None)?;txn.del_internal(*hash, None)?;while txn.del_dep(change_id, None).map_err(UnrecordError::Txn)? {}txn.del_external(change_id, None).map_err(UnrecordError::Txn)?;txn.del_internal(*hash, None).map_err(UnrecordError::Txn)?; - replacement in libpijul/src/unrecord/mod.rs at line 65
txn.del_revdep(dep, Some(change_id))?;txn.del_revdep(dep, Some(change_id)).map_err(UnrecordError::Txn)?; - replacement in libpijul/src/unrecord/mod.rs at line 73
// org id 4kyMdTywL4dWm7Vw3kXLcabNNGbFzSP3FTUptNMLPwg=fn del_channel_changes<T: MutTxnT>(fn del_channel_changes<T: MutTxnT, P: ChangeStore>( - replacement in libpijul/src/unrecord/mod.rs at line 78
) -> Result<(), anyhow::Error> {) -> Result<(), UnrecordError<P::Error, T::Error>> { - replacement in libpijul/src/unrecord/mod.rs at line 82
return Err((Error::ChangeNotOnChannel { change_id }).into());return Err(UnrecordError::ChangeNotInChannel { hash: change_id }); - replacement in libpijul/src/unrecord/mod.rs at line 92
return Err((Error::ChangeIsDependedUpon { change_id }).into());return Err(UnrecordError::ChangeIsDependedUpon { change_id }); - replacement in libpijul/src/unrecord/mod.rs at line 96
txn.del_changes(channel, change_id, timestamp)?;txn.del_changes(channel, change_id, timestamp).map_err(UnrecordError::Txn)?; - replacement in libpijul/src/unrecord/mod.rs at line 100
// org id F70s1W/0AmTkJZfg47g3+OXxINmwCgXU7G5j5QZkvh8= - replacement in libpijul/src/unrecord/mod.rs at line 115
// org id UmzPcrZozUPTljK9LrlZa2FIXJwwvHpPmfRQ9uV4qTs= - replacement in libpijul/src/unrecord/mod.rs at line 122
) -> Result<(), anyhow::Error> {) -> Result<(), UnrecordError<C::Error, T::Error>> { - replacement in libpijul/src/unrecord/mod.rs at line 136
)?;).map_err(UnrecordError::Txn)?; - replacement in libpijul/src/unrecord/mod.rs at line 139
unapply_newvertex(txn, channel, change_id, &mut ws, newvertex)?unapply_newvertex::<T, C>(txn, channel, change_id, &mut ws, newvertex)? - replacement in libpijul/src/unrecord/mod.rs at line 143
repair_newvertex_contexts(txn, channel, &mut ws)?;// org id zX78t6A+99OopoXmY9luuPGgXMHwzPEPT8sYitaxNyc=repair_newvertex_contexts::<T, C>(txn, channel, &mut ws)?; - replacement in libpijul/src/unrecord/mod.rs at line 146
remove_zombies(txn, channel, change_id, n)?;remove_zombies::<T, C>(txn, channel, change_id, n)?; - edit in libpijul/src/unrecord/mod.rs at line 162
// org id ysIZl8M4RTRZyISrNO1VOKOsKxkQsZFux9RvLLl192Y= - replacement in libpijul/src/unrecord/mod.rs at line 181
fn unapply_newvertex<T: MutTxnT>(fn unapply_newvertex<T: MutTxnT, C: ChangeStore>( - replacement in libpijul/src/unrecord/mod.rs at line 187
) -> Result<(), anyhow::Error> {) -> Result<(), UnrecordError<C::Error, T::Error>> { - replacement in libpijul/src/unrecord/mod.rs at line 246
)?;).map_err(UnrecordError::Txn)?; - replacement in libpijul/src/unrecord/mod.rs at line 258
working_copy::undo_file_addition(txn, change_id, new_vertex)?;working_copy::undo_file_addition(txn, change_id, new_vertex).map_err(UnrecordError::Txn)?; - replacement in libpijul/src/unrecord/mod.rs at line 263
fn repair_newvertex_contexts<T: MutTxnT>(fn repair_newvertex_contexts<T: MutTxnT, C: ChangeStore>( - replacement in libpijul/src/unrecord/mod.rs at line 267
) -> Result<(), anyhow::Error> {) -> Result<(), UnrecordError<C::Error, T::Error>> { - replacement in libpijul/src/unrecord/mod.rs at line 312
// org id TtkPh63N/jM5q98a/9yDp97cHPAUzouetXVib5fpVnY= - replacement in libpijul/src/unrecord/mod.rs at line 320
) -> Result<(), anyhow::Error> {) -> Result<(), UnrecordError<P::Error, T::Error>> { - replacement in libpijul/src/unrecord/mod.rs at line 357
working_copy::undo_file_reinsertion(txn, change_id, newedges)?working_copy::undo_file_reinsertion::<P, _>(txn, change_id, newedges)? - replacement in libpijul/src/unrecord/mod.rs at line 371
) -> Result<bool, anyhow::Error> {) -> Result<bool, crate::apply::ApplyError<C::Error, T::Error>> { - edit in libpijul/src/unrecord/mod.rs at line 395
.map_err(crate::apply::ApplyError::Changestore) - replacement in libpijul/src/unrecord/mod.rs at line 404
) -> Result<bool, anyhow::Error> {) -> Result<bool, C::Error> { - replacement in libpijul/src/unrecord/mod.rs at line 422
fn remove_zombies<T: MutTxnT>(fn remove_zombies<T: MutTxnT, C: ChangeStore>( - replacement in libpijul/src/unrecord/mod.rs at line 427
) -> Result<(), anyhow::Error> {) -> Result<(), UnrecordError<C::Error, T::Error>> { - replacement in libpijul/src/unrecord/mod.rs at line 473
)?;).map_err(UnrecordError::Txn)?; - replacement in libpijul/src/unrecord/mod.rs at line 490
put_graph_with_rev(txn, channel, f, u, v, u.change)?;put_graph_with_rev(txn, channel, f, u, v, u.change).map_err(UnrecordError::Txn)?; - replacement in libpijul/src/unrecord/mod.rs at line 495
del_graph_with_rev(txn, channel, e.flag, v, w, e.introduced_by)?;del_graph_with_rev(txn, channel, e.flag, v, w, e.introduced_by).map_err(UnrecordError::Txn)?; - edit in libpijul/src/unrecord/mod.rs at line 503
// org id 4dFFHO4v8n5FooqRmC0cyb1+9EjtjPMqW7wdJCUIRsU= - replacement in libpijul/src/unrecord/mod.rs at line 510
) -> Result<(), anyhow::Error> {) -> Result<(), UnrecordError<P::Error, T::Error>> { - edit in libpijul/src/record.rs at line 5
use crate::diff; - edit in libpijul/src/record.rs at line 11
use crate::{diff, Error}; - edit in libpijul/src/record.rs at line 12
#[derive(Debug, Error)]pub enum RecordError<C: std::error::Error + 'static,W: std::error::Error,T: std::error::Error + 'static,> {#[error("Changestore error: {0}")]Changestore(C),#[error("Working copy error: {0}")]WorkingCopy(W),#[error("System time error: {0}")]SystemTimeError(#[from] std::time::SystemTimeError),#[error(transparent)]Txn(T),#[error(transparent)]Diff(#[from] diff::DiffError<C>),#[error("Path not in repository: {0}")]PathNotInRepo(String),#[error(transparent)]Io(#[from] std::io::Error),} - replacement in libpijul/src/record.rs at line 162
) -> Result<(), anyhow::Error> {) -> Result<(), RecordError<C::Error, W::Error, T::Error>> { - replacement in libpijul/src/record.rs at line 207
self.push_children(self.push_children::<_, _, C>( - replacement in libpijul/src/record.rs at line 225
) -> Result<Option<Position<Option<ChangeId>>>, anyhow::Error> {) -> Result<Option<Position<Option<ChangeId>>>, W::Error> { - replacement in libpijul/src/record.rs at line 323
) -> Result<(), anyhow::Error> {) -> Result<(), RecordError<C::Error, W::Error, T::Error>> { - replacement in libpijul/src/record.rs at line 344
changes.get_contents(|p| txn.get_external(p), name_dest, &mut name)?;changes.get_contents(|p| txn.get_external(p), name_dest, &mut name).map_err(RecordError::Changestore)?; - replacement in libpijul/src/record.rs at line 383
)?).map_err(RecordError::Changestore)? - replacement in libpijul/src/record.rs at line 392
working_copy.read_file(&item.full_path, &mut b)?;working_copy.read_file(&item.full_path, &mut b).map_err(RecordError::WorkingCopy)?; - replacement in libpijul/src/record.rs at line 455
fn push_children<'a, T: MutTxnT, W: WorkingCopy>(fn push_children<'a, T: MutTxnT, W: WorkingCopy, C: ChangeStore>( - replacement in libpijul/src/record.rs at line 464
) -> Result<(), anyhow::Error> {) -> Result<(), RecordError<C::Error, W::Error, T::Error>> { - replacement in libpijul/src/record.rs at line 507
return Err((Error::FileNotInRepo {path: prefix.to_string(),}).into());return Err(RecordError::PathNotInRepo(prefix.to_string())); - replacement in libpijul/src/record.rs at line 517
) -> Result<bool, anyhow::Error> {) -> Result<bool, std::time::SystemTimeError> { - replacement in libpijul/src/record.rs at line 546
) -> Result<(), anyhow::Error> {) -> Result<(), C::Error> { - replacement in libpijul/src/record.rs at line 549
item.metadata.write(&mut self.rec.contents)?;item.metadata.write(&mut self.rec.contents).unwrap(); - replacement in libpijul/src/record.rs at line 628
) -> Result<MovedEdges, anyhow::Error> {) -> Result<MovedEdges, C::Error> { - edit in libpijul/src/pristine/sanakirja.rs at line 19
#[derive(Debug, Error)]pub enum SanakirjaError {#[error(transparent)]Sanakirja(#[from] ::sanakirja::Error),#[error("Pristine locked")]PristineLocked,#[error("Pristine corrupt")]PristineCorrupt,#[error(transparent)]Borrow(#[from] std::cell::BorrowError),} - replacement in libpijul/src/pristine/sanakirja.rs at line 32
pub fn new<P: AsRef<Path>>(name: P) -> Result<Self, anyhow::Error> {pub fn new<P: AsRef<Path>>(name: P) -> Result<Self, SanakirjaError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 35
pub unsafe fn new_nolock<P: AsRef<Path>>(name: P) -> Result<Self, anyhow::Error> {pub unsafe fn new_nolock<P: AsRef<Path>>(name: P) -> Result<Self, SanakirjaError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 38
pub fn new_with_size<P: AsRef<Path>>(name: P, size: u64) -> Result<Self, anyhow::Error> {pub fn new_with_size<P: AsRef<Path>>(name: P, size: u64) -> Result<Self, SanakirjaError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 44
Err(crate::Error::PristineLocked.into())Err(SanakirjaError::PristineLocked) - replacement in libpijul/src/pristine/sanakirja.rs at line 46
Err(e.into())Err(SanakirjaError::Sanakirja(sanakirja::Error::IO(e))) - replacement in libpijul/src/pristine/sanakirja.rs at line 49
Err(e) => Err(e.into()),Err(e) => Err(SanakirjaError::Sanakirja(e)), - replacement in libpijul/src/pristine/sanakirja.rs at line 55
) -> Result<Self, anyhow::Error> {) -> Result<Self, SanakirjaError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 60
pub fn new_anon() -> Result<Self, anyhow::Error> {pub fn new_anon() -> Result<Self, SanakirjaError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 63
pub fn new_anon_with_size(size: u64) -> Result<Self, anyhow::Error> {pub fn new_anon_with_size(size: u64) -> Result<Self, SanakirjaError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 89
pub fn txn_begin(&self) -> Result<Txn, anyhow::Error> {pub fn txn_begin(&self) -> Result<Txn, SanakirjaError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 120
Err(crate::Error::PristineCorrupt.into())Err(SanakirjaError::PristineCorrupt) - edit in libpijul/src/pristine/sanakirja.rs at line 331
type Error = SanakirjaError; - replacement in libpijul/src/pristine/sanakirja.rs at line 352
fn hash_from_prefix(&self, s: &str) -> Result<(Hash, ChangeId), anyhow::Error> {fn hash_from_prefix(&self, s: &str) -> Result<(Hash, ChangeId), super::HashPrefixError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 356
return Err((crate::Error::ParseError { s: s.to_string() }).into());return Err(super::HashPrefixError::Parse(s.to_string())); - replacement in libpijul/src/pristine/sanakirja.rs at line 373
return Err((crate::Error::AmbiguousHashPrefix {prefix: s.to_string(),}).into());return Err(super::HashPrefixError::Ambiguous(s.to_string())); - replacement in libpijul/src/pristine/sanakirja.rs at line 380
Err((crate::Error::ChangeNotFound {hash: s.to_string(),}).into())Err(super::HashPrefixError::NotFound(s.to_string())) - replacement in libpijul/src/pristine/sanakirja.rs at line 388
) -> Result<Hash, anyhow::Error> {) -> Result<Hash, super::HashPrefixError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 393
return Err((crate::Error::ParseError { s: s.to_string() }).into());return Err(super::HashPrefixError::Parse(s.to_string())); - replacement in libpijul/src/pristine/sanakirja.rs at line 410
return Err((crate::Error::AmbiguousHashPrefix {prefix: s.to_string(),}).into());return Err(super::HashPrefixError::Ambiguous(s.to_string())); - replacement in libpijul/src/pristine/sanakirja.rs at line 417
Err((crate::Error::ChangeNotFound {hash: s.to_string(),}).into())Err(super::HashPrefixError::NotFound(s.to_string())) - replacement in libpijul/src/pristine/sanakirja.rs at line 812
) -> Result<bool, anyhow::Error> {) -> Result<bool, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 821
) -> Result<bool, anyhow::Error> {) -> Result<bool, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 826
fn put_partials(&mut self, k: &str, e: Position<ChangeId>) -> Result<bool, anyhow::Error> {fn put_partials(&mut self, k: &str, e: Position<ChangeId>) -> Result<bool, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 840
) -> Result<bool, anyhow::Error> {) -> Result<bool, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 856
) -> Result<Option<Merkle>, anyhow::Error> {) -> Result<Option<Merkle>, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 884
) -> Result<bool, anyhow::Error> {) -> Result<bool, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 918
) -> Result<bool, anyhow::Error> {) -> Result<bool, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 925
fn del_remote(&mut self, remote: &mut RemoteRef<Self>, k: u64) -> Result<bool, anyhow::Error> {fn del_remote(&mut self, remote: &mut RemoteRef<Self>, k: u64) -> Result<bool, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 936
fn open_or_create_channel(&mut self, name: &str) -> Result<ChannelRef<Self>, anyhow::Error> {fn open_or_create_channel(&mut self, name: &str) -> Result<ChannelRef<Self>, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 993
) -> Result<ChannelRef<Self>, anyhow::Error> {) -> Result<ChannelRef<Self>, ForkError<Self::Error>> { - replacement in libpijul/src/pristine/sanakirja.rs at line 1007
graph: self.txn.fork(&mut self.rng, &channel.graph)?,changes: self.txn.fork(&mut self.rng, &channel.changes)?,revchanges: self.txn.fork(&mut self.rng, &channel.revchanges)?,states: self.txn.fork(&mut self.rng, &channel.states)?,graph: self.txn.fork(&mut self.rng, &channel.graph).map_err(|e| ForkError::Txn(e.into()))?,changes: self.txn.fork(&mut self.rng, &channel.changes).map_err(|e| ForkError::Txn(e.into()))?,revchanges: self.txn.fork(&mut self.rng, &channel.revchanges).map_err(|e| ForkError::Txn(e.into()))?,states: self.txn.fork(&mut self.rng, &channel.states).map_err(|e| ForkError::Txn(e.into()))?, - replacement in libpijul/src/pristine/sanakirja.rs at line 1031
Err((crate::Error::ChannelNameExists {name: new_name.to_string(),}).into())Err(super::ForkError::ChannelNameExists(new_name.to_string())) - replacement in libpijul/src/pristine/sanakirja.rs at line 1039
) -> Result<(), anyhow::Error> {) -> Result<(), ForkError<Self::Error>> { - replacement in libpijul/src/pristine/sanakirja.rs at line 1050
self.txn.del(&mut self.rng,&mut self.channels,UnsafeSmallStr::from_small_str(channel.borrow().name.as_small_str()),None,)?;self.txn.del(&mut self.rng,&mut self.channels,UnsafeSmallStr::from_small_str(channel.borrow().name.as_small_str()),None,).map_err(|e| ForkError::Txn(e.into()))?; - replacement in libpijul/src/pristine/sanakirja.rs at line 1071
Err((crate::Error::ChannelNameExists {name: new_name.to_string(),}).into())Err(ForkError::ChannelNameExists(new_name.to_string())) - replacement in libpijul/src/pristine/sanakirja.rs at line 1075
fn drop_channel(&mut self, name: &str) -> Result<bool, anyhow::Error> {fn drop_channel(&mut self, name: &str) -> Result<bool, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 1089
fn open_or_create_remote(&mut self, name: &str) -> Result<RemoteRef<Self>, anyhow::Error> {fn open_or_create_remote(&mut self, name: &str) -> Result<RemoteRef<Self>, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 1129
fn drop_remote(&mut self, remote: RemoteRef<Self>) -> Result<bool, anyhow::Error> {fn drop_remote(&mut self, remote: RemoteRef<Self>) -> Result<bool, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 1142
fn drop_named_remote(&mut self, name: &str) -> Result<bool, anyhow::Error> {fn drop_named_remote(&mut self, name: &str) -> Result<bool, Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 1155
fn commit(mut self) -> Result<(), anyhow::Error> {fn commit(mut self) -> Result<(), Self::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 1217
fn put_channel(&mut self, channel: ChannelRef<Self>) -> Result<(), anyhow::Error> {fn put_channel(&mut self, channel: ChannelRef<Self>) -> Result<(), SanakirjaError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 1258
fn commit_channel(&mut self, channel: ChannelRef<Self>) -> Result<(), anyhow::Error> {fn commit_channel(&mut self, channel: ChannelRef<Self>) -> Result<(), SanakirjaError> { - replacement in libpijul/src/pristine/sanakirja.rs at line 1269
fn put_remotes(&mut self, remote: RemoteRef<Self>) -> Result<(), anyhow::Error> {fn put_remotes(&mut self, remote: RemoteRef<Self>) -> Result<(), ::sanakirja::Error> { - replacement in libpijul/src/pristine/sanakirja.rs at line 1293
fn commit_remote(&mut self, remote: RemoteRef<Self>) -> Result<(), anyhow::Error> {fn commit_remote(&mut self, remote: RemoteRef<Self>) -> Result<(), ::sanakirja::Error> { - replacement in libpijul/src/pristine/mod.rs at line 114
// org id Zm7WF9q4bHktcCg0LXmmKlQP7XVt4IkPEDuF9pREDw4=#[derive(Debug, Error)]pub enum HashPrefixError {#[error("Failed to parse hash prefix: {0}")]Parse(String),#[error("Ambiguous hash prefix: {0}")]Ambiguous(String),#[error("Change not found: {0}")]NotFound(String),}#[derive(Debug, Error)]pub enum ForkError<T: std::error::Error + 'static> {#[error("Channel name already exists: {0}")]ChannelNameExists(String),#[error(transparent)]Txn(T),} - edit in libpijul/src/pristine/mod.rs at line 134
type Error: std::error::Error + Send + Sync + 'static; - replacement in libpijul/src/pristine/mod.rs at line 195
fn hash_from_prefix(&self, prefix: &str) -> Result<(Hash, ChangeId), anyhow::Error>;fn hash_from_prefix(&self, prefix: &str) -> Result<(Hash, ChangeId), HashPrefixError>; - replacement in libpijul/src/pristine/mod.rs at line 200
) -> Result<Hash, anyhow::Error>;) -> Result<Hash, HashPrefixError>; - edit in libpijul/src/pristine/mod.rs at line 346
#[derive(Error, Debug)]#[error("Inconsistent change")]pub struct InconsistentChange {} - replacement in libpijul/src/pristine/mod.rs at line 354
) -> Result<Position<ChangeId>, crate::Error> {) -> Result<Position<ChangeId>, InconsistentChange> { - replacement in libpijul/src/pristine/mod.rs at line 359
return Err(crate::Error::InconsistentChange);return Err(InconsistentChange {}); - replacement in libpijul/src/pristine/mod.rs at line 513
) -> Result<(), anyhow::Error> {) -> Result<(), std::io::Error> { - edit in libpijul/src/pristine/mod.rs at line 536
// org id oGZWRYu9yo9VKkz4S9hipd5OpFx6kQiF5q/T9jSqp5A= - replacement in libpijul/src/pristine/mod.rs at line 543
) -> Result<bool, anyhow::Error> {) -> Result<bool, std::io::Error> { - replacement in libpijul/src/pristine/mod.rs at line 557
) -> Result<(), anyhow::Error> {) -> Result<(), std::io::Error> { - replacement in libpijul/src/pristine/mod.rs at line 597
) -> Result<bool, anyhow::Error> {) -> Result<bool, std::io::Error> { - replacement in libpijul/src/pristine/mod.rs at line 719
) -> Result<(), anyhow::Error> {) -> Result<(), std::io::Error> { - replacement in libpijul/src/pristine/mod.rs at line 1079
) -> Result<bool, anyhow::Error>;) -> Result<bool, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1087
) -> Result<bool, anyhow::Error>;) -> Result<bool, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1096
) -> Result<Option<Merkle>, anyhow::Error>;) -> Result<Option<Merkle>, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1104
) -> Result<bool, anyhow::Error>;) -> Result<bool, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1116
fn open_or_create_channel(&mut self, name: &str) -> Result<ChannelRef<Self>, anyhow::Error>;fn open_or_create_channel(&mut self, name: &str) -> Result<ChannelRef<Self>, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1122
) -> Result<ChannelRef<Self>, anyhow::Error>;) -> Result<ChannelRef<Self>, ForkError<Self::Error>>; - replacement in libpijul/src/pristine/mod.rs at line 1128
) -> Result<(), anyhow::Error>;) -> Result<(), ForkError<Self::Error>>; - replacement in libpijul/src/pristine/mod.rs at line 1130
fn drop_channel(&mut self, name: &str) -> Result<bool, anyhow::Error>;fn drop_channel(&mut self, name: &str) -> Result<bool, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1133
fn commit(self) -> Result<(), anyhow::Error>;fn commit(self) -> Result<(), Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1135
fn put_partials(&mut self, k: &str, e: Position<ChangeId>) -> Result<bool, anyhow::Error>;fn put_partials(&mut self, k: &str, e: Position<ChangeId>) -> Result<bool, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1137
fn del_partials(&mut self,k: &str,e: Option<Position<ChangeId>>,) -> Result<bool, anyhow::Error>;fn del_partials(&mut self, k: &str, e: Option<Position<ChangeId>>)-> Result<bool, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1140
fn open_or_create_remote(&mut self, name: &str) -> Result<RemoteRef<Self>, anyhow::Error>;fn open_or_create_remote(&mut self, name: &str) -> Result<RemoteRef<Self>, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1147
) -> Result<bool, anyhow::Error>;) -> Result<bool, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1149
fn del_remote(&mut self, remote: &mut RemoteRef<Self>, k: u64) -> Result<bool, anyhow::Error>;fn del_remote(&mut self, remote: &mut RemoteRef<Self>, k: u64) -> Result<bool, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1151
fn drop_remote(&mut self, remote: RemoteRef<Self>) -> Result<bool, anyhow::Error>;fn drop_remote(&mut self, remote: RemoteRef<Self>) -> Result<bool, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1153
fn drop_named_remote(&mut self, remote: &str) -> Result<bool, anyhow::Error>;fn drop_named_remote(&mut self, remote: &str) -> Result<bool, Self::Error>; - replacement in libpijul/src/pristine/mod.rs at line 1160
) -> Result<(), anyhow::Error> {) -> Result<(), T::Error> { - replacement in libpijul/src/pristine/mod.rs at line 1170
) -> Result<bool, anyhow::Error> {) -> Result<bool, T::Error> { - replacement in libpijul/src/pristine/mod.rs at line 1183
) -> Result<(), anyhow::Error> {) -> Result<(), T::Error> { - replacement in libpijul/src/pristine/mod.rs at line 1193
) -> Result<bool, anyhow::Error> {) -> Result<bool, T::Error> { - replacement in libpijul/src/pristine/mod.rs at line 1211
) -> Result<(), anyhow::Error> {) -> Result<(), T::Error> { - replacement in libpijul/src/pristine/mod.rs at line 1270
) -> Result<bool, anyhow::Error> {) -> Result<bool, T::Error> { - replacement in libpijul/src/pristine/mod.rs at line 1311
) -> Result<bool, anyhow::Error> {) -> Result<bool, T::Error> { - replacement in libpijul/src/pristine/mod.rs at line 1353
) -> Result<(), anyhow::Error> {) -> Result<(), T::Error> { - replacement in libpijul/src/pristine/mod.rs at line 1432
) -> Result<(), anyhow::Error> {) -> Result<(), std::io::Error> { - edit in libpijul/src/pristine/channel_dump.rs at line 3
#[derive(Debug, Error)]pub enum ChannelDumpError<T: std::error::Error + 'static> {#[error(transparent)]Txn(T),#[error("Channel name already exists: {0}")]ChannelNameExists(String),} - replacement in libpijul/src/pristine/channel_dump.rs at line 309
pub fn read(&mut self, bytes: &[u8]) -> Result<bool, anyhow::Error> {pub fn read(&mut self, bytes: &[u8]) -> Result<bool, T::Error> { - replacement in libpijul/src/pristine/channel_dump.rs at line 395
) -> Result<(), anyhow::Error> {) -> Result<(), T::Error> { - edit in libpijul/src/pristine/block.rs at line 2
#[derive(Debug, Error)]#[error("Block error: {:?}", block)]pub struct BlockError {block: Position<ChangeId>,} - replacement in libpijul/src/pristine/block.rs at line 14
) -> Result<Vertex<ChangeId>, crate::Error> {) -> Result<Vertex<ChangeId>, BlockError> { - replacement in libpijul/src/pristine/block.rs at line 28
return Err(crate::Error::WrongBlock { block: p });return Err(BlockError { block: p }); - replacement in libpijul/src/pristine/block.rs at line 50
return Err(crate::Error::WrongBlock { block: p });return Err(BlockError { block: p }); - replacement in libpijul/src/pristine/block.rs at line 59
Err(crate::Error::WrongBlock { block: p })Err(BlockError { block: p }) - replacement in libpijul/src/pristine/block.rs at line 67
) -> Result<Vertex<ChangeId>, crate::Error> {) -> Result<Vertex<ChangeId>, BlockError> { - replacement in libpijul/src/pristine/block.rs at line 81
return Err(crate::Error::WrongBlock { block: p });return Err(BlockError { block: p }); - replacement in libpijul/src/pristine/block.rs at line 118
Err(crate::Error::WrongBlock { block: p })Err(BlockError { block: p }) - edit in libpijul/src/output/output.rs at line 1
// org id YWj26SRzNLfGg2Qeglz9QVnhMTU+0+RMuMvr6DwSA38= - replacement in libpijul/src/output/output.rs at line 3
use super::{collect_children, OutputItem};use super::{collect_children, OutputError, OutputItem, PristineOutputError}; - edit in libpijul/src/output/output.rs at line 14
// org id LRtRE+PMuzBEsI/KgD1sy2W/K0f0HAN70rZlknlfCWs= - replacement in libpijul/src/output/output.rs at line 24
// org id 0ve7DFbo4xqHFBVPHbChT6lFMPwRxbNcxRs4Yzsb6rs= - replacement in libpijul/src/output/output.rs at line 37
) -> Result<Vec<Conflict>, anyhow::Error> {) -> Result<Vec<Conflict>, OutputError<P::Error, T::Error, R::Error>> { - edit in libpijul/src/output/output.rs at line 49
// org id MpMlEfciwimf8weu0yPEV+/uIP9ErgimOTSV8nipLRA= - replacement in libpijul/src/output/output.rs at line 63
) -> Result<Vec<Conflict>, anyhow::Error> {// org id lpPIIMEW5CckD8tHjyvaRg/qw+G7csmIRQ9jxvSlOrk=) -> Result<Vec<Conflict>, OutputError<P::Error, T::Error, R::Error>> { - replacement in libpijul/src/output/output.rs at line 82
kill_dead_files(txn, repo, &dead)?;kill_dead_files::<T, R, P>(txn, repo, &dead)?; - edit in libpijul/src/output/output.rs at line 91
// org id gsYVU8LjyrWgVuIqAeIYTdCP2GY2jK+dVUaY5EM8DZU= - replacement in libpijul/src/output/output.rs at line 147
// org id 17m71heSzJMzN/R3aNLLqJlxXhZYglRTUOrHQjDCwVs=let inode = move_or_create(let inode = move_or_create::<T, R, P>( - replacement in libpijul/src/output/output.rs at line 158
kill_dead_files(txn, repo, &dead)?;kill_dead_files::<T, R, P>(txn, repo, &dead)?; - edit in libpijul/src/output/output.rs at line 161
// org id 3dDmtOVITWsw6WH+WZ2gvHHNSFGeGJOf7xMvsclLv0M= - replacement in libpijul/src/output/output.rs at line 162
repo.create_dir_all(&path)?;repo.create_dir_all(&path).map_err(OutputError::WorkingCopy)?; - replacement in libpijul/src/output/output.rs at line 176
output_file(txn, channel, changes, &output_item, &mut conflicts, w)})?;output_file::<_, _, R>(txn,channel,changes,&output_item,&mut conflicts,w,)}).map_err(OutputError::from)? - replacement in libpijul/src/output/output.rs at line 192
// org id 2XIp9np3LpR5M9OuJWMtiEOx57jFCeckeuAd61x3hKU=repo.set_permissions(&path, output_item.meta.permissions())?;repo.set_permissions(&path, output_item.meta.permissions()).map_err(OutputError::WorkingCopy)?; - replacement in libpijul/src/output/output.rs at line 199
repo.rename(a, b)?repo.rename(a, b).map_err(OutputError::WorkingCopy)? - edit in libpijul/src/output/output.rs at line 204
// org id zB9X/hdfYcIVLvilzZg7Z+hMNTdYgDxn8Yv0ibiwW9s= - replacement in libpijul/src/output/output.rs at line 214
// org id xBUt7AHfxqCxXNwSBliMDFiMWRNF3c0qpG6MYcEiSH4=fn move_or_create<T: MutTxnT, R: WorkingCopy>(fn move_or_create<T: MutTxnT, R: WorkingCopy, C: ChangeStore>( - replacement in libpijul/src/output/output.rs at line 222
) -> Result<Inode, anyhow::Error> {) -> Result<Inode, OutputError<C::Error, T::Error, R::Error>> { - replacement in libpijul/src/output/output.rs at line 229
// org id xS/j7ZPMIOAF9NgL2r1xaKrwJI6haZ2eBL0EQyNBgyo= - replacement in libpijul/src/output/output.rs at line 239
del_tree_with_rev(txn, parent.as_file_id(), inode)?;del_tree_with_rev(txn, parent.as_file_id(), inode).map_err(PristineOutputError::Txn)?; - replacement in libpijul/src/output/output.rs at line 251
repo.rename(¤t_name, &tmp_path)?;repo.rename(¤t_name, &tmp_path).map_err(OutputError::WorkingCopy)?; - replacement in libpijul/src/output/output.rs at line 258
crate::fs::rec_delete(txn, file_id.clone(), inode, true)?;crate::fs::rec_delete(txn, file_id.clone(), inode, true).map_err(PristineOutputError::Fs)?; - replacement in libpijul/src/output/output.rs at line 261
put_inodes_with_rev(txn, inode, output_item.pos)?;put_tree_with_rev(txn, file_id_, inode)?;put_inodes_with_rev(txn, inode, output_item.pos).map_err(PristineOutputError::Txn)?;put_tree_with_rev(txn, file_id_, inode).map_err(PristineOutputError::Txn)?; - replacement in libpijul/src/output/output.rs at line 268
crate::fs::rec_delete(txn, file_id.clone(), inode, true)?;crate::fs::rec_delete(txn, file_id.clone(), inode, true).map_err(PristineOutputError::Fs)?; - replacement in libpijul/src/output/output.rs at line 271
put_inodes_with_rev(txn, inode, output_item.pos)?;put_tree_with_rev(txn, file_id_, inode)?;put_inodes_with_rev(txn, inode, output_item.pos).map_err(PristineOutputError::Txn)?;put_tree_with_rev(txn, file_id_, inode).map_err(PristineOutputError::Txn)?; - edit in libpijul/src/output/output.rs at line 275
// org id uwWMiVIILtuAREerIsrWeLRjSBFCxhZtjJRLJ1BhHqQ= - replacement in libpijul/src/output/output.rs at line 277
crate::fs::rec_delete(txn, file_id.clone(), inode, true)?;crate::fs::rec_delete(txn, file_id.clone(), inode, true).map_err(PristineOutputError::Fs)?; - replacement in libpijul/src/output/output.rs at line 285
put_inodes_with_rev(txn, inode, output_item.pos)?;put_tree_with_rev(txn, file_id_, inode)?;put_inodes_with_rev(txn, inode, output_item.pos).map_err(PristineOutputError::Txn)?;put_tree_with_rev(txn, file_id_, inode).map_err(PristineOutputError::Txn)?; - replacement in libpijul/src/output/output.rs at line 290
// org id GN2HnMRazrBbQEPBgPOj2kiaHsrz9CfnCmvfQnMs+gU=fn output_file<T: MutTxnT, P: ChangeStore>(fn output_file<T: MutTxnT, P: ChangeStore, W: WorkingCopy>( - replacement in libpijul/src/output/output.rs at line 298
) -> Result<(), anyhow::Error> {) -> Result<(), OutputError<P::Error, T::Error, W::Error>> { - replacement in libpijul/src/output/output.rs at line 302
alive::output_graph(changes, txn, channel, &mut f, &mut l, &mut forward)?;alive::output_graph(changes, txn, channel, &mut f, &mut l, &mut forward).map_err(PristineOutputError::from)?; - replacement in libpijul/src/output/output.rs at line 308
del_graph_with_rev(txn, channel, edge.flag, vertex, dest, edge.introduced_by)?;del_graph_with_rev(txn, channel, edge.flag, vertex, dest, edge.introduced_by).map_err(PristineOutputError::Txn)?; - replacement in libpijul/src/output/output.rs at line 313
// org id 4uIws8SX4Pc6k8n8Gg5W8ukCH1XvjAWIViBruFTA6rg= - replacement in libpijul/src/output/output.rs at line 357
// org id qtncQESQX2X6uNqryalEkYZlRV7d5PeDxHnU2aIx/XA=fn kill_dead_files<T: MutTxnT, W: WorkingCopy>(fn kill_dead_files<T: MutTxnT, W: WorkingCopy, C: ChangeStore>( - replacement in libpijul/src/output/output.rs at line 362
) -> Result<(), anyhow::Error> {) -> Result<(), OutputError<C::Error, T::Error, W::Error>> { - replacement in libpijul/src/output/output.rs at line 365
del_tree_with_rev(txn, fileid.as_file_id(), *inode)?;del_tree_with_rev(txn, fileid.as_file_id(), *inode).map_err(PristineOutputError::Txn)?; - replacement in libpijul/src/output/output.rs at line 368
del_inodes_with_rev(txn, *inode, vertex)?;del_inodes_with_rev(txn, *inode, vertex).map_err(PristineOutputError::Txn)?; - replacement in libpijul/src/output/output.rs at line 371
repo.remove_path(&name)?repo.remove_path(&name).map_err(OutputError::WorkingCopy)? - edit in libpijul/src/output/mod.rs at line 11
#[derive(Debug, Error)]pub enum OutputError<ChangestoreError: std::error::Error + 'static,Txn: std::error::Error + 'static,W: std::error::Error + 'static,> {#[error("Working copy error: {0}")]WorkingCopy(W),#[error(transparent)]Pristine(#[from] PristineOutputError<ChangestoreError, Txn>),}#[derive(Debug, Error)]pub enum PristineOutputError<ChangestoreError: std::error::Error, Txn: std::error::Error + 'static>{#[error(transparent)]Txn(Txn),#[error("Changestore error: {0}")]Changestore(ChangestoreError),#[error(transparent)]Io(#[from] std::io::Error),#[error(transparent)]Fs(#[from] crate::fs::FsError<Txn>),}use crate::working_copy::WriteError;impl<C: std::error::Error, T: std::error::Error + 'static, W: std::error::Error>OutputError<C, T, W>{fn from(e: WriteError<Self>) -> Self {match e {WriteError::Io(e) => OutputError::Pristine(PristineOutputError::Io(e)),WriteError::E(e) => e,}}}#[derive(Debug, Error)]pub enum FileError<ChangestoreError: std::error::Error + 'static> {#[error(transparent)]Changestore(ChangestoreError),#[error(transparent)]Io(#[from] std::io::Error),}impl<C: std::error::Error, T: std::error::Error + 'static> From<FileError<C>>for PristineOutputError<C, T>{fn from(e: FileError<C>) -> Self {match e {FileError::Changestore(e) => PristineOutputError::Changestore(e),FileError::Io(e) => PristineOutputError::Io(e),}}} - replacement in libpijul/src/output/mod.rs at line 87
) -> Result<(), anyhow::Error> {) -> Result<(), PristineOutputError<P::Error, T::Error>> { - edit in libpijul/src/output/mod.rs at line 105
// org id Gb4FgVTFFkCPgh6xtUjeL/ntA6wAsIKhRiiX/8b4Jy8= - replacement in libpijul/src/output/mod.rs at line 108
changes.get_contents(|h| txn.get_external(h), name_vertex, &mut name_buf)?;changes.get_contents(|h| txn.get_external(h), name_vertex, &mut name_buf).map_err(|e| PristineOutputError::Changestore(e))?; - edit in libpijul/src/output/mod.rs at line 124
// org id RFCdVpFfGZuILPerwkNtNS2jmRrxrMOGl0kh7aVMVmM= - edit in libpijul/src/output/archive.rs at line 9
type Error: std::error::Error; - replacement in libpijul/src/output/archive.rs at line 11
fn close_file(&mut self, f: Self::File) -> Result<(), anyhow::Error>;fn close_file(&mut self, f: Self::File) -> Result<(), Self::Error>; - edit in libpijul/src/output/archive.rs at line 53
type Error = std::io::Error; - replacement in libpijul/src/output/archive.rs at line 66
fn close_file(&mut self, file: Self::File) -> Result<(), anyhow::Error> {fn close_file(&mut self, file: Self::File) -> Result<(), Self::Error> { - edit in libpijul/src/output/archive.rs at line 76
}#[derive(Debug, Error)]pub enum ArchiveError<P: std::error::Error + 'static,T: std::error::Error + 'static,A: std::error::Error + 'static,> {#[error(transparent)]A(A),#[error(transparent)]Txn(T),#[error(transparent)]Unrecord(#[from] crate::unrecord::UnrecordError<P, T>),#[error(transparent)]Apply(#[from] crate::apply::ApplyError<P, T>),#[error("State not found: {:?}", state)]StateNotFound { state: crate::pristine::Merkle },#[error(transparent)]File(#[from] crate::output::FileError<P>),#[error(transparent)]Output(#[from] crate::output::PristineOutputError<P, T>), - replacement in libpijul/src/output/archive.rs at line 106
) -> Result<Vec<Conflict>, anyhow::Error> {) -> Result<Vec<Conflict>, ArchiveError<P::Error, T::Error, A::Error>> { - replacement in libpijul/src/output/archive.rs at line 203
arch.close_file(f)?;arch.close_file(f).map_err(ArchiveError::A)?; - edit in libpijul/src/missing_context.rs at line 1
// org id 58v3AKimretz5he0vs+xqV3r0G0SNrO0HFWAzfAI/50= - edit in libpijul/src/missing_context.rs at line 7
#[derive(Debug, Error)]pub enum MissingError<TxnError: std::error::Error + 'static> {#[error(transparent)]Txn(TxnError),#[error(transparent)]Block(#[from] BlockError),#[error(transparent)]Inconsistent(#[from] InconsistentChange),} - replacement in libpijul/src/missing_context.rs at line 24
) -> Result<Option<&(Graph, HashMap<Vertex<ChangeId>, VertexId>)>, crate::Error> {) -> Result<Option<&(Graph, HashMap<Vertex<ChangeId>, VertexId>)>, InconsistentChange> { - replacement in libpijul/src/missing_context.rs at line 33
return Err(crate::Error::InconsistentChange);return Err(InconsistentChange {}); - replacement in libpijul/src/missing_context.rs at line 51
// org id CwY6M+Aa91RfVAJkIYG3StPNDxg5S2/Q0RJB2eWlhFg= - replacement in libpijul/src/missing_context.rs at line 64
) -> Result<(), anyhow::Error> {) -> Result<(), MissingError<T::Error>> { - replacement in libpijul/src/missing_context.rs at line 103
)?;).map_err(MissingError::Txn)?; - replacement in libpijul/src/missing_context.rs at line 114
)?;).map_err(MissingError::Txn)?; - replacement in libpijul/src/missing_context.rs at line 126
) -> Result<(), anyhow::Error> {) -> Result<(), MissingError<T::Error>> { - replacement in libpijul/src/missing_context.rs at line 142
)?;).map_err(MissingError::Txn)?; - replacement in libpijul/src/missing_context.rs at line 147
// org id 33iwKoFwpXhCt1MdikUmkOn7apYc7yMUk23JBOUn5mg= - replacement in libpijul/src/missing_context.rs at line 159
) -> Result<(), anyhow::Error> {) -> Result<(), MissingError<T::Error>> { - replacement in libpijul/src/missing_context.rs at line 189
)?;).map_err(MissingError::Txn)?; - replacement in libpijul/src/missing_context.rs at line 195
// org id GMesFpbMkVsOgAOjes5yxc060bclzWVMLh5KLd/KQc8= - replacement in libpijul/src/missing_context.rs at line 204
) -> Result<(), anyhow::Error>) -> Result<(), MissingError<T::Error>> - edit in libpijul/src/missing_context.rs at line 296
// org id OfylSf5taky9lfC0119yeNkCZSw55LxD7HNIT7E0TO8= - replacement in libpijul/src/missing_context.rs at line 304
) -> Result<(), anyhow::Error>) -> Result<(), MissingError<T::Error>> - replacement in libpijul/src/missing_context.rs at line 322
// org id ueoLxafjHlJdBaAESsgdkbWhSKPGMpMkuFiROTxbrSM= - replacement in libpijul/src/missing_context.rs at line 424
) -> Result<(), anyhow::Error>) -> Result<(), MissingError<T::Error>> - edit in libpijul/src/missing_context.rs at line 428
// org id HPoxuN+RIwX+UvJZERkZAFK6+F5MEAFM39nnpnXs9YY= - edit in libpijul/src/missing_context.rs at line 439
// org id izc8DKE2hSSCYLTpux0cTTOqoMvRdn35r2Hfrdyq82w= - replacement in libpijul/src/missing_context.rs at line 447
)?;).map_err(MissingError::Txn)?; - replacement in libpijul/src/missing_context.rs at line 460
)?;).map_err(MissingError::Txn)?; - edit in libpijul/src/missing_context.rs at line 468
// org id Hux8KrdJakJleVXFgumk9t/dqB3Cl95Q0HD49nlsmD4= - replacement in libpijul/src/missing_context.rs at line 484
) -> Result<(), anyhow::Error> {) -> Result<(), MissingError<T::Error>> { - replacement in libpijul/src/missing_context.rs at line 502
)?;).map_err(MissingError::Txn)?; - replacement in libpijul/src/missing_context.rs at line 509
del_graph_with_rev(txn, channel, e.flag, dest_vertex, p, e.introduced_by)?;del_graph_with_rev(txn, channel, e.flag, dest_vertex, p, e.introduced_by).map_err(MissingError::Txn)?; - replacement in libpijul/src/missing_context.rs at line 526
) -> Result<(), anyhow::Error>) -> Result<(), MissingError<T::Error>> - replacement in libpijul/src/missing_context.rs at line 579
) -> Result<(), anyhow::Error> {) -> Result<(), MissingError<T::Error>> { - replacement in libpijul/src/missing_context.rs at line 596
)?;).map_err(MissingError::Txn)?; - replacement in libpijul/src/missing_context.rs at line 622
put_graph_with_rev(txn, channel, flag, parent_dest, v, change_id)?;put_graph_with_rev(txn, channel, flag, parent_dest, v, change_id).map_err(MissingError::Txn)?; - replacement in libpijul/src/missing_context.rs at line 633
) -> Result<(), anyhow::Error> {) -> Result<(), MissingError<T::Error>> { - replacement in libpijul/src/lib.rs at line 94
pub use crate::fs::WorkingCopyIterator;pub use crate::apply::{ApplyError, LocalApplyError};pub use crate::fs::{FsError, WorkingCopyIterator}; - replacement in libpijul/src/lib.rs at line 116
) -> Result<(u64, pristine::Merkle), anyhow::Error> {) -> Result<(u64, pristine::Merkle), crate::apply::ApplyError<C::Error, Self::Error>> { - replacement in libpijul/src/lib.rs at line 126
) -> Result<(), anyhow::Error> {) -> Result<(), crate::apply::ApplyError<C::Error, Self::Error>> { - replacement in libpijul/src/lib.rs at line 135
) -> Result<(u64, pristine::Merkle), anyhow::Error> {) -> Result<(u64, pristine::Merkle), crate::apply::ApplyError<C::Error, Self::Error>> { - replacement in libpijul/src/lib.rs at line 144
) -> Result<(), anyhow::Error> {) -> Result<(), crate::apply::ApplyError<C::Error, Self::Error>> { - replacement in libpijul/src/lib.rs at line 153
) -> Result<(), anyhow::Error> {) -> Result<(), crate::apply::ApplyError<C::Error, Self::Error>> { - replacement in libpijul/src/lib.rs at line 164
) -> Result<(u64, pristine::Merkle), anyhow::Error> {) -> Result<(u64, pristine::Merkle), crate::apply::LocalApplyError<Self::Error>> { - replacement in libpijul/src/lib.rs at line 174
) -> Result<(u64, pristine::Merkle), anyhow::Error> {) -> Result<(u64, pristine::Merkle), crate::apply::LocalApplyError<Self::Error>> { - replacement in libpijul/src/lib.rs at line 186
) -> Result<(), anyhow::Error> {) -> Result<(), crate::record::RecordError<C::Error, W::Error, Self::Error>> { - replacement in libpijul/src/lib.rs at line 197
) -> Result<record::Recorded, anyhow::Error> {) -> Result<record::Recorded, crate::record::RecordError<C::Error, W::Error, Self::Error>> { - replacement in libpijul/src/lib.rs at line 208
) -> Result<pristine::Hash, anyhow::Error> {) -> Result<pristine::Hash, crate::apply::ApplyError<C::Error, Self::Error>> { - replacement in libpijul/src/lib.rs at line 232
let hash = changestore.save_change(&change)?;let hash = changestore.save_change(&change).map_err(apply::ApplyError::Changestore)?; - replacement in libpijul/src/lib.rs at line 244
) -> Result<bool, anyhow::Error> {) -> Result<bool, unrecord::UnrecordError<C::Error, Self::Error>> { - replacement in libpijul/src/lib.rs at line 255
) -> Result<Vec<output::Conflict>, anyhow::Error> {) -> Result<Vec<output::Conflict>, output::OutputError<C::Error, Self::Error, R::Error>> { - replacement in libpijul/src/lib.rs at line 269
fn add_file(&mut self, path: &str) -> Result<(), anyhow::Error> {fn add_file(&mut self, path: &str) -> Result<(), fs::FsError<Self::Error>> { - replacement in libpijul/src/lib.rs at line 277
fn add_dir(&mut self, path: &str) -> Result<(), anyhow::Error> {fn add_dir(&mut self, path: &str) -> Result<(), fs::FsError<Self::Error>> { - replacement in libpijul/src/lib.rs at line 284
fn add(&mut self, path: &str, is_dir: bool) -> Result<(), anyhow::Error> {fn add(&mut self, path: &str, is_dir: bool) -> Result<(), fs::FsError<Self::Error>> { - replacement in libpijul/src/lib.rs at line 288
fn move_file(&mut self, a: &str, b: &str) -> Result<(), anyhow::Error> {fn move_file(&mut self, a: &str, b: &str) -> Result<(), fs::FsError<Self::Error>> { - replacement in libpijul/src/lib.rs at line 292
fn remove_file(&mut self, a: &str) -> Result<(), anyhow::Error> {fn remove_file(&mut self, a: &str) -> Result<(), fs::FsError<Self::Error>> { - replacement in libpijul/src/lib.rs at line 300
) -> Result<pristine::channel_dump::ChannelFromDump<'a, Self>, anyhow::Error> {) -> Result<pristine::channel_dump::ChannelFromDump<'a, Self>,pristine::channel_dump::ChannelDumpError<Self::Error>,> {use pristine::channel_dump::*; - replacement in libpijul/src/lib.rs at line 306[17.727465]→[17.60362:60444](∅→∅),[17.60444]→[17.727527:727603](∅→∅),[17.727527]→[17.727527:727603](∅→∅)
let channel = pristine::MutTxnT::open_or_create_channel(self, name)?;Ok(pristine::channel_dump::ChannelFromDump::new(self, channel))let channel = pristine::MutTxnT::open_or_create_channel(self, name).map_err(ChannelDumpError::Txn)?;Ok(ChannelFromDump::new(self, channel)) - replacement in libpijul/src/lib.rs at line 310[17.727620]→[17.727620:727664](∅→∅),[17.727664]→[17.727664:727719](∅→∅),[17.727719]→[17.727719:727740](∅→∅)
Err((Error::ChannelNameExists {name: name.to_string(),}).into())Err(ChannelDumpError::ChannelNameExists(name.to_string())) - replacement in libpijul/src/lib.rs at line 321
) -> Result<Vec<output::Conflict>, anyhow::Error> {) -> Result<Vec<output::Conflict>, output::ArchiveError<P::Error, Self::Error, A::Error>> { - replacement in libpijul/src/lib.rs at line 348
) -> Result<Vec<output::Conflict>, anyhow::Error> {) -> Result<Vec<output::Conflict>, output::ArchiveError<P::Error, Self::Error, A::Error>> { - replacement in libpijul/src/lib.rs at line 370
Err((Error::StateNotFound { state }).into())Err(output::ArchiveError::StateNotFound { state }) - replacement in libpijul/src/lib.rs at line 501
) -> Result<(String, bool), anyhow::Error> {) -> Result<(String, bool), C::Error> { - replacement in libpijul/src/lib.rs at line 514
) -> Result<(String, bool), anyhow::Error> {) -> Result<(String, bool), C::Error> { - replacement in libpijul/src/lib.rs at line 527
) -> Result<(pristine::Position<pristine::ChangeId>, bool), anyhow::Error> {) -> Result<(pristine::Position<pristine::ChangeId>, bool), fs::FsError<C::Error>> { - replacement in libpijul/src/lib.rs at line 537
) -> Result<(), anyhow::Error> {) -> Result<(), output::FileError<C::Error>> { - replacement in libpijul/src/lib.rs at line 550
) -> Result<Vec<output::Conflict>, anyhow::Error> {) -> Result<Vec<output::Conflict>, output::ArchiveError<C::Error, Self::Error, A::Error>> { - replacement in libpijul/src/lib.rs at line 560
) -> Result<Vec<output::Conflict>, anyhow::Error> {) -> Result<Vec<output::Conflict>, output::ArchiveError<C::Error, Self::Error, A::Error>> { - edit in libpijul/src/fs.rs at line 1
// org id GEhwQUzK6088geMhP32RRVZ2gKcVn8vpgw30CsBQVAw= - edit in libpijul/src/fs.rs at line 20
use crate::Error; - edit in libpijul/src/fs.rs at line 22
#[derive(Debug, Error)]pub enum FsError<T: std::error::Error + 'static> {#[error("Path not found: {0}")]NotFound(String),#[error("File already in repository: {0}")]AlreadyInRepo(String),#[error(transparent)]Txn(T),} - replacement in libpijul/src/fs.rs at line 103
/// Find the inode corresponding to that path, or return an error if/// there's no such inode.pub fn find_inode<T: TxnT>(txn: &T, path: &str) -> Result<Inode, anyhow::Error> {/// Find the inode corresponding to that path, if it exists.pub fn find_inode<T: TxnT>(txn: &T, path: &str) -> Result<Inode, FsError<T::Error>> { - replacement in libpijul/src/fs.rs at line 110
Err((Error::FileNotInRepo {path: path.to_string(),}).into())Err(FsError::NotFound(path.to_string())) - replacement in libpijul/src/fs.rs at line 162
) -> Result<Inode, anyhow::Error> {) -> Result<Inode, FsError<T::Error>> { - replacement in libpijul/src/fs.rs at line 175
del_tree_with_rev(txn, parent_id.as_file_id(), inode)?;del_tree_with_rev(txn, parent_id.as_file_id(), inode).map_err(FsError::Txn)?; - replacement in libpijul/src/fs.rs at line 177
del_inodes_with_rev(txn, inode, vertex)?;del_inodes_with_rev(txn, inode, vertex).map_err(FsError::Txn)?; - replacement in libpijul/src/fs.rs at line 179
put_tree_with_rev(txn, parent_id.as_file_id(), child)?;put_tree_with_rev(txn, parent_id.as_file_id(), child).map_err(FsError::Txn)?; - replacement in libpijul/src/fs.rs at line 183
Err((Error::FileAlreadyInRepo {path: filename.to_string(),}).into())Err(FsError::AlreadyInRepo(filename.to_string())) - replacement in libpijul/src/fs.rs at line 191
put_tree_with_rev(txn, parent_id.as_file_id(), child_inode)?;put_tree_with_rev(txn, parent_id.as_file_id(), child_inode).map_err(FsError::Txn)?; - replacement in libpijul/src/fs.rs at line 198
txn.put_tree(dir_id.as_file_id(), child_inode)?;txn.put_tree(dir_id.as_file_id(), child_inode).map_err(FsError::Txn)?; - replacement in libpijul/src/fs.rs at line 210
) -> Result<(), anyhow::Error> {) -> Result<(), FsError<T::Error>> { - replacement in libpijul/src/fs.rs at line 236
) -> Result<(), anyhow::Error> {) -> Result<(), FsError<T::Error>> { - replacement in libpijul/src/fs.rs at line 246
) -> Result<(), anyhow::Error> {) -> Result<(), FsError<T::Error>> { - replacement in libpijul/src/fs.rs at line 249
del_tree_with_rev(txn, fileref.as_file_id(), inode)?;del_tree_with_rev(txn, fileref.as_file_id(), inode).map_err(FsError::Txn)?; - replacement in libpijul/src/fs.rs at line 270
) -> Result<(), anyhow::Error> {) -> Result<(), FsError<T::Error>> { - replacement in libpijul/src/fs.rs at line 298
assert!(txn.del_tree(file_id.as_file_id(), Some(inode))?);assert!(txn.del_tree(file_id.as_file_id(), Some(inode)).map_err(FsError::Txn)?); - replacement in libpijul/src/fs.rs at line 302
if del_tree_with_rev(txn, parent.as_file_id(), inode)? {if del_tree_with_rev(txn, parent.as_file_id(), inode).map_err(FsError::Txn)? { - replacement in libpijul/src/fs.rs at line 304
del_inodes_with_rev(txn, inode, vertex)?;del_inodes_with_rev(txn, inode, vertex).map_err(FsError::Txn)?; - replacement in libpijul/src/fs.rs at line 317
pub fn remove_file<T: MutTxnT>(txn: &mut T, path: &str) -> Result<(), anyhow::Error> {pub fn remove_file<T: MutTxnT>(txn: &mut T, path: &str) -> Result<(), FsError<T::Error>> { - replacement in libpijul/src/fs.rs at line 614
) -> Result<(Position<ChangeId>, bool), anyhow::Error> {) -> Result<(Position<ChangeId>, bool), FsError<C::Error>> { - replacement in libpijul/src/fs.rs at line 629
changes.get_contents(|h| txn.get_external(h), name_dest, &mut name_buf)?;changes.get_contents(|h| txn.get_external(h), name_dest, &mut name_buf).map_err(FsError::Txn)?; - replacement in libpijul/src/fs.rs at line 654
return Err((Error::FileNotInRepo {path: path.to_string(),}).into());return Err(FsError::NotFound(path.to_string())); - replacement in libpijul/src/fs.rs at line 666
) -> Result<(String, bool), anyhow::Error> {) -> Result<(String, bool), C::Error> { - edit in libpijul/src/find_alive.rs at line 1
// org id MEBHKxb8oK7gGUqwl4XgvF1rhw0vYcS2SvEcXbaqMok= - replacement in libpijul/src/find_alive.rs at line 3
// org id 7GC7Q2pCnb0s8d1hQ5JvScuZvi24ZElhM713+gpHgeY= - replacement in libpijul/src/find_alive.rs at line 8
) -> Result<HashSet<Vertex<ChangeId>>, crate::Error> {) -> Result<HashSet<Vertex<ChangeId>>, BlockError> { - edit in libpijul/src/find_alive.rs at line 16
// org id naTw4q63bu2EvVqiMcyTpsR2XgGPIlo+Xg0pAHxty50= - edit in libpijul/src/find_alive.rs at line 23
// org id rATmHVXe7ujnLJm9BtP1kGj7iFT2vIEqTj1NygT3jKg= - edit in libpijul/src/find_alive.rs at line 27
// org id zyrR2nOtEiDH3D+9lWuTt+nzSRQoz8jgKSCV9Pn6rBE= - edit in libpijul/src/find_alive.rs at line 41
// org id uQvQHlOvPqlL+IP8xnqczr279XI5bz+CUrzAi0CkA+c= - replacement in libpijul/src/find_alive.rs at line 46
// org id Pw320u7FKY4pwoQyoNx3dm1mLfOcikfMt+ObiMN9njo= - replacement in libpijul/src/find_alive.rs at line 51
) -> Result<(HashSet<Vertex<ChangeId>>, Vec<(Vertex<ChangeId>, Edge)>), crate::Error> {) -> Result<(HashSet<Vertex<ChangeId>>, Vec<(Vertex<ChangeId>, Edge)>), BlockError> { - edit in libpijul/src/find_alive.rs at line 60
// org id 4NHenXps5de4P2CKb7tHKFazsveVGn9JlzWwLKcaDfY= - edit in libpijul/src/find_alive.rs at line 70
// org id yUDemNuncRZ3JF72y4FgQuPPYbQhsyj+3Dw9xom4PyQ= - edit in libpijul/src/find_alive.rs at line 76
// org id wquayIcqrmfRuMmqB4vd/wlbkHCGqWHFKFrwWY7st9g= - edit in libpijul/src/find_alive.rs at line 105
// org id S8/CnGSbU1qxCbYJGuK142RZkxIMPWg2k8LfVRnevOY= - edit in libpijul/src/diff/vertex_buffer.rs at line 1
// org id CuLytHOw5MhIUxraqhZp3RiCvAXraOTYajmAlakyEYY= - edit in libpijul/src/diff/vertex_buffer.rs at line 4
// org id JJDR/iA4tUvr8bHYeAudspj8wfK5zy20N2fayiMztIQ= - edit in libpijul/src/diff/vertex_buffer.rs at line 6
// org id O4woWVifU6a3TB5v+SW/IS06RN6LDal4OOyCtAcxrLg= - edit in libpijul/src/diff/vertex_buffer.rs at line 8
// org id znv/E/xSBDaD0tw5tDrdhOrfa00e2i6hoX4Y0P0M1yU= - edit in libpijul/src/diff/vertex_buffer.rs at line 10
// org id VrcGilQ4pnxnCqaZ30f0AYxuMW5/PAjPKYEV0W8OS3o= - edit in libpijul/src/diff/vertex_buffer.rs at line 11
// org id tHKWG2wUrgq0sWiE8x5vHspQufWcVCF0VBQMdJ/E6PI= - edit in libpijul/src/diff/vertex_buffer.rs at line 12
// org id RtX+AmeBXlMmux4krn3hr2TC5YAQ4dUD0aQ9cG0WmPE= - replacement in libpijul/src/diff/vertex_buffer.rs at line 17
// org id BJp9ZUxNcNZGXbeuELu/m0hxjcCh0Lrworivp2DNz/I= - replacement in libpijul/src/diff/vertex_buffer.rs at line 32
// org id x2fKAxT97bw7IkKwnYnx5G3Ys3zfwC7SQzd3J/n1vPU= - replacement in libpijul/src/diff/vertex_buffer.rs at line 40
// org id CBYn0QVUhTLd+1DPhJGxeuxcQPrCqfoCj5QdyKDc7Hg= - replacement in libpijul/src/diff/vertex_buffer.rs at line 47
// org id a0AuyLQJdOXmDjcbzuLKji89Suyb79UP94XH0DGe0rs= - replacement in libpijul/src/diff/vertex_buffer.rs at line 55
// org id pMXpkacg64vkNGPaLA/BBNw5jtn7ZI+FySQGEkPivNo= - replacement in libpijul/src/diff/vertex_buffer.rs at line 86
// org id NnHmVJ1BuujNsYVWbu4O4GAsabVxPG61uPjBjwLDGXY= - replacement in libpijul/src/diff/vertex_buffer.rs at line 114
// org id Pk25wSBAZ0t4Oeyx6ZTm1xqxX4h54qK8APBYvN+cjoo= - replacement in libpijul/src/diff/vertex_buffer.rs at line 140
fn output_line<C: FnOnce(&mut Vec<u8>) -> Result<(), anyhow::Error>>(&mut self,v: crate::pristine::Vertex<ChangeId>,c: C,) -> Result<(), anyhow::Error> {fn output_line<E, C>(&mut self, v: crate::pristine::Vertex<ChangeId>, c: C) -> Result<(), E>whereE: From<std::io::Error>,C: FnOnce(&mut Vec<u8>) -> Result<(), E>,{ - replacement in libpijul/src/diff/vertex_buffer.rs at line 159
// org id 0I3Htm1AUtdNytI0fsyZC9DaKebRuVAOWnCAp1eM4As=fn begin_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/diff/vertex_buffer.rs at line 165
fn begin_cyclic_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_cyclic_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/diff/vertex_buffer.rs at line 172
fn begin_zombie_conflict(&mut self) -> Result<(), anyhow::Error> {fn begin_zombie_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/diff/vertex_buffer.rs at line 176
// org id zJgaktpjBecKJlgqzyViT+wt457sbkOEgjcJ7OGLOcU=fn end_conflict(&mut self) -> Result<(), anyhow::Error> {fn end_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/diff/vertex_buffer.rs at line 193
fn end_cyclic_conflict(&mut self) -> Result<(), anyhow::Error> {fn end_cyclic_conflict(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/diff/vertex_buffer.rs at line 199
// org id W0ejcsiNdGBeNc6omb0+BUSF8MKjBtY+mLMyyqcvPBU=fn conflict_next(&mut self) -> Result<(), anyhow::Error> {fn conflict_next(&mut self) -> Result<(), std::io::Error> { - replacement in libpijul/src/diff/vertex_buffer.rs at line 212
// org id kwhiQGVdomF6A7ajQbYvVGPQrMY24ay2R9148GsaXPw=fn output_conflict_marker(&mut self, marker: &str) -> Result<(), anyhow::Error> {fn output_conflict_marker(&mut self, marker: &str) -> Result<(), std::io::Error> { - replacement in libpijul/src/diff/vertex_buffer.rs at line 243
// org id JBb+2glaECLGIRa7HRodwcjfm5JxXetKLaq3zZ/Nmlk= - edit in libpijul/src/diff/mod.rs at line 32
#[derive(Debug, Error)]pub enum DiffError<P: std::error::Error + 'static> {#[error(transparent)]Output(#[from] crate::output::FileError<P>),} - replacement in libpijul/src/diff/mod.rs at line 50
) -> Result<(), anyhow::Error> {) -> Result<(), DiffError<P::Error>> { - edit in libpijul/src/changestore/mod.rs at line 20
type Error: std::error::Error+ std::fmt::Debug+ Send+ Sync+ From<std::str::Utf8Error>+ From<crate::change::ChangeError>+ 'static; - replacement in libpijul/src/changestore/mod.rs at line 33
) -> Result<usize, anyhow::Error>;fn get_header(&self, h: &Hash) -> Result<ChangeHeader, anyhow::Error> {) -> Result<usize, Self::Error>;fn get_header(&self, h: &Hash) -> Result<ChangeHeader, Self::Error> { - replacement in libpijul/src/changestore/mod.rs at line 41
) -> Result<usize, anyhow::Error>;fn get_dependencies(&self, hash: &Hash) -> Result<Vec<Hash>, anyhow::Error> {) -> Result<usize, Self::Error>;fn get_dependencies(&self, hash: &Hash) -> Result<Vec<Hash>, Self::Error> { - replacement in libpijul/src/changestore/mod.rs at line 45
fn get_extra_known(&self, hash: &Hash) -> Result<Vec<Hash>, anyhow::Error> {fn get_extra_known(&self, hash: &Hash) -> Result<Vec<Hash>, Self::Error> { - replacement in libpijul/src/changestore/mod.rs at line 48
fn knows(&self, hash0: &Hash, hash1: &Hash) -> Result<bool, anyhow::Error> {fn knows(&self, hash0: &Hash, hash1: &Hash) -> Result<bool, Self::Error> { - replacement in libpijul/src/changestore/mod.rs at line 57
) -> Result<bool, anyhow::Error> {) -> Result<bool, Self::Error> { - replacement in libpijul/src/changestore/mod.rs at line 66
) -> Result<Vec<Hash>, anyhow::Error>;fn save_change(&self, p: &Change) -> Result<Hash, anyhow::Error>;fn del_change(&self, h: &Hash) -> Result<bool, anyhow::Error>;fn get_change(&self, h: &Hash) -> Result<Change, anyhow::Error>;) -> Result<Vec<Hash>, Self::Error>;fn save_change(&self, p: &Change) -> Result<Hash, Self::Error>;fn del_change(&self, h: &Hash) -> Result<bool, Self::Error>;fn get_change(&self, h: &Hash) -> Result<Change, Self::Error>; - replacement in libpijul/src/changestore/mod.rs at line 75
) -> Result<(InodeMetadata, &'a str), anyhow::Error> {) -> Result<(InodeMetadata, &'a str), Self::Error> { - edit in libpijul/src/changestore/memory.rs at line 5
use crate::Error; - edit in libpijul/src/changestore/memory.rs at line 22
#[derive(Debug, Error)]pub enum Error {#[error(transparent)]Io(#[from] std::io::Error),#[error(transparent)]Utf8(#[from] std::str::Utf8Error),#[error(transparent)]Change(#[from] crate::change::ChangeError),#[error("Change not found: {:?}", hash)]ChangeNotFound { hash: crate::Hash },#[error(transparent)]Bincode(#[from] bincode::Error),} - edit in libpijul/src/changestore/memory.rs at line 37
type Error = Error; - replacement in libpijul/src/changestore/memory.rs at line 48
) -> Result<usize, anyhow::Error> {) -> Result<usize, Self::Error> { - replacement in libpijul/src/changestore/memory.rs at line 65
) -> Result<usize, anyhow::Error> {) -> Result<usize, Self::Error> { - replacement in libpijul/src/changestore/memory.rs at line 87
) -> Result<Vec<Hash>, anyhow::Error> {) -> Result<Vec<Hash>, Self::Error> { - replacement in libpijul/src/changestore/memory.rs at line 98
fn save_change(&self, p: &Change) -> Result<Hash, anyhow::Error> {fn save_change(&self, p: &Change) -> Result<Hash, Self::Error> { - replacement in libpijul/src/changestore/memory.rs at line 104
fn del_change(&self, h: &Hash) -> Result<bool, anyhow::Error> {fn del_change(&self, h: &Hash) -> Result<bool, Self::Error> { - replacement in libpijul/src/changestore/memory.rs at line 108
fn get_change(&self, h: &Hash) -> Result<Change, anyhow::Error> {fn get_change(&self, h: &Hash) -> Result<Change, Self::Error> { - replacement in libpijul/src/changestore/memory.rs at line 113
use crate::pristine::Base32;Err((Error::ChangeNotFound {hash: h.to_base32(),}).into())Err(Error::ChangeNotFound { hash: *h }) - edit in libpijul/src/changestore/filesystem.rs at line 17
}#[derive(Debug, Error)]pub enum Error {#[error(transparent)]Io(#[from] std::io::Error),#[error(transparent)]Utf8(#[from] std::str::Utf8Error),#[error(transparent)]ChangeFile(#[from] crate::change::ChangeError),#[error(transparent)]Persist(#[from] tempfile::PersistError), - replacement in libpijul/src/changestore/filesystem.rs at line 79
anyhow::Error,crate::change::ChangeError, - replacement in libpijul/src/changestore/filesystem.rs at line 96
) -> Result<(), anyhow::Error> {) -> Result<(), crate::change::ChangeError> { - replacement in libpijul/src/changestore/filesystem.rs at line 98
self.save_from_buf_unchecked(buf, hash, change_id)self.save_from_buf_unchecked(buf, hash, change_id)?;Ok(()) - replacement in libpijul/src/changestore/filesystem.rs at line 107
) -> Result<(), anyhow::Error> {) -> Result<(), std::io::Error> { - edit in libpijul/src/changestore/filesystem.rs at line 124
type Error = Error; - replacement in libpijul/src/changestore/filesystem.rs at line 148
fn get_header(&self, h: &Hash) -> Result<ChangeHeader, anyhow::Error> {fn get_header(&self, h: &Hash) -> Result<ChangeHeader, Self::Error> { - replacement in libpijul/src/changestore/filesystem.rs at line 159
) -> Result<usize, anyhow::Error> {) -> Result<usize, Self::Error> { - replacement in libpijul/src/changestore/filesystem.rs at line 174
) -> Result<usize, anyhow::Error> {) -> Result<usize, Self::Error> { - replacement in libpijul/src/changestore/filesystem.rs at line 193
) -> Result<Vec<Hash>, anyhow::Error> {) -> Result<Vec<Hash>, Self::Error> { - replacement in libpijul/src/changestore/filesystem.rs at line 205
fn save_change(&self, p: &Change) -> Result<Hash, anyhow::Error> {fn save_change(&self, p: &Change) -> Result<Hash, Self::Error> { - replacement in libpijul/src/changestore/filesystem.rs at line 217
fn del_change(&self, hash: &Hash) -> Result<bool, anyhow::Error> {fn del_change(&self, hash: &Hash) -> Result<bool, Self::Error> { - replacement in libpijul/src/changestore/filesystem.rs at line 224
fn get_change(&self, h: &Hash) -> Result<Change, anyhow::Error> {fn get_change(&self, h: &Hash) -> Result<Change, Self::Error> { - edit in libpijul/src/change.rs at line 1
// org id 4+w2sTG9zBScwyjzB8qqUXj0dCYZg3xGYPeKsGKua2k=use super::Error; - edit in libpijul/src/change.rs at line 4
#[cfg(feature = "zstd")]pub mod v3; - edit in libpijul/src/change.rs at line 7
#[cfg(feature = "text-changes")]mod text_changes;mod change_file;pub use change_file::*;#[derive(Debug, Error)]pub enum ChangeError {#[error("Version mismatch")]VersionMismatch,#[error(transparent)]Io(#[from] std::io::Error),#[error(transparent)]Bincode(#[from] bincode::Error),#[error(transparent)]Zstd(#[from] zstd_seekable::Error),#[error(transparent)]TomlDe(#[from] toml::de::Error),#[error(transparent)]TomlSer(#[from] toml::ser::Error),#[error("Missing contents for change {:?}", hash)]MissingContents { hash: crate::pristine::Hash },#[error("Change hash mismatch, claimed {:?}, computed {:?}", claimed, computed)]ChangeHashMismatch {claimed: crate::pristine::Hash,computed: crate::pristine::Hash,},#[error("Change contents hash mismatch, claimed {:?}, computed {:?}",claimed,computed)]ContentsHashMismatch {claimed: crate::pristine::Hash,computed: crate::pristine::Hash,},} - replacement in libpijul/src/change.rs at line 1169
fn compress<W: Write>(input: &[u8], mut w: W) -> Result<(), anyhow::Error> {fn compress<W: Write>(input: &[u8], mut w: W) -> Result<(), ChangeError> { - replacement in libpijul/src/change.rs at line 1190
) -> Result<u64, anyhow::Error> {) -> Result<u64, ChangeError> { - replacement in libpijul/src/change.rs at line 1196
return Err(Error::VersionMismatch.into());return Err(ChangeError::VersionMismatch); - replacement in libpijul/src/change.rs at line 1206
pub fn serialize<W: Write>(&self, mut w: W) -> Result<Hash, anyhow::Error> {pub fn serialize<W: Write>(&self, mut w: W) -> Result<Hash, ChangeError> { - replacement in libpijul/src/change.rs at line 1254
pub fn check_from_buffer(buf: &[u8], hash: &Hash) -> Result<(), anyhow::Error> {pub fn check_from_buffer(buf: &[u8], hash: &Hash) -> Result<(), ChangeError> { - replacement in libpijul/src/change.rs at line 1257
return Err(Error::VersionMismatch.into());return Err(ChangeError::VersionMismatch); - replacement in libpijul/src/change.rs at line 1273
return Err((Error::ChangeHashMismatch {return Err((ChangeError::ChangeHashMismatch { - replacement in libpijul/src/change.rs at line 1295
return Err((Error::ContentsHashMismatch {return Err(ChangeError::ContentsHashMismatch { - replacement in libpijul/src/change.rs at line 1298
}).into());}); - replacement in libpijul/src/change.rs at line 1305
pub fn deserialize(file: &str, hash: Option<&Hash>) -> Result<Self, anyhow::Error> {pub fn deserialize(file: &str, hash: Option<&Hash>) -> Result<Self, ChangeError> { - replacement in libpijul/src/change.rs at line 1312
return Err(Error::VersionMismatch.into());return Err(ChangeError::VersionMismatch); - replacement in libpijul/src/change.rs at line 1329
return Err((Error::ChangeHashMismatch {return Err(ChangeError::ChangeHashMismatch { - replacement in libpijul/src/change.rs at line 1332
}).into());}); - replacement in libpijul/src/change.rs at line 1374
pub fn hash(&self) -> Result<Hash, anyhow::Error> {pub fn hash(&self) -> Result<Hash, bincode::Error> { - edit in libpijul/src/change.rs at line 1381[17.876662]→[17.876662:878745](∅→∅),[17.878745]→[17.878745:878841](∅→∅),[17.878841]→[17.878841:878977](∅→∅),[17.878977]→[17.878977:880955](∅→∅),[17.880955]→[17.880955:881040](∅→∅),[17.881040]→[17.881040:882461](∅→∅),[17.882461]→[17.1240:1323](∅→∅),[17.1323]→[17.882554:885299](∅→∅),[17.882554]→[17.882554:885299](∅→∅),[17.885299]→[17.1324:1399](∅→∅),[17.1399]→[17.885376:885517](∅→∅),[17.885376]→[17.885376:885517](∅→∅),[17.885517]→[17.1400:1470](∅→∅),[17.1470]→[17.885589:886662](∅→∅),[17.885589]→[17.885589:886662](∅→∅),[17.886662]→[17.886662:886733](∅→∅),[17.886733]→[17.886733:886865](∅→∅),[17.886865]→[17.886865:887016](∅→∅),[17.887016]→[17.887016:887744](∅→∅),[17.887744]→[9.418:452](∅→∅),[9.452]→[17.887782:888474](∅→∅),[17.887782]→[17.887782:888474](∅→∅),[17.888474]→[9.453:487](∅→∅),[9.487]→[17.888512:888888](∅→∅),[17.888512]→[17.888512:888888](∅→∅),[17.888888]→[9.488:518](∅→∅),[9.518]→[17.888922:889088](∅→∅),[17.888922]→[17.888922:889088](∅→∅),[17.889088]→[9.519:553](∅→∅),[9.553]→[17.889126:889214](∅→∅),[17.889126]→[17.889126:889214](∅→∅),[17.889214]→[17.889214:889239](∅→∅),[17.889239]→[9.554:588](∅→∅),[9.588]→[17.889277:889551](∅→∅),[17.889277]→[17.889277:889551](∅→∅),[17.889551]→[9.589:619](∅→∅),[9.619]→[17.889585:889753](∅→∅),[17.889585]→[17.889585:889753](∅→∅),[17.889753]→[17.889753:889841](∅→∅),[17.889841]→[17.889841:889866](∅→∅),[17.889866]→[9.620:654](∅→∅),[9.654]→[17.889904:891488](∅→∅),[17.889904]→[17.889904:891488](∅→∅),[17.891488]→[17.891488:891541](∅→∅),[17.891541]→[17.891541:891869](∅→∅),[17.891869]→[17.618:648](∅→∅),[17.648]→[17.891903:891957](∅→∅),[17.891903]→[17.891903:891957](∅→∅),[17.891957]→[17.891957:892039](∅→∅),[17.892039]→[17.892039:892327](∅→∅),[17.892327]→[17.649:679](∅→∅),[17.679]→[17.892361:892474](∅→∅),[17.892361]→[17.892361:892474](∅→∅),[17.892474]→[17.892474:892643](∅→∅),[17.892643]→[17.892643:892938](∅→∅),[17.892938]→[9.655:685](∅→∅),[9.685]→[17.892972:893324](∅→∅),[17.892972]→[17.892972:893324](∅→∅),[17.893324]→[9.686:716](∅→∅),[9.716]→[17.893358:893723](∅→∅),[17.893358]→[17.893358:893723](∅→∅),[17.893723]→[17.680:710](∅→∅),[17.710]→[17.893757:893811](∅→∅),[17.893757]→[17.893757:893811](∅→∅),[17.893811]→[17.1210:1292](∅→∅),[17.1292]→[17.893811:894129](∅→∅),[17.893811]→[17.893811:894129](∅→∅),[17.894129]→[17.711:741](∅→∅),[17.741]→[17.894163:894217](∅→∅),[17.894163]→[17.894163:894217](∅→∅),[17.894217]→[17.1293:1375](∅→∅),[17.1375]→[17.894217:894291](∅→∅),[17.894217]→[17.894217:894291](∅→∅),[17.894291]→[17.66822:66993](∅→∅),[17.93]→[17.894369:894429](∅→∅),[17.66993]→[17.894369:894429](∅→∅),[17.894369]→[17.894369:894429](∅→∅),[17.894429]→[17.742:772](∅→∅),[17.128]→[17.894486:894540](∅→∅),[17.772]→[17.894486:894540](∅→∅),[17.894486]→[17.894486:894540](∅→∅),[17.894540]→[17.1376:1458](∅→∅),[17.1458]→[17.894540:896408](∅→∅),[17.894540]→[17.894540:896408](∅→∅),[17.896408]→[17.129:251](∅→∅),[17.251]→[17.896503:904855](∅→∅),[17.896503]→[17.896503:904855](∅→∅),[17.904855]→[17.252:912](∅→∅),[17.912]→[17.66994:67014](∅→∅),[17.931]→[17.904855:905077](∅→∅),[17.67014]→[17.904855:905077](∅→∅),[17.904855]→[17.904855:905077](∅→∅),[17.905077]→[17.6772:6816](∅→∅),[17.6816]→[17.905121:905792](∅→∅),[17.905121]→[17.905121:905792](∅→∅),[17.905792]→[17.6817:6869](∅→∅),[17.6869]→[17.905844:905985](∅→∅),[17.905844]→[17.905844:905985](∅→∅),[17.905985]→[17.6870:6922](∅→∅),[17.6922]→[17.906037:910672](∅→∅),[17.906037]→[17.906037:910672](∅→∅),[17.910672]→[2.4331:4375](∅→∅),[2.4375]→[17.910672:911073](∅→∅),[17.910672]→[17.910672:911073](∅→∅),[17.911073]→[17.6923:6975](∅→∅),[17.6975]→[17.911125:912754](∅→∅),[17.911125]→[17.911125:912754](∅→∅),[17.912917]→[17.912917:912947](∅→∅),[17.912947]→[17.1459:1536](∅→∅),[17.1536]→[17.912947:912973](∅→∅),[17.912947]→[17.912947:912973](∅→∅),[17.912973]→[17.6976:7028](∅→∅),[17.7028]→[17.913025:914758](∅→∅),[17.913025]→[17.913025:914758](∅→∅),[17.914758]→[17.1537:2006](∅→∅),[17.2006]→[17.914819:915263](∅→∅),[17.914819]→[17.914819:915263](∅→∅),[17.915263]→[17.2007:2613](∅→∅),[17.2613]→[17.915427:917686](∅→∅),[17.915427]→[17.915427:917686](∅→∅),[17.917686]→[17.7029:7107](∅→∅),[17.7107]→[17.917890:918425](∅→∅),[17.917890]→[17.917890:918425](∅→∅),[17.918425]→[2.4376:4450](∅→∅),[2.4450]→[17.918425:919617](∅→∅),[17.918425]→[17.918425:919617](∅→∅),[17.919617]→[17.7108:7143](∅→∅),[17.7143]→[17.919652:921737](∅→∅),[17.919652]→[17.919652:921737](∅→∅),[17.921737]→[17.921737:921783](∅→∅),[17.921783]→[17.921783:921847](∅→∅),[17.921847]→[17.921847:921884](∅→∅),[17.921884]→[17.0:67](∅→∅),[17.67]→[15.0:87](∅→∅),[15.87]→[17.142:380](∅→∅),[17.142]→[17.142:380](∅→∅),[17.380]→[17.922035:922066](∅→∅),[17.922035]→[17.922035:922066](∅→∅),[17.922066]→[17.922066:922146](∅→∅),[17.922146]→[17.922146:922156](∅→∅),[17.922156]→[17.922156:922178](∅→∅),[17.922178]→[17.922178:922247](∅→∅),[17.922247]→[17.922247:922356](∅→∅),[17.922356]→[17.922356:922536](∅→∅),[17.922536]→[17.922536:922580](∅→∅),[17.922580]→[17.922580:923124](∅→∅),[17.923124]→[17.923124:923179](∅→∅),[17.923179]→[17.923179:927244](∅→∅),[17.927244]→[9.717:739](∅→∅),[9.739]→[17.927270:930990](∅→∅),[17.927270]→[17.927270:930990](∅→∅)
// org id SY0PPKJcw1SQ8DEsOkicihzeXjmhMRxFEiBeypeSfTY=use crate::changestore::*;use std::collections::hash_map::Entry;use std::collections::HashMap;use std::io::BufRead;#[cfg(feature = "text-changes")]impl LocalChange<Local> {const DEPS_LINE: &'static str = "# Dependencies\n";const CHANGES_LINE: &'static str = "# Changes\n";pub fn write_all_deps<F: FnMut(Hash) -> Result<(), anyhow::Error>>(&self,mut f: F,) -> Result<(), anyhow::Error> {for c in self.changes.iter() {for c in c.iter() {match *c {Atom::NewVertex(ref n) => {for change in n.up_context.iter().chain(n.down_context.iter()).map(|c| c.change).chain(std::iter::once(n.inode.change)){if let Some(change) = change {if let Hash::None = change {continue;}f(change)?}}}Atom::EdgeMap(ref e) => {for edge in e.edges.iter() {for change in &[edge.from.change,edge.to.change,edge.introduced_by,e.inode.change,] {if let Some(change) = *change {if let Hash::None = change {continue;}f(change)?}}}}}}}Ok(())}pub fn write<W: Write, C: ChangeStore, F: FnMut(&Local, Position<Option<Hash>>) -> String>(&self,changes: &C,hash: Option<Hash>,mut file_name: F,write_header: bool,mut w: W,) -> Result<(), anyhow::Error> {if let Some(h) = hash {// Check if we have the full contentslet mut hasher = Hasher::default();hasher.update(&self.contents);let hash = hasher.finish();if hash != self.contents_hash {return Err((Error::MissingContents {hash: h.to_base32(),}).into());}}if write_header {w.write_all(toml::ser::to_string_pretty(&self.header)?.as_bytes())?;w.write_all(b"\n")?;}let mut hashes = HashMap::new();let mut i = 2;let mut needs_newline = false;if !self.dependencies.is_empty() {w.write_all(Self::DEPS_LINE.as_bytes())?;needs_newline = true;for dep in self.dependencies.iter() {hashes.insert(*dep, i);writeln!(w, "[{}] {}", i, dep.to_base32())?;i += 1;}}self.write_all_deps(|change| {if let Entry::Vacant(e) = hashes.entry(change) {e.insert(i);if !needs_newline {w.write_all(Self::DEPS_LINE.as_bytes())?;needs_newline = true;}writeln!(w, "[{}]+{}", i, change.to_base32())?;i += 1;}Ok(())})?;if !self.extra_known.is_empty() {needs_newline = true;for dep in self.extra_known.iter() {writeln!(w, "[*] {}", dep.to_base32())?;i += 1;}}if !self.changes.is_empty() {if needs_newline {w.write_all(b"\n")?}w.write_all(Self::CHANGES_LINE.as_bytes())?;for (n, rec) in self.changes.iter().enumerate() {write!(w, "\n{}. ", n + 1)?;rec.write(changes, &mut file_name, &hashes, &self.contents, &mut w)?}}Ok(())}}impl Change {pub fn read_and_deps<R: BufRead, T: TxnT>(r: R,updatables: &mut HashMap<usize, crate::InodeUpdate>,txn: &T,channel: &ChannelRef<T>,) -> Result<Self, anyhow::Error> {let (mut change, extra_dependencies) = Self::read_(r, updatables)?;let (mut deps, extra) = dependencies(txn, channel, change.hashed.changes.iter());deps.extend(extra_dependencies.into_iter());change.hashed.dependencies = deps;change.hashed.extra_known = extra;Ok(change)}pub fn read<R: BufRead>(r: R,updatables: &mut HashMap<usize, crate::InodeUpdate>,) -> Result<Self, anyhow::Error> {Ok(Self::read_(r, updatables)?.0)}fn read_<R: BufRead>(mut r: R,updatables: &mut HashMap<usize, crate::InodeUpdate>,) -> Result<(Self, HashSet<Hash>), anyhow::Error> {use self::text_changes::*;let mut section = Section::Header(String::new());let mut change = Change {offsets: Offsets::default(),hashed: Hashed {version: VERSION,header: ChangeHeader {authors: Vec::new(),message: String::new(),description: None,timestamp: chrono::Utc::now(),},dependencies: Vec::new(),extra_known: Vec::new(),metadata: Vec::new(),changes: Vec::new(),contents_hash: Hasher::default().finish(),},unhashed: None,contents: Vec::new(),};let conclude_section = |change: &mut Change,section: Section,contents: &mut Vec<u8>|-> Result<(), anyhow::Error> {match section {Section::Header(ref s) => {debug!("header = {:?}", s);change.header = toml::de::from_str(&s)?;Ok(())}Section::Deps => Ok(()),Section::Changes {mut changes,current,..} => {if has_newvertices(¤t) {contents.push(0)}if let Some(c) = current {debug!("next action = {:?}", c);changes.push(c)}change.changes = changes;Ok(())}}};let mut h = String::new();let mut contents = Vec::new();let mut deps = HashMap::new();let mut extra_dependencies = HashSet::new();while r.read_line(&mut h)? > 0 {debug!("h = {:?}", h);if h == Self::DEPS_LINE {let section = std::mem::replace(&mut section, Section::Deps);conclude_section(&mut change, section, &mut contents)?;} else if h == Self::CHANGES_LINE {let section = std::mem::replace(&mut section,Section::Changes {changes: Vec::new(),current: None,offsets: HashMap::new(),},);conclude_section(&mut change, section, &mut contents)?;} else {use regex::Regex;lazy_static! {static ref DEPS: Regex = Regex::new(r#"\[(\d*|\*)\](\+| ) *(\S*)"#).unwrap();static ref KNOWN: Regex = Regex::new(r#"(\S*)"#).unwrap();}match section {Section::Header(ref mut s) => s.push_str(&h),Section::Deps => {if let Some(d) = DEPS.captures(&h) {let hash = Hash::from_base32(d[3].as_bytes()).unwrap();if let Ok(n) = d[1].parse() {if &d[2] == " " {change.hashed.dependencies.push(hash);}deps.insert(n, hash);} else if &d[1] == "*" {change.hashed.extra_known.push(hash);} else {extra_dependencies.insert(hash);}}}Section::Changes {ref mut current,ref mut changes,ref mut offsets,} => {if let Some(next) =Record::read(updatables, current, &mut contents, &deps, offsets, &h)?{debug!("next action = {:?}", next);changes.push(next)}}}}h.clear();}conclude_section(&mut change, section, &mut contents)?;change.contents = contents;change.contents_hash = {let mut hasher = Hasher::default();hasher.update(&change.contents);hasher.finish()};Ok((change, extra_dependencies))}}#[cfg(feature = "text-changes")]impl Record<Option<Hash>, Local> {fn write<W: std::io::Write,C: ChangeStore,F: FnMut(&Local, Position<Option<Hash>>) -> String,>(&self,changes: &C,mut file_name: F,hashes: &HashMap<Hash, usize>,change_contents: &[u8],mut w: W,) -> Result<(), anyhow::Error> {use self::text_changes::*;match self {Record::FileMove { del, add, path } => match add {Atom::NewVertex(ref add) => {let name = std::str::from_utf8(&change_contents[add.start.0 as usize + 2..add.end.0 as usize],).unwrap();let perms = crate::pristine::InodeMetadata::from_basename(&change_contents[add.start.0 as usize..add.start.0 as usize + 2],);write!(w, "Moved: {:?} {:?} {:o} ", path, name, perms.0)?;write_pos(&mut w, hashes, del.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &del)?;write!(w, "up")?;for c in add.up_context.iter() {write!(w, " ")?;write_pos(&mut w, hashes, *c)?}write!(w, ", down")?;for c in add.down_context.iter() {write!(w, " ")?;write_pos(&mut w, hashes, *c)?}w.write_all(b"\n")?;}Atom::EdgeMap(_) => {write!(w, "Moved: {:?} ", path)?;write_pos(&mut w, hashes, del.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &add)?;write_atom(&mut w, hashes, &del)?;}},Record::FileDel {del,contents,path,} => {write!(w, "File deletion: {:?} ", path)?;write_pos(&mut w, hashes, del.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &del)?;if let Some(ref contents) = contents {write_atom(&mut w, hashes, &contents)?;writeln!(w)?;print_change_contents(&mut w, changes, contents, change_contents)?;} else {writeln!(w)?;}}Record::FileUndel {undel,contents,path,} => {write!(w, "File un-deletion: {:?} ", path)?;write_pos(&mut w, hashes, undel.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &undel)?;if let Some(ref contents) = contents {write_atom(&mut w, hashes, &contents)?;print_change_contents(&mut w, changes, contents, change_contents)?;} else {writeln!(w)?;}}Record::FileAdd {add_name,contents,path,..} => {if let Atom::NewVertex(ref n) = add_name {let name = std::str::from_utf8(&change_contents[n.start.0 as usize + 2..n.end.0 as usize],).unwrap();let perms = crate::pristine::InodeMetadata::from_basename(&change_contents[n.start.0 as usize..n.start.0 as usize + 2],);let parent = if let Some(p) = crate::path::parent(&path) {if p.is_empty() {"/"} else {p}} else {"/"};write!(w,"File addition: {:?} in {:?} {:o}\n up",name, parent, perms.0)?;assert!(n.down_context.is_empty());for c in n.up_context.iter() {write!(w, " ")?;write_pos(&mut w, hashes, *c)?}writeln!(w, ", new {}:{}", n.start.0, n.end.0)?;}if let Some(Atom::NewVertex(ref n)) = contents {let c = &change_contents[n.start.0 as usize..n.end.0 as usize];print_contents(&mut w, "+", c)?;if !c.ends_with(b"\n") {writeln!(w, "\\")?}}}Record::Edit { change, local } => {write!(w, "Edit in {} ", file_name(&local, change.inode()))?;write_pos(&mut w, hashes, change.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &change)?;print_change_contents(&mut w, changes, change, change_contents)?;}Record::Replacement {change,replacement,local,} => {write!(w, "Replacement in {} ", file_name(&local, change.inode()))?;write_pos(&mut w, hashes, change.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &change)?;write_atom(&mut w, hashes, &replacement)?;print_change_contents(&mut w, changes, change, change_contents)?;print_change_contents(&mut w, changes, replacement, change_contents)?;}Record::SolveNameConflict { name, path } => {write!(w, "Solving a name conflict in {:?} ", path)?;write_pos(&mut w, hashes, name.inode())?;write!(w, ": ")?;write_deleted_names(&mut w, changes, name)?;writeln!(w)?;write_atom(&mut w, hashes, &name)?;}Record::UnsolveNameConflict { name, path } => {write!(w, "Un-solving a name conflict in {:?} ", path)?;write_pos(&mut w, hashes, name.inode())?;write!(w, ": ")?;write_deleted_names(&mut w, changes, name)?;writeln!(w)?;write_atom(&mut w, hashes, &name)?;}Record::SolveOrderConflict { change, local } => {write!(w,"Solving an order conflict in {} ",file_name(&local, change.inode()))?;write_pos(&mut w, hashes, change.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &change)?;print_change_contents(&mut w, changes, change, change_contents)?;}Record::UnsolveOrderConflict { change, local } => {write!(w,"Un-solving an order conflict in {} ",file_name(&local, change.inode()))?;write_pos(&mut w, hashes, change.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &change)?;print_change_contents(&mut w, changes, change, change_contents)?;}Record::ResurrectZombies { change, local } => {write!(w,"Resurrecting zombie lines in {:?}:{} ",local.path, local.line)?;write_pos(&mut w, hashes, change.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &change)?;print_change_contents(&mut w, changes, change, change_contents)?;}}Ok(())}}#[cfg(feature = "text-changes")]impl Record<Option<Hash>, Local> {fn read(updatables: &mut HashMap<usize, crate::InodeUpdate>,current: &mut Option<Self>,mut contents_: &mut Vec<u8>,changes: &HashMap<usize, Hash>,offsets: &mut HashMap<u64, ChangePosition>,h: &str,) -> Result<Option<Self>, Error> {use self::text_changes::*;use regex::Regex;lazy_static! {static ref FILE_ADDITION: Regex =Regex::new(r#"(?P<n>\d+)\. File addition: "(?P<name>[^"]*)" in "(?P<parent>[^"]*)" (?P<perm>\d+)"#).unwrap();static ref EDIT: Regex =Regex::new(r#"(\d+)\. Edit in ([^:]+):(\d+) (\d+\.\d+)"#).unwrap();static ref REPLACEMENT: Regex =Regex::new(r#"(\d+)\. Replacement in ([^:]+):(\d+) (\d+\.\d+)"#).unwrap();static ref FILE_DELETION: Regex =Regex::new(r#"(\d+)\. File deletion: "([^"]*)" (\d+\.\d+)"#).unwrap();static ref FILE_UNDELETION: Regex =Regex::new(r#"(\d+)\. File un-deletion: "([^"]*)" (\d+\.\d+)"#).unwrap();static ref MOVE: Regex =Regex::new(r#"(\d+)\. Moved: "(?P<former>[^"]*)" "(?P<new>[^"]*)" (?P<perm>\d+) (?P<inode>.*)"#).unwrap();static ref MOVE_: Regex = Regex::new(r#"(\d+)\. Moved: "([^"]*)" (.*)"#).unwrap();static ref NAME_CONFLICT: Regex = Regex::new(r#"(\d+)\. ((Solving)|(Un-solving)) a name conflict in "([^"]*)" (.*): .*"#).unwrap();static ref ORDER_CONFLICT: Regex = Regex::new(r#"(\d+)\. ((Solving)|(Un-solving)) an order conflict in (.*):(\d+) (\d+\.\d+)"#).unwrap();static ref ZOMBIE: Regex =Regex::new(r#"(\d+)\. Resurrecting zombie lines in (?P<path>"[^"]+"):(?P<line>\d+) (?P<inode>\d+\.\d+)"#).unwrap();static ref CONTEXT: Regex = Regex::new(r#"up ((\d+\.\d+ )*\d+\.\d+)(, new (\d+):(\d+))?(, down ((\d+\.\d+ )*\d+\.\d+))?"#).unwrap();}if let Some(cap) = FILE_ADDITION.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut add_name = default_newvertex();add_name.start = ChangePosition(contents_.len() as u64);add_name.flag = EdgeFlags::FOLDER | EdgeFlags::BLOCK;let name = &cap.name("name").unwrap().as_str();let path = {let parent = cap.name("parent").unwrap().as_str();(if parent == "/" {String::new()} else {parent.to_string()}) + name};let meta = cap.name("perm").unwrap().as_str().chars().fold(0, |x, c| x * 8 + (c as u16 - b'0' as u16));let meta = InodeMetadata(meta);meta.write(&mut contents_).unwrap();contents_.extend(name.as_bytes());add_name.end = ChangePosition(contents_.len() as u64);let mut add_inode = default_newvertex();add_inode.flag = EdgeFlags::FOLDER | EdgeFlags::BLOCK;add_inode.up_context.push(Position {change: None,pos: ChangePosition(contents_.len() as u64),});contents_.push(0);add_inode.start = ChangePosition(contents_.len() as u64);add_inode.end = ChangePosition(contents_.len() as u64);contents_.push(0);let n = cap.name("n").unwrap().as_str().parse().unwrap();if let Entry::Occupied(mut e) = updatables.entry(n) {if let crate::InodeUpdate::Add { ref mut pos, .. } = e.get_mut() {*pos = add_inode.start}}Ok(std::mem::replace(current,Some(Record::FileAdd {add_name: Atom::NewVertex(add_name),add_inode: Atom::NewVertex(add_inode),contents: None,path,}),))} else if let Some(cap) = EDIT.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut v = default_newvertex();v.inode = parse_pos(changes, &cap[4]);Ok(std::mem::replace(current,Some(Record::Edit {change: Atom::NewVertex(v),local: Local {path: cap[2].to_string(),line: cap[3].parse().unwrap(),},}),))} else if let Some(cap) = REPLACEMENT.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut v = default_newvertex();v.inode = parse_pos(changes, &cap[4]);Ok(std::mem::replace(current,Some(Record::Replacement {change: Atom::NewVertex(v.clone()),replacement: Atom::NewVertex(v),local: Local {path: cap[2].to_string(),line: cap[3].parse().unwrap(),},}),))} else if let Some(cap) = FILE_DELETION.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut del = default_edgemap();del.inode = parse_pos(changes, &cap[3]);Ok(std::mem::replace(current,Some(Record::FileDel {del: Atom::EdgeMap(del),contents: None,path: cap[2].to_string(),}),))} else if let Some(cap) = FILE_UNDELETION.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut undel = default_edgemap();undel.inode = parse_pos(changes, &cap[3]);Ok(std::mem::replace(current,Some(Record::FileUndel {undel: Atom::EdgeMap(undel),contents: None,path: cap[2].to_string(),}),))} else if let Some(cap) = NAME_CONFLICT.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut name = default_edgemap();debug!("cap = {:?}", cap);name.inode = parse_pos(changes, &cap[6]);Ok(std::mem::replace(current,if &cap[2] == "Solving" {Some(Record::SolveNameConflict {name: Atom::EdgeMap(name),path: cap[5].to_string(),})} else {Some(Record::UnsolveNameConflict {name: Atom::EdgeMap(name),path: cap[5].to_string(),})},))} else if let Some(cap) = MOVE.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut add = default_newvertex();add.start = ChangePosition(contents_.len() as u64);add.flag = EdgeFlags::FOLDER | EdgeFlags::BLOCK;let name = cap.name("new").unwrap().as_str();let meta = cap.name("perm").unwrap().as_str().chars().fold(0, |x, c| x * 8 + (c as u16 - b'0' as u16));let meta = InodeMetadata(meta);meta.write(&mut contents_).unwrap();contents_.extend(name.as_bytes());add.end = ChangePosition(contents_.len() as u64);let mut del = default_edgemap();del.inode = parse_pos(changes, cap.name("inode").unwrap().as_str());Ok(std::mem::replace(current,Some(Record::FileMove {del: Atom::EdgeMap(del),add: Atom::NewVertex(add),path: cap[2].to_string(),}),))} else if let Some(cap) = MOVE_.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut add = default_edgemap();let mut del = default_edgemap();add.inode = parse_pos(changes, &cap[3]);del.inode = add.inode;Ok(std::mem::replace(current,Some(Record::FileMove {del: Atom::EdgeMap(del),add: Atom::EdgeMap(add),path: cap[2].to_string(),}),))} else if let Some(cap) = ORDER_CONFLICT.captures(h) {if has_newvertices(current) {contents_.push(0)}Ok(std::mem::replace(current,Some(if &cap[2] == "Solving" {let mut v = default_newvertex();v.inode = parse_pos(changes, &cap[7]);Record::SolveOrderConflict {change: Atom::NewVertex(v),local: Local {path: cap[5].to_string(),line: cap[6].parse().unwrap(),},}} else {let mut v = default_edgemap();v.inode = parse_pos(changes, &cap[7]);Record::UnsolveOrderConflict {change: Atom::EdgeMap(v),local: Local {path: cap[5].to_string(),line: cap[6].parse().unwrap(),},}}),))} else if let Some(cap) = ZOMBIE.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut v = default_edgemap();v.inode = parse_pos(changes, &cap.name("inode").unwrap().as_str());Ok(std::mem::replace(current,Some(Record::ResurrectZombies {change: Atom::EdgeMap(v),local: Local {path: cap.name("path").unwrap().as_str().parse().unwrap(),line: cap.name("line").unwrap().as_str().parse().unwrap(),},}),))} else {match current {Some(Record::FileAdd {ref mut contents,ref mut add_name,..}) => {if h.starts_with('+') {if contents.is_none() {let mut v = default_newvertex();let inode = Position {change: None,pos: ChangePosition(contents_.len() as u64 - 1),};v.up_context.push(inode);v.inode = inode;v.start = ChangePosition(contents_.len() as u64);*contents = Some(Atom::NewVertex(v));}if let Some(Atom::NewVertex(ref mut contents)) = contents {if h.starts_with('+') {text_changes::parse_line_add(h, contents, contents_)}}} else if h.starts_with('\\') {if let Some(Atom::NewVertex(ref mut contents)) = contents {if contents_[contents.end.0 as usize - 1] == b'\n' {assert_eq!(contents.end.0 as usize, contents_.len());contents_.pop();contents.end.0 -= 1;}}} else if let Some(cap) = CONTEXT.captures(h) {if let Atom::NewVertex(ref mut name) = add_name {name.up_context = parse_pos_vec(changes, offsets, &cap[1])?;if let (Some(new_start), Some(new_end)) = (cap.get(4), cap.get(5)) {offsets.insert(new_start.as_str().parse().unwrap(), name.start);offsets.insert(new_end.as_str().parse().unwrap(), name.end);offsets.insert(new_end.as_str().parse::<u64>().unwrap() + 1,name.end + 1,);}}}Ok(None)}Some(Record::FileDel {ref mut del,ref mut contents,..}) => {if let Some(edges) = parse_edges(changes, h) {if let Atom::EdgeMap(ref mut e) = del {if edges[0].flag.contains(EdgeFlags::FOLDER) {*e = EdgeMap {inode: e.inode,edges,}} else {*contents = Some(Atom::EdgeMap(EdgeMap {inode: e.inode,edges,}))}}}Ok(None)}Some(Record::FileUndel {ref mut undel,ref mut contents,..}) => {if let Some(edges) = parse_edges(changes, h) {if let Atom::EdgeMap(ref mut e) = undel {if edges[0].flag.contains(EdgeFlags::FOLDER) {*e = EdgeMap {inode: e.inode,edges,}} else {*contents = Some(Atom::EdgeMap(EdgeMap {inode: e.inode,edges,}))}}}Ok(None)}Some(Record::FileMove {ref mut del,ref mut add,..}) => {if let Some(edges) = parse_edges(changes, h) {if edges[0].flag.contains(EdgeFlags::DELETED) {*del = Atom::EdgeMap(EdgeMap {inode: del.inode(),edges,});return Ok(None);} else if let Atom::EdgeMap(ref mut add) = add {if add.edges.is_empty() {*add = EdgeMap {inode: add.inode,edges,};return Ok(None);}}} else if let Some(cap) = CONTEXT.captures(h) {if let Atom::NewVertex(ref mut c) = add {debug!("cap = {:?}", cap);c.up_context = parse_pos_vec(changes, offsets, &cap[1])?;if let Some(cap) = cap.get(7) {c.down_context = parse_pos_vec(changes, offsets, cap.as_str())?;}}}Ok(None)}Some(Record::Edit { ref mut change, .. }) => {debug!("edit {:?}", h);if h.starts_with("+ ") {if let Atom::NewVertex(ref mut change) = change {if change.start == change.end {change.start = ChangePosition(contents_.len() as u64);}text_changes::parse_line_add(h, change, contents_)}} else if h.starts_with('\\') {if let Atom::NewVertex(ref mut change) = change {if contents_[change.end.0 as usize - 1] == b'\n' {assert_eq!(change.end.0 as usize, contents_.len());contents_.pop();change.end.0 -= 1;}}} else if let Some(cap) = CONTEXT.captures(h) {if let Atom::NewVertex(ref mut c) = change {debug!("cap = {:?}", cap);c.up_context = parse_pos_vec(changes, offsets, &cap[1])?;if let Some(cap) = cap.get(7) {c.down_context = parse_pos_vec(changes, offsets, cap.as_str())?;}}} else if let Some(edges) = parse_edges(changes, h) {*change = Atom::EdgeMap(EdgeMap {inode: change.inode(),edges,});}Ok(None)}Some(Record::Replacement {ref mut change,ref mut replacement,..}) => {if h.starts_with("+ ") {if let Atom::NewVertex(ref mut repl) = replacement {if repl.start == repl.end {repl.start = ChangePosition(contents_.len() as u64);}text_changes::parse_line_add(h, repl, contents_)}} else if h.starts_with('\\') {if let Atom::NewVertex(ref mut repl) = replacement {if contents_[repl.end.0 as usize - 1] == b'\n' {assert_eq!(repl.end.0 as usize, contents_.len());contents_.pop();repl.end.0 -= 1;}}} else if let Some(cap) = CONTEXT.captures(h) {debug!("cap = {:?}", cap);if let Atom::NewVertex(ref mut repl) = replacement {repl.up_context = parse_pos_vec(changes, offsets, &cap[1])?;if let Some(cap) = cap.get(7) {repl.down_context = parse_pos_vec(changes, offsets, cap.as_str())?;}}} else if let Some(edges) = parse_edges(changes, h) {*change = Atom::EdgeMap(EdgeMap {inode: change.inode(),edges,});}Ok(None)}Some(Record::SolveNameConflict { ref mut name, .. })| Some(Record::UnsolveNameConflict { ref mut name, .. }) => {if let Some(edges) = parse_edges(changes, h) {*name = Atom::EdgeMap(EdgeMap {edges,inode: name.inode(),})}Ok(None)}Some(Record::SolveOrderConflict { ref mut change, .. }) => {if h.starts_with("+ ") {if let Atom::NewVertex(ref mut change) = change {if change.start == change.end {change.start = ChangePosition(contents_.len() as u64);}text_changes::parse_line_add(h, change, contents_)}} else if let Some(cap) = CONTEXT.captures(h) {debug!("cap = {:?}", cap);if let Atom::NewVertex(ref mut change) = change {change.up_context = parse_pos_vec(changes, offsets, &cap[1])?;if let Some(cap) = cap.get(7) {change.down_context =parse_pos_vec(changes, offsets, cap.as_str())?;}if let (Some(new_start), Some(new_end)) = (cap.get(4), cap.get(5)) {let new_start = new_start.as_str().parse::<u64>().unwrap();let new_end = new_end.as_str().parse::<u64>().unwrap();change.start = ChangePosition(contents_.len() as u64);change.end =ChangePosition(contents_.len() as u64 + new_end - new_start);offsets.insert(new_end, change.end);}}}Ok(None)}Some(Record::UnsolveOrderConflict { ref mut change, .. }) => {if let Some(edges) = parse_edges(changes, h) {if let Atom::EdgeMap(ref mut change) = change {change.edges = edges}}Ok(None)}Some(Record::ResurrectZombies { ref mut change, .. }) => {if let Some(edges) = parse_edges(changes, h) {if let Atom::EdgeMap(ref mut change) = change {change.edges = edges}}Ok(None)}None => {debug!("current = {:#?}", current);debug!("h = {:?}", h);Ok(None)}}}}}#[cfg(feature = "text-changes")]mod text_changes {use super::*;lazy_static! {static ref POS: regex::Regex = regex::Regex::new(r#"(\d+)\.(\d+)"#).unwrap();static ref EDGE: regex::Regex =regex::Regex::new(r#"\s*(?P<prev>[BFD]*):(?P<flag>[BFD]*)\s+(?P<up_c>\d+)\.(?P<up_l>\d+)\s*->\s*(?P<c>\d+)\.(?P<l0>\d+):(?P<l1>\d+)/(?P<intro>\d+)\s*"#).unwrap();}pub fn default_newvertex() -> NewVertex<Option<Hash>> {NewVertex {start: ChangePosition(0),end: ChangePosition(0),flag: EdgeFlags::empty(),up_context: Vec::new(),down_context: Vec::new(),inode: Position {change: Some(Hash::None),pos: ChangePosition(0),},}}pub fn default_edgemap() -> EdgeMap<Option<Hash>> {EdgeMap {edges: Vec::new(),inode: Position {change: Some(Hash::None),pos: ChangePosition(0),},}}pub fn has_newvertices<L>(current: &Option<Record<Option<Hash>, L>>) -> bool {match current {Some(Record::FileAdd { contents: None, .. }) | None => false,Some(rec) => rec.iter().any(|e| matches!(e, Atom::NewVertex(_))),}}pub fn parse_pos_vec(changes: &HashMap<usize, Hash>,offsets: &HashMap<u64, ChangePosition>,s: &str,) -> Result<Vec<Position<Option<Hash>>>, Error> {let mut v = Vec::new();for pos in POS.captures_iter(s) {let change: usize = (&pos[1]).parse().unwrap();let pos: u64 = (&pos[2]).parse().unwrap();let pos = if change == 0 {if let Some(&pos) = offsets.get(&pos) {pos} else {debug!("inconsistent change: {:?} {:?}", s, offsets);return Err(Error::InconsistentChange);}} else {ChangePosition(pos)};v.push(Position {change: change_ref(changes, change),pos,})}Ok(v)}fn change_ref(changes: &HashMap<usize, Hash>, change: usize) -> Option<Hash> {debug!("change_ref {:?} {:?}", changes, change);if change == 0 {None} else if change == 1 {Some(Hash::None)} else {Some(*changes.get(&change).unwrap())}}pub fn parse_pos(changes: &HashMap<usize, Hash>, s: &str) -> Position<Option<Hash>> {let pos = POS.captures(s).unwrap();let change: usize = (&pos[1]).parse().unwrap();let pos: u64 = (&pos[2]).parse().unwrap();Position {change: change_ref(changes, change),pos: ChangePosition(pos),}}pub fn parse_edges(changes: &HashMap<usize, Hash>,s: &str,) -> Option<Vec<NewEdge<Option<Hash>>>> {debug!("parse_edges {:?}", s);let mut result = Vec::new();for edge in s.split(',') {debug!("parse edge {:?}", edge);if let Some(cap) = EDGE.captures(edge) {let previous = read_flag(cap.name("prev").unwrap().as_str());let flag = read_flag(cap.name("flag").unwrap().as_str());let change0: usize = cap.name("up_c").unwrap().as_str().parse().unwrap();let pos0: u64 = cap.name("up_l").unwrap().as_str().parse().unwrap();let change1: usize = cap.name("c").unwrap().as_str().parse().unwrap();let start1: u64 = cap.name("l0").unwrap().as_str().parse().unwrap();let end1: u64 = cap.name("l1").unwrap().as_str().parse().unwrap();let introduced_by: usize = cap.name("intro").unwrap().as_str().parse().unwrap();result.push(NewEdge {previous,flag,from: Position {change: change_ref(changes, change0),pos: ChangePosition(pos0),},to: Vertex {change: change_ref(changes, change1),start: ChangePosition(start1),end: ChangePosition(end1),},introduced_by: change_ref(changes, introduced_by),})} else {debug!("not parsed");return None;}}Some(result)}pub fn parse_line_add(h: &str, change: &mut NewVertex<Option<Hash>>, contents_: &mut Vec<u8>) {let h = h.as_bytes();debug!("parse_line_add {:?} {:?}", change.end, change.start);debug!("parse_line_add {:?}", h);if h.len() > 2 {let h = &h[2..h.len()];contents_.extend(h);} else if h.len() > 1 {contents_.push(b'\n');}debug!("contents_.len() = {:?}", contents_.len());trace!("contents_ = {:?}", contents_);change.end = ChangePosition(contents_.len() as u64);}pub fn print_contents<W: std::io::Write>(w: &mut W,pref: &str,contents: &[u8],) -> Result<(), anyhow::Error> {if let Ok(mut contents) = std::str::from_utf8(&contents) {while let Some(n) = contents.as_bytes().iter().position(|&c| c == b'\n') {let (a, b) = contents.split_at(n + 1);contents = b;write!(w, "{} {}", pref, a)?;}if !contents.is_empty() {writeln!(w, "{} {}", pref, contents)?;}} else {writeln!(w, "{}b{}", pref, data_encoding::BASE64.encode(contents))?}Ok(())}pub fn print_change_contents<W: std::io::Write, C: ChangeStore>(w: &mut W,changes: &C,change: &Atom<Option<Hash>>,change_contents: &[u8],) -> Result<(), anyhow::Error> {match change {Atom::NewVertex(ref n) => {let c = &change_contents[n.start.0 as usize..n.end.0 as usize];print_contents(w, "+", c)?;if !c.ends_with(b"\n") {writeln!(w, "\\")?}Ok(())}Atom::EdgeMap(ref n) if n.edges[0].flag.contains(EdgeFlags::DELETED) => {let mut buf = Vec::new();let mut current = None;for e in n.edges.iter() {if Some(e.to) == current {continue;}buf.clear();changes.get_contents_ext(e.to, &mut buf)?;print_contents(w, "-", &buf[..])?;current = Some(e.to)}Ok(())}_ => Ok(()),}}pub fn write_deleted_names<W: std::io::Write, C: ChangeStore>(w: &mut W,changes: &C,del: &Atom<Option<Hash>>,) -> Result<(), anyhow::Error> {if let Atom::EdgeMap(ref e) = del {let mut buf = Vec::new();let mut is_first = true;for d in e.edges.iter() {buf.clear();changes.get_contents_ext(d.to, &mut buf)?;if !buf.is_empty() {let name = std::str::from_utf8(buf.split_at(2).1).unwrap();write!(w, "{}{:?}", if is_first { "" } else { ", " }, name)?;is_first = false;}}}Ok(())}pub fn write_flag<W: std::io::Write>(mut w: W, flag: EdgeFlags) -> Result<(), anyhow::Error> {if flag.contains(EdgeFlags::BLOCK) {w.write_all(b"B")?;}if flag.contains(EdgeFlags::FOLDER) {w.write_all(b"F")?;}if flag.contains(EdgeFlags::DELETED) {w.write_all(b"D")?;}assert!(!flag.contains(EdgeFlags::PARENT));assert!(!flag.contains(EdgeFlags::PSEUDO));Ok(())}pub fn read_flag(s: &str) -> EdgeFlags {let mut f = EdgeFlags::empty();for i in s.chars() {match i {'B' => f |= EdgeFlags::BLOCK,'F' => f |= EdgeFlags::FOLDER,'D' => f |= EdgeFlags::DELETED,c => panic!("read_flag: {:?}", c),}}f}pub fn write_pos<W: std::io::Write>(mut w: W,hashes: &HashMap<Hash, usize>,pos: Position<Option<Hash>>,) -> Result<(), anyhow::Error> {let change = if let Some(Hash::None) = pos.change {1} else if let Some(ref c) = pos.change {*hashes.get(c).unwrap()} else {0};write!(w, "{}.{}", change, pos.pos.0)?;Ok(())}pub fn write_atom<W: std::io::Write>(w: &mut W,hashes: &HashMap<Hash, usize>,atom: &Atom<Option<Hash>>,) -> Result<(), anyhow::Error> {match atom {Atom::NewVertex(ref n) => write_newvertex(w, hashes, n),Atom::EdgeMap(ref n) => write_edgemap(w, hashes, n),}}pub fn write_newvertex<W: std::io::Write>(mut w: W,hashes: &HashMap<Hash, usize>,n: &NewVertex<Option<Hash>>,) -> Result<(), anyhow::Error> {write!(w, " up")?;for c in n.up_context.iter() {write!(w, " ")?;write_pos(&mut w, hashes, *c)?}write!(w, ", new {}:{}", n.start.0, n.end.0)?;if !n.down_context.is_empty() {write!(w, ", down")?;for c in n.down_context.iter() {write!(w, " ")?;write_pos(&mut w, hashes, *c)?}}w.write_all(b"\n")?;Ok(())}pub fn write_edgemap<W: std::io::Write>(mut w: W,hashes: &HashMap<Hash, usize>,n: &EdgeMap<Option<Hash>>,) -> Result<(), anyhow::Error> {let mut is_first = true;for c in n.edges.iter() {if !is_first {write!(w, ", ")?;}is_first = false;write_flag(&mut w, c.previous)?;write!(w, ":")?;write_flag(&mut w, c.flag)?;write!(w, " ")?;write_pos(&mut w, hashes, c.from)?;write!(w, " -> ")?;write_pos(&mut w, hashes, c.to.start_pos())?;let h = if let Some(h) = hashes.get(c.introduced_by.as_ref().unwrap()) {h} else {panic!("introduced_by = {:?}, not found", c.introduced_by);};write!(w, ":{}/{}", c.to.end.0, h)?;}writeln!(w)?;Ok(())}#[cfg(feature = "text-changes")]#[derive(Debug, Clone, PartialEq, Eq)]pub enum Section {Header(String),Deps,Changes {changes: Vec<Record<Option<Hash>, Local>>,current: Option<Record<Option<Hash>, Local>>,offsets: HashMap<u64, ChangePosition>,},}}// org id XDu/0rcMPSdaCWLiWWDiw32Rl45EX9uwvy9vprRXJbg=/// An open, seekable change file.#[cfg(feature = "zstd")]pub struct ChangeFile<'a> {s: Option<zstd_seekable::Seekable<'a, OffFile>>,hashed: Hashed<Local>,hash: Hash,unhashed: Option<toml::Value>,}struct OffFile {f: std::fs::File,start: u64,}unsafe impl Send for OffFile {}impl std::io::Read for OffFile {fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {self.f.read(buf)}}impl std::io::Seek for OffFile {fn seek(&mut self, from: std::io::SeekFrom) -> Result<u64, std::io::Error> {use std::io::SeekFrom;let from = match from {SeekFrom::Start(s) => SeekFrom::Start(s + self.start),c => c,};self.f.seek(from)}}#[cfg(feature = "zstd")]impl<'a> ChangeFile<'a> {/// Open a change file from a path.pub fn open(hash: Hash, path: &str) -> Result<Self, anyhow::Error> {use std::io::Read;let mut r = std::fs::File::open(path)?;let mut buf = Vec::new();buf.resize(Change::OFFSETS_SIZE as usize, 0);r.read_exact(&mut buf)?;let offsets: Offsets = bincode::deserialize(&buf)?;if offsets.version != VERSION {return Err(Error::VersionMismatch.into());}buf.clear();buf.resize((offsets.unhashed_off - Change::OFFSETS_SIZE) as usize, 0);r.read_exact(&mut buf)?;let mut buf2 = vec![0u8; offsets.hashed_len as usize];let hashed: Hashed<Local> = {let mut s = zstd_seekable::Seekable::init_buf(&buf)?;s.decompress(&mut buf2, 0)?;bincode::deserialize(&buf2)?};buf.resize((offsets.contents_off - offsets.unhashed_off) as usize, 0);let unhashed = if buf.is_empty() {None} else {r.read_exact(&mut buf)?;let mut s = zstd_seekable::Seekable::init_buf(&buf)?;buf2.resize(offsets.unhashed_len as usize, 0);s.decompress(&mut buf2, 0)?;Some(toml::de::from_slice(&buf2)?)};let m = r.metadata()?;let s = if offsets.contents_off >= m.len() {None} else {Some(zstd_seekable::Seekable::init(Box::new(OffFile {f: r,start: offsets.contents_off,}))?)};Ok(ChangeFile {s,hashed,hash,unhashed,})}pub fn has_contents(&self) -> bool {self.s.is_some()}/// Reads the contents at an offset into `buf`, and returns the/// number of bytes read. The bounds of the change's "contents"/// section are not checked.pub fn read_contents(&mut self, offset: u64, buf: &mut [u8]) -> Result<usize, anyhow::Error> {debug!("read_contents {:?} {:?}", offset, buf.len());if let Some(ref mut s) = self.s {Ok(s.decompress(buf, offset)?)} else {Err((Error::MissingContents {hash: self.hash.to_base32(),}).into())}}pub fn hashed(&self) -> &Hashed<Local> {&self.hashed}pub fn unhashed(&self) -> &Option<toml::Value> {&self.unhashed}} - file deletion: v3.rs
use super::*;#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]enum Atom3<Change> {NewVertex(NewVertex<Change>),EdgeMap(EdgeMap3<Change>),}impl Atom3<Option<Hash>> {fn to_v4(self, translation: &HashMap<Option<Hash>, Option<Hash>>) -> Atom<Option<Hash>> {match self {Atom3::NewVertex(n) => Atom::NewVertex(NewVertex {up_context: n.up_context.into_iter().map(|x| Position {change: *translation.get(&x.change).unwrap(),..x}).collect(),down_context: n.down_context.into_iter().map(|x| Position {change: *translation.get(&x.change).unwrap(),..x}).collect(),flag: n.flag,start: n.start,end: n.end,inode: Position {change: *translation.get(&n.inode.change).unwrap(),..n.inode},}),Atom3::EdgeMap(e) => Atom::EdgeMap(e.to_v4(translation)),}}}#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]struct EdgeMap3<Change> {pub previous: EdgeFlags,pub flag: EdgeFlags,pub edges: Vec<NewEdge3<Change>>,pub inode: Position<Change>,}impl EdgeMap3<Option<Hash>> {fn to_v4(self, translations: &HashMap<Option<Hash>, Option<Hash>>) -> EdgeMap<Option<Hash>> {let flag = self.flag;let previous = self.previous;EdgeMap {inode: Position {change: *translations.get(&self.inode.change).unwrap(),..self.inode},edges: self.edges.into_iter().map(|e| NewEdge {previous,flag,from: Position {change: *translations.get(&e.from.change).unwrap(),..e.from},to: Vertex {change: *translations.get(&e.to.change).unwrap(),..e.to},introduced_by: *translations.get(&e.introduced_by).unwrap(),}).collect(),}}}#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]struct NewEdge3<Change> {pub from: Position<Change>,pub to: Vertex<Change>,pub introduced_by: Change,}#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]enum Record3<Hash, Local> {FileMove {del: Atom3<Hash>,add: Atom3<Hash>,confirm: Option<Atom3<Hash>>,path: String,},FileDel {del: Atom3<Hash>,confirm: Option<Atom3<Hash>>,contents: Option<Atom3<Hash>>,path: String,},FileUndel {undel: Atom3<Hash>,confirm: Option<Atom3<Hash>>,contents: Option<Atom3<Hash>>,path: String,},FileAdd {add_name: Atom3<Hash>,add_inode: Atom3<Hash>,contents: Option<Atom3<Hash>>,path: String,},SolveNameConflict {name: Atom3<Hash>,confirm: Option<Atom3<Hash>>,path: String,},UnsolveNameConflict {name: Atom3<Hash>,confirm: Option<Atom3<Hash>>,path: String,},Edit {change: Atom3<Hash>,local: Local,},Replacement {change: Atom3<Hash>,replacement: Atom3<Hash>,local: Local,},SolveOrderConflict {change: Atom3<Hash>,local: Local,},UnsolveOrderConflict {change: Atom3<Hash>,local: Local,},ResurrectZombies {alive: Atom3<Hash>,dead: Atom3<Hash>,local: Local,},}impl Record3<Option<Hash>, Local> {fn to_v4(self,translation: &HashMap<Option<Hash>, Option<Hash>>,) -> Record<Option<Hash>, Local> {match self {Record3::FileMove {del,add,confirm,path,} => {let mut del = del.to_v4(translation);if let Atom::EdgeMap(ref mut e) = del {if let Some(Atom3::EdgeMap(c)) = confirm {let c = c.to_v4(translation);e.edges.extend(c.edges.into_iter())}}let add = add.to_v4(translation);Record::FileMove { del, add, path }}Record3::FileDel {del,confirm,contents,path,} => {let mut del = del.to_v4(translation);if let Atom::EdgeMap(ref mut e) = del {if let Some(Atom3::EdgeMap(c)) = confirm {let c = c.to_v4(translation);e.edges.extend(c.edges.into_iter())}}let contents = contents.map(|c| c.to_v4(translation));Record::FileDel {del,contents,path,}}Record3::FileUndel {undel,confirm,contents,path,} => {let mut undel = undel.to_v4(translation);if let Atom::EdgeMap(ref mut e) = undel {if let Some(Atom3::EdgeMap(c)) = confirm {let c = c.to_v4(translation);e.edges.extend(c.edges.into_iter())}}let contents = contents.map(|c| c.to_v4(translation));Record::FileUndel {undel,contents,path,}}Record3::FileAdd {add_name,add_inode,contents,path,} => Record::FileAdd {add_name: add_name.to_v4(translation),add_inode: add_inode.to_v4(translation),contents: contents.map(|c| c.to_v4(translation)),path,},Record3::SolveNameConflict {name,confirm,path,} => {let mut name = name.to_v4(translation);if let Atom::EdgeMap(ref mut e) = name {if let Some(Atom3::EdgeMap(c)) = confirm {let c = c.to_v4(translation);e.edges.extend(c.edges.into_iter())}}Record::SolveNameConflict { name, path }}Record3::UnsolveNameConflict {name,confirm,path,} => {let mut name = name.to_v4(translation);if let Atom::EdgeMap(ref mut e) = name {if let Some(Atom3::EdgeMap(c)) = confirm {let c = c.to_v4(translation);e.edges.extend(c.edges.into_iter())}}Record::UnsolveNameConflict { name, path }}Record3::Edit { change, local } => Record::Edit {change: change.to_v4(translation),local,},Record3::Replacement {change,replacement,local,} => Record::Replacement {change: change.to_v4(translation),replacement: replacement.to_v4(translation),local,},Record3::SolveOrderConflict { change, local } => Record::SolveOrderConflict {change: change.to_v4(translation),local,},Record3::UnsolveOrderConflict { change, local } => Record::UnsolveOrderConflict {change: change.to_v4(translation),local,},Record3::ResurrectZombies { alive, dead, local } => {let mut change = alive.to_v4(translation);if let Atom::EdgeMap(ref mut e) = change {if let Atom3::EdgeMap(c) = dead {let c = c.to_v4(translation);e.edges.extend(c.edges.into_iter())}}Record::ResurrectZombies { change, local }}}}}#[derive(Clone, Debug, PartialEq)]pub struct LocalChange3<Local> {offsets: Offsets,hashed: Hashed3<Local>,unhashed: Option<toml::Value>,contents: Vec<u8>,}const VERSION: u64 = 3;#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]struct Hashed3<Local> {version: u64,header: ChangeHeader,dependencies: BTreeSet<Hash>,extra_known: BTreeSet<Hash>,metadata: Vec<u8>,changes: Vec<Record3<Option<Hash>, Local>>,contents_hash: Hash,}impl Hashed3<Local> {fn to_v4(self, translation: &HashMap<Option<Hash>, Option<Hash>>) -> Hashed<Local> {Hashed {version: 4,header: self.header,dependencies: self.dependencies.into_iter().map(|x| translation.get(&Some(x)).unwrap().unwrap()).collect(),extra_known: self.extra_known.into_iter().filter_map(|x| translation.get(&Some(x)).map(|x| x.unwrap())).collect(),metadata: self.metadata,contents_hash: self.contents_hash,changes: self.changes.into_iter().map(|x| x.to_v4(translation)).collect(),}}}impl LocalChange3<Local> {const OFFSETS_SIZE: u64 = 56;pub fn deserialize(file: &str, hash: Option<&Hash>) -> Result<Self, anyhow::Error> {use std::io::Read;let mut r = std::fs::File::open(file)?;let mut buf = vec![0u8; Self::OFFSETS_SIZE as usize];r.read_exact(&mut buf)?;let offsets: Offsets = bincode::deserialize(&buf)?;if offsets.version != VERSION {return Err(Error::VersionMismatch.into());}debug!("offsets = {:?}", offsets);buf.clear();buf.resize((offsets.unhashed_off - Self::OFFSETS_SIZE) as usize, 0);r.read_exact(&mut buf)?;let hashed: Hashed3<Local> = {let mut s = zstd_seekable::Seekable::init_buf(&buf[..])?;let mut out = vec![0u8; offsets.hashed_len as usize];s.decompress(&mut out[..], 0)?;let mut hasher = Hasher::default();hasher.update(&out);let computed_hash = hasher.finish();if let Some(hash) = hash {if &computed_hash != hash {return Err((Error::ChangeHashMismatch {claimed: *hash,computed: computed_hash,}).into());}}bincode::deserialize_from(&out[..])?};buf.clear();buf.resize((offsets.contents_off - offsets.unhashed_off) as usize, 0);let unhashed = if buf.is_empty() {None} else {r.read_exact(&mut buf)?;let mut s = zstd_seekable::Seekable::init_buf(&buf[..])?;let mut out = vec![0u8; offsets.unhashed_len as usize];s.decompress(&mut out[..], 0)?;Some(toml::de::from_slice(&out)?)};debug!("unhashed = {:?}", unhashed);buf.clear();buf.resize((offsets.total - offsets.contents_off) as usize, 0);let contents = if r.read_exact(&mut buf).is_ok() {let mut s = zstd_seekable::Seekable::init_buf(&buf[..])?;let mut contents = vec![0u8; offsets.contents_len as usize];s.decompress(&mut contents[..], 0)?;contents} else {Vec::new()};debug!("contents = {:?}", contents);Ok(LocalChange3 {offsets,hashed,unhashed,contents,})}pub fn to_v4(self, translation: &HashMap<Option<Hash>, Option<Hash>>) -> LocalChange<Local> {LocalChange {offsets: self.offsets,hashed: self.hashed.to_v4(translation),unhashed: self.unhashed,contents: self.contents,}}} - file addition: text_changes.rs[17.931000]
use super::*;use crate::changestore::*;use std::collections::hash_map::Entry;use std::collections::HashMap;use std::io::BufRead;#[derive(Debug, Error)]pub enum TextDeError {#[error(transparent)]Io(#[from] std::io::Error),#[error(transparent)]TomlDe(#[from] toml::de::Error),#[error("Missing change [{0}]")]MissingChange(usize),}#[derive(Debug, Error)]pub enum TextSerError<C: std::error::Error + 'static> {#[error(transparent)]C(C),#[error(transparent)]Io(#[from] std::io::Error),#[error(transparent)]TomlSer(#[from] toml::ser::Error),#[error("Missing contents in change {:?}", h)]MissingContents { h: Hash },#[error(transparent)]Change(#[from] ChangeError),}impl LocalChange<Local> {const DEPS_LINE: &'static str = "# Dependencies\n";const CHANGES_LINE: &'static str = "# Changes\n";pub fn write_all_deps<F: FnMut(Hash) -> Result<(), ChangeError>>(&self,mut f: F,) -> Result<(), ChangeError> {for c in self.changes.iter() {for c in c.iter() {match *c {Atom::NewVertex(ref n) => {for change in n.up_context.iter().chain(n.down_context.iter()).map(|c| c.change).chain(std::iter::once(n.inode.change)){if let Some(change) = change {if let Hash::None = change {continue;}f(change)?}}}Atom::EdgeMap(ref e) => {for edge in e.edges.iter() {for change in &[edge.from.change,edge.to.change,edge.introduced_by,e.inode.change,] {if let Some(change) = *change {if let Hash::None = change {continue;}f(change)?}}}}}}}Ok(())}pub fn write<W: Write, C: ChangeStore, F: FnMut(&Local, Position<Option<Hash>>) -> String>(&self,changes: &C,hash: Option<Hash>,mut file_name: F,write_header: bool,mut w: W,) -> Result<(), TextSerError<C::Error>> {if let Some(h) = hash {// Check if we have the full contentslet mut hasher = Hasher::default();hasher.update(&self.contents);let hash = hasher.finish();if hash != self.contents_hash {return Err((TextSerError::MissingContents { h }).into());}}if write_header {w.write_all(toml::ser::to_string_pretty(&self.header)?.as_bytes())?;w.write_all(b"\n")?;}let mut hashes = HashMap::new();let mut i = 2;let mut needs_newline = false;if !self.dependencies.is_empty() {w.write_all(Self::DEPS_LINE.as_bytes())?;needs_newline = true;for dep in self.dependencies.iter() {hashes.insert(*dep, i);writeln!(w, "[{}] {}", i, dep.to_base32())?;i += 1;}}self.write_all_deps(|change| {if let Entry::Vacant(e) = hashes.entry(change) {e.insert(i);if !needs_newline {w.write_all(Self::DEPS_LINE.as_bytes())?;needs_newline = true;}writeln!(w, "[{}]+{}", i, change.to_base32())?;i += 1;}Ok(())})?;if !self.extra_known.is_empty() {needs_newline = true;for dep in self.extra_known.iter() {writeln!(w, "[*] {}", dep.to_base32())?;i += 1;}}if !self.changes.is_empty() {if needs_newline {w.write_all(b"\n")?}w.write_all(Self::CHANGES_LINE.as_bytes())?;for (n, rec) in self.changes.iter().enumerate() {write!(w, "\n{}. ", n + 1)?;rec.write(changes, &mut file_name, &hashes, &self.contents, &mut w)?}}Ok(())}}impl Change {pub fn read_and_deps<R: BufRead, T: TxnT>(r: R,updatables: &mut HashMap<usize, crate::InodeUpdate>,txn: &T,channel: &ChannelRef<T>,) -> Result<Self, TextDeError> {let (mut change, extra_dependencies) = Self::read_(r, updatables)?;let (mut deps, extra) = dependencies(txn, channel, change.hashed.changes.iter());deps.extend(extra_dependencies.into_iter());change.hashed.dependencies = deps;change.hashed.extra_known = extra;Ok(change)}pub fn read<R: BufRead>(r: R,updatables: &mut HashMap<usize, crate::InodeUpdate>,) -> Result<Self, TextDeError> {Ok(Self::read_(r, updatables)?.0)}fn read_<R: BufRead>(mut r: R,updatables: &mut HashMap<usize, crate::InodeUpdate>,) -> Result<(Self, HashSet<Hash>), TextDeError> {use self::text_changes::*;let mut section = Section::Header(String::new());let mut change = Change {offsets: Offsets::default(),hashed: Hashed {version: VERSION,header: ChangeHeader {authors: Vec::new(),message: String::new(),description: None,timestamp: chrono::Utc::now(),},dependencies: Vec::new(),extra_known: Vec::new(),metadata: Vec::new(),changes: Vec::new(),contents_hash: Hasher::default().finish(),},unhashed: None,contents: Vec::new(),};let conclude_section = |change: &mut Change,section: Section,contents: &mut Vec<u8>|-> Result<(), TextDeError> {match section {Section::Header(ref s) => {debug!("header = {:?}", s);change.header = toml::de::from_str(&s)?;Ok(())}Section::Deps => Ok(()),Section::Changes {mut changes,current,..} => {if has_newvertices(¤t) {contents.push(0)}if let Some(c) = current {debug!("next action = {:?}", c);changes.push(c)}change.changes = changes;Ok(())}}};let mut h = String::new();let mut contents = Vec::new();let mut deps = HashMap::new();let mut extra_dependencies = HashSet::new();while r.read_line(&mut h)? > 0 {debug!("h = {:?}", h);if h == Self::DEPS_LINE {let section = std::mem::replace(&mut section, Section::Deps);conclude_section(&mut change, section, &mut contents)?;} else if h == Self::CHANGES_LINE {let section = std::mem::replace(&mut section,Section::Changes {changes: Vec::new(),current: None,offsets: HashMap::new(),},);conclude_section(&mut change, section, &mut contents)?;} else {use regex::Regex;lazy_static! {static ref DEPS: Regex = Regex::new(r#"\[(\d*|\*)\](\+| ) *(\S*)"#).unwrap();static ref KNOWN: Regex = Regex::new(r#"(\S*)"#).unwrap();}match section {Section::Header(ref mut s) => s.push_str(&h),Section::Deps => {if let Some(d) = DEPS.captures(&h) {let hash = Hash::from_base32(d[3].as_bytes()).unwrap();if let Ok(n) = d[1].parse() {if &d[2] == " " {change.hashed.dependencies.push(hash);}deps.insert(n, hash);} else if &d[1] == "*" {change.hashed.extra_known.push(hash);} else {extra_dependencies.insert(hash);}}}Section::Changes {ref mut current,ref mut changes,ref mut offsets,} => {if let Some(next) =Record::read(updatables, current, &mut contents, &deps, offsets, &h)?{debug!("next action = {:?}", next);changes.push(next)}}}}h.clear();}conclude_section(&mut change, section, &mut contents)?;change.contents = contents;change.contents_hash = {let mut hasher = Hasher::default();hasher.update(&change.contents);hasher.finish()};Ok((change, extra_dependencies))}}impl Record<Option<Hash>, Local> {fn write<W: std::io::Write,C: ChangeStore,F: FnMut(&Local, Position<Option<Hash>>) -> String,>(&self,changes: &C,mut file_name: F,hashes: &HashMap<Hash, usize>,change_contents: &[u8],mut w: W,) -> Result<(), TextSerError<C::Error>> {use self::text_changes::*;match self {Record::FileMove { del, add, path } => match add {Atom::NewVertex(ref add) => {let name = std::str::from_utf8(&change_contents[add.start.0 as usize + 2..add.end.0 as usize],).unwrap();let perms = crate::pristine::InodeMetadata::from_basename(&change_contents[add.start.0 as usize..add.start.0 as usize + 2],);write!(w, "Moved: {:?} {:?} {:o} ", path, name, perms.0)?;write_pos(&mut w, hashes, del.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &del)?;write!(w, "up")?;for c in add.up_context.iter() {write!(w, " ")?;write_pos(&mut w, hashes, *c)?}write!(w, ", down")?;for c in add.down_context.iter() {write!(w, " ")?;write_pos(&mut w, hashes, *c)?}w.write_all(b"\n")?;}Atom::EdgeMap(_) => {write!(w, "Moved: {:?} ", path)?;write_pos(&mut w, hashes, del.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &add)?;write_atom(&mut w, hashes, &del)?;}},Record::FileDel {del,contents,path,} => {write!(w, "File deletion: {:?} ", path)?;write_pos(&mut w, hashes, del.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &del)?;if let Some(ref contents) = contents {write_atom(&mut w, hashes, &contents)?;writeln!(w)?;print_change_contents(&mut w, changes, contents, change_contents)?;} else {writeln!(w)?;}}Record::FileUndel {undel,contents,path,} => {write!(w, "File un-deletion: {:?} ", path)?;write_pos(&mut w, hashes, undel.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &undel)?;if let Some(ref contents) = contents {write_atom(&mut w, hashes, &contents)?;print_change_contents(&mut w, changes, contents, change_contents)?;} else {writeln!(w)?;}}Record::FileAdd {add_name,contents,path,..} => {if let Atom::NewVertex(ref n) = add_name {let name = std::str::from_utf8(&change_contents[n.start.0 as usize + 2..n.end.0 as usize],).unwrap();let perms = crate::pristine::InodeMetadata::from_basename(&change_contents[n.start.0 as usize..n.start.0 as usize + 2],);let parent = if let Some(p) = crate::path::parent(&path) {if p.is_empty() {"/"} else {p}} else {"/"};write!(w,"File addition: {:?} in {:?} {:o}\n up",name, parent, perms.0)?;assert!(n.down_context.is_empty());for c in n.up_context.iter() {write!(w, " ")?;write_pos(&mut w, hashes, *c)?}writeln!(w, ", new {}:{}", n.start.0, n.end.0)?;}if let Some(Atom::NewVertex(ref n)) = contents {let c = &change_contents[n.start.0 as usize..n.end.0 as usize];print_contents(&mut w, "+", c)?;if !c.ends_with(b"\n") {writeln!(w, "\\")?}}}Record::Edit { change, local } => {write!(w, "Edit in {} ", file_name(&local, change.inode()))?;write_pos(&mut w, hashes, change.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &change)?;print_change_contents(&mut w, changes, change, change_contents)?;}Record::Replacement {change,replacement,local,} => {write!(w, "Replacement in {} ", file_name(&local, change.inode()))?;write_pos(&mut w, hashes, change.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &change)?;write_atom(&mut w, hashes, &replacement)?;print_change_contents(&mut w, changes, change, change_contents)?;print_change_contents(&mut w, changes, replacement, change_contents)?;}Record::SolveNameConflict { name, path } => {write!(w, "Solving a name conflict in {:?} ", path)?;write_pos(&mut w, hashes, name.inode())?;write!(w, ": ")?;write_deleted_names(&mut w, changes, name)?;writeln!(w)?;write_atom(&mut w, hashes, &name)?;}Record::UnsolveNameConflict { name, path } => {write!(w, "Un-solving a name conflict in {:?} ", path)?;write_pos(&mut w, hashes, name.inode())?;write!(w, ": ")?;write_deleted_names(&mut w, changes, name)?;writeln!(w)?;write_atom(&mut w, hashes, &name)?;}Record::SolveOrderConflict { change, local } => {write!(w,"Solving an order conflict in {} ",file_name(&local, change.inode()))?;write_pos(&mut w, hashes, change.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &change)?;print_change_contents(&mut w, changes, change, change_contents)?;}Record::UnsolveOrderConflict { change, local } => {write!(w,"Un-solving an order conflict in {} ",file_name(&local, change.inode()))?;write_pos(&mut w, hashes, change.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &change)?;print_change_contents(&mut w, changes, change, change_contents)?;}Record::ResurrectZombies { change, local } => {write!(w,"Resurrecting zombie lines in {:?}:{} ",local.path, local.line)?;write_pos(&mut w, hashes, change.inode())?;writeln!(w)?;write_atom(&mut w, hashes, &change)?;print_change_contents(&mut w, changes, change, change_contents)?;}}Ok(())}}impl Record<Option<Hash>, Local> {fn read(updatables: &mut HashMap<usize, crate::InodeUpdate>,current: &mut Option<Self>,mut contents_: &mut Vec<u8>,changes: &HashMap<usize, Hash>,offsets: &mut HashMap<u64, ChangePosition>,h: &str,) -> Result<Option<Self>, TextDeError> {use self::text_changes::*;use regex::Regex;lazy_static! {static ref FILE_ADDITION: Regex =Regex::new(r#"(?P<n>\d+)\. File addition: "(?P<name>[^"]*)" in "(?P<parent>[^"]*)" (?P<perm>\d+)"#).unwrap();static ref EDIT: Regex =Regex::new(r#"(\d+)\. Edit in ([^:]+):(\d+) (\d+\.\d+)"#).unwrap();static ref REPLACEMENT: Regex =Regex::new(r#"(\d+)\. Replacement in ([^:]+):(\d+) (\d+\.\d+)"#).unwrap();static ref FILE_DELETION: Regex =Regex::new(r#"(\d+)\. File deletion: "([^"]*)" (\d+\.\d+)"#).unwrap();static ref FILE_UNDELETION: Regex =Regex::new(r#"(\d+)\. File un-deletion: "([^"]*)" (\d+\.\d+)"#).unwrap();static ref MOVE: Regex =Regex::new(r#"(\d+)\. Moved: "(?P<former>[^"]*)" "(?P<new>[^"]*)" (?P<perm>\d+) (?P<inode>.*)"#).unwrap();static ref MOVE_: Regex = Regex::new(r#"(\d+)\. Moved: "([^"]*)" (.*)"#).unwrap();static ref NAME_CONFLICT: Regex = Regex::new(r#"(\d+)\. ((Solving)|(Un-solving)) a name conflict in "([^"]*)" (.*): .*"#).unwrap();static ref ORDER_CONFLICT: Regex = Regex::new(r#"(\d+)\. ((Solving)|(Un-solving)) an order conflict in (.*):(\d+) (\d+\.\d+)"#).unwrap();static ref ZOMBIE: Regex =Regex::new(r#"(\d+)\. Resurrecting zombie lines in (?P<path>"[^"]+"):(?P<line>\d+) (?P<inode>\d+\.\d+)"#).unwrap();static ref CONTEXT: Regex = Regex::new(r#"up ((\d+\.\d+ )*\d+\.\d+)(, new (\d+):(\d+))?(, down ((\d+\.\d+ )*\d+\.\d+))?"#).unwrap();}if let Some(cap) = FILE_ADDITION.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut add_name = default_newvertex();add_name.start = ChangePosition(contents_.len() as u64);add_name.flag = EdgeFlags::FOLDER | EdgeFlags::BLOCK;let name = &cap.name("name").unwrap().as_str();let path = {let parent = cap.name("parent").unwrap().as_str();(if parent == "/" {String::new()} else {parent.to_string()}) + name};let meta = cap.name("perm").unwrap().as_str().chars().fold(0, |x, c| x * 8 + (c as u16 - b'0' as u16));let meta = InodeMetadata(meta);meta.write(&mut contents_).unwrap();contents_.extend(name.as_bytes());add_name.end = ChangePosition(contents_.len() as u64);let mut add_inode = default_newvertex();add_inode.flag = EdgeFlags::FOLDER | EdgeFlags::BLOCK;add_inode.up_context.push(Position {change: None,pos: ChangePosition(contents_.len() as u64),});contents_.push(0);add_inode.start = ChangePosition(contents_.len() as u64);add_inode.end = ChangePosition(contents_.len() as u64);contents_.push(0);let n = cap.name("n").unwrap().as_str().parse().unwrap();if let Entry::Occupied(mut e) = updatables.entry(n) {if let crate::InodeUpdate::Add { ref mut pos, .. } = e.get_mut() {*pos = add_inode.start}}Ok(std::mem::replace(current,Some(Record::FileAdd {add_name: Atom::NewVertex(add_name),add_inode: Atom::NewVertex(add_inode),contents: None,path,}),))} else if let Some(cap) = EDIT.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut v = default_newvertex();v.inode = parse_pos(changes, &cap[4]);Ok(std::mem::replace(current,Some(Record::Edit {change: Atom::NewVertex(v),local: Local {path: cap[2].to_string(),line: cap[3].parse().unwrap(),},}),))} else if let Some(cap) = REPLACEMENT.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut v = default_newvertex();v.inode = parse_pos(changes, &cap[4]);Ok(std::mem::replace(current,Some(Record::Replacement {change: Atom::NewVertex(v.clone()),replacement: Atom::NewVertex(v),local: Local {path: cap[2].to_string(),line: cap[3].parse().unwrap(),},}),))} else if let Some(cap) = FILE_DELETION.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut del = default_edgemap();del.inode = parse_pos(changes, &cap[3]);Ok(std::mem::replace(current,Some(Record::FileDel {del: Atom::EdgeMap(del),contents: None,path: cap[2].to_string(),}),))} else if let Some(cap) = FILE_UNDELETION.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut undel = default_edgemap();undel.inode = parse_pos(changes, &cap[3]);Ok(std::mem::replace(current,Some(Record::FileUndel {undel: Atom::EdgeMap(undel),contents: None,path: cap[2].to_string(),}),))} else if let Some(cap) = NAME_CONFLICT.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut name = default_edgemap();debug!("cap = {:?}", cap);name.inode = parse_pos(changes, &cap[6]);Ok(std::mem::replace(current,if &cap[2] == "Solving" {Some(Record::SolveNameConflict {name: Atom::EdgeMap(name),path: cap[5].to_string(),})} else {Some(Record::UnsolveNameConflict {name: Atom::EdgeMap(name),path: cap[5].to_string(),})},))} else if let Some(cap) = MOVE.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut add = default_newvertex();add.start = ChangePosition(contents_.len() as u64);add.flag = EdgeFlags::FOLDER | EdgeFlags::BLOCK;let name = cap.name("new").unwrap().as_str();let meta = cap.name("perm").unwrap().as_str().chars().fold(0, |x, c| x * 8 + (c as u16 - b'0' as u16));let meta = InodeMetadata(meta);meta.write(&mut contents_).unwrap();contents_.extend(name.as_bytes());add.end = ChangePosition(contents_.len() as u64);let mut del = default_edgemap();del.inode = parse_pos(changes, cap.name("inode").unwrap().as_str());Ok(std::mem::replace(current,Some(Record::FileMove {del: Atom::EdgeMap(del),add: Atom::NewVertex(add),path: cap[2].to_string(),}),))} else if let Some(cap) = MOVE_.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut add = default_edgemap();let mut del = default_edgemap();add.inode = parse_pos(changes, &cap[3]);del.inode = add.inode;Ok(std::mem::replace(current,Some(Record::FileMove {del: Atom::EdgeMap(del),add: Atom::EdgeMap(add),path: cap[2].to_string(),}),))} else if let Some(cap) = ORDER_CONFLICT.captures(h) {if has_newvertices(current) {contents_.push(0)}Ok(std::mem::replace(current,Some(if &cap[2] == "Solving" {let mut v = default_newvertex();v.inode = parse_pos(changes, &cap[7]);Record::SolveOrderConflict {change: Atom::NewVertex(v),local: Local {path: cap[5].to_string(),line: cap[6].parse().unwrap(),},}} else {let mut v = default_edgemap();v.inode = parse_pos(changes, &cap[7]);Record::UnsolveOrderConflict {change: Atom::EdgeMap(v),local: Local {path: cap[5].to_string(),line: cap[6].parse().unwrap(),},}}),))} else if let Some(cap) = ZOMBIE.captures(h) {if has_newvertices(current) {contents_.push(0)}let mut v = default_edgemap();v.inode = parse_pos(changes, &cap.name("inode").unwrap().as_str());Ok(std::mem::replace(current,Some(Record::ResurrectZombies {change: Atom::EdgeMap(v),local: Local {path: cap.name("path").unwrap().as_str().parse().unwrap(),line: cap.name("line").unwrap().as_str().parse().unwrap(),},}),))} else {match current {Some(Record::FileAdd {ref mut contents,ref mut add_name,..}) => {if h.starts_with('+') {if contents.is_none() {let mut v = default_newvertex();let inode = Position {change: None,pos: ChangePosition(contents_.len() as u64 - 1),};v.up_context.push(inode);v.inode = inode;v.start = ChangePosition(contents_.len() as u64);*contents = Some(Atom::NewVertex(v));}if let Some(Atom::NewVertex(ref mut contents)) = contents {if h.starts_with('+') {text_changes::parse_line_add(h, contents, contents_)}}} else if h.starts_with('\\') {if let Some(Atom::NewVertex(ref mut contents)) = contents {if contents_[contents.end.0 as usize - 1] == b'\n' {assert_eq!(contents.end.0 as usize, contents_.len());contents_.pop();contents.end.0 -= 1;}}} else if let Some(cap) = CONTEXT.captures(h) {if let Atom::NewVertex(ref mut name) = add_name {name.up_context = parse_pos_vec(changes, offsets, &cap[1])?;if let (Some(new_start), Some(new_end)) = (cap.get(4), cap.get(5)) {offsets.insert(new_start.as_str().parse().unwrap(), name.start);offsets.insert(new_end.as_str().parse().unwrap(), name.end);offsets.insert(new_end.as_str().parse::<u64>().unwrap() + 1,name.end + 1,);}}}Ok(None)}Some(Record::FileDel {ref mut del,ref mut contents,..}) => {if let Some(edges) = parse_edges(changes, h) {if let Atom::EdgeMap(ref mut e) = del {if edges[0].flag.contains(EdgeFlags::FOLDER) {*e = EdgeMap {inode: e.inode,edges,}} else {*contents = Some(Atom::EdgeMap(EdgeMap {inode: e.inode,edges,}))}}}Ok(None)}Some(Record::FileUndel {ref mut undel,ref mut contents,..}) => {if let Some(edges) = parse_edges(changes, h) {if let Atom::EdgeMap(ref mut e) = undel {if edges[0].flag.contains(EdgeFlags::FOLDER) {*e = EdgeMap {inode: e.inode,edges,}} else {*contents = Some(Atom::EdgeMap(EdgeMap {inode: e.inode,edges,}))}}}Ok(None)}Some(Record::FileMove {ref mut del,ref mut add,..}) => {if let Some(edges) = parse_edges(changes, h) {if edges[0].flag.contains(EdgeFlags::DELETED) {*del = Atom::EdgeMap(EdgeMap {inode: del.inode(),edges,});return Ok(None);} else if let Atom::EdgeMap(ref mut add) = add {if add.edges.is_empty() {*add = EdgeMap {inode: add.inode,edges,};return Ok(None);}}} else if let Some(cap) = CONTEXT.captures(h) {if let Atom::NewVertex(ref mut c) = add {debug!("cap = {:?}", cap);c.up_context = parse_pos_vec(changes, offsets, &cap[1])?;if let Some(cap) = cap.get(7) {c.down_context = parse_pos_vec(changes, offsets, cap.as_str())?;}}}Ok(None)}Some(Record::Edit { ref mut change, .. }) => {debug!("edit {:?}", h);if h.starts_with("+ ") {if let Atom::NewVertex(ref mut change) = change {if change.start == change.end {change.start = ChangePosition(contents_.len() as u64);}text_changes::parse_line_add(h, change, contents_)}} else if h.starts_with('\\') {if let Atom::NewVertex(ref mut change) = change {if contents_[change.end.0 as usize - 1] == b'\n' {assert_eq!(change.end.0 as usize, contents_.len());contents_.pop();change.end.0 -= 1;}}} else if let Some(cap) = CONTEXT.captures(h) {if let Atom::NewVertex(ref mut c) = change {debug!("cap = {:?}", cap);c.up_context = parse_pos_vec(changes, offsets, &cap[1])?;if let Some(cap) = cap.get(7) {c.down_context = parse_pos_vec(changes, offsets, cap.as_str())?;}}} else if let Some(edges) = parse_edges(changes, h) {*change = Atom::EdgeMap(EdgeMap {inode: change.inode(),edges,});}Ok(None)}Some(Record::Replacement {ref mut change,ref mut replacement,..}) => {if h.starts_with("+ ") {if let Atom::NewVertex(ref mut repl) = replacement {if repl.start == repl.end {repl.start = ChangePosition(contents_.len() as u64);}text_changes::parse_line_add(h, repl, contents_)}} else if h.starts_with('\\') {if let Atom::NewVertex(ref mut repl) = replacement {if contents_[repl.end.0 as usize - 1] == b'\n' {assert_eq!(repl.end.0 as usize, contents_.len());contents_.pop();repl.end.0 -= 1;}}} else if let Some(cap) = CONTEXT.captures(h) {debug!("cap = {:?}", cap);if let Atom::NewVertex(ref mut repl) = replacement {repl.up_context = parse_pos_vec(changes, offsets, &cap[1])?;if let Some(cap) = cap.get(7) {repl.down_context = parse_pos_vec(changes, offsets, cap.as_str())?;}}} else if let Some(edges) = parse_edges(changes, h) {*change = Atom::EdgeMap(EdgeMap {inode: change.inode(),edges,});}Ok(None)}Some(Record::SolveNameConflict { ref mut name, .. })| Some(Record::UnsolveNameConflict { ref mut name, .. }) => {if let Some(edges) = parse_edges(changes, h) {*name = Atom::EdgeMap(EdgeMap {edges,inode: name.inode(),})}Ok(None)}Some(Record::SolveOrderConflict { ref mut change, .. }) => {if h.starts_with("+ ") {if let Atom::NewVertex(ref mut change) = change {if change.start == change.end {change.start = ChangePosition(contents_.len() as u64);}text_changes::parse_line_add(h, change, contents_)}} else if let Some(cap) = CONTEXT.captures(h) {debug!("cap = {:?}", cap);if let Atom::NewVertex(ref mut change) = change {change.up_context = parse_pos_vec(changes, offsets, &cap[1])?;if let Some(cap) = cap.get(7) {change.down_context =parse_pos_vec(changes, offsets, cap.as_str())?;}if let (Some(new_start), Some(new_end)) = (cap.get(4), cap.get(5)) {let new_start = new_start.as_str().parse::<u64>().unwrap();let new_end = new_end.as_str().parse::<u64>().unwrap();change.start = ChangePosition(contents_.len() as u64);change.end =ChangePosition(contents_.len() as u64 + new_end - new_start);offsets.insert(new_end, change.end);}}}Ok(None)}Some(Record::UnsolveOrderConflict { ref mut change, .. }) => {if let Some(edges) = parse_edges(changes, h) {if let Atom::EdgeMap(ref mut change) = change {change.edges = edges}}Ok(None)}Some(Record::ResurrectZombies { ref mut change, .. }) => {if let Some(edges) = parse_edges(changes, h) {if let Atom::EdgeMap(ref mut change) = change {change.edges = edges}}Ok(None)}None => {debug!("current = {:#?}", current);debug!("h = {:?}", h);Ok(None)}}}}}lazy_static! {static ref POS: regex::Regex = regex::Regex::new(r#"(\d+)\.(\d+)"#).unwrap();static ref EDGE: regex::Regex =regex::Regex::new(r#"\s*(?P<prev>[BFD]*):(?P<flag>[BFD]*)\s+(?P<up_c>\d+)\.(?P<up_l>\d+)\s*->\s*(?P<c>\d+)\.(?P<l0>\d+):(?P<l1>\d+)/(?P<intro>\d+)\s*"#).unwrap();}pub fn default_newvertex() -> NewVertex<Option<Hash>> {NewVertex {start: ChangePosition(0),end: ChangePosition(0),flag: EdgeFlags::empty(),up_context: Vec::new(),down_context: Vec::new(),inode: Position {change: Some(Hash::None),pos: ChangePosition(0),},}}pub fn default_edgemap() -> EdgeMap<Option<Hash>> {EdgeMap {edges: Vec::new(),inode: Position {change: Some(Hash::None),pos: ChangePosition(0),},}}pub fn has_newvertices<L>(current: &Option<Record<Option<Hash>, L>>) -> bool {match current {Some(Record::FileAdd { contents: None, .. }) | None => false,Some(rec) => rec.iter().any(|e| matches!(e, Atom::NewVertex(_))),}}pub fn parse_pos_vec(changes: &HashMap<usize, Hash>,offsets: &HashMap<u64, ChangePosition>,s: &str,) -> Result<Vec<Position<Option<Hash>>>, TextDeError> {let mut v = Vec::new();for pos in POS.captures_iter(s) {let change: usize = (&pos[1]).parse().unwrap();let pos: u64 = (&pos[2]).parse().unwrap();let pos = if change == 0 {if let Some(&pos) = offsets.get(&pos) {pos} else {debug!("inconsistent change: {:?} {:?}", s, offsets);return Err(TextDeError::MissingChange(change));}} else {ChangePosition(pos)};v.push(Position {change: change_ref(changes, change),pos,})}Ok(v)}fn change_ref(changes: &HashMap<usize, Hash>, change: usize) -> Option<Hash> {debug!("change_ref {:?} {:?}", changes, change);if change == 0 {None} else if change == 1 {Some(Hash::None)} else {Some(*changes.get(&change).unwrap())}}pub fn parse_pos(changes: &HashMap<usize, Hash>, s: &str) -> Position<Option<Hash>> {let pos = POS.captures(s).unwrap();let change: usize = (&pos[1]).parse().unwrap();let pos: u64 = (&pos[2]).parse().unwrap();Position {change: change_ref(changes, change),pos: ChangePosition(pos),}}pub fn parse_edges(changes: &HashMap<usize, Hash>, s: &str) -> Option<Vec<NewEdge<Option<Hash>>>> {debug!("parse_edges {:?}", s);let mut result = Vec::new();for edge in s.split(',') {debug!("parse edge {:?}", edge);if let Some(cap) = EDGE.captures(edge) {let previous = read_flag(cap.name("prev").unwrap().as_str());let flag = read_flag(cap.name("flag").unwrap().as_str());let change0: usize = cap.name("up_c").unwrap().as_str().parse().unwrap();let pos0: u64 = cap.name("up_l").unwrap().as_str().parse().unwrap();let change1: usize = cap.name("c").unwrap().as_str().parse().unwrap();let start1: u64 = cap.name("l0").unwrap().as_str().parse().unwrap();let end1: u64 = cap.name("l1").unwrap().as_str().parse().unwrap();let introduced_by: usize = cap.name("intro").unwrap().as_str().parse().unwrap();result.push(NewEdge {previous,flag,from: Position {change: change_ref(changes, change0),pos: ChangePosition(pos0),},to: Vertex {change: change_ref(changes, change1),start: ChangePosition(start1),end: ChangePosition(end1),},introduced_by: change_ref(changes, introduced_by),})} else {debug!("not parsed");return None;}}Some(result)}pub fn parse_line_add(h: &str, change: &mut NewVertex<Option<Hash>>, contents_: &mut Vec<u8>) {let h = h.as_bytes();debug!("parse_line_add {:?} {:?}", change.end, change.start);debug!("parse_line_add {:?}", h);if h.len() > 2 {let h = &h[2..h.len()];contents_.extend(h);} else if h.len() > 1 {contents_.push(b'\n');}debug!("contents_.len() = {:?}", contents_.len());trace!("contents_ = {:?}", contents_);change.end = ChangePosition(contents_.len() as u64);}pub fn print_contents<W: std::io::Write>(w: &mut W,pref: &str,contents: &[u8],) -> Result<(), std::io::Error> {if let Ok(mut contents) = std::str::from_utf8(&contents) {while let Some(n) = contents.as_bytes().iter().position(|&c| c == b'\n') {let (a, b) = contents.split_at(n + 1);contents = b;write!(w, "{} {}", pref, a)?;}if !contents.is_empty() {writeln!(w, "{} {}", pref, contents)?;}} else {writeln!(w, "{}b{}", pref, data_encoding::BASE64.encode(contents))?}Ok(())}pub fn print_change_contents<W: std::io::Write, C: ChangeStore>(w: &mut W,changes: &C,change: &Atom<Option<Hash>>,change_contents: &[u8],) -> Result<(), TextSerError<C::Error>> {match change {Atom::NewVertex(ref n) => {let c = &change_contents[n.start.0 as usize..n.end.0 as usize];print_contents(w, "+", c)?;if !c.ends_with(b"\n") {writeln!(w, "\\")?}Ok(())}Atom::EdgeMap(ref n) if n.edges[0].flag.contains(EdgeFlags::DELETED) => {let mut buf = Vec::new();let mut current = None;for e in n.edges.iter() {if Some(e.to) == current {continue;}buf.clear();changes.get_contents_ext(e.to, &mut buf).map_err(TextSerError::C)?;print_contents(w, "-", &buf[..])?;current = Some(e.to)}Ok(())}_ => Ok(()),}}pub fn write_deleted_names<W: std::io::Write, C: ChangeStore>(w: &mut W,changes: &C,del: &Atom<Option<Hash>>,) -> Result<(), TextSerError<C::Error>> {if let Atom::EdgeMap(ref e) = del {let mut buf = Vec::new();let mut is_first = true;for d in e.edges.iter() {buf.clear();changes.get_contents_ext(d.to, &mut buf).map_err(TextSerError::C)?;if !buf.is_empty() {let name = std::str::from_utf8(buf.split_at(2).1).unwrap();write!(w, "{}{:?}", if is_first { "" } else { ", " }, name)?;is_first = false;}}}Ok(())}pub fn write_flag<W: std::io::Write>(mut w: W, flag: EdgeFlags) -> Result<(), std::io::Error> {if flag.contains(EdgeFlags::BLOCK) {w.write_all(b"B")?;}if flag.contains(EdgeFlags::FOLDER) {w.write_all(b"F")?;}if flag.contains(EdgeFlags::DELETED) {w.write_all(b"D")?;}assert!(!flag.contains(EdgeFlags::PARENT));assert!(!flag.contains(EdgeFlags::PSEUDO));Ok(())}pub fn read_flag(s: &str) -> EdgeFlags {let mut f = EdgeFlags::empty();for i in s.chars() {match i {'B' => f |= EdgeFlags::BLOCK,'F' => f |= EdgeFlags::FOLDER,'D' => f |= EdgeFlags::DELETED,c => panic!("read_flag: {:?}", c),}}f}pub fn write_pos<W: std::io::Write>(mut w: W,hashes: &HashMap<Hash, usize>,pos: Position<Option<Hash>>,) -> Result<(), std::io::Error> {let change = if let Some(Hash::None) = pos.change {1} else if let Some(ref c) = pos.change {*hashes.get(c).unwrap()} else {0};write!(w, "{}.{}", change, pos.pos.0)?;Ok(())}pub fn write_atom<W: std::io::Write>(w: &mut W,hashes: &HashMap<Hash, usize>,atom: &Atom<Option<Hash>>,) -> Result<(), std::io::Error> {match atom {Atom::NewVertex(ref n) => write_newvertex(w, hashes, n),Atom::EdgeMap(ref n) => write_edgemap(w, hashes, n),}}pub fn write_newvertex<W: std::io::Write>(mut w: W,hashes: &HashMap<Hash, usize>,n: &NewVertex<Option<Hash>>,) -> Result<(), std::io::Error> {write!(w, " up")?;for c in n.up_context.iter() {write!(w, " ")?;write_pos(&mut w, hashes, *c)?}write!(w, ", new {}:{}", n.start.0, n.end.0)?;if !n.down_context.is_empty() {write!(w, ", down")?;for c in n.down_context.iter() {write!(w, " ")?;write_pos(&mut w, hashes, *c)?}}w.write_all(b"\n")?;Ok(())}pub fn write_edgemap<W: std::io::Write>(mut w: W,hashes: &HashMap<Hash, usize>,n: &EdgeMap<Option<Hash>>,) -> Result<(), std::io::Error> {let mut is_first = true;for c in n.edges.iter() {if !is_first {write!(w, ", ")?;}is_first = false;write_flag(&mut w, c.previous)?;write!(w, ":")?;write_flag(&mut w, c.flag)?;write!(w, " ")?;write_pos(&mut w, hashes, c.from)?;write!(w, " -> ")?;write_pos(&mut w, hashes, c.to.start_pos())?;let h = if let Some(h) = hashes.get(c.introduced_by.as_ref().unwrap()) {h} else {panic!("introduced_by = {:?}, not found", c.introduced_by);};write!(w, ":{}/{}", c.to.end.0, h)?;}writeln!(w)?;Ok(())}#[derive(Debug, Clone, PartialEq, Eq)]pub enum Section {Header(String),Deps,Changes {changes: Vec<Record<Option<Hash>, Local>>,current: Option<Record<Option<Hash>, Local>>,offsets: HashMap<u64, ChangePosition>,},} - file addition: change_file.rs[17.931000]
use super::*;/// An open, seekable change file.#[cfg(feature = "zstd")]pub struct ChangeFile<'a> {s: Option<zstd_seekable::Seekable<'a, OffFile>>,hashed: Hashed<Local>,hash: Hash,unhashed: Option<toml::Value>,}struct OffFile {f: std::fs::File,start: u64,}unsafe impl Send for OffFile {}impl std::io::Read for OffFile {fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {self.f.read(buf)}}impl std::io::Seek for OffFile {fn seek(&mut self, from: std::io::SeekFrom) -> Result<u64, std::io::Error> {use std::io::SeekFrom;let from = match from {SeekFrom::Start(s) => SeekFrom::Start(s + self.start),c => c,};self.f.seek(from)}}#[cfg(feature = "zstd")]impl<'a> ChangeFile<'a> {/// Open a change file from a path.pub fn open(hash: Hash, path: &str) -> Result<Self, ChangeError> {use std::io::Read;let mut r = std::fs::File::open(path)?;let mut buf = Vec::new();buf.resize(Change::OFFSETS_SIZE as usize, 0);r.read_exact(&mut buf)?;let offsets: Offsets = bincode::deserialize(&buf)?;if offsets.version != VERSION {return Err(ChangeError::VersionMismatch);}buf.clear();buf.resize((offsets.unhashed_off - Change::OFFSETS_SIZE) as usize, 0);r.read_exact(&mut buf)?;let mut buf2 = vec![0u8; offsets.hashed_len as usize];let hashed: Hashed<Local> = {let mut s = zstd_seekable::Seekable::init_buf(&buf)?;s.decompress(&mut buf2, 0)?;bincode::deserialize(&buf2)?};buf.resize((offsets.contents_off - offsets.unhashed_off) as usize, 0);let unhashed = if buf.is_empty() {None} else {r.read_exact(&mut buf)?;let mut s = zstd_seekable::Seekable::init_buf(&buf)?;buf2.resize(offsets.unhashed_len as usize, 0);s.decompress(&mut buf2, 0)?;Some(toml::de::from_slice(&buf2)?)};let m = r.metadata()?;let s = if offsets.contents_off >= m.len() {None} else {Some(zstd_seekable::Seekable::init(Box::new(OffFile {f: r,start: offsets.contents_off,}))?)};Ok(ChangeFile {s,hashed,hash,unhashed,})}pub fn has_contents(&self) -> bool {self.s.is_some()}/// Reads the contents at an offset into `buf`, and returns the/// number of bytes read. The bounds of the change's "contents"/// section are not checked.pub fn read_contents(&mut self, offset: u64, buf: &mut [u8]) -> Result<usize, ChangeError> {debug!("read_contents {:?} {:?}", offset, buf.len());if let Some(ref mut s) = self.s {Ok(s.decompress(buf, offset)?)} else {Err(ChangeError::MissingContents { hash: self.hash })}}pub fn hashed(&self) -> &Hashed<Local> {&self.hashed}pub fn unhashed(&self) -> &Option<toml::Value> {&self.unhashed}} - edit in libpijul/src/apply.rs at line 1
// org id g5piHODDo9cz2FFDRisMQw4h8fj1SqTfQ3I/i2p+EGc= - edit in libpijul/src/apply.rs at line 7
use crate::Error; - replacement in libpijul/src/apply.rs at line 8
// org id Fn0IzU5GRCA4xymOneQzYPhm7xvcbR8viQt+xz5AzSU=use thiserror::Error;#[derive(Debug, Error)]pub enum ApplyError<ChangestoreError: std::error::Error, TxnError: std::error::Error + 'static> {#[error("Changestore error: {0}")]Changestore(ChangestoreError),#[error("Local change error: {err}")]LocalChange {#[from]err: LocalApplyError<TxnError>,},}#[derive(Debug, Error)]pub enum LocalApplyError<TxnError: std::error::Error> {#[error("Dependency missing: {:?}", hash)]DependencyMissing { hash: crate::pristine::Hash },#[error("Change already on channel: {:?}", hash)]ChangeAlreadyOnChannel { hash: crate::pristine::Hash },#[error("Transaction error: {0}")]Txn(TxnError),#[error(transparent)]Block(#[from] crate::pristine::BlockError),#[error(transparent)]InconsistentChange(#[from] crate::pristine::InconsistentChange),}impl<TxnError: std::error::Error> LocalApplyError<TxnError> {fn from_missing(err: MissingError<TxnError>) -> Self {match err {MissingError::Txn(e) => LocalApplyError::Txn(e),MissingError::Block(e) => LocalApplyError::Block(e),MissingError::Inconsistent(e) => LocalApplyError::InconsistentChange(e),}}} - replacement in libpijul/src/apply.rs at line 55
) -> Result<(u64, Merkle), anyhow::Error> {) -> Result<(u64, Merkle), ApplyError<P::Error, T::Error>> { - replacement in libpijul/src/apply.rs at line 59
let change = changes.get_change(&hash)?;let change = changes.get_change(&hash).map_err(ApplyError::Changestore)?; - replacement in libpijul/src/apply.rs at line 70
return Err((Error::DependencyMissing { hash }).into());return Err((LocalApplyError::DependencyMissing { hash }).into()); - replacement in libpijul/src/apply.rs at line 77
register_change(txn, internal, hash, &change)?;register_change(txn, internal, hash, &change).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 81
apply_change_to_channel(txn, &mut channel, internal, &hash, &change, workspace)Ok(apply_change_to_channel(txn,&mut channel,internal,&hash,&change,workspace,)?) - replacement in libpijul/src/apply.rs at line 98
) -> Result<(), anyhow::Error> {) -> Result<(), ApplyError<P::Error, T::Error>> { - replacement in libpijul/src/apply.rs at line 106
let change = changes.get_change(&hash)?;let change = changes.get_change(&hash).map_err(ApplyError::Changestore)?; - replacement in libpijul/src/apply.rs at line 138
register_change(txn, internal, hash, &change)?;register_change(txn, internal, hash, &change).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 156
) -> Result<(u64, Merkle), anyhow::Error> {) -> Result<(u64, Merkle), ApplyError<P::Error, T::Error>> { - replacement in libpijul/src/apply.rs at line 167
) -> Result<(), anyhow::Error> {) -> Result<(), ApplyError<P::Error, T::Error>> { - replacement in libpijul/src/apply.rs at line 186
) -> Result<(u64, Merkle), anyhow::Error> {) -> Result<(u64, Merkle), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 189[17.948963]→[17.948963:948980](∅→∅),[17.948980]→[17.948980:949073](∅→∅),[17.949073]→[17.949073:949104](∅→∅),[17.949104]→[17.949104:949184](∅→∅),[17.949184]→[17.949184:949195](∅→∅)
let merkle =if let Some(m) = txn.put_changes(channel, change_id, channel.apply_counter, hash)? {m} else {return Err((Error::ChangeAlreadyOnChannel { hash: *hash }).into());};let merkle = if let Some(m) = txn.put_changes(channel, change_id, channel.apply_counter, hash).map_err(LocalApplyError::Txn)?{m} else {return Err(LocalApplyError::ChangeAlreadyOnChannel { hash: *hash });}; - replacement in libpijul/src/apply.rs at line 214
|_, _, _, _| Ok(true),|_, _, _, _| Ok::<bool, LocalApplyError<T::Error>>(true), - replacement in libpijul/src/apply.rs at line 229
Ok(true)Ok::<bool, LocalApplyError<T::Error>>(true) - edit in libpijul/src/apply.rs at line 231
// org id aNVimxa4oSqbTYJ033w2QbZTCVMG/+tO2ymc1QSWPH0= - replacement in libpijul/src/apply.rs at line 239
)?// org id hXW9eN25ZM8EQ5B2Ew8NMra+xi7hFv6CN8no+qg8GpY=).map_err(LocalApplyError::from_missing)? - replacement in libpijul/src/apply.rs at line 254
channel.last_modified = std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH)?.as_secs();if let Ok(duration) =std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH){channel.last_modified = duration.as_secs();} - replacement in libpijul/src/apply.rs at line 274
) -> Result<(u64, Merkle), anyhow::Error> {) -> Result<(u64, Merkle), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 287
return Err((Error::DependencyMissing { hash }).into());return Err((LocalApplyError::DependencyMissing { hash }).into()); - replacement in libpijul/src/apply.rs at line 290
register_change(txn, internal, hash, &change)?;register_change(txn, internal, hash, &change).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 306
) -> Result<(u64, Merkle), anyhow::Error> {) -> Result<(u64, Merkle), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 322
) -> Result<(), anyhow::Error> {) -> Result<(), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 335
put_inodes_with_rev(txn, inode, vertex)?;put_inodes_with_rev(txn, inode, vertex).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 342
del_tree_with_rev(txn, parent.as_file_id(), inode)?;del_tree_with_rev(txn, parent.as_file_id(), inode).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 352
)?;).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 355
del_inodes_with_rev(txn, inode, vertex)?;del_inodes_with_rev(txn, inode, vertex).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 369
) -> Result<(), anyhow::Error> {) -> Result<(), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 395
put_graph_with_rev(txn, channel, flag, up, vertex, *change)?;put_graph_with_rev(txn, channel, flag, up, vertex, *change).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 405
put_graph_with_rev(txn, channel, flag, up, vertex, change)?;put_graph_with_rev(txn, channel, flag, up, vertex, change).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 418
)?;).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 428
)?;).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 443
) -> Result<(), anyhow::Error> {) -> Result<(), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 459
split_block(txn, channel, k, up.pos)?split_block(txn, channel, k, up.pos).map_err(LocalApplyError::Txn)? - replacement in libpijul/src/apply.rs at line 498
) -> Result<Vertex<ChangeId>, anyhow::Error> {) -> Result<Vertex<ChangeId>, LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 515
split_block(txn, channel, k, down.pos)?split_block(txn, channel, k, down.pos).map_err(LocalApplyError::Txn)? - replacement in libpijul/src/apply.rs at line 590
// org id wwZDqGk+qPaB9Oabmhr4ziOpXgWClHLLbxpCOAo1zpI=pub(crate) fn put_newedge<T, F>(pub(crate) fn put_newedge<T, E, F>( - replacement in libpijul/src/apply.rs at line 599
) -> Result<(), anyhow::Error>) -> Result<(), E> - replacement in libpijul/src/apply.rs at line 602
F: Fn(&mut T,&mut Channel<T>,Vertex<ChangeId>,Vertex<ChangeId>,) -> Result<bool, anyhow::Error>,E: From<LocalApplyError<T::Error>>,F: Fn(&mut T, &mut Channel<T>, Vertex<ChangeId>, Vertex<ChangeId>) -> Result<bool, E>, - replacement in libpijul/src/apply.rs at line 606
ws.missing_context.load_graph(txn, channel, inode)?;ws.missing_context.load_graph(txn, channel, inode).map_err(LocalApplyError::InconsistentChange)?; - replacement in libpijul/src/apply.rs at line 617
return Err(crate::Error::InconsistentChange.into());return Err(LocalApplyError::InconsistentChange(crate::pristine::InconsistentChange {}).into(),); - replacement in libpijul/src/apply.rs at line 646
split_block(txn, channel, target, n.to.end)?;split_block(txn, channel, target, n.to.end).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 659
let del = del_graph_with_rev(txn, channel, n.previous, source, target, n_introduced_by)?;let del = del_graph_with_rev(txn, channel, n.previous, source, target, n_introduced_by).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 665
put_graph_with_rev(txn, channel, n.flag, source, target, change)?;put_graph_with_rev(txn, channel, n.flag, source, target, change).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 675
target = find_block(txn, channel, target.end_pos())?;target = find_block(txn, channel, target.end_pos()).map_err(LocalApplyError::Block)?; - replacement in libpijul/src/apply.rs at line 690
) -> Result<Vertex<ChangeId>, anyhow::Error> {) -> Result<Vertex<ChangeId>, LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 714
split_block(txn, channel, source, from.pos)?;split_block(txn, channel, source, from.pos).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 728
) -> Result<Vertex<ChangeId>, anyhow::Error> {) -> Result<Vertex<ChangeId>, LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 753
split_block(txn, channel, target, to.start)?;split_block(txn, channel, target, to.start).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 765
) -> Result<(), anyhow::Error> {) -> Result<(), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 798
) -> Result<(), anyhow::Error> {) -> Result<(), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 820
return Err(crate::Error::InconsistentChange.into());return Err((InconsistentChange {}).into()); - replacement in libpijul/src/apply.rs at line 842
put_graph_with_rev(txn, channel, EdgeFlags::PSEUDO, p, *c, ChangeId::ROOT)?;put_graph_with_rev(txn, channel, EdgeFlags::PSEUDO, p, *c, ChangeId::ROOT).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 854
) -> Result<(), anyhow::Error> {) -> Result<(), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 885
)? {).map_err(LocalApplyError::Txn)?{ - replacement in libpijul/src/apply.rs at line 896
)?).map_err(LocalApplyError::from_missing)? - replacement in libpijul/src/apply.rs at line 909
)? {).map_err(LocalApplyError::Txn)?{ - replacement in libpijul/src/apply.rs at line 921
)?).map_err(LocalApplyError::from_missing)? - replacement in libpijul/src/apply.rs at line 932
)?;).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 945
) -> Result<(), anyhow::Error> {) -> Result<(), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 947
crate::missing_context::repair_parents_of_deleted(txn, channel, &mut ws.missing_context)?;crate::missing_context::repair_parents_of_deleted(txn, channel, &mut ws.missing_context).map_err(LocalApplyError::from_missing)?; - replacement in libpijul/src/apply.rs at line 971
)?).map_err(LocalApplyError::from_missing)? - replacement in libpijul/src/apply.rs at line 996
)?).map_err(LocalApplyError::from_missing)? - replacement in libpijul/src/apply.rs at line 1016
)?).map_err(LocalApplyError::from_missing)? - replacement in libpijul/src/apply.rs at line 1036
)?).map_err(LocalApplyError::from_missing)? - replacement in libpijul/src/apply.rs at line 1042
crate::missing_context::delete_pseudo_edges(txn, channel, &mut ws.missing_context)?;crate::missing_context::delete_pseudo_edges(txn, channel, &mut ws.missing_context).map_err(LocalApplyError::from_missing)?; - replacement in libpijul/src/apply.rs at line 1054
) -> Result<(), anyhow::Error> {) -> Result<(), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 1076
) -> Result<(), anyhow::Error> {) -> Result<(), LocalApplyError<T::Error>> { - replacement in libpijul/src/apply.rs at line 1087
return Err(crate::Error::InconsistentChange.into());return Err((crate::pristine::InconsistentChange {}).into()); - replacement in libpijul/src/apply.rs at line 1112
)?;).map_err(LocalApplyError::Txn)?; - replacement in libpijul/src/apply.rs at line 1123
) -> Result<bool, crate::Error> {) -> Result<bool, LocalApplyError<T::Error>> { - replacement in libpijul/src/alive/retrieve.rs at line 113
) -> Result<(), anyhow::Error> {) -> Result<(), T::Error> { - edit in libpijul/src/alive/output.rs at line 1
// org id rugGQSda+7h3fgWnFg5o6rrh0FxPthevqf1C7yFpDXo= - edit in libpijul/src/alive/output.rs at line 4
use crate::output::FileError; - replacement in libpijul/src/alive/output.rs at line 8
// org id 83qmEYXouVuMdaYiRx+rqfb1HtaYFvovt7XmeQIpuuI= - edit in libpijul/src/alive/output.rs at line 15
- replacement in libpijul/src/alive/output.rs at line 24
) -> Result<(), anyhow::Error> {) -> Result<(), FileError<P::Error>> { - edit in libpijul/src/alive/output.rs at line 32
// org id OQlVwkimOiJb/Ruz+/oEO0Pz1khIxRkvwN+/W8om9Nc= - edit in libpijul/src/alive/output.rs at line 34
// org id roGnEVojWYAOJ0zF3ObAAA8Kuqfjs3on9NNRV0mgRIc= - replacement in libpijul/src/alive/output.rs at line 50
// org id GmZmOnTyQotgknRlrewBJc6+O1mQfhuF2lNOYlgkys4= - replacement in libpijul/src/alive/output.rs at line 77
// org id TAF52f6cZFJyHIBx5wfYk6RR2l7NG8tOHboIyrGFakc= - replacement in libpijul/src/alive/output.rs at line 89
// org id U/M8FDWU06DAEBXf7bvPvuN33e6GPJLmgvUK84CFuJg= - replacement in libpijul/src/alive/output.rs at line 131
// org id 4fCwUx872WHp3z4W0/WwwMhX1cFRa2iPigNaXNpaEpA= - replacement in libpijul/src/alive/output.rs at line 138
) -> Result<(), anyhow::Error> {) -> Result<(), FileError<P::Error>> { - replacement in libpijul/src/alive/output.rs at line 140
vbuf.begin_cyclic_conflict()?vbuf.begin_cyclic_conflict()?; - edit in libpijul/src/alive/output.rs at line 151
let now = std::time::Instant::now(); - replacement in libpijul/src/alive/output.rs at line 152
changes.get_contents(|p| txn.get_external(p), vertex, buf)?;Ok(())let now = std::time::Instant::now();let result = changes.get_contents(|p| txn.get_external(p), vertex, buf).map(|_| ()).map_err(FileError::Changestore);crate::TIMERS.lock().unwrap().alive_contents += now.elapsed();result - edit in libpijul/src/alive/output.rs at line 160
crate::TIMERS.lock().unwrap().alive_contents += now.elapsed(); - replacement in libpijul/src/alive/output.rs at line 176
// org id RA5o6M3qAtAD3/CSapAI6tIWd7yWNmsb/uCKXtvMf6c= - replacement in libpijul/src/alive/output.rs at line 184
) -> Result<(), anyhow::Error> {) -> Result<(), crate::output::FileError<P::Error>> { - edit in libpijul/src/alive/mod.rs at line 1
// org id ae+cN7ii/nf6mJV7ygVX+QzaT1iUIKfCuf/x9VMpjjQ= - replacement in libpijul/src/alive/mod.rs at line 10
// org id ccK061RVWq8mU8p92w938EIRcX5xf53Y/5klJaCYV5c= - replacement in libpijul/src/alive/mod.rs at line 29
// org id vnQ9DifkEHpAgUd3zjGq5N9u+oBkZGdVua6BJxF9jTg= - replacement in libpijul/src/alive/mod.rs at line 75
// org id SzNAy0qgvhYjwiibrE05FzjomcwRYrc00kLuPE6TWsA= - replacement in libpijul/src/alive/mod.rs at line 86
// org id IhdHg3+NO19nL+0XTy56j0KXgReFfEe/3TjQW3vU47s= - edit in libpijul/src/alive/mod.rs at line 128
// org id YjNtUksz6F4FDjsnoWIdFtsnyqrhhwGB81kMPoQh1y0= - edit in libpijul/src/alive/dfs.rs at line 1
// org id FN4X/UQj4sOrdr1L/34stLjMnN7aRX6dGB8ovnXm4g4= - replacement in libpijul/src/alive/dfs.rs at line 5
// org id a6g8r8xMc72herurxBoGK09TlqlNFesqMxOlGye7+wU= - replacement in libpijul/src/alive/dfs.rs at line 28
// org id Evvo1XwskiRIPyqRTa8pr3UJx6bL0a0ky0UqCjDbj7k= - replacement in libpijul/src/alive/dfs.rs at line 48
// org id rs9ua+JLr5uzyFxLi79zXVVGmVsbPAbn4+J7Pz+itfQ= - edit in libpijul/src/alive/dfs.rs at line 52
// org id 1jLjvnQC+CzGcbSN/yGdM+O7tiu5ytCDkvQ7ddM/K8s= - edit in libpijul/src/alive/dfs.rs at line 53
// org id ops5Ku702mQyuAsCratzGLyafN90+9XdMoqHYonqqiY= - edit in libpijul/src/alive/dfs.rs at line 54
// org id I6sttXHyuv42p25LtpQ6rm+GHXz6XX3RSkXdPtw++rs= - edit in libpijul/src/alive/dfs.rs at line 55
// org id tLdXR6Nj0fAJXI2MuYhja197v7oPjfGj5UsZwSsPFfc= - replacement in libpijul/src/alive/dfs.rs at line 57
// org id ZKZCQZOOiAuzQ2hplUivR12avMGPrw2HbcBPp1dM96U= - edit in libpijul/src/alive/dfs.rs at line 148
// org id fTBj4yfBA4uziK5nATQHePJ03VSVY5lNtqx3jpU4djc= - edit in libpijul/src/alive/dfs.rs at line 156
// org id GWpsS0aAAfDTvTAz0PS0OxCQeAXMwg/YHlEzPlHN6OA= - edit in libpijul/src/alive/dfs.rs at line 185
// org id +IS4jNPNEDK5HDBm4U7DLoNFfhwvHzn40JAm4tKnBHk= - edit in libpijul/src/alive/dfs.rs at line 199
// org id FHiJPM0yAi0g9oxzzog93HBlJMVO+zkyPcyOIqCcvwI= - replacement in libpijul/src/alive/dfs.rs at line 202
// org id iFf2gT1lTCyh5S5G9chCOQSV/yv6LUhW94o0G2+xy8s= - edit in libpijul/src/alive/dfs.rs at line 210
// org id +ptaxUWOVF6qdFxwHAnI2hr3kJfCBRh7am0SWZ+zdOg= - edit in libpijul/src/alive/dfs.rs at line 213
// org id gf22ooM9FpFRowUF1cPE6ISPMkymBIWZOjPS3Y1ktgQ= - edit in libpijul/src/alive/dfs.rs at line 218
// org id I/pQaV+bTryz+byZO/sdFhxqPD1EYTVf6PbC+JNJFTM= - edit in libpijul/src/alive/dfs.rs at line 225
// let mut f = std::fs::File::create("debug_alive").unwrap();// graph.debug_raw(&mut f).unwrap(); - edit in libpijul/src/alive/dfs.rs at line 238
// org id tppibf8fu/NgBP2gA4yEeGMCsZjARmQ3FsU1mfY8/VY= - replacement in libpijul/src/alive/dfs.rs at line 246
// org id PAb27lKMvw3ODopZ9ed0R1+VLBapBvGicfts0Qfgoyk= - replacement in libpijul/src/alive/dfs.rs at line 263
// org id +EtEUqu55ysMiPbQtSxlpzsP1Ghbgr/qJg/w1dYu0Tw= - edit in libpijul/src/alive/dfs.rs at line 273
// org id UnhSWIMI7GsPiN8g1SS8LsKzx++g5mrRn7+M1c+VfV4= - edit in libpijul/src/alive/dfs.rs at line 274
// org id Bd49Fx5qUr95VSDjZvf4LiwAmliSU/tlBb1NId/a1H8= - edit in libpijul/src/alive/dfs.rs at line 280
// org id Kh9EOwJWoqxbWMdM/TBylYAtuhQKoDTzX9am56rGfAU= - edit in libpijul/src/alive/dfs.rs at line 283
// org id eDtZjLZ89YmK+LQZwf0JXAHwC8hahJ+UmZGJJY9FPyw= - edit in libpijul/src/alive/dfs.rs at line 293
// org id X+Vkv6E9j5wcfbqV6wd0zJcU5h4pk/xoB0fNy+jTt1w= - edit in libpijul/src/alive/dfs.rs at line 300
// org id Jzso6NctQ7yQrJvt+kp4n6+R+C/j21VYuljDPYbovE0= - edit in libpijul/src/alive/dfs.rs at line 302
// org id XJWvAQc9UuYzztlyavXZtb9f5v+8Q3s9dKVWBgc9Cnc= - replacement in libpijul/src/alive/dfs.rs at line 315
// org id 99XChhgQdUuM9P0XMZXaiLSvZkshZYwisljAQKwv5ZA= - edit in libpijul/src/alive/dfs.rs at line 327
// org id t4p2vXw81IHi1A61czKB1ySau+YllpLXCs+03dU030Q= - edit in libpijul/src/alive/dfs.rs at line 330
// org id XkcQPnFnid03vRjpdNnv8fkp8TtbYYOh0VE3JOtW6xw= - edit in libpijul/src/alive/dfs.rs at line 345
// org id qQ8ru9vhgn8xaCAW63XcBxFqrHy0K6dYJZQWCeoXNMA= - replacement in libpijul/src/alive/dfs.rs at line 357
// org id LsKadSAjaUm19infXAsCqtTnGC1RMQq6d6h3WfZwioo= - edit in libpijul/src/alive/dfs.rs at line 374
// org id duMgQ0jpJDLTmJMPqpgkKy6QBJyDJpNZzOsgqHhs/EI= - edit in libpijul/src/alive/debug.rs at line 1
// org id rTQeEfoXKaEkHQXFyQtWhOFf2crR1lhKU0pRUjLxfb0= - replacement in libpijul/src/alive/debug.rs at line 18
) -> Result<(), anyhow::Error> {) -> Result<(), std::io::Error> { - replacement in libpijul/src/alive/debug.rs at line 35
changes.get_contents(|h| txn.get_external(h), line.vertex, &mut buf)?;changes.get_contents(|h| txn.get_external(h), line.vertex, &mut buf).unwrap(); - replacement in libpijul/src/alive/debug.rs at line 136
pub fn debug_raw<W: Write>(&self, mut w: W) -> Result<(), anyhow::Error> {pub fn debug_raw<W: Write>(&self, mut w: W) -> Result<(), std::io::Error> { - edit in libpijul/Cargo.toml at line 99
anyhow = "1.0" - edit in Cargo.lock at line 968
"anyhow",