Adding a root inode (aka supporting submodules)
Dependencies
- [2]
GBX4AFASCollecting conflicts in output (broken by parallel output) - [3]
RUBSM5DRFixing a bug when outputting changes in text format - [4]
SAADQM3HFiner-grained detection of metadata on Windows - [5]
OQQ4TGEMPrinting modifications only once in pijul diff - [6]
V6J6DTJCDo not compute the entire diff if all we want is --json --untracked - [7]
7KNPYIDUSplitting the WorkingCopy trait into a read-only record and a read/write output - [8]
KJOOI346Cleanup and formatting - [9]
2VXTRPO4Custom diff separators - [10]
HOTQHK5UFixing tests - [11]
LLT3GY6UWhen recording, do not consider deleted filenames as current - [12]
VYHHOEYHVersions and formatting - [13]
3S6LU2U5abstract out FileMetadata (de)serialistion - [14]
C4MJ7D7QVerbose printing of conflicts to stderr - [15]
2RXOCWUWMaking libpijul deterministic (and getting rid of `rand`) - [16]
RRCSHAYZFormatting - [17]
XR7MNOMUfile encoding in updates - [18]
BXD3IQYNFixing --features git - [19]
3KRGVQFUDo not update the mtime of unmodified files - [20]
ZHABNS3SCanonicalize all paths - [21]
246V5TYIdecode existing files - [22]
AJEH3FSPProperly propagate errors in `libpijul::record::record` instead of unwrap()ing - [23]
6YMDOZIBRefactoring apply - [24]
5BRU2RRWCleanup (debugging a crash related to trees/inodes) - [25]
GHO6DWPIRefactoring iterators - [26]
GJZWSXHQDo not remove files not tracked in the new channel when outputting - [27]
27PYHR6LMaking the get_latest_touch function (useful to make archives) public in libpijul - [28]
3AMEP2Y5More convenient interface for channels - [29]
P6WE7YKLUnrecord did not check whether a file already existed before adding it back - [30]
YN63NUZOSanakirja 1.0 - [31]
BD5PC25ADeleting conflict resolution vertices when the sides are deleted - [32]
TVVW53HZConflict resolution - [33]
VO5OQW4WRemoving anyhow in libpijul - [34]
3I4PAA2AMaking a few types and methods public - [35]
DJYHARZ7Skipping old files when recording - [36]
SXEYMYF7Fixing the bad changes in history (unfortunately, by rebooting). - [37]
VNBLGT6GDo not output unmodified files when resetting (fix) - [38]
MDADYULSFix a panic when switching between channels that have different files - [39]
G6S6PWZEDo not touch the channel if this is a partial record - [40]
I52XSRUHMassive cleanup, and simplification - [41]
CCLLB7OIUpgrading to Sanakirja 0.15 + version bump - [42]
WZVCLZKYaddress clippy lints - [43]
IIV3EL2XCleanup, formatting, and fixing the Git feature - [44]
NUAOEIXMAdding inode and byte to Local - [45]
CCFJ7VO3Renaming "Record" to "Hunk" in the changes - [46]
XA23FMQMReset only files that have been modified - [47]
YCEZL7VFMoving to temporary paths when outputting - [48]
I24UEJQLVarious post-fire fixes - [49]
PKIHBUGTSetting the oldest modification time to EPOCH if no file has changed - [50]
FXEDPLRIResurrecting tests, and type cleanup (no need for Arc<RwLock<…>> anymore) - [51]
ADPAFSMYProper old metadata when recording - [52]
ZSF3YFZTencoded file deletion - [53]
LGEJSLTYFixing output (including its uses in reset and pull) - [54]
ZAEUSICJFile deletions were not shown with their names in the metadata during record - [55]
NYOF5766track file encoding in the record, including change text for file adds - [56]
LERRJNFCFixing the text change version of "FileMove" to include the former path - [*]
O4DNWMPDCleaunp and proofreading of libpijul::record
Change contents
- edit in "pijul/src/commands/diff.rs" at line 152
Hunk::AddRoot { .. } => "root",Hunk::DelRoot { .. } => "unroot", - edit in "pijul/src/commands/diff.rs" at line 202
Hunk::AddRoot { .. } | Hunk::DelRoot { .. } => true - edit in "libpijul/src/unrecord/working_copy.rs" at line 62
debug!("source = {:?}, dest = {:?}", source, dest); - replacement in "libpijul/src/unrecord/working_copy.rs" at line 93
stack.push((source, dest));stack.push((grandparent, source_parent));if grandparent.is_root() || grandparent.start == grandparent.end {return_value = restore_inode(txn, changes, source, dest, Inode::ROOT, salt)?;} else {stack.push((source, dest));stack.push((grandparent, source_parent));} - replacement in "libpijul/src/tests/add_file.rs" at line 56
let (key, _, name) = it.next().unwrap().unwrap();let key_ = get_inode_vertex(&txn, &channel.graph, Position::ROOT)?;assert_eq!(key, key_);let (_, _, name) = it.next().unwrap().unwrap(); - replacement in "libpijul/src/tests/add_file.rs" at line 846
let txn = env.arc_txn_begin().unwrap();let env2 = pristine::sanakirja::Pristine::new_anon()?;let txn = env2.arc_txn_begin().unwrap(); - edit in "libpijul/src/tests/add_file.rs" at line 860
{let txn_ = txn.write();let mut f = std::fs::File::create("add_file2.dot")?;crate::pristine::debug(&*txn_, &txn_.graph(&*channel.read()), &mut f)?;} - edit in "libpijul/src/tests/add_file.rs" at line 866
// Check that there's a name conflict.assert_eq!(repo.list_files().len(), 8); - edit in "libpijul/src/record.rs" at line 73
new_root: Arc<Mutex<Option<ChangePosition>>>, - edit in "libpijul/src/record.rs" at line 106
new_root: Arc<Mutex<Option<ChangePosition>>>, - edit in "libpijul/src/record.rs" at line 118
new_root: Arc::new(Mutex::new(None)), - edit in "libpijul/src/record.rs" at line 147
new_root: self.new_root.clone(), - replacement in "libpijul/src/record.rs" at line 346
info!("Starting to record"); - edit in "libpijul/src/record.rs" at line 355
let mut root_vertices = Vec::new(); - edit in "libpijul/src/record.rs" at line 361[11.493385]→[11.493385:493422](∅→∅),[11.493422]→[11.47069:47097](∅→∅),[11.47127]→[11.493422:493487](∅→∅),[11.493422]→[11.493422:493487](∅→∅)
self.recorded_inodes.lock().insert(Inode::ROOT, Position::OPTION_ROOT); - replacement in "libpijul/src/record.rs" at line 365[11.97005]→[11.47316:47351](∅→∅),[11.47316]→[11.47316:47351](∅→∅),[11.47351]→[11.493487:493534](∅→∅),[11.493487]→[11.493487:493534](∅→∅),[11.493534]→[11.47352:47420](∅→∅),[11.47420]→[11.97006:97040](∅→∅),[11.47463]→[11.0:29](∅→∅),[11.97040]→[11.0:29](∅→∅),[11.493623]→[11.0:29](∅→∅),[11.29]→[11.493623:493660](∅→∅),[11.493623]→[11.493623:493660](∅→∅),[11.493660]→[11.493660:493696](∅→∅),[11.493696]→[11.32844:32864](∅→∅),[11.32864]→[11.493715:493753](∅→∅),[11.493715]→[11.493715:493753](∅→∅)
debug!("TAKEN 2");self.delete_obsolete_children(&*txn,txn.graph(&channel),working_copy,changes,&item.full_path,Position::ROOT,)?;Position::OPTION_ROOT// Test for a "root" vertex below the 0 one.let f0 = EdgeFlags::FOLDER | EdgeFlags::BLOCK;let f1 = f0 | EdgeFlags::PSEUDO;self.recorded_inodes.lock().insert(Inode::ROOT, Position::ROOT.to_option());let mut has_nonempty_root = false;for e in iter_adjacent(&*txn, txn.graph(&*channel), Vertex::ROOT, f0, f1)? {let e = e?;let child = txn.find_block(txn.graph(&*channel), e.dest()).unwrap();if child.start == child.end {let grandchild =iter_adjacent(&*txn, txn.graph(&*channel), *child, f0, f1)?.next().unwrap()?.dest();root_vertices.push(grandchild);self.delete_obsolete_children(&*txn,txn.graph(&channel),working_copy,changes,&item.full_path,grandchild,)?;} else {has_nonempty_root = true}}if has_nonempty_root && !root_vertices.is_empty() {// This repository is mixed between "zero" roots,// and new-style-roots.root_vertices.push(Position::ROOT)}Position::ROOT.to_option() - replacement in "libpijul/src/record.rs" at line 444[11.495196]→[11.495196:495237](∅→∅),[11.495237]→[11.49041:49088](∅→∅),[11.49088]→[11.97574:97652](∅→∅),[11.49184]→[11.11697:11740](∅→∅),[11.97652]→[11.11697:11740](∅→∅),[11.495237]→[11.11697:11740](∅→∅),[11.11740]→[11.49185:49235](∅→∅),[11.49235]→[11.97653:97683](∅→∅),[11.49274]→[11.495346:495373](∅→∅),[11.97683]→[11.495346:495373](∅→∅),[11.495346]→[11.495346:495373](∅→∅),[11.495373]→[11.49275:49308](∅→∅),[11.49308]→[11.495373:495449](∅→∅),[11.495373]→[11.495373:495449](∅→∅),[11.495449]→[11.1585:1610](∅→∅),[11.1610]→[11.495449:495465](∅→∅),[11.495449]→[11.495449:495465](∅→∅)
// Move on to the next step.debug!("TAKING LOCK {}", line!());let txn = txn.read();let channel = channel.r.read();self.push_children::<_, _, C>(&*txn,&*channel,working_copy,&mut item,&mut components,vertex,&mut stack,prefix,changes,)?;if root_vertices.is_empty() {// Move on to the next step.debug!("TAKING LOCK {}", line!());let txn = txn.read();let channel = channel.r.read();self.push_children::<_, _, C>(&*txn,&*channel,working_copy,&mut item,&mut components,vertex,&mut stack,prefix,changes,)?;} else {for vertex in root_vertices {let txn = txn.read();let channel = channel.r.read();self.push_children::<_, _, C>(&*txn,&*channel,working_copy,&mut item,&mut components,vertex.to_option(),&mut stack,prefix,changes,)?;}} - edit in "libpijul/src/record.rs" at line 547
if child.start == child.end {// This is an empty name, i.e. the grandchild is a root vertex.continue;} - replacement in "libpijul/src/record.rs" at line 617
debug!("push_children, item = {:?}", item);debug!("push_children, vertex = {:?}, item = {:?}", vertex, item); - replacement in "libpijul/src/record.rs" at line 628
if fileid_.parent_inode < fileid.parent_inode || fileid_.basename.is_empty() {assert!(fileid_.parent_inode >= fileid.parent_inode);if fileid_.basename.is_empty() { - edit in "libpijul/src/record.rs" at line 648
debug!("full_path = {:?}, meta = {:?}", full_path, meta); - edit in "libpijul/src/record.rs" at line 677
debug!("push_children done"); - edit in "libpijul/src/record.rs" at line 706
fn add_root_if_needed(&mut self,v_papa: Position<Option<ChangeId>>,) -> Position<Option<ChangeId>> {let mut contents = self.contents.lock();if v_papa.change == Some(ChangeId::ROOT) {let mut new_root = self.new_root.lock();if let Some(pos) = *new_root {Position { change: None, pos }} else {contents.push(0);let pos = ChangePosition(contents.len().into());contents.push(0);let pos2 = ChangePosition(contents.len().into());contents.push(0);self.actions.push(Hunk::FileAdd {add_name: Atom::NewVertex(NewVertex {up_context: vec![v_papa],down_context: vec![],start: pos2,end: pos2,flag: EdgeFlags::FOLDER | EdgeFlags::BLOCK,inode: v_papa,}),add_inode: Atom::NewVertex(NewVertex {up_context: vec![Position {change: None,pos: pos2,}],down_context: vec![],start: pos,end: pos,flag: EdgeFlags::FOLDER | EdgeFlags::BLOCK,inode: v_papa,}),contents: None,path: "/".to_string(),encoding: None,});*new_root = Some(pos);Position { change: None, pos }}} else {v_papa}} - edit in "libpijul/src/record.rs" at line 760
// If we're inserting at the root, add an extra "root// directory" empty vertex.let item_v_papa = self.add_root_if_needed(item.v_papa); - replacement in "libpijul/src/record.rs" at line 812
up_context: vec![item.v_papa],up_context: vec![item_v_papa], - replacement in "libpijul/src/record.rs" at line 872
"record_existing_file {:?}: {:?} {:?}",item.full_path, item.inode, vertex"record_existing_file {:?}: {:?} {:?} {:?}",item.full_path, item.inode, vertex, new_papa, - edit in "libpijul/src/record.rs" at line 876[11.499882]→[11.58136:58181](∅→∅),[11.58181]→[11.499919:500045](∅→∅),[11.499919]→[11.499919:500045](∅→∅)
let mut former_parents = Vec::new();let f0 = EdgeFlags::FOLDER | EdgeFlags::PARENT;let f1 = EdgeFlags::all();let mut is_deleted = true; - replacement in "libpijul/src/record.rs" at line 878[11.98198]→[11.58270:58442](∅→∅),[11.58270]→[11.58270:58442](∅→∅),[11.58442]→[11.49753:49796](∅→∅),[11.1378]→[11.49753:49796](∅→∅),[11.1378]→[11.33350:33382](∅→∅),[11.28511]→[11.33350:33382](∅→∅),[11.49796]→[11.33350:33382](∅→∅),[11.33350]→[11.33350:33382](∅→∅),[11.33382]→[11.49797:49892](∅→∅),[11.49892]→[11.33439:33479](∅→∅),[11.33439]→[11.33439:33479](∅→∅),[11.33479]→[11.49893:49952](∅→∅),[11.49952]→[11.500308:500452](∅→∅),[11.500308]→[11.500308:500452](∅→∅),[11.500452]→[11.58443:58546](∅→∅),[11.58546]→[11.6515:6542](∅→∅),[11.6515]→[11.6515:6542](∅→∅),[11.6542]→[11.2008:2180](∅→∅),[11.2180]→[11.361:393](∅→∅),[11.361]→[11.361:393](∅→∅),[11.393]→[11.1397:1469](∅→∅),[11.1469]→[11.6645:6677](∅→∅),[11.58619]→[11.6645:6677](∅→∅),[11.6645]→[11.6645:6677](∅→∅),[11.6677]→[11.2181:2212](∅→∅),[11.2212]→[11.6708:6726](∅→∅),[11.6708]→[11.6708:6726](∅→∅),[11.6726]→[11.11969:12022](∅→∅),[11.33653]→[11.11969:12022](∅→∅),[11.50149]→[11.11969:12022](∅→∅),[11.11969]→[11.11969:12022](∅→∅),[11.500855]→[11.773:905](∅→∅),[11.905]→[11.58620:58744](∅→∅),[11.50251]→[11.495:509](∅→∅),[11.58744]→[11.495:509](∅→∅),[11.495]→[11.495:509](∅→∅),[11.509]→[11.33752:33790](∅→∅),[11.1571]→[11.33752:33790](∅→∅),[11.28702]→[11.33752:33790](∅→∅),[11.33752]→[11.33752:33790](∅→∅),[11.33790]→[11.50252:50317](∅→∅),[11.50317]→[11.1470:1519](∅→∅),[11.1519]→[11.394:450](∅→∅),[11.204]→[11.394:450](∅→∅),[11.450]→[11.238:272](∅→∅),[11.238]→[11.238:272](∅→∅),[11.272]→[11.2213:2247](∅→∅),[11.2247]→[11.50318:50377](∅→∅),[11.272]→[11.50318:50377](∅→∅),[11.50377]→[11.329:370](∅→∅),[11.329]→[11.329:370](∅→∅),[11.370]→[11.501198:501222](∅→∅),[11.501198]→[11.501198:501222](∅→∅)
for name_ in iter_adjacent(&*txn_,txn_.graph(&*channel_),vertex.inode_vertex(),f0,f1,)? {debug!("name_ = {:?}", name_);let name_ = name_?;if !name_.flag().contains(EdgeFlags::PARENT) {debug!("continue");continue;}if name_.flag().contains(EdgeFlags::DELETED) {debug!("is_deleted {:?}: {:?}", item.full_path, name_);is_deleted = true;break;}let name_dest = txn_.find_block_end(txn_.graph(&*channel_), name_.dest()).unwrap();let mut meta = Vec::new();let FileMetadata {basename,metadata,encoding,} = changes.get_file_meta(|p| txn_.get_external(&p).unwrap().map(From::from),*name_dest,&mut meta,).map_err(RecordError::Changestore)?;debug!("former basename of {:?}: {:?} {:?}",vertex, basename, metadata);if let Some(v_papa) =iter_adjacent(&*txn_, txn_.graph(&*channel_), *name_dest, f0, f1)?.next(){let v_papa = v_papa?;if !v_papa.flag().contains(EdgeFlags::DELETED) {former_parents.push(Parent {basename: basename.to_string(),metadata,encoding,parent: v_papa.dest().to_option(),})}}}let (former_parents, is_deleted) =collect_former_parents::<C, W, T>(changes, &*txn_, &*channel_, vertex)?; - replacement in "libpijul/src/record.rs" at line 886[11.501478]→[11.501478:501527](∅→∅),[11.501527]→[11.58888:59113](∅→∅),[11.59113]→[11.501772:501816](∅→∅),[11.501772]→[11.501772:501816](∅→∅),[11.501939]→[11.501939:501992](∅→∅),[11.501992]→[11.33791:33842](∅→∅),[11.33842]→[11.502032:502061](∅→∅),[11.502032]→[11.502032:502061](∅→∅),[11.502061]→[11.59114:59142](∅→∅),[11.59142]→[11.538:570](∅→∅),[11.570]→[11.502116:502171](∅→∅),[11.1612]→[11.502116:502171](∅→∅),[11.28742]→[11.502116:502171](∅→∅),[11.33879]→[11.502116:502171](∅→∅),[11.59186]→[11.502116:502171](∅→∅),[11.502116]→[11.502116:502171](∅→∅),[11.502171]→[11.59187:59226](∅→∅),[11.59226]→[11.1521:1521](∅→∅),[11.1521]→[11.1522:1578](∅→∅),[11.1578]→[11.33880:33899](∅→∅),[11.2309]→[11.33880:33899](∅→∅),[11.59226]→[11.33880:33899](∅→∅),[11.502254]→[11.33880:33899](∅→∅),[11.12093]→[11.502273:502359](∅→∅),[11.33899]→[11.502273:502359](∅→∅),[11.502273]→[11.502273:502359](∅→∅),[11.502359]→[11.59227:59346](∅→∅),[11.59346]→[11.98199:98238](∅→∅),[11.59393]→[11.452:517](∅→∅),[11.98238]→[11.452:517](∅→∅),[11.452]→[11.452:517](∅→∅),[11.517]→[11.502452:502466](∅→∅),[11.1500]→[11.502452:502466](∅→∅),[11.28844]→[11.502452:502466](∅→∅),[11.502452]→[11.502452:502466](∅→∅),[11.502466]→[11.59394:59475](∅→∅),[11.1773]→[11.502529:502569](∅→∅),[11.28918]→[11.502529:502569](∅→∅),[11.33970]→[11.502529:502569](∅→∅),[11.59475]→[11.502529:502569](∅→∅),[11.502529]→[11.502529:502569](∅→∅),[11.502569]→[11.73:117](∅→∅),[11.117]→[11.1102:1160](∅→∅),[11.12123]→[11.1102:1160](∅→∅),[11.1160]→[11.12179:12236](∅→∅),[11.12179]→[11.12179:12236](∅→∅),[11.12236]→[11.502635:502673](∅→∅),[11.502635]→[11.502635:502673](∅→∅),[11.502673]→[11.59476:59522](∅→∅),[11.59522]→[11.502723:502779](∅→∅),[11.502723]→[11.502723:502779](∅→∅),[11.502779]→[11.59523:59583](∅→∅),[11.59583]→[11.502834:502914](∅→∅),[11.502834]→[11.502834:502914](∅→∅),[11.502914]→[11.58:90](∅→∅),[11.90]→[11.502914:503008](∅→∅),[11.502914]→[11.502914:503008](∅→∅),[11.503008]→[11.118:149](∅→∅),[11.149]→[9.274:304](∅→∅),[11.149]→[11.503008:503028](∅→∅),[9.304]→[11.503008:503028](∅→∅),[11.503008]→[11.503008:503028](∅→∅),[11.503028]→[11.59584:59630](∅→∅),[11.59630]→[11.1551:1644](∅→∅),[11.1551]→[11.1551:1644](∅→∅),[11.1644]→[11.59631:59780](∅→∅),[11.59780]→[11.224:257](∅→∅),[11.224]→[11.224:257](∅→∅),[11.257]→[11.59781:59869](∅→∅),[11.59869]→[11.353:379](∅→∅),[11.353]→[11.353:379](∅→∅),[11.379]→[11.1736:1776](∅→∅),[11.1736]→[11.1736:1776](∅→∅),[11.1776]→[11.2801:2878](∅→∅),[11.503028]→[11.2801:2878](∅→∅),[11.2878]→[11.59870:59956](∅→∅),[11.59956]→[11.2972:2991](∅→∅),[11.2972]→[11.2972:2991](∅→∅),[11.2991]→[11.503104:503118](∅→∅),[11.503104]→[11.503104:503118](∅→∅)
debug!("new_meta = {:?}", new_meta);if former_parents.len() > 1|| former_parents[0].basename != item.basename|| former_parents[0].metadata != item.metadata|| former_parents[0].parent != item.v_papa|| is_deleted{debug!("new_papa = {:?}", new_papa);self.record_moved_file::<_, _, W>(changes,&*txn_,&*channel_,&item,vertex,new_papa.unwrap(),former_parents[0].encoding.clone(),)?}if new_meta.is_file()&& (self.force_rediff|| modified_since_last_commit(&*txn_,&*channel_,&working_copy,&item.full_path,)?){let mut ret = retrieve(&*txn_, txn_.graph(&*channel_), vertex)?;let mut b = Vec::new();let encoding = working_copy.decode_file(&item.full_path, &mut b).map_err(RecordError::WorkingCopy)?;debug!("diffing…");let len = self.actions.len();self.diff(changes,&*txn_,&*channel_,diff_algorithm,item.full_path.clone(),item.inode,vertex.to_option(),&mut ret,&b,&encoding,diff_sep,)?;if self.actions.len() > len {if let Ok(last_modified) = working_copy.modified_time(&item.full_path) {if self.oldest_change == std::time::SystemTime::UNIX_EPOCH {self.oldest_change = last_modified;} else {self.oldest_change = self.oldest_change.min(last_modified);}}}debug!("new actions: {:?}, total {:?}",&self.actions.len() - len,self.actions.len());}self.record_nondeleted(&*txn_,diff_algorithm,diff_sep,&*channel_,working_copy,changes,item,new_papa,vertex,new_meta,&former_parents,is_deleted,)? - edit in "libpijul/src/record.rs" at line 908
changes,)?}Ok(())}fn record_nondeleted<T: ChannelTxnT + TreeTxnT<TreeError = <T as GraphTxnT>::GraphError>,W: WorkingCopyRead + Clone,C: ChangeStore,>(&mut self,txn: &T,diff_algorithm: diff::Algorithm,diff_sep: ®ex::bytes::Regex,channel: &T::Channel,working_copy: W,changes: &C,item: &RecordItem,new_papa: Option<Position<Option<ChangeId>>>,vertex: Position<ChangeId>,new_meta: InodeMetadata,former_parents: &[Parent],is_deleted: bool,) -> Result<(), RecordError<C::Error, W::Error, T::GraphError>>where<W as crate::working_copy::WorkingCopyRead>::Error: 'static,{if former_parents.len() > 1|| former_parents[0].basename != item.basename|| former_parents[0].metadata != item.metadata|| former_parents[0].parent != item.v_papa|| is_deleted{debug!("new_papa = {:?}", new_papa);self.record_moved_file::<_, _, W>( - edit in "libpijul/src/record.rs" at line 945
txn,channel,&item,vertex,new_papa.unwrap(),former_parents[0].encoding.clone(), - edit in "libpijul/src/record.rs" at line 952
}if new_meta.is_file()&& (self.force_rediff|| modified_since_last_commit(txn, channel, &working_copy, &item.full_path)?){let mut ret = retrieve(txn, txn.graph(channel), vertex)?;let mut b = Vec::new();let encoding = working_copy.decode_file(&item.full_path, &mut b).map_err(RecordError::WorkingCopy)?;debug!("diffing…");let len = self.actions.len();self.diff(changes,txn,channel,diff_algorithm,item.full_path.clone(),item.inode,vertex.to_option(),&mut ret,&b,&encoding,diff_sep,)?;if self.actions.len() > len {if let Ok(last_modified) = working_copy.modified_time(&item.full_path) {if self.oldest_change == std::time::SystemTime::UNIX_EPOCH {self.oldest_change = last_modified;} else {self.oldest_change = self.oldest_change.min(last_modified);}}}debug!("new actions: {:?}, total {:?}",&self.actions.len() - len,self.actions.len()); - replacement in "libpijul/src/record.rs" at line 1008
debug!("record_moved_file {:?}", item);debug!("record_moved_file {:?} {:?}", item, vertex); - edit in "libpijul/src/record.rs" at line 1083
- edit in "libpijul/src/record.rs" at line 1116[58.5][11.510565]
fn collect_former_parents<C: ChangeStore, W: WorkingCopyRead, T: ChannelTxnT>(changes: &C,txn: &T,channel: &T::Channel,vertex: Position<ChangeId>,) -> Result<(Vec<Parent>, bool), RecordError<C::Error, W::Error, T::GraphError>>whereW::Error: 'static,{let mut former_parents = Vec::new();let f0 = EdgeFlags::FOLDER | EdgeFlags::PARENT;let f1 = EdgeFlags::all();let mut is_deleted = true;for name_ in iter_adjacent(txn, txn.graph(channel), vertex.inode_vertex(), f0, f1)? {debug!("name_ = {:?}", name_);let name_ = name_?;if !name_.flag().contains(EdgeFlags::PARENT) {debug!("continue");continue;}if name_.flag().contains(EdgeFlags::DELETED) {debug!("is_deleted {:?}", name_);is_deleted = true;break;}let name_dest = txn.find_block_end(txn.graph(channel), name_.dest()).unwrap();let mut meta = Vec::new();let FileMetadata {basename,metadata,encoding,} = changes.get_file_meta(|p| txn.get_external(&p).unwrap().map(From::from),*name_dest,&mut meta,).map_err(RecordError::Changestore)?;debug!("former basename of {:?}: {:?} {:?}",vertex, basename, metadata);if let Some(v_papa) = iter_adjacent(txn, txn.graph(channel), *name_dest, f0, f1)?.next() {let v_papa = v_papa?;if !v_papa.flag().contains(EdgeFlags::DELETED) {former_parents.push(Parent {basename: basename.to_string(),metadata,encoding,parent: v_papa.dest().to_option(),})}}}Ok((former_parents, is_deleted))} - replacement in "libpijul/src/record.rs" at line 1288
"grandparent_dest {:?} {:?}","grandparent_dest {:?} {:?}, parent_pos = {:?}", - replacement in "libpijul/src/record.rs" at line 1290
std::str::from_utf8(&previous_name[2..])std::str::from_utf8(&previous_name[2..]),parent_pos, - replacement in "libpijul/src/record.rs" at line 1293
let grandparent_changed = parent_pos != grandparent.dest().to_option();let grandparent_changed = if parent_pos.change == Some(ChangeId::ROOT) {!is_root_vertex(txn, channel, grandparent.dest())?} else {parent_pos != grandparent.dest().to_option()}; - edit in "libpijul/src/record.rs" at line 1400
}fn is_root_vertex<T: GraphTxnT>(txn: &T,channel: &T::Graph,v: Position<ChangeId>,) -> Result<bool, TxnErr<T::GraphError>> {for parent in iter_adjacent(txn,channel,v.inode_vertex(),EdgeFlags::FOLDER | EdgeFlags::PARENT,EdgeFlags::FOLDER | EdgeFlags::PARENT | EdgeFlags::PSEUDO | EdgeFlags::BLOCK,)? {let p = parent?.dest();let p = txn.find_block_end(channel, p).unwrap();if p.start == p.end {return Ok(true);} else {return Ok(false);}}Ok(false) - edit in "libpijul/src/pristine/vertex.rs" at line 172
- edit in "libpijul/src/pristine/vertex.rs" at line 173
- edit in "libpijul/src/pristine/inode_metadata.rs" at line 9
pub const DIR: Self = InodeMetadata(DIR_BIT); - replacement in "libpijul/src/output/output.rs" at line 168[11.20226]→[11.673931:673967](∅→∅),[11.76470]→[11.673931:673967](∅→∅),[11.82151]→[11.673931:673967](∅→∅),[11.673931]→[11.673931:673967](∅→∅)
let mut conflicts = Vec::new();let mut state = OutputState {done_vertices: HashMap::default(),actual_moves: Vec::new(),conflicts: Vec::new(),output_name_conflicts,work: work.clone(),done_inodes: HashSet::new(),salt,if_modified_after,next_prefix_basename: prefix.next(),is_following_prefix: true,pending_change_id,}; - replacement in "libpijul/src/output/output.rs" at line 184[11.76556]→[11.674044:674094](∅→∅),[11.674044]→[11.674044:674094](∅→∅),[11.674094]→[11.906:980](∅→∅),[11.980]→[11.76557:76578](∅→∅),[11.76578]→[11.102074:102151](∅→∅),[11.102151]→[11.76673:76810](∅→∅),[11.76673]→[11.76673:76810](∅→∅),[11.76810]→[11.1077:1133](∅→∅),[11.1077]→[11.1077:1133](∅→∅),[11.1133]→[11.76811:76841](∅→∅),[11.76841]→[11.102152:102191](∅→∅),[11.102191]→[11.0:76](∅→∅),[11.76]→[11.76962:76972](∅→∅),[11.102257]→[11.76962:76972](∅→∅),[11.76962]→[11.76962:76972](∅→∅),[11.76972]→[11.1188:1225](∅→∅),[11.1188]→[11.1188:1225](∅→∅)
let mut next_prefix_basename = prefix.next();let mut is_first_none = true;if next_prefix_basename.is_none() {let dead = {let txn_ = txn.read();let channel = channel.read();let graph = txn_.graph(&*channel);collect_dead_files(&*txn_, graph, pending_change_id, Inode::ROOT)?};debug!("dead (line {}) = {:?}", line!(), dead);if !dead.is_empty() {let mut txn = txn.write();kill_dead_files::<T, R, P>(&mut *txn, &channel, &repo, &dead)?;}is_first_none = false;}state.kill_dead_files::<_, _, P>(repo, &txn, &channel)?; - replacement in "libpijul/src/output/output.rs" at line 196
next_prefix_basename,state.next_prefix_basename, - edit in "libpijul/src/output/output.rs" at line 201
let mut done_inodes = HashSet::default();let mut done_vertices: HashMap<_, (Vertex<ChangeId>, String)> = HashMap::default(); - edit in "libpijul/src/output/output.rs" at line 203
let mut actual_moves = Vec::new(); - replacement in "libpijul/src/output/output.rs" at line 206
next_prefix_basename = prefix.next();state.next_prefix_basename = prefix.next(); - replacement in "libpijul/src/output/output.rs" at line 208[11.675107]→[11.675107:675153](∅→∅),[11.675153]→[11.77408:77422](∅→∅),[11.77422]→[11.102327:102365](∅→∅)
debug!("files: {:?} {:?}", a, b);{let txn = txn.read();sort_conflicting_names(&txn, &channel, &mut b);state.output_name(repo, changes, &txn, &channel, &mut next_files, a, b)?;}std::mem::swap(&mut files, &mut next_files);}stop.store(true, std::sync::atomic::Ordering::Relaxed);let o = output_loop(repo, changes, txn, channel, work, stop, 0);for t in threads {state.conflicts.extend(t.join().unwrap()?.into_iter());}state.conflicts.extend(o?.into_iter());for (a, b) in state.actual_moves.iter() {repo.rename(a, b).map_err(OutputError::WorkingCopy)?}Ok(state.conflicts)}fn sort_conflicting_names<T: ChannelTxnT + Send + Sync + 'static>(txn: &ArcTxn<T>,channel: &ChannelRef<T>,b: &mut [(Vertex<ChangeId>, OutputItem)],) {debug!("files: {:?}", b);let txn = txn.read();let channel = channel.read();b.sort_unstable_by(|u, v| {txn.get_changeset(txn.changes(&channel), &u.0.change).unwrap().cmp(&txn.get_changeset(txn.changes(&channel), &v.0.change).unwrap(),)});}struct OutputState<'a> {actual_moves: Vec<(String, String)>,output_name_conflicts: bool,done_vertices: HashMap<Position<ChangeId>, (Vertex<ChangeId>, String)>,conflicts: Vec<Conflict>,work: Arc<crossbeam_deque::Injector<(OutputItem, String, Option<String>)>>,done_inodes: HashSet<Inode>,salt: u64,if_modified_after: Option<std::time::SystemTime>,next_prefix_basename: Option<&'a str>,is_following_prefix: bool,pending_change_id: ChangeId,}impl<'a> OutputState<'a> {fn kill_dead_files<T: TreeMutTxnT+ ChannelMutTxnT+ GraphMutTxnT<GraphError = <T as TreeTxnT>::TreeError>+ Send+ Sync+ 'static,R: WorkingCopy + Clone + Send + Sync + 'static,P: ChangeStore + Clone + 'static,>(&mut self,repo: &R,txn: &ArcTxn<T>,channel: &ChannelRef<T>,) -> Result<(), OutputError<P::Error, T::TreeError, R::Error>> {if self.next_prefix_basename.is_none() && self.is_following_prefix {let dead = {let txn_ = txn.read(); - replacement in "libpijul/src/output/output.rs" at line 277
b.sort_unstable_by(|u, v| {txn.get_changeset(txn.changes(&channel), &u.0.change).unwrap().cmp(&txn.get_changeset(txn.changes(&channel), &v.0.change).unwrap(),)});let graph = txn_.graph(&*channel);collect_dead_files(&*txn_, graph, self.pending_change_id, Inode::ROOT)?};debug!("dead (line {}) = {:?}", line!(), dead);if !dead.is_empty() {let mut txn = txn.write();kill_dead_files::<T, R, P>(&mut *txn, &channel, &repo, &dead)?; - replacement in "libpijul/src/output/output.rs" at line 285[11.77892]→[11.675466:675559](∅→∅),[11.675466]→[11.675466:675559](∅→∅),[11.675559]→[11.4635:4713](∅→∅),[11.1332]→[11.675611:675655](∅→∅),[11.4713]→[11.675611:675655](∅→∅),[11.675611]→[11.675611:675655](∅→∅),[11.675655]→[8.120:401](∅→∅),[8.401]→[11.4714:4765](∅→∅),[11.675741]→[11.4714:4765](∅→∅),[11.4765]→[11.675791:675914](∅→∅),[11.675791]→[11.675791:675914](∅→∅),[11.675914]→[11.4766:4823](∅→∅),[11.4823]→[11.675914:676028](∅→∅),[11.675914]→[11.675914:676028](∅→∅),[11.676028]→[8.402:569](∅→∅),[8.569]→[11.4867:4886](∅→∅),[11.4867]→[11.4867:4886](∅→∅)
let mut is_first_name = true;for (name_key, mut output_item) in b {let name_entry = match done_vertices.entry(output_item.pos) {Entry::Occupied(e) => {debug!("pos already visited: {:?} {:?} {:?} {:?}",a,output_item.pos,e.get(),name_key);if e.get().0 != name_key {conflicts.push(Conflict::MultipleNames {pos: output_item.pos,path: e.get().1.clone(),});}continue;}Entry::Vacant(e) => {debug!("first visit {:?} {:?}", a, output_item.pos);e}};self.is_following_prefix = false;}Ok(())} - replacement in "libpijul/src/output/output.rs" at line 290[11.82272]→[11.77893:77935](∅→∅),[11.77935]→[11.102412:102454](∅→∅),[11.77986]→[11.119905:120070](∅→∅),[11.102454]→[11.119905:120070](∅→∅),[11.82312]→[11.119905:120070](∅→∅),[11.120070]→[11.82474:82532](∅→∅),[11.82474]→[11.82474:82532](∅→∅),[11.82532]→[11.77987:78028](∅→∅)
let output_item_inode = {let txn = txn.read();if let Some(inode) = txn.get_revinodes(&output_item.pos, None)? {Some((*inode, *txn.get_inodes(inode, None)?.unwrap()))} else {None}};fn make_inode(&mut self,a: &str,name_key: Vertex<ChangeId>,output_item: &mut OutputItem,is_first_name: &mut bool,) -> MakeInode {let name_entry = match self.done_vertices.entry(output_item.pos) {Entry::Occupied(e) => {debug!("pos already visited: {:?} {:?} {:?} {:?}",a,output_item.pos,e.get(),name_key);if e.get().0 != name_key {// The same inode has more than one name.self.conflicts.push(Conflict::MultipleNames {pos: output_item.pos,path: e.get().1.clone(),});}return MakeInode::AlreadyOutput;}Entry::Vacant(e) => {debug!("first visit {:?} {:?}", a, output_item.pos);e}};let name = if !*is_first_name {// Multiple inodes share the same name.if self.output_name_conflicts {let name = make_conflicting_name(&a, name_key);self.conflicts.push(Conflict::Name { path: name.clone() });name} else {debug!("not outputting {:?} {:?}", a, name_key);self.conflicts.push(Conflict::Name {path: a.to_string(),});return MakeInode::NameConflict;}} else {*is_first_name = false;a.to_string()};debug!("name = {:?} {:?}", name, name_key);let file_name = path::file_name(&name).unwrap();path::push(&mut output_item.path, file_name);name_entry.insert((name_key, output_item.path.clone()));MakeInode::Ok(name)} - replacement in "libpijul/src/output/output.rs" at line 344[11.82556]→[11.82556:82618](∅→∅),[11.82618]→[11.676216:676268](∅→∅),[11.676216]→[11.676216:676268](∅→∅)
if let Some((inode, _)) = output_item_inode {if !done_inodes.insert(inode) {fn output_name<T: TreeMutTxnT+ ChannelMutTxnT+ GraphMutTxnT<GraphError = <T as TreeTxnT>::TreeError>+ Send+ Sync+ 'static,R: WorkingCopy + Clone + Send + Sync + 'static,P: ChangeStore + Send + Clone + 'static,>(&mut self,repo: &R,changes: &P,txn: &ArcTxn<T>,channel: &ChannelRef<T>,next_files: &mut HashMap<String, Vec<(Vertex<ChangeId>, OutputItem)>>,a: String,b: Vec<(Vertex<ChangeId>, OutputItem)>,) -> Result<(), OutputError<P::Error, T::TreeError, R::Error>> {let mut is_first_name = true;for (name_key, mut output_item) in b {debug!("name_key = {:?} {:?}", name_key, output_item);let name = match self.make_inode(&a, name_key, &mut output_item, &mut is_first_name) {MakeInode::Ok(file_name) => file_name,MakeInode::AlreadyOutput => continue,MakeInode::NameConflict => break,};let output_item_inode = {let txn = txn.read();if let Some(inode) = txn.get_revinodes(&output_item.pos, None)? {if !self.done_inodes.insert(*inode) { - replacement in "libpijul/src/output/output.rs" at line 378
}let name = if !is_first_name {if output_name_conflicts {let name = make_conflicting_name(&a, name_key);conflicts.push(Conflict::Name { path: name.clone() });name} else {debug!("not outputting {:?} {:?}", a, name_key);conflicts.push(Conflict::Name {path: a.to_string(),});break;}Some((*inode, *txn.get_inodes(inode, None)?.unwrap())) - replacement in "libpijul/src/output/output.rs" at line 380[11.677007]→[11.677007:677226](∅→∅),[11.677226]→[11.4887:4962](∅→∅),[11.4962]→[11.432:559](∅→∅),[11.677226]→[11.432:559](∅→∅),[11.559]→[11.677226:677310](∅→∅),[11.677226]→[11.677226:677310](∅→∅),[11.677310]→[11.560:614](∅→∅),[11.614]→[11.20283:20338](∅→∅),[11.677310]→[11.20283:20338](∅→∅),[11.20338]→[11.78029:78062](∅→∅),[11.78062]→[11.102455:102482](∅→∅),[11.78096]→[11.677476:677510](∅→∅),[11.102482]→[11.677476:677510](∅→∅),[11.677476]→[11.677476:677510](∅→∅),[11.677510]→[11.82619:82658](∅→∅),[11.82658]→[11.677510:677537](∅→∅),[11.677510]→[11.677510:677537](∅→∅),[11.677537]→[11.615:645](∅→∅),[11.645]→[11.677537:677608](∅→∅),[11.677537]→[11.677537:677608](∅→∅),[11.677608]→[11.3605:3631](∅→∅),[11.3631]→[11.677608:677628](∅→∅),[11.677608]→[11.677608:677628](∅→∅),[11.677628]→[11.78097:78144](∅→∅),[11.78144]→[11.677628:677697](∅→∅),[11.677628]→[11.677628:677697](∅→∅),[11.677697]→[11.78145:78178](∅→∅),[11.78178]→[11.102483:102584](∅→∅),[11.102584]→[11.78297:78421](∅→∅),[11.78297]→[11.78297:78421](∅→∅),[11.4719]→[11.677788:677856](∅→∅),[11.58151]→[11.677788:677856](∅→∅),[11.78421]→[11.677788:677856](∅→∅),[11.82758]→[11.677788:677856](∅→∅),[11.677788]→[11.677788:677856](∅→∅),[11.677856]→[11.78422:78464](∅→∅),[11.78464]→[11.102585:102636](∅→∅),[11.102636]→[11.77:165](∅→∅),[11.165]→[11.78609:78631](∅→∅),[11.102714]→[11.78609:78631](∅→∅),[11.78609]→[11.78609:78631](∅→∅),[11.20406]→[11.677912:677955](∅→∅),[11.78631]→[11.677912:677955](∅→∅),[11.677912]→[11.677912:677955](∅→∅)
is_first_name = false;a.clone()};let file_name = path::file_name(&name).unwrap();path::push(&mut output_item.path, file_name);name_entry.insert((name_key, output_item.path.clone()));if let Some(ref mut tmp) = output_item.tmp {path::push(tmp, file_name);}let path = std::mem::replace(&mut output_item.path, String::new());let mut tmp = output_item.tmp.take();let inode = move_or_create::<T, R, P>(txn.clone(),&repo,&output_item,output_item_inode,&path,&mut tmp,&file_name,&mut actual_moves,salt,)?;debug!("inode = {:?}", inode);if next_prefix_basename.is_none() && is_first_none {let dead = {let txn_ = txn.read();let channel = channel.read();collect_dead_files(&*txn_, txn_.graph(&*channel), pending_change_id, inode)?};debug!("dead (line {}) = {:?}", line!(), dead);if !dead.is_empty() {let mut txn = txn.write();kill_dead_files::<T, R, P>(&mut *txn, &channel, &repo, &dead)?;}is_first_none = false;None - replacement in "libpijul/src/output/output.rs" at line 382
if output_item.meta.is_dir() {};let file_name = path::file_name(&name).unwrap();let mut tmp = output_item.tmp.take().map(|mut tmp| {path::push(&mut tmp, file_name);tmp});let path = std::mem::replace(&mut output_item.path, String::new());let inode = move_or_create::<T, R, P>(txn.clone(),&repo,&output_item,output_item_inode,&path,&mut tmp,&file_name,&mut self.actual_moves,self.salt,)?;debug!("inode = {:?}", inode);self.kill_dead_files::<_, _, P>(repo, txn, channel)?;if output_item.meta.is_dir() {if !path.is_empty() { - edit in "libpijul/src/output/output.rs" at line 408[11.20515]→[11.78632:78654](∅→∅),[11.78654]→[11.102715:102815](∅→∅),[11.102815]→[11.78772:79053](∅→∅),[11.78772]→[11.78772:79053](∅→∅),[11.79053]→[11.757:801](∅→∅),[11.801]→[11.79053:79264](∅→∅),[11.79053]→[11.79053:79264](∅→∅)
{let txn = txn.read();let channel = channel.read();collect_children(&*txn,&*changes,txn.graph(&*channel),output_item.pos,inode,&path,tmp.as_deref(),next_prefix_basename,&mut next_files,)?;}debug!("setting permissions for {:?}", path); - edit in "libpijul/src/output/output.rs" at line 410[11.79405]→[11.678486:678511](∅→∅),[11.82824]→[11.678486:678511](∅→∅),[11.678486]→[11.678486:678511](∅→∅),[11.678511]→[11.102816:102886](∅→∅),[11.102886]→[11.882:967](∅→∅),[11.79485]→[11.882:967](∅→∅),[11.967]→[11.963:1052](∅→∅),[11.1297]→[11.963:1052](∅→∅),[11.79557]→[11.963:1052](∅→∅),[11.2574]→[11.963:1052](∅→∅),[11.1052]→[11.2574:2596](∅→∅),[11.2574]→[11.2574:2596](∅→∅)
} else {if needs_output(repo, if_modified_after, &path) {work.push((output_item.clone(), path.clone(), tmp.clone()));} else {debug!("Not outputting {:?}", path)} - replacement in "libpijul/src/output/output.rs" at line 411
if output_item.is_zombie {conflicts.push(Conflict::ZombieFile {path: name.to_string(),})let txn = txn.read();let channel = channel.read();collect_children(&*txn,&*changes,txn.graph(&*channel),output_item.pos,inode,&path,tmp.as_deref(),self.next_prefix_basename,next_files,)?;} else {if needs_output(repo, self.if_modified_after, &path) {self.work.push((output_item.clone(), path.clone(), tmp.clone()));} else {debug!("Not outputting {:?}", path) - edit in "libpijul/src/output/output.rs" at line 431
}if output_item.is_zombie {self.conflicts.push(Conflict::ZombieFile {path: name.to_string(),}) - replacement in "libpijul/src/output/output.rs" at line 438[11.679083]→[11.679083:679142](∅→∅),[11.79565]→[11.79565:79625](∅→∅),[11.79625]→[11.102887:102956](∅→∅),[11.1045]→[11.79694:79717](∅→∅),[11.102956]→[11.79694:79717](∅→∅),[11.79694]→[11.79694:79717](∅→∅),[11.79717]→[2.134:192](∅→∅),[2.192]→[11.679209:679215](∅→∅),[11.21082]→[11.679209:679215](∅→∅),[11.79744]→[11.679209:679215](∅→∅),[11.679209]→[11.679209:679215](∅→∅),[11.679215]→[2.193:231](∅→∅),[2.231]→[11.1046:1147](∅→∅),[11.79753]→[11.1046:1147](∅→∅)
std::mem::swap(&mut files, &mut next_files);}stop.store(true, std::sync::atomic::Ordering::Relaxed);let o = output_loop(repo, changes, txn, channel, work, stop, 0);for t in threads {conflicts.extend(t.join().unwrap()?.into_iter());}conflicts.extend(o?.into_iter());for (a, b) in actual_moves.iter() {repo.rename(a, b).map_err(OutputError::WorkingCopy)?Ok(()) - replacement in "libpijul/src/output/output.rs" at line 440[11.1153]→[11.679215:679233](∅→∅),[11.79753]→[11.679215:679233](∅→∅),[11.679215]→[11.679215:679233](∅→∅)
Ok(conflicts)}enum MakeInode {AlreadyOutput,NameConflict,Ok(String), - replacement in "libpijul/src/output/mod.rs" at line 101[11.24839]→[11.686875:686908](∅→∅),[11.86337]→[11.686875:686908](∅→∅),[11.686875]→[11.686875:686908](∅→∅)
debug!("path = {:?}", path);debug!("path = {:?}, inode_pos = {:?}", path, inode_pos); - edit in "libpijul/src/output/mod.rs" at line 110
debug!("e = {:?}", e); - replacement in "libpijul/src/output/mod.rs" at line 112[11.56162]→[11.687480:687519](∅→∅),[11.58558]→[11.687480:687519](∅→∅),[11.86454]→[11.687480:687519](∅→∅),[11.122089]→[11.687480:687519](∅→∅),[11.687480]→[11.687480:687519](∅→∅),[11.687519]→[11.1478:1556](∅→∅),[11.1556]→[11.3999:4014](∅→∅),[11.4014]→[11.1556:1604](∅→∅),[11.1556]→[11.1556:1604](∅→∅),[11.1604]→[11.17583:17652](∅→∅),[11.17583]→[11.17583:17652](∅→∅)
let mut name_buf = Vec::new();let FileMetadata {basename,metadata: perms,..} = changes.get_file_meta(|h| txn.get_external(&h).unwrap().map(|x| x.into()),if name_vertex.start != name_vertex.end {debug!("name_vertex: {:?} {:?}", e, name_vertex);collect(txn,changes,channel,inode,path,tmp,prefix_basename,files,name_vertex,)?} else {let inode_pos = iter_adjacent(txn,channel, - replacement in "libpijul/src/output/mod.rs" at line 130[11.17682]→[11.17682:17727](∅→∅),[11.17727]→[11.86543:86600](∅→∅),[11.122198]→[11.86543:86600](∅→∅),[11.86543]→[11.86543:86600](∅→∅),[11.687814]→[11.687814:688082](∅→∅),[11.688145]→[11.688145:688203](∅→∅),[11.688346]→[11.56334:56407](∅→∅),[11.56407]→[11.86601:86622](∅→∅),[11.86622]→[11.122199:122225](∅→∅),[11.122225]→[11.56454:56555](∅→∅),[11.56454]→[11.56454:56555](∅→∅),[11.56555]→[11.86623:86634](∅→∅),[11.86634]→[11.56565:56591](∅→∅),[11.56565]→[11.56565:56591](∅→∅),[11.56591]→[11.86635:86654](∅→∅),[11.86654]→[11.56609:56626](∅→∅),[11.56609]→[11.56609:56626](∅→∅),[11.56626]→[11.86655:86688](∅→∅)
&mut name_buf,).map_err(PristineOutputError::Changestore)?;debug!("filename: {:?} {:?}", perms, basename);let mut name = path.to_string();if let Some(next) = prefix_basename {if next != basename {continue;}}path::push(&mut name, basename);debug!("name_vertex: {:?} {:?}", e, name_vertex);let child = if let Some(child) = iter_adjacent(txn,channel,*name_vertex,EdgeFlags::FOLDER,EdgeFlags::FOLDER | EdgeFlags::BLOCK | EdgeFlags::PSEUDO,)?.next(){child?} else {let mut edge = None;EdgeFlags::FOLDER,EdgeFlags::FOLDER | EdgeFlags::PSEUDO | EdgeFlags::BLOCK,)?.next().unwrap()?.dest(); - replacement in "libpijul/src/output/mod.rs" at line 139
*name_vertex,inode_pos.inode_vertex(), - replacement in "libpijul/src/output/mod.rs" at line 141
EdgeFlags::all(),EdgeFlags::FOLDER | EdgeFlags::PSEUDO | EdgeFlags::BLOCK, - replacement in "libpijul/src/output/mod.rs" at line 144[11.86796]→[11.122257:122316](∅→∅),[11.122316]→[11.86853:86934](∅→∅),[11.86853]→[11.86853:86934](∅→∅)
if !e.flag().contains(EdgeFlags::PARENT) {edge = Some(e);break;}debug!("e = {:?}", e);let name_vertex = txn.find_block(channel, e.dest()).unwrap();collect(txn,changes,channel,inode,path,tmp,prefix_basename,files,name_vertex,)? - replacement in "libpijul/src/output/mod.rs" at line 158[11.86948]→[11.86948:86983](∅→∅),[11.86983]→[11.688898:688970](∅→∅),[11.688898]→[11.688898:688970](∅→∅),[11.688970]→[11.122317:122404](∅→∅),[11.962]→[11.689072:689115](∅→∅),[11.3292]→[11.689072:689115](∅→∅),[11.56894]→[11.689072:689115](∅→∅),[11.87069]→[11.689072:689115](∅→∅),[11.122404]→[11.689072:689115](∅→∅),[11.689072]→[11.689072:689115](∅→∅)
let e = edge.unwrap();let mut f = std::fs::File::create("debug_output").unwrap();debug_root(txn, channel, e.dest().inode_vertex(), &mut f, false).unwrap();panic!("no child");};}}Ok(())} - replacement in "libpijul/src/output/mod.rs" at line 163[11.689116]→[11.689116:689154](∅→∅),[11.689352]→[11.4958:5018](∅→∅),[11.5018]→[11.689409:689426](∅→∅),[11.689409]→[11.689409:689426](∅→∅)
debug!("child: {:?}", child);let v = files.entry(name).or_insert_with(Vec::new);v.push((fn collect<T: GraphTxnT, P: ChangeStore>(txn: &T,changes: &P,channel: &T::Graph,inode: Inode,path: &str,tmp: Option<&str>,prefix_basename: Option<&str>,files: &mut HashMap<String, Vec<(Vertex<ChangeId>, OutputItem)>>,name_vertex: &Vertex<ChangeId>,) -> Result<(), PristineOutputError<P::Error, T::GraphError>> {let mut name_buf = Vec::new();let FileMetadata {basename,metadata: perms,..} = changes.get_file_meta(|h| txn.get_external(&h).unwrap().map(|x| x.into()), - replacement in "libpijul/src/output/mod.rs" at line 183[11.122431]→[11.689451:689547](∅→∅),[11.689451]→[11.689451:689547](∅→∅),[11.689547]→[11.1427:1471](∅→∅),[11.1471]→[11.689547:689576](∅→∅),[11.689547]→[11.689547:689576](∅→∅),[11.689576]→[11.122432:122534](∅→∅),[11.87135]→[11.689709:689736](∅→∅),[11.122534]→[11.689709:689736](∅→∅),[11.689709]→[11.689709:689736](∅→∅)
OutputItem {parent: inode,path: path.to_string(),tmp: tmp.map(String::from),meta: perms,pos: child.dest(),is_zombie: is_zombie(txn, channel, child.dest())?,},));&mut name_buf,).map_err(PristineOutputError::Changestore)?;debug!("filename: {:?} {:?}", perms, basename);let mut name = path.to_string();if let Some(next) = prefix_basename {if next != basename {return Ok(());} - edit in "libpijul/src/output/mod.rs" at line 193
path::push(&mut name, basename);let child = if let Some(child) = iter_adjacent(txn,channel,*name_vertex,EdgeFlags::FOLDER,EdgeFlags::FOLDER | EdgeFlags::BLOCK | EdgeFlags::PSEUDO,)?.next(){child?} else {let mut edge = None;for e in iter_adjacent(txn,channel,*name_vertex,EdgeFlags::FOLDER,EdgeFlags::all(),)? {let e = e?;if !e.flag().contains(EdgeFlags::PARENT) {edge = Some(e);break;}}let e = edge.unwrap();let mut f = std::fs::File::create("debug_output").unwrap();debug_root(txn, channel, e.dest().inode_vertex(), &mut f, false).unwrap();panic!("no child");};debug!("child: {:?}", child);let v = files.entry(name).or_insert_with(Vec::new);v.push((*name_vertex,OutputItem {parent: inode,path: path.to_string(),tmp: tmp.map(String::from),meta: perms,pos: child.dest(),is_zombie: is_zombie(txn, channel, child.dest())?,},)); - edit in "libpijul/src/fs.rs" at line 568
adj2: Option<AdjacentIterator<'txn, T>>, - replacement in "libpijul/src/fs.rs" at line 578
let child = match self.adj.next()? {Ok(child) => child,Err(e) => return Some(Err(e.0)),let dest = loop {debug!("adj2 = {:?}", self.adj2.is_some());if let Some(mut adj2) = self.adj2.take() {match adj2.next() {None => {}Some(Ok(ch)) => {self.adj2 = Some(adj2);break self.txn.find_block(self.channel, ch.dest()).unwrap();}Some(Err(e)) => return Some(Err(e.0)),}}match self.adj.next() {Some(Ok(child)) => {let d = self.txn.find_block(self.channel, child.dest()).unwrap();if d.start == d.end {match iter_adjacent(self.txn,self.channel,*d,EdgeFlags::FOLDER,EdgeFlags::FOLDER | EdgeFlags::PSEUDO | EdgeFlags::BLOCK,).and_then(|mut it| it.next().unwrap()).and_then(|x| {iter_adjacent(self.txn,self.channel,x.dest().inode_vertex(),EdgeFlags::FOLDER,EdgeFlags::FOLDER | EdgeFlags::PSEUDO | EdgeFlags::BLOCK,)}) {Ok(adj) => self.adj2 = Some(adj),Err(e) => return Some(Err(e.0)),}} else {break d;}}Some(Err(e)) => return Some(Err(e.0)),None => return None,} - replacement in "libpijul/src/fs.rs" at line 622
let dest = self.txn.find_block(self.channel, child.dest()).unwrap();debug!("dest = {:?}", dest); - edit in "libpijul/src/fs.rs" at line 685
adj2: None, - replacement in "libpijul/src/fs.rs" at line 907
while !v.change.is_root() {'outer: while !v.change.is_root() { - edit in "libpijul/src/fs.rs" at line 929
if name.dest().is_root() {break 'outer;} - edit in "libpijul/src/fs.rs" at line 968
if name.start == name.end {// Non-zero root vertexassert!(next.change.is_root());break;} - edit in "libpijul/src/change.rs" at line 561
Hunk::AddRoot { change } => Hunk::DelRoot {change: change.inverse(hash),},Hunk::DelRoot { change } => Hunk::AddRoot {change: change.inverse(hash),}, - edit in "libpijul/src/change.rs" at line 755
},AddRoot {change: Atom, - edit in "libpijul/src/change.rs" at line 759
DelRoot {change: Atom,}, - edit in "libpijul/src/change.rs" at line 847
Hunk::AddRoot { change } | Hunk::DelRoot { change } => Some(change), - edit in "libpijul/src/change.rs" at line 910
Hunk::AddRoot { ref change } | Hunk::DelRoot { ref change } => Some(change), - edit in "libpijul/src/change.rs" at line 992
Hunk::AddRoot { ref change } | Hunk::DelRoot { ref change } => Some(change), - edit in "libpijul/src/change.rs" at line 1111
Hunk::AddRoot { .. } | Hunk::DelRoot { .. } => "/", - edit in "libpijul/src/change.rs" at line 1224
BaseHunk::AddRoot { change } => BaseHunk::AddRoot { change: f(change)? },BaseHunk::DelRoot { change } => BaseHunk::DelRoot { change: f(change)? }, - replacement in "libpijul/src/change/text_changes.rs" at line 453[11.4295]→[11.2861:2981](∅→∅),[11.51864]→[11.2861:2981](∅→∅),[11.2981]→[11.5417:5444](∅→∅),[11.5444]→[3.101:197](∅→∅)
let FileMetadata {basename: name,metadata: perms,..} = FileMetadata::read(&change_contents[n.start.0.into()..n.end.0.into()]);let (name, perms) = if n.start == n.end {("", InodeMetadata::DIR)} else {let FileMetadata {basename: name,metadata: perms,..} = FileMetadata::read(&change_contents[n.start.0.into()..n.end.0.into()]);(name, perms)}; - edit in "libpijul/src/change/text_changes.rs" at line 589
}Hunk::AddRoot { change } => {writeln!(w, "Root",)?;write_atom(&mut w, hashes, &change)?;}Hunk::DelRoot { change } => {writeln!(w, "Unroot",)?;write_atom(&mut w, hashes, &change)?; - edit in "libpijul/src/change/text_changes.rs" at line 1172
_ => unimplemented!(),