edit in pijul-remote/src/lib.rs at line 1048
+ let mut working_copy =
+ libpijul::working_copy::filesystem::FileSystem::from_root(&l.root);
replacement in pijul-remote/src/lib.rs at line 1057
[10.227]→[10.227:323](∅→∅) − txn.archive_with_state(&changes, &channel, &state, extra, &mut tarball, 0)?
+ txn.archive_with_state(
+ &changes,
+ &channel,
+ &state,
+ extra,
+ &mut tarball,
+ 0,
+ &mut working_copy,
+ )?
replacement in pijul/src/commands/unrecord.rs at line 128
[10.998]→[10.2116:2186](∅→∅) − txn.write().unrecord(&repo.changes, &channel, &hash, 0)?;
+ txn.write()
+ .unrecord(&repo.changes, &channel, &hash, 0, &repo.working_copy)?;
replacement in pijul/src/commands/unrecord.rs at line 146
[10.5939]→[10.2273:2340](∅→∅) − txn.write().unrecord(&repo.changes, &channel, &h, 0)?;
+ txn.write()
+ .unrecord(&repo.changes, &channel, &h, 0, &repo.working_copy)?;
edit in pijul/src/commands/record.rs at line 123
replacement in pijul/src/commands/pushpull.rs at line 745
− txn.write().unrecord(&repo.changes, &mut channel, h, 0)?;
+ txn.write()
+ .unrecord(&repo.changes, &mut channel, h, 0, &repo.working_copy)?;
replacement in pijul/src/commands/pushpull.rs at line 892
[10.120988]→[10.11296:11367](∅→∅) − txn.write().unrecord(&repo.changes, &mut channel, &h, 0)?;
+ txn.write()
+ .unrecord(&repo.changes, &mut channel, &h, 0, &repo.working_copy)?;
edit in pijul/src/commands/protocol.rs at line 312
replacement in pijul/src/commands/fork.rs at line 57
[10.1912]→[10.1912:1988](∅→∅) − txn.unrecord(&repo.changes, &mut fork, &h, 0)?;
+ txn.unrecord(&repo.changes, &mut fork, &h, 0, &repo.working_copy)?;
edit in pijul/src/commands/archive.rs at line 120
edit in libpijul/src/working_copy/mod.rs at line 50
+
+ fn touch(&self, _name: &str, time: std::time::SystemTime) -> Result<(), Self::Error> {
+ Ok(())
+ }
edit in libpijul/src/working_copy/memory.rs at line 332
+ }
+
+ fn touch(&self, file: &str, time: std::time::SystemTime) -> Result<(), Self::Error> {
+ let mut m = self.0.lock();
+ if let Some(f) = m.get_file_mut(file) {
+ if let Inode::File {
+ ref mut last_modified,
+ ..
+ } = f
+ {
+ *last_modified = time
+ } else {
+ unreachable!()
+ }
+ }
+ Ok(())
edit in libpijul/src/working_copy/filesystem.rs at line 487
+
+ fn touch(&self, file: &str, time: std::time::SystemTime) -> Result<(), Self::Error> {
+ let p = self.path(file);
+ let src = std::fs::metadata(&p)?;
+ let dest = std::fs::File::open(&p)?;
+ let times = std::fs::FileTimes::new().set_modified(time);
+ dest.set_times(times)?;
+ Ok(())
+ }
edit in libpijul/src/unrecord/working_copy.rs at line 5
+ use crate::working_copy::WorkingCopy;
replacement in libpijul/src/unrecord/working_copy.rs at line 24
[10.3]→[10.8900:8984](∅→∅) − pub fn undo_file_deletion<T: ChannelTxnT + TreeMutTxnT + TreeTxnT, P: ChangeStore>(
+ pub fn undo_file_deletion<
+ T: ChannelTxnT + TreeMutTxnT + TreeTxnT,
+ P: ChangeStore,
+ W: crate::working_copy::WorkingCopy,
+ >(
replacement in libpijul/src/unrecord/working_copy.rs at line 35
[10.2060]→[10.8985:9038](∅→∅) − ) -> Result<(), super::UnrecordError<P::Error, T>> {
+ ) -> Result<(), super::UnrecordError<P::Error, W::Error, T>> {
replacement in libpijul/src/unrecord/working_copy.rs at line 42
[10.6696]→[10.2061:2125](∅→∅) − restore(txn, changes, channel, source, dest, salt)?
+ restore::<_, _, W>(txn, changes, channel, source, dest, salt)?
replacement in libpijul/src/unrecord/working_copy.rs at line 48
[10.5]→[10.9039:9108](∅→∅) − fn restore<T: ChannelTxnT + TreeMutTxnT + TreeTxnT, P: ChangeStore>(
+ fn restore<T: ChannelTxnT + TreeMutTxnT + TreeTxnT, P: ChangeStore, W: WorkingCopy>(
replacement in libpijul/src/unrecord/working_copy.rs at line 55
[10.2141]→[10.9109:9162](∅→∅) − ) -> Result<(), super::UnrecordError<P::Error, T>> {
+ ) -> Result<(), super::UnrecordError<P::Error, W::Error, T>> {
replacement in libpijul/src/unrecord/working_copy.rs at line 62
[10.92]→[10.2142:2237](∅→∅) − return_value = restore_inode(txn, changes, source, dest, parent_inode, salt)?;
+ return_value =
+ restore_inode::<_, _, W>(txn, changes, source, dest, parent_inode, salt)?;
replacement in libpijul/src/unrecord/working_copy.rs at line 86
[10.228382]→[10.2238:2328](∅→∅) − return_value = restore_inode(txn, changes, source, dest, Inode::ROOT, salt)?;
+ return_value = restore_inode::<_, _, W>(txn, changes, source, dest, Inode::ROOT, salt)?;
replacement in libpijul/src/unrecord/working_copy.rs at line 88
[10.15052]→[10.2329:2413](∅→∅) − return_value = restore_inode(txn, changes, source, dest, inode, salt)?;
+ return_value = restore_inode::<_, _, W>(txn, changes, source, dest, inode, salt)?;
replacement in libpijul/src/unrecord/working_copy.rs at line 92
[10.336]→[10.336:430](∅→∅) − return_value = restore_inode(txn, changes, source, dest, Inode::ROOT, salt)?;
+ return_value =
+ restore_inode::<_, _, W>(txn, changes, source, dest, Inode::ROOT, salt)?;
replacement in libpijul/src/unrecord/working_copy.rs at line 103
[10.9]→[10.9163:9236](∅→∅) − fn restore_inode<T: TreeMutTxnT + GraphTxnT + TreeTxnT, P: ChangeStore>(
+ fn restore_inode<T: TreeMutTxnT + GraphTxnT + TreeTxnT, P: ChangeStore, W: WorkingCopy>(
replacement in libpijul/src/unrecord/working_copy.rs at line 110
[10.2429]→[10.9237:9301](∅→∅) − ) -> Result<Option<Inode>, super::UnrecordError<P::Error, T>> {
+ ) -> Result<Option<Inode>, super::UnrecordError<P::Error, W::Error, T>> {
edit in libpijul/src/unrecord/working_copy.rs at line 188
replacement in libpijul/src/unrecord/working_copy.rs at line 193
[10.230916]→[10.9302:9355](∅→∅) − ) -> Result<(), super::UnrecordError<P::Error, T>> {
+ ) -> Result<(), super::UnrecordError<P::Error, W::Error, T>> {
replacement in libpijul/src/unrecord/mod.rs at line 5
[10.231689]→[10.231689:231690](∅→∅) + use crate::working_copy::WorkingCopy;
replacement in libpijul/src/unrecord/mod.rs at line 11
[10.9373]→[10.9373:9470](∅→∅) − pub enum UnrecordError<ChangestoreError: std::error::Error + 'static, T: GraphTxnT + TreeTxnT> {
+ pub enum UnrecordError<
+ ChangestoreError: std::error::Error + 'static,
+ WorkingCopyError: std::error::Error + 'static,
+ T: GraphTxnT + TreeTxnT,
+ > {
edit in libpijul/src/unrecord/mod.rs at line 39
+ #[error(transparent)]
+ WorkingCopy(WorkingCopyError),
replacement in libpijul/src/unrecord/mod.rs at line 43
[10.22321]→[10.9929:10023](∅→∅) − impl<C: std::error::Error, T: GraphTxnT + TreeTxnT> std::fmt::Debug for UnrecordError<C, T> {
+ impl<C: std::error::Error, W: std::error::Error, T: GraphTxnT + TreeTxnT> std::fmt::Debug
+ for UnrecordError<C, W, T>
+ {
edit in libpijul/src/unrecord/mod.rs at line 68
+ UnrecordError::WorkingCopy(e) => std::fmt::Debug::fmt(e, fmt),
replacement in libpijul/src/unrecord/mod.rs at line 73
[10.8614]→[10.231752:231797](∅→∅),
[10.231752]→[10.231752:231797](∅→∅) − pub fn unrecord<T: MutTxnT, P: ChangeStore>(
+ pub fn unrecord<T: MutTxnT, P: ChangeStore, W: WorkingCopy>(
replacement in libpijul/src/unrecord/mod.rs at line 79
[10.2521]→[10.11142:11190](∅→∅) − ) -> Result<bool, UnrecordError<P::Error, T>> {
+ working_copy: &W,
+ ) -> Result<bool, UnrecordError<P::Error, W::Error, T>> {
replacement in libpijul/src/unrecord/mod.rs at line 89
[10.232195]→[10.8769:8833](∅→∅) − del_channel_changes::<T, P>(txn, &mut channel, change_id)?;
+ del_channel_changes::<T, P, W>(txn, &mut channel, change_id)?;
replacement in libpijul/src/unrecord/mod.rs at line 95
[4.99]→[10.2522:2590](∅→∅),
[10.232252]→[10.2522:2590](∅→∅) − unapply(txn, &mut channel, changes, change_id, &change, salt)?;
+ unapply(
+ txn,
+ &mut channel,
+ changes,
+ change_id,
+ &change,
+ salt,
+ working_copy,
+ )?;
edit in libpijul/src/unrecord/mod.rs at line 123
replacement in libpijul/src/unrecord/mod.rs at line 128
[10.232905]→[10.11279:11325](∅→∅) − ) -> Result<(), UnrecordError<P::Error, T>> {
+ ) -> Result<(), UnrecordError<P::Error, W::Error, T>> {
edit in libpijul/src/unrecord/mod.rs at line 179
replacement in libpijul/src/unrecord/mod.rs at line 187
[10.2606]→[10.11326:11372](∅→∅) − ) -> Result<(), UnrecordError<C::Error, T>> {
+ working_copy: &W,
+ ) -> Result<(), UnrecordError<C::Error, W::Error, T>> {
replacement in libpijul/src/unrecord/mod.rs at line 199
[10.244]→[10.244:275](∅→∅) + unapply_edges::<_, _, W>(
replacement in libpijul/src/unrecord/mod.rs at line 217
[10.234880]→[10.1909:1952](∅→∅) − unapply_newvertex::<T, C>(
+ unapply_newvertex::<T, C, W>(
replacement in libpijul/src/unrecord/mod.rs at line 233
[10.737]→[10.2220:2308](∅→∅),
[10.2017]→[10.2220:2308](∅→∅) − remove_zombies::<_, C>(txn, T::graph_mut(channel), &mut ws, change_id, n)?;
+ remove_zombies::<_, C, W>(txn, T::graph_mut(channel), &mut ws, change_id, n)?;
replacement in libpijul/src/unrecord/mod.rs at line 242
[10.372]→[10.723:777](∅→∅) − working_copy::undo_file_deletion(
+ working_copy::undo_file_deletion::<_, _, W>(
replacement in libpijul/src/unrecord/mod.rs at line 246
[10.653]→[10.653:744](∅→∅) − working_copy::undo_file_reinsertion::<C, _>(txn, change_id, newedges)?
+ working_copy::undo_file_reinsertion::<C, _, W>(txn, change_id, newedges)?
replacement in libpijul/src/unrecord/mod.rs at line 261
[10.839]→[10.839:873](∅→∅) − for inode in touched_inodes {
+ for inode in touched_inodes.iter() {
replacement in libpijul/src/unrecord/mod.rs at line 264
[10.1201]→[10.968:1034](∅→∅),
[10.968]→[10.968:1034](∅→∅) − if let Ok(inode) = internal_pos(txn, &inode, change_id) {
+ if let Ok(inode) = internal_pos(txn, inode, change_id) {
replacement in libpijul/src/unrecord/mod.rs at line 305
[10.2573]→[10.884:925](∅→∅) − txn.touch_channel(channel, Some(0));
+
+ let now = std::time::SystemTime::now();
+ for inode in touched_inodes.iter() {
+ if let Ok(inode) = internal_pos(txn, inode, change_id) {
+ if let Some(inode) = txn.get_revinodes(&inode, None)? {
+ if let Some(name) = crate::fs::inode_filename(txn, *inode)? {
+ debug!(
+ "touching file {:?} {:?}",
+ name,
+ now.duration_since(std::time::SystemTime::UNIX_EPOCH)
+ .unwrap()
+ .as_millis()
+ );
+ working_copy
+ .touch(&name, now)
+ .map_err(UnrecordError::WorkingCopy)?
+ }
+ }
+ }
+ }
replacement in libpijul/src/unrecord/mod.rs at line 342
[10.235980]→[10.11373:11439](∅→∅) − fn unapply_newvertex<T: GraphMutTxnT + TreeTxnT, C: ChangeStore>(
+ fn unapply_newvertex<T: GraphMutTxnT + TreeTxnT, C: ChangeStore, W: WorkingCopy>(
replacement in libpijul/src/unrecord/mod.rs at line 348
[10.236377]→[10.11440:11486](∅→∅) − ) -> Result<(), UnrecordError<C::Error, T>> {
+ ) -> Result<(), UnrecordError<C::Error, W::Error, T>> {
replacement in libpijul/src/unrecord/mod.rs at line 378
[10.238115]→[10.990:1045](∅→∅) − ws.perform_del::<C, T>(txn, channel, vertex)?;
+ ws.perform_del::<C, T, W>(txn, channel, vertex)?;
replacement in libpijul/src/unrecord/mod.rs at line 387
[10.1166]→[10.11487:11551](∅→∅) − fn perform_del<C: ChangeStore, T: GraphMutTxnT + TreeTxnT>(
+ fn perform_del<C: ChangeStore, T: GraphMutTxnT + TreeTxnT, W: WorkingCopy>(
replacement in libpijul/src/unrecord/mod.rs at line 392
[10.1322]→[10.11552:11602](∅→∅) − ) -> Result<(), UnrecordError<C::Error, T>> {
+ ) -> Result<(), UnrecordError<C::Error, W::Error, T>> {
replacement in libpijul/src/unrecord/mod.rs at line 413
[10.10239]→[10.11725:11787](∅→∅) − fn unapply_edges<T: GraphMutTxnT + TreeTxnT, P: ChangeStore>(
+ fn unapply_edges<T: GraphMutTxnT + TreeTxnT, P: ChangeStore, W: WorkingCopy>(
replacement in libpijul/src/unrecord/mod.rs at line 420
[10.240557]→[10.11788:11834](∅→∅) − ) -> Result<(), UnrecordError<P::Error, T>> {
+ ) -> Result<(), UnrecordError<P::Error, W::Error, T>> {
replacement in libpijul/src/unrecord/mod.rs at line 446
[10.569]→[10.1342:1375](∅→∅) + if must_reintroduce::<_, _, W>(
replacement in libpijul/src/unrecord/mod.rs at line 499
[10.241975]→[10.11835:11897](∅→∅) − fn must_reintroduce<T: GraphTxnT + TreeTxnT, C: ChangeStore>(
+ fn must_reintroduce<T: GraphTxnT + TreeTxnT, C: ChangeStore, W: WorkingCopy>(
replacement in libpijul/src/unrecord/mod.rs at line 508
[10.1958]→[10.11898:11946](∅→∅) − ) -> Result<bool, UnrecordError<C::Error, T>> {
+ ) -> Result<bool, UnrecordError<C::Error, W::Error, T>> {
replacement in libpijul/src/unrecord/mod.rs at line 539
[10.243198]→[10.243198:243261](∅→∅) − edge_is_in_channel(txn, changes, b_ext, intro, &mut stack)
+ edge_is_in_channel::<_, _, W>(txn, changes, b_ext, intro, &mut stack)
replacement in libpijul/src/unrecord/mod.rs at line 542
[10.243264]→[10.11947:12011](∅→∅) − fn edge_is_in_channel<T: GraphTxnT + TreeTxnT, C: ChangeStore>(
+ fn edge_is_in_channel<T: GraphTxnT + TreeTxnT, C: ChangeStore, W: WorkingCopy>(
replacement in libpijul/src/unrecord/mod.rs at line 548
[10.243431]→[10.12012:12060](∅→∅) − ) -> Result<bool, UnrecordError<C::Error, T>> {
+ ) -> Result<bool, UnrecordError<C::Error, W::Error, T>> {
replacement in libpijul/src/unrecord/mod.rs at line 571
[7.1048]→[10.12061:12124](∅→∅),
[10.243938]→[10.12061:12124](∅→∅) − fn remove_zombies<T: GraphMutTxnT + TreeTxnT, C: ChangeStore>(
+ fn remove_zombies<T: GraphMutTxnT + TreeTxnT, C: ChangeStore, W: WorkingCopy>(
replacement in libpijul/src/unrecord/mod.rs at line 577
[10.244079]→[10.12125:12171](∅→∅) − ) -> Result<(), UnrecordError<C::Error, T>> {
+ ) -> Result<(), UnrecordError<C::Error, W::Error, T>> {
replacement in libpijul/src/tests/unrecord.rs at line 30
[10.1353]→[10.1353:1432](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 68
[10.1907]→[10.1907:1986](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 106
[10.252428]→[10.2451:2530](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 203
[10.255738]→[10.4125:4204](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h2, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h2, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 259
[10.257744]→[10.5018:5097](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h2, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h2, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 294
[10.258960]→[10.5328:5409](∅→∅) − crate::unrecord::unrecord(&mut *txn2.write(), &channel2, &changes, &h1, 0)?;
+ crate::unrecord::unrecord(&mut *txn2.write(), &channel2, &changes, &h1, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 331
[10.260384]→[10.5987:6066](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 388
[10.262135]→[10.6628:6713](∅→∅) − match crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h0, 0) {
+ match crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h0, 0, &repo) {
replacement in libpijul/src/tests/unrecord.rs at line 395
[10.6811]→[10.6811:6897](∅→∅) − match crate::unrecord::unrecord(&mut *txn.write(), &channel2, &changes, &h0, 0) {
+ match crate::unrecord::unrecord(&mut *txn.write(), &channel2, &changes, &h0, 0, &repo) {
replacement in libpijul/src/tests/unrecord.rs at line 405
[10.6991]→[10.6991:7070](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 412
[10.7164]→[10.7164:7243](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h0, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h0, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 451
[10.264448]→[10.7795:7873](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 462
[10.264932]→[10.7938:8017](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h0, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h0, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 532
[10.267354]→[10.8726:8808](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &mut channel, &changes, &c, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &mut channel, &changes, &c, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 622
[10.270241]→[10.9344:9426](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h_inv, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h_inv, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 680
[10.272403]→[10.10093:10172](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h2, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h2, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 736
[10.274399]→[10.10847:10930](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &mut channel, &changes, &h2, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &mut channel, &changes, &h2, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 771
[10.275627]→[10.11154:11238](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &mut channel2, &changes, &h1, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &mut channel2, &changes, &h1, 0, &repo)?;
replacement in libpijul/src/tests/unrecord.rs at line 817
[10.1611]→[10.11905:12063](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0)?;
− crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h2, 0)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0, &repo)?;
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h2, 0, &repo)?;
edit in libpijul/src/tests/unrecord.rs at line 826
+ Ok(())
+ }
+
+ /// Delete the same file on two different channels, merge, unrecord each patch on the same channel. What happens to tree/revtree?
+ #[test]
+ fn fs_times() -> Result<(), anyhow::Error> {
+ env_logger::try_init().unwrap_or(());
+
+ let repo = working_copy::memory::Memory::new();
+ let changes = changestore::memory::Memory::new();
+
+ let env = pristine::sanakirja::Pristine::new_anon()?;
+ let txn = env.arc_txn_begin().unwrap();
+ let channel = txn.write().open_or_create_channel("main")?;
+
+ repo.add_file("file", b"blabla\nblibli\nblublu\n".to_vec());
+ repo.add_file("file2", b"blabla\nblibli\nblublu\n".to_vec());
+ txn.write().add_file("file", 0)?;
+ txn.write().add_file("file2", 0)?;
+ let h0 = record_all(&repo, &changes, &txn, &channel, "")?;
+ debug!("h0 = {:?}", h0);
+ repo.write_file("file", Inode::ROOT)?
+ .write_all(b"blabla\nblublu\n")?;
+
+ let h1 = record_all(&repo, &changes, &txn, &channel, "")?;
+
+ debug!("last {:?}", txn.read().last_modified(&channel.r.read()));
+
+ // Modify file2, but set its modification time one hour ago, so we
+ // can check that `unrecord` doesn't read the entire repo.
+ repo.write_file("file2", Inode::ROOT)?
+ .write_all(b"blabla\nblublu\n")?;
+ repo.touch(
+ "file2",
+ std::time::SystemTime::now() - std::time::Duration::from_hours(1),
+ )?;
+
+ crate::unrecord::unrecord(&mut *txn.write(), &channel, &changes, &h1, 0, &repo)?;
+
+ debug!("last {:?}", txn.read().last_modified(&channel.r.read()));
+
+ info!("Final record");
+ let h1 = record_all(&repo, &changes, &txn, &channel, "")?;
+ let change1 = changes.get_change(&h1).unwrap();
+ assert_eq!(change1.changes.len(), 1);
+
edit in libpijul/src/tests/missing_context.rs at line 101
replacement in libpijul/src/tests/missing_context.rs at line 103
[10.22508]→[10.22508:22602](∅→∅) − crate::unrecord::unrecord(&mut *txn_alice.write(), &channel_alice, &changes, &bob_h, 0)?;
+ crate::unrecord::unrecord(
+ &mut *txn_alice.write(),
+ &channel_alice,
+ &changes,
+ &bob_h,
+ 0,
+ &repo_alice,
+ )?;
edit in libpijul/src/tests/missing_context.rs at line 155
edit in libpijul/src/tests/file_conflicts.rs at line 1460
replacement in libpijul/src/tests/diff.rs at line 28
[10.1138]→[10.1138:1230](∅→∅),
[10.1230]→[9.81:108](∅→∅),
[9.108]→[10.1290:1301](∅→∅),
[10.1290]→[10.1290:1301](∅→∅) − contents.extend(
− (&mut rng)
− .sample_iter(&Alphanumeric)
− .take(80),
− );
+ contents.extend((&mut rng).sample_iter(&Alphanumeric).take(80));
replacement in libpijul/src/tests/conflict.rs at line 179
[10.362243]→[10.51524:51623](∅→∅) − crate::unrecord::unrecord(&mut *txn.write(), &channel_bob, &changes, &resolution, 0).unwrap();
+ crate::unrecord::unrecord(
+ &mut *txn.write(),
+ &channel_bob,
+ &changes,
+ &resolution,
+ 0,
+ &repo_bob,
+ )
+ .unwrap();
edit in libpijul/src/tests/conflict.rs at line 2279
edit in libpijul/src/record.rs at line 550
+
+ txn.write().touch_channel(&mut channel.write(), None);
replacement in libpijul/src/record.rs at line 909
[10.160]→[10.56558:56597](∅→∅),
[10.56558]→[10.56558:56597](∅→∅) − txn.last_modified(channel)
+ txn.last_modified(channel),
edit in libpijul/src/record.rs at line 922
+ debug!("recording = {:?}", last_mod >= channel_mod);
replacement in libpijul/src/record.rs at line 1357
[10.2023]→[10.2023:2051](∅→∅) replacement in libpijul/src/pristine/mod.rs at line 2156
[10.750]→[10.590:633](∅→∅),
[10.2073]→[10.590:633](∅→∅),
[10.77352]→[10.590:633](∅→∅),
[10.590]→[10.590:633](∅→∅) − let path = path.replace("/", "_");
+ let path = path.join("_");
edit in libpijul/src/output/archive.rs at line 3
+ use crate::working_copy::WorkingCopy;
edit in libpijul/src/output/archive.rs at line 104
+ W: std::error::Error + 'static,
replacement in libpijul/src/output/archive.rs at line 115
[10.25482]→[10.25482:25542](∅→∅) − Unrecord(#[from] crate::unrecord::UnrecordError<P, T>),
+ Unrecord(#[from] crate::unrecord::UnrecordError<P, W, T>),
replacement in libpijul/src/output/archive.rs at line 126
[10.692169]→[10.31345:31485](∅→∅) − impl<P: std::error::Error + 'static, T: GraphTxnT + TreeTxnT, A: std::error::Error + 'static>
− std::fmt::Debug for ArchiveError<P, T, A>
+ impl<
+ P: std::error::Error + 'static,
+ T: GraphTxnT + TreeTxnT,
+ A: std::error::Error + 'static,
+ W: std::error::Error + 'static,
+ > std::fmt::Debug for ArchiveError<P, T, A, W>
edit in libpijul/src/output/archive.rs at line 154
replacement in libpijul/src/output/archive.rs at line 161
[10.692359]→[10.32308:32374](∅→∅) − ) -> Result<Vec<Conflict>, ArchiveError<P::Error, T, A::Error>> {
+ ) -> Result<Vec<Conflict>, ArchiveError<P::Error, T, A::Error, W::Error>> {
replacement in libpijul/src/lib.rs at line 219
[10.725196]→[10.725196:725242](∅→∅) − fn unrecord<C: changestore::ChangeStore>(
+ fn unrecord<C: changestore::ChangeStore, W: working_copy::WorkingCopy>(
replacement in libpijul/src/lib.rs at line 225
[10.4209]→[10.33168:33233](∅→∅),
[10.33233]→[10.4210:4273](∅→∅),
[10.94683]→[10.4210:4273](∅→∅) − ) -> Result<bool, unrecord::UnrecordError<C::Error, Self>> {
− unrecord::unrecord(self, channel, changes, hash, salt)
+ working_copy: &W,
+ ) -> Result<bool, unrecord::UnrecordError<C::Error, W::Error, Self>> {
+ unrecord::unrecord(self, channel, changes, hash, salt, working_copy)
replacement in libpijul/src/lib.rs at line 431
[10.732181]→[10.104220:104291](∅→∅) − fs::find_path(changes, self, &channel.read(), false, position)
+ if let Some((a, b)) = fs::find_path(changes, self, &channel.read(), false, position)? {
+ Ok(Some((a.join("/"), b)))
+ } else {
+ Ok(None)
+ }
replacement in libpijul/src/lib.rs at line 448
[10.732653]→[10.104292:104362](∅→∅) − fs::find_path(changes, self, &channel.read(), true, position)
+ if let Some((a, b)) = fs::find_path(changes, self, &channel.read(), true, position)? {
+ Ok(Some((a.join("/"), b)))
+ } else {
+ Ok(None)
+ }
replacement in libpijul/src/lib.rs at line 476
[10.6399]→[10.6399:6460](∅→∅) − pub fn archive<C: changestore::ChangeStore, A: Archive>(
+ pub fn archive<C: changestore::ChangeStore, A: Archive, W: working_copy::WorkingCopy>(
replacement in libpijul/src/lib.rs at line 481
[10.733724]→[10.6505:6591](∅→∅),
[10.6591]→[10.733780:733859](∅→∅),
[10.30328]→[10.733780:733859](∅→∅),
[10.34199]→[10.733780:733859](∅→∅),
[10.99249]→[10.733780:733859](∅→∅),
[10.733780]→[10.733780:733859](∅→∅) − ) -> Result<Vec<output::Conflict>, output::ArchiveError<C::Error, T, A::Error>> {
− output::archive(changes, self, channel, &mut std::iter::empty(), arch)
+ ) -> Result<Vec<output::Conflict>, output::ArchiveError<C::Error, T, A::Error, W::Error>> {
+ output::archive::<_, _, _, _, W>(changes, self, channel, &mut std::iter::empty(), arch)
edit in libpijul/src/lib.rs at line 490
+ W: working_copy::WorkingCopy,
replacement in libpijul/src/lib.rs at line 497
[10.734091]→[10.6777:6863](∅→∅),
[10.6863]→[10.734147:734209](∅→∅),
[10.30425]→[10.734147:734209](∅→∅),
[10.34289]→[10.734147:734209](∅→∅),
[10.99355]→[10.734147:734209](∅→∅),
[10.734147]→[10.734147:734209](∅→∅) − ) -> Result<Vec<output::Conflict>, output::ArchiveError<C::Error, T, A::Error>> {
− output::archive(changes, self, channel, prefix, arch)
+ ) -> Result<Vec<output::Conflict>, output::ArchiveError<C::Error, T, A::Error, W::Error>> {
+ output::archive::<_, _, _, _, W>(changes, self, channel, prefix, arch)
replacement in libpijul/src/lib.rs at line 503
[10.6902]→[10.6902:6974](∅→∅) − pub fn archive_with_state<P: changestore::ChangeStore, A: Archive>(
+ pub fn archive_with_state<
+ P: changestore::ChangeStore,
+ A: Archive,
+ W: working_copy::WorkingCopy,
+ >(
replacement in libpijul/src/lib.rs at line 515
[10.7162]→[10.7162:7248](∅→∅) − ) -> Result<Vec<output::Conflict>, output::ArchiveError<P::Error, T, A::Error>> {
+ working_copy: &W,
+ ) -> Result<Vec<output::Conflict>, output::ArchiveError<P::Error, T, A::Error, W::Error>> {
edit in libpijul/src/lib.rs at line 525
edit in libpijul/src/lib.rs at line 536
+ W: working_copy::WorkingCopy,
replacement in libpijul/src/lib.rs at line 547
[10.7966]→[10.7966:8052](∅→∅) − ) -> Result<Vec<output::Conflict>, output::ArchiveError<P::Error, T, A::Error>> {
+ working_copy: &W,
+ ) -> Result<Vec<output::Conflict>, output::ArchiveError<P::Error, T, A::Error, W::Error>> {
replacement in libpijul/src/lib.rs at line 566
[10.8641]→[10.8641:8717](∅→∅) − unrecord::unrecord(&mut *txn, channel, changes, &h, salt)?;
+ unrecord::unrecord(&mut *txn, channel, changes, &h, salt, working_copy)?;
replacement in libpijul/src/lib.rs at line 575
[10.9003]→[10.9003:9069](∅→∅) − output::archive(changes, self, channel, prefix, arch)
+ output::archive::<_, _, _, _, W>(changes, self, channel, prefix, arch)
replacement in libpijul/src/fs.rs at line 181
[10.9]→[10.741561:741617](∅→∅),
[10.4882]→[10.741561:741617](∅→∅),
[10.741561]→[10.741561:741617](∅→∅) − /// Find the filename leading from the root to ~inode~.
+ /// Find the filename leading from the root to `inode`.
edit in libpijul/src/fs.rs at line 952
+ /// Compute either the oldest or the youngest filesystem path to a
+ /// graph vertex.
replacement in libpijul/src/fs.rs at line 960
[10.761102]→[10.36150:36227](∅→∅) − ) -> Result<Option<(String, bool)>, crate::output::FileError<C::Error, T>> {
+ ) -> Result<Option<(Vec<String>, bool)>, crate::output::FileError<C::Error, T>> {
replacement in libpijul/src/fs.rs at line 1062
[10.763251]→[10.2748:2790](∅→∅) − Ok(Some((path.join("/"), all_alive)))
+ Ok(Some((path, all_alive)))