Tag synchronisation

pmeunier
Dec 21, 2021, 10:55 AM
DO2Y5TY5JQISUHCVNPI2FXO7WWZVJQ3LGPWF4DNADMGZRIO6PT2QC

Dependencies

  • [2] 2GQCLJZG Displaying errors returned by the server in the protocol
  • [3] FGVTXN52 Filter linebreak from http::get_state() response
  • [4] 3OW3YNZX Dependencies completion in push and pull, updated after stabilisation of remote caches
  • [5] YD7QFAD7 Simplifying pijul::remote::PushDelta
  • [6] ILZ44DEY simplify outputting with no touched paths
  • [7] JZADJIA3 Handling HTTP errors
  • [8] TA5VXGFG Fixing compilation errors
  • [9] 5MRZLKBH Changing the type of the tags db, to make it identical to remote tags
  • [10] CQ3FIUY4 Fixing tag corruption
  • [11] SXEYMYF7 Fixing the bad changes in history (unfortunately, by rebooting).
  • [12] SE4RJYBZ No pager on Windows (really not)
  • [13] GHO6DWPI Refactoring iterators
  • [14] 2V33SO6I dont unwrap name() for RemoteRepo::LocalChannel
  • [15] FXEDPLRI Resurrecting tests, and type cleanup (no need for Arc<RwLock<…>> anymore)
  • [16] BVVMTOYW Proper renaming of changes downloaded over HTTP
  • [17] FE5ES6Q4 Stop pushing/pulling if the remote returns an error
  • [18] WKX5S4Z4 remove unneccesary explicit lifetimes
  • [19] CCLLB7OI Upgrading to Sanakirja 0.15 + version bump
  • [20] JRENVH5D Reqwest 0.11
  • [21] 3KRGVQFU Do not update the mtime of unmodified files
  • [22] XSRTXUAS Pull: show progress bar when applying
  • [23] L4JXJHWX pijul/*: reorganize imports and remove extern crate
  • [24] BE7GUCI2 Completing dependencies only with changes the remote does not have
  • [25] IQ4FCHPZ HTTP connections: pooling + retry on error
  • [26] GNMZNKB4 Cursors cleanup
  • [27] BAUL3WR2 Format, versions, README
  • [28] L5IUD2DS Fixing the regular expression parsing the protocol lines
  • [29] YN63NUZO Sanakirja 1.0
  • [30] I24UEJQL Various post-fire fixes
  • [31] EUZFFJSO Updating Pijul with the latest changes in Libpijul
  • [32] WZVCLZKY address clippy lints
  • [33] 7ZROQSSN Handling TAG uploads from the `pijul protocol` command
  • [34] AETYXHGO Using an LruCache instead of a HashMap for loaded pages in a tag
  • [35] AF5AKUTO Cleanup after the text changes refactoring
  • [36] OIOMXESD Better error handling in HTTP
  • [37] Q45QHPO4 Feedback on network stuff
  • [38] 5SCFAC4I Fixing the unrecord of tags
  • [39] KI2AFWOS Fixing a panic in pull
  • [40] BNPSVXIC Friendlier progress bars
  • [41] KTTKF3RW Locking stderr and the progress bar in SSH
  • [42] PCEJFKFX Progress bar for upload and apply
  • [43] C5XGFNKI Simplify return type for remote get_id
  • [44] PIQCNEEB Upgrading to Clap 3.0.0-alpha.5
  • [45] AI73GKAO Adding a UserAgent header to the http downloader
  • [46] I52XSRUH Massive cleanup, and simplification
  • [47] 76PCXGML Pushing to, and pulling from the local repository
  • [48] C267PHOH Tags: dropping useless Hashes in favour of Merkles
  • [49] JLVRAJA5 Using iter_graph in pijul
  • [50] Y6EVFMTA Don't output files if they aren't in the current channel
  • [51] 44BN7FWS Do not output files introduced by patches that were not applied during a push
  • [52] A3RM526Y Integrating identity malleability
  • [53] SLJ3OHD4 unrecord: show list of changes if none were given as arguments
  • [54] ISCWVXO6 Progress bar for push
  • [55] ZSFJT4SF Allow remotes to have a different push and pull address
  • [56] N3X5YP7P Adding tag/txn.rs, now that the parser allows it
  • [57] RM225IDQ Exchanging tagged states over SSH
  • [58] 5HF7C67M push/pull: fixed "changes" arguments
  • [59] 367UBQ6K Forwarding SSH stderr, and progress bar for push
  • [60] SMMBFECL Converting to the new patch format "online"
  • [61] VO5OQW4W Removing anyhow in libpijul
  • [62] GLRGFBCW Checking the version of less we have
  • [63] 2D7P2VKJ Change completions (where the whole progress bar story started)
  • [64] L3RCAPPK Add --repository to tag commands
  • [65] GYXIF25T Proper parsing of URLs
  • [66] WLUID7NA Do not block when downloading more than 100 changes over SSH
  • [67] VBMXB443 Retrying if the HTTP connection drops while reading the body
  • [68] M5FK3ABT Complete dependencies when pushing and pulling
  • [69] TKEVOH7H Fixing a bug when downloading changes, and making change download more efficient (more async)
  • [70] IIV3EL2X Cleanup, formatting, and fixing the Git feature
  • [71] AAXP2534 Tags: completing the subcommand
  • [72] 5OGOE4VW Store the current channel in the pristine
  • [73] IVLLXQ5Z Improved push/pull reporting
  • [74] Q7CAYX5N Fixing Windows compilation
  • [75] YS2HLPX6 Don't propose an empty list of changes to push
  • [76] 5BRU2RRW Cleanup (debugging a crash related to trees/inodes)
  • [77] K6GWUOD5 Styling progress bars
  • [78] MU5GSJAW Partial push and pull (WARNING: breaks the existing protocol)
  • [79] ZRUPLBBT Colours in diff and change: separating concerns and dependencies
  • [80] UTEVDVGB Don't hardlink the same changefile twice
  • [81] QL6K2ZM3 Tags
  • [82] L2VH4BYK Downloading changelists from channels without an id (Nest discussions)
  • [83] K4CVMIUK Do not present changes we know as "unknown" on the remote
  • [84] TPEH2XNB 1.0.0-alpha.28, with Tokio 1.0
  • [85] 27RZYCM3 Pushing/pulling from/to Nest discussions again
  • [86] 7SQ7COLT Add length check to pijul remote delete
  • [87] ZDK3GNDB Tag transactions (including a massive refactoring of errors)
  • [88] 7HOBLRD4 Fixing remote push/pull
  • [89] QDP3R3BG Updating with the latest Sanakirja
  • [90] 6ZPDI7QG pull uses None as the base case path when outputing repo
  • [91] 3WO4H2MM Fixing async issues in downloads
  • [92] XWETQ4DE Upgrading versions
  • [93] X6YFD4WV Do not download changes if we already have them
  • [94] 5SLOJYHG Fixing the Git feature
  • [95] UDHP4ZVB Fixing SSH asynchronicity issues
  • [96] GUL4M5FI Cleanup and formatting
  • [97] RRCSHAYZ Formatting
  • [98] 3ZAS64J6 Solving conflicts
  • [*] FBXYP7QM Forgot to add remote::http
  • [*] AEPEFS7O Write help for each argument
  • [*] 4H2XTVJ2 Fix some mistakes in the docs
  • [*] FDEVV5NG Tag check
  • [*] RIAA2QKF Making Merkle std::hash::Hash

Change contents

  • edit in pijul/src/remote/ssh.rs at line 19
    [11.62]
    [11.384]
    use crate::remote::CS;
  • replacement in pijul/src/remote/ssh.rs at line 299
    [11.255][11.255:332]()
    sender: Option<tokio::sync::oneshot::Sender<Option<(u64, Merkle)>>>,
    [11.255]
    [11.332]
    sender: Option<tokio::sync::oneshot::Sender<Option<(u64, Merkle, Merkle)>>>,
  • replacement in pijul/src/remote/ssh.rs at line 305
    [11.353][11.353:410]()
    sender: Option<tokio::sync::mpsc::Sender<Hash>>,
    [11.353]
    [11.410]
    sender: Option<tokio::sync::mpsc::Sender<CS>>,
  • replacement in pijul/src/remote/ssh.rs at line 310
    [11.29][11.492:539](),[11.492][11.492:539]()
    hashes: Vec<libpijul::pristine::Hash>,
    [11.29]
    [11.539]
    hashes: Vec<CS>,
  • replacement in pijul/src/remote/ssh.rs at line 456
    [11.1995][11.1995:2117]()
    debug!("s = {:?}", s);
    if let (Some(n), Some(m)) = (s.next(), s.next()) {
    [11.1995]
    [11.2117]
    if let (Some(n), Some(m), Some(m2)) = (s.next(), s.next(), s.next()) {
  • replacement in pijul/src/remote/ssh.rs at line 459
    [11.2208][11.2208:2308]()
    .send(Some((n, Merkle::from_base32(m.trim().as_bytes()).unwrap())))
    [11.2208]
    [11.2308]
    .send(Some((
    n,
    Merkle::from_base32(m.trim().as_bytes()).unwrap(),
    Merkle::from_base32(m2.trim().as_bytes()).unwrap(),
    )))
  • replacement in pijul/src/remote/ssh.rs at line 512
    [11.72][11.72:276](),[11.276][11.3706:3847](),[11.3706][11.3706:3847](),[11.3847][11.277:556]()
    libpijul::changestore::filesystem::push_filename(
    final_path,
    &hashes[*current],
    );
    final_path.set_extension("change");
    debug!("moving {:?} to {:?}", path, final_path);
    std::fs::create_dir_all(&final_path.parent().unwrap())?;
    let r = std::fs::rename(&path, &final_path);
    libpijul::changestore::filesystem::pop_filename(final_path);
    r?;
    [11.72]
    [11.0]
    match hashes[*current] {
    CS::Change(ref h) => {
    libpijul::changestore::filesystem::push_filename(final_path, h);
    debug!("moving {:?} to {:?}", path, final_path);
    std::fs::create_dir_all(&final_path.parent().unwrap())?;
    let r = std::fs::rename(&path, &final_path);
    libpijul::changestore::filesystem::pop_filename(final_path);
    r?;
    }
    CS::State(h) => {
    libpijul::changestore::filesystem::push_tag_filename(
    final_path, &h,
    );
    debug!("moving {:?} to {:?}", path, final_path);
    std::fs::create_dir_all(&final_path.parent().unwrap())?;
    let r = std::fs::rename(&path, &final_path);
    libpijul::changestore::filesystem::pop_filename(final_path);
    r?;
    }
    }
  • replacement in pijul/src/remote/ssh.rs at line 737
    [11.36194][11.36194:36250]()
    ) -> Result<Option<(u64, Merkle)>, anyhow::Error> {
    [11.36194]
    [11.7760]
    ) -> Result<Option<(u64, Merkle, Merkle)>, anyhow::Error> {
  • replacement in pijul/src/remote/ssh.rs at line 889
    [11.528][11.91:184]()
    super::ListLine::Change { n, h, m, is_tagged } => f(a, n, h, m, is_tagged)?,
    [11.528]
    [11.659]
    super::ListLine::Change { n, h, m, tag } => f(a, n, h, m, tag)?,
  • replacement in pijul/src/remote/ssh.rs at line 910
    [11.44434][11.44434:44460]()
    changes: &[Hash],
    [11.44434]
    [11.44460]
    changes: &[CS],
  • edit in pijul/src/remote/ssh.rs at line 916
    [11.31][11.44594:44796](),[11.44594][11.44594:44796](),[11.44796][11.0:82](),[11.82][11.44880:44965](),[11.44880][11.44880:44965]()
    libpijul::changestore::filesystem::push_filename(&mut local, &c);
    let mut change_file = std::fs::File::open(&local)?;
    let change_len = change_file.metadata()?.len();
    let mut change = thrussh::CryptoVec::new_zeroed(change_len as usize);
    use std::io::Read;
    change_file.read_exact(&mut change[..])?;
  • replacement in pijul/src/remote/ssh.rs at line 921
    [11.45116][11.45116:45306](),[11.499][11.45306:45379](),[11.633][11.45306:45379](),[11.45306][11.45306:45379]()
    self.c
    .data(format!("apply {} {} {}\n", to_channel, c.to_base32(), change_len).as_bytes())
    .await?;
    self.c.data(&change[..]).await?;
    libpijul::changestore::filesystem::pop_filename(&mut local);
    [11.45116]
    [11.23]
    match c {
    CS::Change(c) => {
    libpijul::changestore::filesystem::push_filename(&mut local, &c);
    let mut change_file = std::fs::File::open(&local)?;
    let change_len = change_file.metadata()?.len();
    let mut change = thrussh::CryptoVec::new_zeroed(change_len as usize);
    use std::io::Read;
    change_file.read_exact(&mut change[..])?;
    self.c
    .data(
    format!("apply {} {} {}\n", to_channel, c.to_base32(), change_len)
    .as_bytes(),
    )
    .await?;
    self.c.data(&change[..]).await?;
    libpijul::changestore::filesystem::pop_filename(&mut local);
    }
    CS::State(c) => {
    libpijul::changestore::filesystem::push_tag_filename(&mut local, &c);
    let mut tag_file = libpijul::tag::OpenTagFile::open(&local, &c)?;
    let mut v = Vec::new();
    tag_file.short(&mut v)?;
    self.c
    .data(
    format!("tagup {} {} {}\n", c.to_base32(), to_channel, v.len())
    .as_bytes(),
    )
    .await?;
    self.c.data(&v[..]).await?;
    libpijul::changestore::filesystem::pop_filename(&mut local);
    }
    }
  • replacement in pijul/src/remote/ssh.rs at line 961
    [11.22][11.143:223](),[11.143][11.143:223](),[11.223][11.8746:8820](),[11.536][11.8746:8820](),[11.8746][11.8746:8820]()
    c: &mut tokio::sync::mpsc::UnboundedReceiver<libpijul::pristine::Hash>,
    sender: &mut tokio::sync::mpsc::Sender<libpijul::pristine::Hash>,
    [11.22]
    [11.8820]
    c: &mut tokio::sync::mpsc::UnboundedReceiver<CS>,
    sender: &mut tokio::sync::mpsc::Sender<CS>,
  • replacement in pijul/src/remote/ssh.rs at line 973
    [11.120][11.374:536](),[11.374][11.374:536]()
    c: &mut tokio::sync::mpsc::UnboundedReceiver<libpijul::pristine::Hash>,
    sender: Option<&mut tokio::sync::mpsc::Sender<libpijul::pristine::Hash>>,
    [11.120]
    [11.334]
    c: &mut tokio::sync::mpsc::UnboundedReceiver<CS>,
    sender: Option<&mut tokio::sync::mpsc::Sender<CS>>,
  • replacement in pijul/src/remote/ssh.rs at line 1010
    [11.1197][11.1197:1497]()
    if full {
    self.c
    .data(format!("change {}\n", h.to_base32()).as_bytes())
    .await?;
    } else {
    self.c
    .data(format!("partial {}\n", h.to_base32()).as_bytes())
    .await?;
    [11.1197]
    [11.1443]
    match h {
    CS::Change(h) if full => {
    self.c
    .data(format!("change {}\n", h.to_base32()).as_bytes())
    .await?;
    }
    CS::Change(h) => {
    self.c
    .data(format!("partial {}\n", h.to_base32()).as_bytes())
    .await?;
    }
    CS::State(h) => {
    self.c
    .data(format!("tag {}\n", h.to_base32()).as_bytes())
    .await?;
    }
  • edit in pijul/src/remote/mod.rs at line 35
    [11.52848]
    [11.52848]
    }
    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
    pub enum CS {
    Change(Hash),
    State(Merkle),
  • replacement in pijul/src/remote/mod.rs at line 167
    [5.30][11.1300:1330](),[11.1300][11.1300:1330](),[11.1372][11.1372:1449]()
    pub to_upload: Vec<Hash>,
    pub remote_unrecs: Vec<(u64, Hash)>,
    pub unknown_changes: Vec<Hash>,
    [5.30]
    [11.1449]
    pub to_upload: Vec<CS>,
    pub remote_unrecs: Vec<(u64, CS)>,
    pub unknown_changes: Vec<CS>,
  • replacement in pijul/src/remote/mod.rs at line 195
    [11.2895][11.2895:2927](),[11.2927][11.185:216]()
    pub to_download: Vec<Hash>,
    pub tags: HashSet<Merkle>,
    [11.2895]
    [11.2927]
    pub to_download: Vec<CS>,
  • replacement in pijul/src/remote/mod.rs at line 197
    [11.2969][11.2969:3063]()
    pub ours_ge_dichotomy_set: HashSet<Hash>,
    pub theirs_ge_dichotomy_set: HashSet<Hash>,
    [11.2969]
    [11.3063]
    pub ours_ge_dichotomy_set: HashSet<CS>,
    pub theirs_ge_dichotomy_set: HashSet<CS>,
  • replacement in pijul/src/remote/mod.rs at line 202
    [11.278][11.3250:3291](),[11.3250][11.3250:3291]()
    pub remote_unrecs: Vec<(u64, Hash)>,
    [11.278]
    [11.3291]
    pub remote_unrecs: Vec<(u64, CS)>,
  • replacement in pijul/src/remote/mod.rs at line 216
    [5.75][11.3701:3749](),[11.3701][11.3701:3749]()
    let mut to_upload = Vec::<Hash>::new();
    [5.75]
    [11.3749]
    let mut to_upload = Vec::new();
  • replacement in pijul/src/remote/mod.rs at line 226
    [11.4209][11.4209:4258]()
    to_upload.push(h.into())
    [11.4209]
    [11.4258]
    to_upload.push(CS::Change(h.into()))
  • replacement in pijul/src/remote/mod.rs at line 230
    [11.4418][11.4418:4476]()
    to_upload.push(h.into());
    [11.4418]
    [11.4476]
    to_upload.push(CS::Change(h.into()));
  • replacement in pijul/src/remote/mod.rs at line 258
    [5.120][11.5372:5420](),[11.5372][11.5372:5420]()
    let mut to_upload = Vec::<Hash>::new();
    [5.120]
    [11.5420]
    let mut to_upload = Vec::new();
  • edit in pijul/src/remote/mod.rs at line 261
    [11.5542]
    [11.5542]
    let mut tags: HashSet<Merkle> = HashSet::new();
    for x in txn.rev_iter_tags(&channel.read().tags, None)? {
    let (n, m) = x?;
    debug!("rev_iter_tags {:?} {:?}", n, m);
    // First, if the remote has exactly the same first n tags, break.
    if let Some((_, p)) = txn.get_remote_tag(&remote_ref.lock().tags, (*n).into())? {
    if p.b == m.b {
    debug!("the remote has tag {:?}", p.a);
    break;
    }
    if p.a != m.a {
    // What to do here? It is possible that state
    // `n` is a different state than `m.a` in the
    // remote, and is also tagged.
    }
    } else {
    tags.insert(m.a.into());
    }
    }
    debug!("tags = {:?}", tags);
  • replacement in pijul/src/remote/mod.rs at line 283
    [11.5644][11.5644:5730]()
    if txn.remote_has_state(remote_ref, &m)? {
    break;
    [11.5644]
    [11.5730]
    let h_unrecorded = self
    .remote_unrecs
    .iter()
    .any(|(_, hh)| hh == &CS::Change(h.into()));
    if !h_unrecorded {
    if txn.remote_has_state(remote_ref, &m)?.is_some() {
    debug!("remote_has_state: {:?}", m);
    break;
    }
  • replacement in pijul/src/remote/mod.rs at line 298
    [11.6075][11.6075:6134](),[11.6134][11.6134:6206]()
    if !txn.remote_has_change(remote_ref, &h)?
    && !self.theirs_ge_dichotomy_set.contains(&h_deser)
    [11.6075]
    [11.6206]
    if (!txn.remote_has_change(remote_ref, &h)? || h_unrecorded)
    && !self.theirs_ge_dichotomy_set.contains(&CS::Change(h_deser))
  • replacement in pijul/src/remote/mod.rs at line 302
    [11.6267][11.6267:6315]()
    to_upload.push(h_deser)
    [11.6267]
    [11.6315]
    if tags.remove(&m.into()) {
    to_upload.push(CS::State(m.into()));
    }
    to_upload.push(CS::Change(h_deser));
  • replacement in pijul/src/remote/mod.rs at line 309
    [11.6475][11.6475:6532]()
    to_upload.push(h_deser);
    [11.6475]
    [11.6532]
    to_upload.push(CS::Change(h_deser));
    if tags.remove(&m.into()) {
    to_upload.push(CS::State(m.into()));
    }
  • edit in pijul/src/remote/mod.rs at line 317
    [11.6649]
    [11.6649]
    }
    }
    for t in tags.iter() {
    if let Some(n) = txn.remote_has_state(&remote_ref, &t.into())? {
    if !txn.is_tagged(&remote_ref.lock().tags, n)? {
    to_upload.push(CS::State(*t));
    }
    } else {
    debug!("the remote doesn't have state {:?}", t);
  • replacement in pijul/src/remote/mod.rs at line 333
    [11.6896][11.6896:6984](),[11.6984][11.279:320](),[11.320][11.0:132](),[11.7022][11.0:132]()
    let unknown_changes = self
    .theirs_ge_dichotomy
    .iter()
    .filter_map(|(_, h, _, _)| {
    if self.ours_ge_dichotomy_set.contains(h)
    || txn.get_revchanges(&channel, h).unwrap().is_some()
    [11.6896]
    [11.132]
    let mut unknown_changes = Vec::new();
    for (_, h, m, is_tag) in self.theirs_ge_dichotomy.iter() {
    let h_is_known = txn.get_revchanges(&channel, h).unwrap().is_some();
    let change = CS::Change(*h);
    if !(self.ours_ge_dichotomy_set.contains(&change) || h_is_known) {
    unknown_changes.push(change)
    }
    if *is_tag {
    let m_is_known = if let Some(n) = txn
    .channel_has_state(txn.states(&*channel.read()), &m.into())
    .unwrap()
  • replacement in pijul/src/remote/mod.rs at line 345
    [11.150][11.7082:7107](),[11.7082][11.7082:7107]()
    None
    [11.150]
    [11.7107]
    txn.is_tagged(txn.tags(&*channel.read()), n.into()).unwrap()
  • replacement in pijul/src/remote/mod.rs at line 347
    [11.7132][11.7132:7161]()
    Some(*h)
    [11.7132]
    [11.7161]
    false
    };
    if !m_is_known {
    unknown_changes.push(CS::State(*m))
  • replacement in pijul/src/remote/mod.rs at line 352
    [11.7179][11.7179:7194](),[11.7194][11.7194:7231]()
    })
    .collect::<Vec<Hash>>();
    [11.7179]
    [11.7231]
    }
    }
  • replacement in pijul/src/remote/mod.rs at line 379
    [11.316][11.321:358]()
    to_download.push(h);
    [11.316]
    [11.352]
    to_download.push(CS::Change(h));
  • edit in pijul/src/remote/mod.rs at line 385
    [11.402][11.359:393]()
    tags: HashSet::new(),
  • edit in pijul/src/remote/mod.rs at line 399
    [11.8828][11.394:433]()
    let mut tags = HashSet::new();
  • replacement in pijul/src/remote/mod.rs at line 402
    [11.9021][11.434:472]()
    let (n, (h, m)) = x?;
    [11.9021]
    [11.9056]
    let (_, (h, m)) = x?;
  • replacement in pijul/src/remote/mod.rs at line 421
    [11.9776][11.473:671]()
    to_download.push(h.into());
    if txn.is_tagged(&remote_channel.tags, n)? {
    tags.insert(m.into());
    }
    [11.9776]
    [11.9827]
    to_download.push(CS::Change(h.into()));
  • edit in pijul/src/remote/mod.rs at line 429
    [11.9961][11.672:690]()
    tags,
  • replacement in pijul/src/remote/mod.rs at line 505
    [11.165][11.43:43](),[11.43][11.56987:57008](),[11.165][11.56987:57008](),[11.6499][11.56987:57008](),[11.56987][11.56987:57008](),[11.57008][11.269:331](),[11.331][11.57072:57093](),[11.567][11.57072:57093](),[11.57072][11.57072:57093]()
    let n = self
    .dichotomy_changelist(txn, &remote.lock().remote)
    .await?;
    [11.165]
    [11.57093]
    let n = self.dichotomy_changelist(txn, &remote.lock()).await?;
  • edit in pijul/src/remote/mod.rs at line 522
    [11.57419]
    [11.57419]
    }
    let v: Vec<_> = txn
    .iter_tags(&remote.lock().tags, n)?
    .filter_map(|k| {
    debug!("filter_map {:?}", k);
    let k = (*k.unwrap().0).into();
    if k >= n {
    Some(k)
    } else {
    None
    }
    })
    .collect();
    for k in v {
    debug!("deleting {:?}", k);
    txn.del_tags(&mut remote.lock().tags, k)?;
  • edit in pijul/src/remote/mod.rs at line 539
    [11.57429]
    [11.7225]
  • edit in pijul/src/remote/mod.rs at line 543
    [11.1102]
    [11.57516]
    }
    async fn update_changelist_pushpull_from_scratch(
    &mut self,
    txn: &mut MutTxn<()>,
    path: &[String],
    current_channel: &ChannelRef<MutTxn<()>>,
    ) -> Result<RemoteDelta<MutTxn<()>>, anyhow::Error> {
    debug!("no id, starting from scratch");
    let (inodes, theirs_ge_dichotomy) = self.download_changelist_nocache(0, path).await?;
    let mut theirs_ge_dichotomy_set = HashSet::new();
    let mut to_download = Vec::new();
    for (_, h, m, is_tag) in theirs_ge_dichotomy.iter() {
    theirs_ge_dichotomy_set.insert(CS::Change(*h));
    if txn.get_revchanges(current_channel, h)?.is_none() {
    to_download.push(CS::Change(*h));
    }
    if *is_tag {
    let ch = current_channel.read();
    if let Some(n) = txn.channel_has_state(txn.states(&*ch), &m.into())? {
    if !txn.is_tagged(txn.tags(&*ch), n.into())? {
    to_download.push(CS::State(*m));
    }
    } else {
    to_download.push(CS::State(*m));
    }
    }
    }
    Ok(RemoteDelta {
    inodes,
    remote_ref: None,
    to_download,
    ours_ge_dichotomy_set: HashSet::new(),
    theirs_ge_dichotomy,
    theirs_ge_dichotomy_set,
    remote_unrecs: Vec::new(),
    })
  • edit in pijul/src/remote/mod.rs at line 602
    [11.11077]
    [11.11077]
    is_tag: bool,
  • replacement in pijul/src/remote/mod.rs at line 620
    [11.357][11.488:540](),[11.540][11.357:455](),[11.357][11.357:455](),[11.455][11.455:563](),[11.563][11.691:803](),[11.803][11.621:673](),[11.621][11.621:673](),[11.673][11.541:654](),[11.654][11.804:881](),[11.881][11.881:903](),[11.903][11.654:672](),[11.654][11.654:672](),[11.672][11.711:848](),[11.711][11.711:848](),[11.848][11.904:926](),[11.926][11.848:1051](),[11.848][11.848:1051](),[11.86][11.11504:11668](),[11.1051][11.11504:11668](),[11.11504][11.11504:11668]()
    debug!("no id, starting from scratch");
    let (inodes, theirs_ge_dichotomy) = self.download_changelist_nocache(0, path).await?;
    let mut theirs_ge_dichotomy_set = HashSet::new();
    let mut to_download = Vec::new();
    let mut tags = HashSet::new();
    for (_, h, m, is_tagged) in theirs_ge_dichotomy.iter() {
    theirs_ge_dichotomy_set.insert(*h);
    if txn.get_revchanges(current_channel, h)?.is_none() {
    to_download.push(*h);
    if *is_tagged {
    tags.insert(*m);
    }
    }
    }
    return Ok(RemoteDelta {
    inodes,
    remote_ref: None,
    to_download,
    tags,
    ours_ge_dichotomy_set: HashSet::new(),
    theirs_ge_dichotomy,
    theirs_ge_dichotomy_set,
    remote_unrecs: Vec::new(),
    });
    };
    let mut remote_ref = if let Some(name) = self.name() {
    txn.open_or_create_remote(id, name).unwrap()
    } else {
    unreachable!()
    [11.357]
    [11.11668]
    return self
    .update_changelist_pushpull_from_scratch(txn, path, current_channel)
    .await;
  • replacement in pijul/src/remote/mod.rs at line 624
    [11.11679][11.11679:11710](),[11.11710][11.11710:11776](),[11.11776][11.11776:11797](),[11.11797][11.11797:11851]()
    let dichotomy_n = self
    .dichotomy_changelist(txn, &remote_ref.lock().remote)
    .await?;
    let ours_ge_dichotomy: Vec<(u64, Hash)> = txn
    [11.11679]
    [11.11851]
    let mut remote_ref = txn.open_or_create_remote(id, self.name().unwrap()).unwrap();
    let dichotomy_n = self.dichotomy_changelist(txn, &remote_ref.lock()).await?;
    let ours_ge_dichotomy: Vec<(u64, CS)> = txn
  • replacement in pijul/src/remote/mod.rs at line 634
    [11.12221][11.12221:12265]()
    Some((k, hash))
    [11.12221]
    [11.12265]
    Some((k, CS::Change(hash)))
  • edit in pijul/src/remote/mod.rs at line 644
    [11.12552]
    [11.12552]
    debug!("theirs_ge_dichotomy = {:?}", theirs_ge_dichotomy);
  • edit in pijul/src/remote/mod.rs at line 648
    [11.12655][11.12655:12677](),[11.12677][11.12677:12718](),[11.12718][11.12718:12796](),[11.12796][11.927:962]()
    .copied()
    .collect::<HashSet<Hash>>();
    let theirs_ge_dichotomy_set = theirs_ge_dichotomy
    .iter()
    .map(|(_, h, _, _)| h)
  • replacement in pijul/src/remote/mod.rs at line 649
    [11.12850][11.12850:12891](),[11.12891][11.12891:13257](),[11.13257][11.13257:13434](),[11.13434][11.13434:13455](),[11.13455][11.13455:13503]()
    .collect::<HashSet<Hash>>();
    // remote_unrecs = {x: (u64, Hash) | x \in ours_ge_dichot /\ ~(x \in theirs_ge_dichot) /\ x \in current_channel }
    let mut remote_unrecs = Vec::new();
    for (n, hash) in &ours_ge_dichotomy {
    if theirs_ge_dichotomy_set.contains(hash) {
    // If this change is still present in the remote, skip
    continue;
    } else if txn.get_revchanges(&current_channel, &hash)?.is_none() {
    // If this unrecord wasn't in our current channel, skip
    continue;
    } else {
    remote_unrecs.push((*n, *hash))
    [11.12850]
    [11.13503]
    .collect::<HashSet<CS>>();
    let mut theirs_ge_dichotomy_set = HashSet::new();
    for (_, h, m, is_tag) in theirs_ge_dichotomy.iter() {
    theirs_ge_dichotomy_set.insert(CS::Change(*h));
    if *is_tag {
    theirs_ge_dichotomy_set.insert(CS::State(*m));
  • replacement in pijul/src/remote/mod.rs at line 657
    [11.13527][11.13527:13611]()
    let should_cache = force_cache.unwrap_or_else(|| remote_unrecs.is_empty());
    [11.13527]
    [11.13611]
    // remote_unrecs = {x: (u64, Hash) | x \in ours_ge_dichot /\ ~(x \in theirs_ge_dichot) /\ x \in current_channel }
    let remote_unrecs = remote_unrecs(
    txn,
    current_channel,
    &ours_ge_dichotomy,
    &theirs_ge_dichotomy_set,
    )?;
    let should_cache = if let Some(true) = force_cache {
    true
    } else {
    remote_unrecs.is_empty()
    };
    debug!(
    "should_cache = {:?} {:?} {:?}",
    force_cache, remote_unrecs, should_cache
    );
  • replacement in pijul/src/remote/mod.rs at line 675
    [11.13637][11.13637:13699](),[11.13699][11.13699:13752]()
    for (k, _) in ours_ge_dichotomy.iter().copied() {
    txn.del_remote(&mut remote_ref, k)?;
    [11.13637]
    [11.13752]
    use libpijul::ChannelMutTxnT;
    for (k, t) in ours_ge_dichotomy.iter().copied() {
    match t {
    CS::State(_) => txn.del_tags(&mut remote_ref.lock().tags, k)?,
    CS::Change(_) => {
    txn.del_remote(&mut remote_ref, k)?;
    }
    }
  • replacement in pijul/src/remote/mod.rs at line 684
    [11.13766][11.963:1097]()
    for (n, h, m, t) in theirs_ge_dichotomy.iter().copied() {
    txn.put_remote(&mut remote_ref, n, (h, m, t))?;
    [11.13766]
    [11.13894]
    for (n, h, m, is_tag) in theirs_ge_dichotomy.iter().copied() {
    debug!("theirs: {:?} {:?} {:?}", n, h, m);
    txn.put_remote(&mut remote_ref, n, (h, m))?;
    if is_tag {
    txn.put_tags(&mut remote_ref.lock().tags, n, &m)?;
    }
  • edit in pijul/src/remote/mod.rs at line 692
    [11.13918][11.13918:14140](),[11.14140][11.14140:14255](),[11.14255][11.14255:14281](),[11.14281][11.14281:14308](),[11.14308][11.14308:14319](),[11.14319][11.57522:57523](),[11.57522][11.57522:57523](),[11.57523][11.14320:14811]()
    let state_cond = |txn: &MutTxn<()>, merkle: &libpijul::pristine::SerializedMerkle| {
    txn.channel_has_state(txn.states(&*current_channel.read()), merkle)
    .map(|x| x.is_some())
    };
    let change_cond = |txn: &MutTxn<()>, hash: &Hash| {
    txn.get_revchanges(&current_channel, hash)
    .unwrap()
    .is_none()
    };
    // IF:
    // The user only wanted to push/pull specific changes
    // ELIF:
    // The user specified no changes and there were no remote unrecords
    // effecting the current channel means we can auto-cache
    // the local remote cache
    // ELSE:
    // The user specified no changes but there were remote unrecords
    // effecting the current channel meaning we can't auto-cache
    // the local remote cache.
  • edit in pijul/src/remote/mod.rs at line 693
    [11.14853]
    [11.14853]
    // Here, the user only wanted to push/pull specific changes
  • replacement in pijul/src/remote/mod.rs at line 696
    [11.14924][11.14924:14981]()
    .map(|h| Ok(txn.hash_from_prefix(h)?.0))
    [11.14924]
    [11.14981]
    .map(|h| {
    if is_tag {
    Ok(CS::State(
    txn.state_from_prefix(&*current_channel.read(), h)?.0,
    ))
    } else {
    Ok(CS::Change(txn.hash_from_prefix(h)?.0))
    }
    })
  • edit in pijul/src/remote/mod.rs at line 710
    [11.15184][11.1098:1136]()
    tags: HashSet::new(),
  • replacement in pijul/src/remote/mod.rs at line 715
    [11.15347][11.15347:15380](),[11.15380][11.15380:15437](),[11.15437][11.1137:1180](),[11.1180][11.1180:1239](),[11.1239][11.1239:1719](),[11.1719][11.1719:1745]()
    } else if should_cache {
    let mut to_download: Vec<Hash> = Vec::new();
    let mut tags = HashSet::new();
    {
    let rem = remote_ref.lock();
    for thing in txn.iter_remote(&rem.remote, 0)? {
    let (n, libpijul::pristine::Pair { a: hash, b: merkle }) = thing?;
    if state_cond(txn, &merkle)? {
    break;
    } else if change_cond(txn, &hash.into()) {
    to_download.push(Hash::from(hash));
    if txn.is_tagged(&rem.tags, (*n).into())? {
    tags.insert(merkle.into());
    }
    [11.15347]
    [11.1745]
    } else {
    let mut to_download: Vec<CS> = Vec::new();
    for (n, h, m, is_tag) in theirs_ge_dichotomy.iter() {
    // In all cases, add this new change/state/tag to `to_download`.
    let ch = CS::Change(*h);
    if txn.get_revchanges(&current_channel, h).unwrap().is_none() {
    to_download.push(ch.clone());
    if *is_tag {
    to_download.push(CS::State(*m));
  • replacement in pijul/src/remote/mod.rs at line 725
    [11.1767][11.15783:15815](),[11.15783][11.15783:15815](),[11.15816][11.15816:15944](),[11.15944][11.1768:1790](),[11.1790][11.15944:16124](),[11.15944][11.15944:16124](),[11.16124][11.16124:16595]()
    }
    }
    Ok(RemoteDelta {
    inodes,
    remote_ref: Some(remote_ref),
    to_download,
    tags,
    ours_ge_dichotomy_set,
    theirs_ge_dichotomy,
    theirs_ge_dichotomy_set,
    remote_unrecs,
    })
    } else {
    let mut to_download: Vec<Hash> = Vec::new();
    for thing in txn.iter_remote(&remote_ref.lock().remote, 0)? {
    let (n, libpijul::pristine::Pair { a: hash, b: merkle }) = thing?;
    if u64::from(*n) < dichotomy_n {
    if state_cond(txn, &merkle)? {
    continue;
    } else if change_cond(txn, &hash.into()) {
    to_download.push(Hash::from(hash));
    [11.1767]
    [11.16595]
    } else if *is_tag {
    let has_tag = if let Some(n) =
    txn.channel_has_state(txn.states(&current_channel.read()), &m.into())?
    {
    txn.is_tagged(txn.tags(&current_channel.read()), n.into())?
    } else {
    false
    };
    if !has_tag {
    to_download.push(CS::State(*m));
  • replacement in pijul/src/remote/mod.rs at line 737
    [11.16635][11.16635:16649](),[11.16649][11.1791:1897](),[11.1897][11.16709:16793](),[11.16709][11.16709:16793](),[11.16793][11.16793:16902](),[11.16902][11.1898:1972]()
    }
    let mut tags = HashSet::new();
    for (_, hash, merkle, t) in &theirs_ge_dichotomy {
    if state_cond(txn, &merkle.into())? {
    continue;
    } else if change_cond(txn, &hash) {
    to_download.push(Hash::from(*hash));
    if *t {
    tags.insert(*merkle);
    [11.16635]
    [11.1972]
    // Additionally, if there are no remote unrecords
    // (i.e. if `should_cache`), cache.
    if should_cache && ours_ge_dichotomy_set.get(&ch).is_none() {
    use libpijul::ChannelMutTxnT;
    txn.put_remote(&mut remote_ref, *n, (*h, *m))?;
    if *is_tag {
    let mut rem = remote_ref.lock();
    txn.put_tags(&mut rem.tags, *n, m)?;
  • edit in pijul/src/remote/mod.rs at line 748
    [11.16934][11.16934:16935]()
  • edit in pijul/src/remote/mod.rs at line 752
    [11.17063][11.1995:2017]()
    tags,
  • replacement in pijul/src/remote/mod.rs at line 769
    [11.17675][11.2111:2182]()
    let f = |v: &mut Vec<(u64, Hash, Merkle, bool)>, n, h, m, t| {
    [11.17675]
    [11.17737]
    let f = |v: &mut Vec<(u64, Hash, Merkle, bool)>, n, h, m, m2| {
  • replacement in pijul/src/remote/mod.rs at line 771
    [11.17778][11.2183:2220]()
    Ok(v.push((n, h, m, t)))
    [11.17778]
    [11.17812]
    Ok(v.push((n, h, m, m2)))
  • replacement in pijul/src/remote/mod.rs at line 789
    [11.57606][11.57606:57634]()
    remote: &T::Remote,
    [11.57606]
    [11.57634]
    remote: &libpijul::pristine::Remote<T>,
  • replacement in pijul/src/remote/mod.rs at line 792
    [11.57695][11.7253:7344]()
    let (mut b, state): (_, Merkle) = if let Some((u, v)) = txn.last_remote(remote)? {
    [11.57695]
    [11.7344]
    let (mut b, state): (_, Merkle) = if let Some((u, v)) = txn.last_remote(&remote.remote)? {
  • replacement in pijul/src/remote/mod.rs at line 799
    [11.57913][11.1721:1789](),[11.1789][11.57976:58004](),[11.57976][11.57976:58004]()
    if let Some((_, s)) = self.get_state(txn, Some(b)).await? {
    if s == state {
    [11.57913]
    [11.58004]
    let last_statet = if let Some((_, _, v)) = txn.last_remote_tag(&remote.tags)? {
    v.into()
    } else {
    Merkle::zero()
    };
    debug!("last_state: {:?} {:?}", state, last_statet);
    if let Some((_, s, st)) = self.get_state(txn, Some(b)).await? {
    debug!("remote last_state: {:?} {:?}", s, st);
    if s == state && st == last_statet {
  • replacement in pijul/src/remote/mod.rs at line 817
    [11.58358][11.7437:7513]()
    let (mid, state) = txn.get_remote_state(remote, mid)?.unwrap();
    [11.58358]
    [11.1790]
    let (mid, state) = {
    let (a, b) = txn.get_remote_state(&remote.remote, mid)?.unwrap();
    (a, b.b)
    };
    let statet = if let Some((_, b)) = txn.get_remote_tag(&remote.tags, mid)? {
    // There's still a tag at position >= mid in the
    // sequence.
    b.b.into()
    } else {
    // No tag at or after mid, the last state, `statet`,
    // is the right answer in that case.
    last_statet
    };
  • replacement in pijul/src/remote/mod.rs at line 833
    [11.58577][11.58577:58637](),[11.58637][11.7514:7559]()
    if let Some((_, remote_state)) = remote_state {
    if remote_state == state.b {
    [11.58577]
    [11.58680]
    if let Some((_, remote_state, remote_statet)) = remote_state {
    if remote_state == state && remote_statet == statet {
  • replacement in pijul/src/remote/mod.rs at line 856
    [11.59114][11.59114:59170]()
    ) -> Result<Option<(u64, Merkle)>, anyhow::Error> {
    [11.59114]
    [11.59170]
    ) -> Result<Option<(u64, Merkle, Merkle)>, anyhow::Error> {
  • replacement in pijul/src/remote/mod.rs at line 936
    [11.1161][11.2221:2297]()
    let f = |a: &mut (&mut T, &mut RemoteRef<T>), n, h, m, is_tagged| {
    [11.1161]
    [11.518]
    let f = |a: &mut (&mut T, &mut RemoteRef<T>), n, h, m, is_tag| {
  • replacement in pijul/src/remote/mod.rs at line 938
    [11.570][11.2298:2357]()
    txn.put_remote(remote, n, (h, m, is_tagged))?;
    [11.570]
    [11.618]
    txn.put_remote(remote, n, (h, m))?;
    if is_tag {
    txn.put_tags(&mut remote.lock().tags, n, &m.into())?;
    }
  • replacement in pijul/src/remote/mod.rs at line 966
    [11.65261][11.65261:65287]()
    changes: &[Hash],
    [11.65261]
    [11.65287]
    changes: &[CS],
  • replacement in pijul/src/remote/mod.rs at line 1001
    [11.398][11.1589:1674](),[11.1589][11.1589:1674](),[11.1205][11.10700:10772](),[11.1674][11.10700:10772](),[11.10700][11.10700:10772]()
    hashes: &mut tokio::sync::mpsc::UnboundedReceiver<libpijul::pristine::Hash>,
    send: &mut tokio::sync::mpsc::Sender<libpijul::pristine::Hash>,
    [11.398]
    [11.66747]
    hashes: &mut tokio::sync::mpsc::UnboundedReceiver<CS>,
    send: &mut tokio::sync::mpsc::Sender<CS>,
  • replacement in pijul/src/remote/mod.rs at line 1047
    [11.68892][11.160:187]()
    to_apply: &[Hash],
    [11.68892]
    [11.1320]
    to_apply: &[CS],
  • replacement in pijul/src/remote/mod.rs at line 1050
    [11.68948][11.1363:1407]()
    ) -> Result<Vec<Hash>, anyhow::Error> {
    [11.68948]
    [11.711]
    ) -> Result<Vec<CS>, anyhow::Error> {
  • replacement in pijul/src/remote/mod.rs at line 1085
    [11.259][11.259:402](),[11.402][11.3096:3173]()
    libpijul::changestore::filesystem::push_filename(&mut change_path_, h);
    if std::fs::metadata(&change_path_).is_err() {
    hash_send.send(*h)?;
    to_download.insert(*h);
    [11.259]
    [11.440]
    if let CS::Change(h) = h {
    libpijul::changestore::filesystem::push_filename(&mut change_path_, h);
    if std::fs::metadata(&change_path_).is_err() {
    hash_send.send(CS::Change(*h))?;
    to_download.insert(CS::Change(*h));
    }
    libpijul::changestore::filesystem::pop_filename(&mut change_path_);
  • edit in pijul/src/remote/mod.rs at line 1093
    [11.454][11.454:534]()
    libpijul::changestore::filesystem::pop_filename(&mut change_path_);
  • replacement in pijul/src/remote/mod.rs at line 1113
    [11.1641][11.1641:2262]()
    let changes = repo.changes.get_changes(h)?;
    changes.iter().any(|c| {
    c.iter().any(|c| {
    let inode = c.inode();
    debug!("inode = {:?}", inode);
    if let Some(h) = inode.change {
    inodes.contains(&Position {
    change: h,
    pos: inode.pos,
    })
    } else {
    false
    }
    [11.1641]
    [11.2262]
    if let CS::Change(h) = h {
    let changes = repo.changes.get_changes(h)?;
    changes.iter().any(|c| {
    c.iter().any(|c| {
    let inode = c.inode();
    debug!("inode = {:?}", inode);
    if let Some(h) = inode.change {
    inodes.contains(&Position {
    change: h,
    pos: inode.pos,
    })
    } else {
    false
    }
    })
  • replacement in pijul/src/remote/mod.rs at line 1129
    [11.2289][11.2289:2312]()
    })
    [11.2289]
    [11.2312]
    } else {
    false
    }
  • replacement in pijul/src/remote/mod.rs at line 1133
    [11.2330][11.2330:2392]()
    || { inodes.iter().any(|i| i.change == *h) };
    [11.2330]
    [11.2392]
    || { inodes.iter().any(|i| CS::Change(i.change) == *h) };
  • replacement in pijul/src/remote/mod.rs at line 1145
    [11.3600][11.478:529](),[11.529][11.60:139](),[11.60][11.60:139]()
    let mut channel = channel.write();
    txn.apply_change_ws(&repo.changes, &mut channel, h, &mut ws)?;
    [11.3600]
    [11.3601]
    if let CS::Change(h) = h {
    let mut channel = channel.write();
    txn.apply_change_ws(&repo.changes, &mut channel, h, &mut ws)?;
    }
  • replacement in pijul/src/remote/mod.rs at line 1199
    [11.71974][11.4069:4101]()
    send_hash.send(h)?;
    [11.71974]
    [11.72012]
    send_hash.send(CS::Change(h))?;
  • replacement in pijul/src/remote/mod.rs at line 1205
    [11.72174][11.72174:72533](),[11.72533][11.4102:4140]()
    libpijul::changestore::filesystem::push_filename(&mut change_path, &hash);
    std::fs::create_dir_all(change_path.parent().unwrap())?;
    use libpijul::changestore::ChangeStore;
    hashes.push(hash);
    for dep in repo.changes.get_dependencies(&hash)? {
    let dep: libpijul::pristine::Hash = dep;
    send_hash.send(dep)?;
    [11.72174]
    [11.72577]
    if let CS::Change(hash) = hash {
    libpijul::changestore::filesystem::push_filename(&mut change_path, &hash);
    std::fs::create_dir_all(change_path.parent().unwrap())?;
    use libpijul::changestore::ChangeStore;
    hashes.push(CS::Change(hash));
    for dep in repo.changes.get_dependencies(&hash)? {
    let dep: libpijul::pristine::Hash = dep;
    send_hash.send(CS::Change(dep))?;
    }
    libpijul::changestore::filesystem::pop_filename(&mut change_path);
  • edit in pijul/src/remote/mod.rs at line 1216
    [11.72591][11.72591:72670]()
    libpijul::changestore::filesystem::pop_filename(&mut change_path);
  • replacement in pijul/src/remote/mod.rs at line 1223
    [11.247][11.247:330]()
    txn.apply_change_ws(&repo.changes, &mut channel_, hash, &mut ws)?;
    [11.247]
    [11.330]
    if let CS::Change(hash) = hash {
    txn.apply_change_ws(&repo.changes, &mut channel_, hash, &mut ws)?;
    }
  • replacement in pijul/src/remote/mod.rs at line 1254
    [11.7876][11.7876:7914]()
    to_pull.push(p.a.into());
    [11.7876]
    [11.7914]
    to_pull.push(CS::Change(p.a.into()));
  • replacement in pijul/src/remote/mod.rs at line 1277
    [11.74955][11.74955:74981]()
    changes: &[Hash],
    [11.74955]
    [11.74981]
    changes: &[CS],
  • edit in pijul/src/remote/mod.rs at line 1303
    [11.76104]
    [11.7945]
    let c = if let CS::Change(c) = c {
    c
    } else {
    unreachable!()
    };
  • replacement in pijul/src/remote/mod.rs at line 1318
    [11.76328][11.4513:4550]()
    send_hash.send(*c)?;
    [11.76328]
    [11.2508]
    send_hash.send(CS::Change(*c))?;
  • replacement in pijul/src/remote/mod.rs at line 1342
    [11.2672][11.4551:4592]()
    send_hash.send(*c)?;
    [11.2672]
    [11.2575]
    send_hash.send(CS::Change(*c))?;
  • replacement in pijul/src/remote/mod.rs at line 1373
    [11.8353][11.8353:8395]()
    pullable.push(p.a.into())
    [11.8353]
    [11.8395]
    pullable.push(CS::Change(p.a.into()))
  • replacement in pijul/src/remote/mod.rs at line 1403
    [11.2588][11.2588:2613]()
    is_tagged: bool,
    [11.2588]
    [11.2613]
    tag: bool,
  • replacement in pijul/src/remote/mod.rs at line 1420
    [11.3818][11.2621:2676]()
    is_tagged: caps.name("tag").is_some(),
    [11.3818]
    [11.3818]
    tag: caps.name("tag").is_some(),
  • edit in pijul/src/remote/mod.rs at line 1442
    [2.373]
    [11.79731]
    }
    /// Compare the remote set (theirs_ge_dichotomy) with our current
    /// version of that (ours_ge_dichotomy) and return the changes in our
    /// current version that are not in the remote anymore.
    fn remote_unrecs<T: TxnTExt + ChannelTxnT>(
    txn: &T,
    current_channel: &ChannelRef<T>,
    ours_ge_dichotomy: &[(u64, CS)],
    theirs_ge_dichotomy_set: &HashSet<CS>,
    ) -> Result<Vec<(u64, CS)>, anyhow::Error> {
    let mut remote_unrecs = Vec::new();
    for (n, hash) in ours_ge_dichotomy {
    debug!("ours_ge_dichotomy: {:?} {:?}", n, hash);
    if theirs_ge_dichotomy_set.contains(hash) {
    // If this change is still present in the remote, skip
    debug!("still present");
    continue;
    } else {
    let has_it = match hash {
    CS::Change(hash) => txn.get_revchanges(&current_channel, &hash)?.is_some(),
    CS::State(state) => {
    let ch = current_channel.read();
    if let Some(n) = txn.channel_has_state(txn.states(&*ch), &state.into())? {
    txn.is_tagged(txn.tags(&*ch), n.into())?
    } else {
    false
    }
    }
    };
    if has_it {
    remote_unrecs.push((*n, *hash))
    } else {
    // If this unrecord wasn't in our current channel, skip
    continue;
    }
    }
    }
    Ok(remote_unrecs)
  • edit in pijul/src/remote/local.rs at line 9
    [11.552]
    [11.79900]
    use crate::remote::CS;
  • replacement in pijul/src/remote/local.rs at line 25
    [11.3106][11.9863:9915](),[11.9915][11.3135:3164](),[11.3135][11.3135:3164](),[11.3164][11.9916:9983]()
    ) -> Result<Option<(u64, Merkle)>, anyhow::Error> {
    if let Some(mid) = mid {
    Ok(txn.get_changes(&channel, mid)?.map(|(_, m)| (mid, m)))
    [11.3106]
    [11.3226]
    ) -> Result<Option<(u64, Merkle, Merkle)>, anyhow::Error> {
    if let Some(x) = txn.reverse_log(&*channel.read(), mid)?.next() {
    let (n, (_, m)) = x?;
    if let Some(m2) = txn
    .rev_iter_tags(txn.tags(&*channel.read()), Some(n.into()))?
    .next()
    {
    let (_, m2) = m2?;
    Ok(Some((n, m.into(), m2.b.into())))
    } else {
    Ok(Some((n, m.into(), Merkle::zero())))
    }
  • replacement in pijul/src/remote/local.rs at line 38
    [11.3239][11.939:1008](),[11.909][11.10054:10096](),[11.1008][11.10054:10096](),[11.10054][11.10054:10096](),[11.10096][11.8666:8692](),[11.8692][11.10115:10127](),[11.10115][11.10115:10127]()
    Ok(txn.reverse_log(&*channel.read(), None)?.next().map(|n| {
    let (n, (_, m)) = n.unwrap();
    (n, m.into())
    }))
    [11.3239]
    [11.3347]
    Ok(None)
  • replacement in pijul/src/remote/local.rs at line 43
    [11.80117][11.80117:80217]()
    pub fn get_state(&mut self, mid: Option<u64>) -> Result<Option<(u64, Merkle)>, anyhow::Error> {
    [11.80117]
    [11.80217]
    pub fn get_state(
    &mut self,
    mid: Option<u64>,
    ) -> Result<Option<(u64, Merkle, Merkle)>, anyhow::Error> {
  • replacement in pijul/src/remote/local.rs at line 107
    [11.8962][11.1113:1179]()
    for x in remote_txn.log(&*remote_channel.read(), from)? {
    [11.8962]
    [11.10768]
    let rem = remote_channel.read();
    let tags: Vec<u64> = remote_txn
    .iter_tags(remote_txn.tags(&*rem), from)?
    .map(|k| (*k.unwrap().0).into())
    .collect();
    let mut tagsi = 0;
    for x in remote_txn.log(&*rem, from)? {
  • replacement in pijul/src/remote/local.rs at line 128
    [11.9387][11.2758:2978]()
    f(
    a,
    n,
    h.into(),
    m.into(),
    remote_txn.is_tagged(&remote_channel.read().tags, n)?,
    )?;
    [11.9387]
    [11.82051]
    if tags.get(tagsi) == Some(&n) {
    f(a, n, h.into(), m.into(), true)?;
    tagsi += 1;
    } else {
    f(a, n, h.into(), m.into(), false)?;
    }
  • replacement in pijul/src/remote/local.rs at line 144
    [11.82205][11.82205:82231]()
    changes: &[Hash],
    [11.82205]
    [11.82231]
    changes: &[CS],
  • replacement in pijul/src/remote/local.rs at line 155
    [11.82584][11.82584:82751]()
    libpijul::changestore::filesystem::push_filename(&mut local, &c);
    libpijul::changestore::filesystem::push_filename(&mut self.changes_dir, &c);
    [11.82584]
    [11.82751]
    match c {
    CS::Change(c) => {
    libpijul::changestore::filesystem::push_filename(&mut local, &c);
    libpijul::changestore::filesystem::push_filename(&mut self.changes_dir, &c);
    }
    CS::State(c) => {
    libpijul::changestore::filesystem::push_tag_filename(&mut local, &c);
    libpijul::changestore::filesystem::push_tag_filename(&mut self.changes_dir, &c);
    }
    }
  • edit in pijul/src/remote/local.rs at line 172
    [11.3543]
    [11.83218]
    debug!("hard link done");
    libpijul::changestore::filesystem::pop_filename(&mut local);
    libpijul::changestore::filesystem::pop_filename(&mut self.changes_dir);
  • replacement in pijul/src/remote/local.rs at line 196
    [11.2860][11.4665:4750](),[11.4665][11.4665:4750](),[11.2841][11.11767:11839](),[11.4750][11.11767:11839](),[11.11767][11.11767:11839]()
    hashes: &mut tokio::sync::mpsc::UnboundedReceiver<libpijul::pristine::Hash>,
    send: &mut tokio::sync::mpsc::Sender<libpijul::pristine::Hash>,
    [11.2860]
    [11.11839]
    hashes: &mut tokio::sync::mpsc::UnboundedReceiver<CS>,
    send: &mut tokio::sync::mpsc::Sender<CS>,
  • replacement in pijul/src/remote/local.rs at line 201
    [11.2892][11.2892:3058](),[11.3058][11.2861:2926](),[11.270][11.12057:12157](),[11.2926][11.12057:12157](),[11.3058][11.12057:12157](),[11.4807][11.12057:12157](),[11.12057][11.12057:12157]()
    libpijul::changestore::filesystem::push_filename(&mut self.changes_dir, &c);
    libpijul::changestore::filesystem::push_filename(&mut path, &c);
    super::PROGRESS.borrow_mut().unwrap()[pro_n].incr();
    if std::fs::metadata(&path).is_ok() {
    debug!("metadata {:?} ok", path);
    [11.2892]
    [11.12157]
    if let CS::Change(c) = c {
    libpijul::changestore::filesystem::push_filename(&mut self.changes_dir, &c);
    libpijul::changestore::filesystem::push_filename(&mut path, &c);
    super::PROGRESS.borrow_mut().unwrap()[pro_n].incr();
    if std::fs::metadata(&path).is_ok() {
    debug!("metadata {:?} ok", path);
    libpijul::changestore::filesystem::pop_filename(&mut path);
    continue;
    }
    std::fs::create_dir_all(&path.parent().unwrap())?;
    if std::fs::hard_link(&self.changes_dir, &path).is_err() {
    std::fs::copy(&self.changes_dir, &path)?;
    }
    debug!("hard link done");
    libpijul::changestore::filesystem::pop_filename(&mut self.changes_dir);
  • edit in pijul/src/remote/local.rs at line 217
    [11.12233][11.943:969](),[11.969][11.12258:12272](),[11.12258][11.12258:12272](),[11.12272][11.12272:12464]()
    continue;
    }
    std::fs::create_dir_all(&path.parent().unwrap())?;
    if std::fs::hard_link(&self.changes_dir, &path).is_err() {
    std::fs::copy(&self.changes_dir, &path)?;
  • edit in pijul/src/remote/local.rs at line 218
    [11.12478][11.12478:12672]()
    debug!("hard link done");
    libpijul::changestore::filesystem::pop_filename(&mut self.changes_dir);
    libpijul::changestore::filesystem::pop_filename(&mut path);
  • replacement in pijul/src/remote/local.rs at line 263
    [11.394][11.3988:4010](),[11.3988][11.3988:4010]()
    changes: &[Hash],
    [11.394]
    [11.4010]
    changes: &[CS],
  • replacement in pijul/src/remote/local.rs at line 268
    [11.4116][11.444:508]()
    txn.apply_change_ws(store, &mut *channel, c, &mut ws)?;
    [11.4116]
    [11.930]
    match c {
    CS::Change(c) => {
    txn.apply_change_ws(store, &mut *channel, c, &mut ws)?;
    }
    CS::State(c) => {
    if let Some(n) = txn.channel_has_state(txn.states(&*channel), &c.into())? {
    let tags = txn.tags_mut(&mut *channel);
    txn.put_tags(tags, n.into(), c)?;
    } else {
    bail!(
    "Cannot add tag {}: channel {:?} does not have that state",
    c.to_base32(),
    txn.name(&*channel)
    )
    }
    }
    }
  • edit in pijul/src/remote/local.rs at line 289
    [11.3543][11.82954:83149](),[11.82954][11.82954:83149]()
    debug!("hard link done");
    libpijul::changestore::filesystem::pop_filename(&mut local);
    libpijul::changestore::filesystem::pop_filename(&mut self.changes_dir);
  • resolve order conflict in pijul/src/remote/local.rs at line 289
    [11.4265]
  • edit in pijul/src/remote/http.rs at line 9
    [11.32]
    [11.0]
    use crate::remote::CS;
  • replacement in pijul/src/remote/http.rs at line 25
    [11.124][11.124:157](),[11.157][11.0:55](),[11.55][11.190:259](),[11.190][11.190:259]()
    c: libpijul::pristine::Hash,
    ) -> Result<libpijul::pristine::Hash, anyhow::Error> {
    libpijul::changestore::filesystem::push_filename(&mut path, &c);
    [11.124]
    [11.259]
    c: CS,
    ) -> Result<CS, anyhow::Error> {
    let (req, c32) = match c {
    CS::Change(c) => {
    libpijul::changestore::filesystem::push_filename(&mut path, &c);
    ("change", c.to_base32())
    }
    CS::State(c) => {
    libpijul::changestore::filesystem::push_tag_filename(&mut path, &c);
    if std::fs::metadata(&path).is_ok() {
    bail!("Tag already downloaded: {}", c.to_base32())
    }
    ("tag", c.to_base32())
    }
    };
  • edit in pijul/src/remote/http.rs at line 43
    [11.89][11.406:499](),[11.406][11.406:499]()
    libpijul::changestore::filesystem::pop_filename(&mut path);
    let c32 = c.to_base32();
  • replacement in pijul/src/remote/http.rs at line 67
    [11.139][11.139:179]()
    .query(&[("change", &c32)])
    [11.139]
    [11.179]
    .query(&[(req, &c32)])
  • replacement in pijul/src/remote/http.rs at line 121
    [11.1318][11.1318:1385]()
    std::fs::rename(&path_, &path_.with_extension("change"))?;
    [11.1318]
    [11.1385]
    match c {
    CS::Change(_) => {
    std::fs::rename(&path_, &path)?;
    }
    CS::State(_) => {
    std::fs::rename(&path_, &path)?;
    }
    }
  • replacement in pijul/src/remote/http.rs at line 139
    [11.2949][11.4891:4976](),[11.4891][11.4891:4976](),[11.3169][11.1180:1252](),[11.4976][11.1180:1252](),[11.1180][11.1180:1252]()
    hashes: &mut tokio::sync::mpsc::UnboundedReceiver<libpijul::pristine::Hash>,
    send: &mut tokio::sync::mpsc::Sender<libpijul::pristine::Hash>,
    [11.2949]
    [11.1436]
    hashes: &mut tokio::sync::mpsc::UnboundedReceiver<CS>,
    send: &mut tokio::sync::mpsc::Sender<CS>,
  • replacement in pijul/src/remote/http.rs at line 190
    [11.938][11.938:974]()
    changes: &[libpijul::Hash],
    [11.938]
    [11.974]
    changes: &[CS],
  • edit in pijul/src/remote/http.rs at line 193
    [11.1148][11.1148:1226]()
    libpijul::changestore::filesystem::push_filename(&mut local, &c);
  • edit in pijul/src/remote/http.rs at line 203
    [11.1541][11.1289:1338](),[11.1289][11.1289:1338]()
    let change = std::fs::read(&local)?;
  • replacement in pijul/src/remote/http.rs at line 208
    [11.1506][11.1506:1585]()
    let c = c.to_base32();
    to_channel.push(("apply", &c));
    [11.1506]
    [11.1585]
    let base32;
    let body = match c {
    CS::Change(c) => {
    libpijul::changestore::filesystem::push_filename(&mut local, &c);
    let change = std::fs::read(&local)?;
    base32 = c.to_base32();
    to_channel.push(("apply", &base32));
    change
    }
    CS::State(c) => {
    libpijul::changestore::filesystem::push_tag_filename(&mut local, &c);
    let mut tag_file = libpijul::tag::OpenTagFile::open(&local, &c)?;
    let mut v = Vec::new();
    tag_file.short(&mut v)?;
    base32 = c.to_base32();
    to_channel.push(("tagup", &base32));
    v
    }
    };
    libpijul::changestore::filesystem::pop_filename(&mut local);
  • replacement in pijul/src/remote/http.rs at line 234
    [11.355][11.1727:1757](),[11.1727][11.1727:1757]()
    .body(change)
    [11.355]
    [11.1757]
    .body(body)
  • edit in pijul/src/remote/http.rs at line 250
    [7.597][11.1835:1908](),[11.1835][11.1835:1908]()
    libpijul::changestore::filesystem::pop_filename(&mut local);
  • replacement in pijul/src/remote/http.rs at line 303
    [11.6079][11.3070:3171]()
    super::ListLine::Change { n, m, h, is_tagged } => f(a, n, h, m, is_tagged)?,
    [11.6079]
    [11.6234]
    super::ListLine::Change { n, m, h, tag } => f(a, n, h, m, tag)?,
  • replacement in pijul/src/remote/http.rs at line 323
    [11.242][11.242:308]()
    ) -> Result<Option<(u64, libpijul::Merkle)>, anyhow::Error> {
    [11.242]
    [11.308]
    ) -> Result<Option<(u64, libpijul::Merkle, libpijul::Merkle)>, anyhow::Error> {
  • replacement in pijul/src/remote/http.rs at line 348
    [3.45][11.1028:1066](),[11.1028][11.1028:1066]()
    if let (Some(n), Some(m)) = (
    [3.45]
    [11.1066]
    if let (Some(n), Some(m), Some(m2)) = (
  • edit in pijul/src/remote/http.rs at line 352
    [11.1214]
    [11.1214]
    s.next()
    .and_then(|m| libpijul::Merkle::from_base32(m.as_bytes())),
  • replacement in pijul/src/remote/http.rs at line 355
    [11.1226][11.1226:1255]()
    Ok(Some((n, m)))
    [11.1226]
    [11.1255]
    Ok(Some((n, m, m2)))
  • edit in pijul/src/commands/unrecord.rs at line 4
    [11.871]
    [11.871]
    use crate::remote::CS;
    use crate::repository::Repository;
  • edit in pijul/src/commands/unrecord.rs at line 12
    [11.95786][11.1252:1287](),[11.1287][11.1287:1288]()
    use crate::repository::Repository;
  • replacement in pijul/src/commands/unrecord.rs at line 74
    [11.1926][11.3416:3466](),[11.3416][11.3416:3466]()
    .map(|h| (h.unwrap().1).0.into())
    [11.1926]
    [11.3466]
    .map(|h| CS::Change((h.unwrap().1).0.into()))
  • replacement in pijul/src/commands/unrecord.rs at line 79
    [11.3695][11.3695:3769]()
    hashes.push((*h, *txn.get_internal(&h.into())?.unwrap()))
    [11.3695]
    [11.3769]
    if let CS::Change(h) = h {
    hashes.push((*h, *txn.get_internal(&h.into())?.unwrap()))
    }
  • edit in pijul/src/commands/tag.rs at line 16
    [11.32]
    [11.652]
    #[clap(long = "repository")]
    repo_path: Option<PathBuf>,
    #[clap(long = "channel")]
    channel: Option<String>,
  • replacement in pijul/src/commands/tag.rs at line 187
    [11.268][11.690:747]()
    let repo = Repository::find_root(None)?;
    [11.268]
    [11.440]
    let repo = Repository::find_root(self.repo_path)?;
  • replacement in pijul/src/commands/tag.rs at line 189
    [11.494][11.602:769]()
    let channel_name = txn
    .current_channel()
    .unwrap_or(crate::DEFAULT_CHANNEL)
    .to_string();
    [11.494]
    [11.494]
    let channel_name = self.channel.unwrap_or_else(|| {
    txn.current_channel()
    .unwrap_or(crate::DEFAULT_CHANNEL)
    .to_string()
    });
  • replacement in pijul/src/commands/tag.rs at line 202
    [11.3209][11.821:936]()
    let t = (*t?).into();
    let (_, m) = txn.get_changes(&channel, t)?.unwrap();
    [11.3209]
    [11.936]
    let (t, _) = t?;
    let (_, m) = txn.get_changes(&channel, (*t).into())?.unwrap();
  • replacement in pijul/src/commands/pushpull.rs at line 17
    [11.4805][11.18517:18574]()
    use crate::remote::{PushDelta, RemoteDelta, RemoteRepo};
    [11.4805]
    [11.1761]
    use crate::remote::{PushDelta, RemoteDelta, RemoteRepo, CS};
  • edit in pijul/src/commands/pushpull.rs at line 94
    [11.113523]
    [101.1896]
    /// Push tags instead of regular changes.
    #[clap(long = "tag")]
    is_tag: bool,
  • edit in pijul/src/commands/pushpull.rs at line 131
    [11.371]
    [102.1648]
    /// Pull tags instead of regular changes.
    #[clap(long = "tag")]
    is_tag: bool,
  • edit in pijul/src/commands/pushpull.rs at line 153
    [11.19337]
    [5.121]
    is_tag: bool,
  • edit in pijul/src/commands/pushpull.rs at line 163
    [11.19645]
    [11.19645]
    is_tag,
  • replacement in pijul/src/commands/pushpull.rs at line 234
    [11.20360][11.20360:20436]()
    .to_upload(&mut *txn.write(), &mut channel, &repo, &mut remote)
    [11.20360]
    [11.7019]
    .to_upload(
    &mut *txn.write(),
    &mut channel,
    &repo,
    &mut remote,
    self.is_tag,
    )
  • replacement in pijul/src/commands/pushpull.rs at line 255
    [11.426][11.11039:11096]()
    let mut u: Vec<libpijul::Hash> = Vec::new();
    [11.426]
    [11.462]
    let mut u: Vec<CS> = Vec::new();
  • replacement in pijul/src/commands/pushpull.rs at line 261
    [11.39][11.39:136]()
    if to_upload.contains(&hash) {
    u.push(hash);
    [11.39]
    [11.136]
    if to_upload.contains(&CS::Change(hash)) {
    u.push(CS::Change(hash));
  • replacement in pijul/src/commands/pushpull.rs at line 273
    [11.913][11.673:884]()
    u.sort_by(|a, b| {
    let na = txn.get_revchanges(&channel, a).unwrap().unwrap();
    let nb = txn.get_revchanges(&channel, b).unwrap().unwrap();
    na.cmp(&nb)
    [11.913]
    [11.884]
    u.sort_by(|a, b| match (a, b) {
    (CS::Change(a), CS::Change(b)) => {
    let na = txn.get_revchanges(&channel, a).unwrap().unwrap();
    let nb = txn.get_revchanges(&channel, b).unwrap().unwrap();
    na.cmp(&nb)
    }
    (CS::State(a), CS::State(b)) => {
    let na = txn
    .channel_has_state(txn.states(&*channel.read()), &a.into())
    .unwrap()
    .unwrap();
    let nb = txn
    .channel_has_state(txn.states(&*channel.read()), &b.into())
    .unwrap()
    .unwrap();
    na.cmp(&nb)
    }
    _ => unreachable!(),
  • edit in pijul/src/commands/pushpull.rs at line 344
    [11.20987]
    [11.20987]
    is_tag: bool,
  • edit in pijul/src/commands/pushpull.rs at line 359
    [11.21407]
    [11.21407]
    is_tag,
  • edit in pijul/src/commands/pushpull.rs at line 424
    [11.21985][9.107:125]()
    tags,
  • replacement in pijul/src/commands/pushpull.rs at line 426
    [11.22017][11.22017:22099]()
    .to_download(&mut *txn.write(), &mut channel, &mut repo, &mut remote)
    [11.22017]
    [11.9431]
    .to_download(
    &mut *txn.write(),
    &mut channel,
    &mut repo,
    &mut remote,
    self.is_tag,
    )
  • replacement in pijul/src/commands/pushpull.rs at line 479
    [11.197][11.11789:11872]()
    txn.apply_change_rec_ws(&repo.changes, &mut channel, h, &mut ws)?;
    [11.197]
    [11.268]
    match h {
    CS::Change(h) => {
    txn.apply_change_rec_ws(&repo.changes, &mut channel, h, &mut ws)?;
    }
    CS::State(s) => {
    if let Some(n) = txn.channel_has_state(&channel.states, &s.into())? {
    txn.put_tags(&mut channel.tags, n.into(), s)?;
    } else {
    bail!(
    "Cannot add tag {}: channel {:?} does not have that state",
    s.to_base32(),
    channel.name
    )
    }
    }
    }
  • replacement in pijul/src/commands/pushpull.rs at line 510
    [11.839][11.10396:10518](),[11.10518][11.952:1144](),[11.952][11.952:1144](),[11.1144][11.1144:1166](),[11.1166][11.1166:1227](),[11.1227][11.10519:10602](),[11.10602][11.1301:1432](),[11.12018][11.1301:1432](),[11.1301][11.1301:1432](),[11.1432][11.16143:16191]()
    if let Some(int) = txn_.get_internal(&d.into())? {
    for inode in txn_.iter_rev_touched(int)? {
    let (int_, inode) = inode?;
    if int_ < int {
    continue;
    } else if int_ > int {
    break;
    }
    let ext = libpijul::pristine::Position {
    change: txn_.get_external(&inode.change)?.unwrap().into(),
    pos: inode.pos,
    };
    if inodes.is_empty() || inodes.contains(&ext) {
    touched.insert(*inode);
    [11.839]
    [11.1479]
    match d {
    CS::Change(d) => {
    if let Some(int) = txn_.get_internal(&d.into())? {
    for inode in txn_.iter_rev_touched(int)? {
    let (int_, inode) = inode?;
    if int_ < int {
    continue;
    } else if int_ > int {
    break;
    }
    let ext = libpijul::pristine::Position {
    change: txn_.get_external(&inode.change)?.unwrap().into(),
    pos: inode.pos,
    };
    if inodes.is_empty() || inodes.contains(&ext) {
    touched.insert(*inode);
    }
    }
  • edit in pijul/src/commands/pushpull.rs at line 529
    [11.1501]
    [11.1501]
    }
    CS::State(_) => {
    // No need to do anything for now here, we don't
    // output after downloading a tag.
  • replacement in pijul/src/commands/pushpull.rs at line 552
    [11.1301][6.0:42]()
    if touched_paths.is_empty() {
    [11.1301]
    [6.42]
    if touched_paths.is_empty() && !self.is_tag {
  • replacement in pijul/src/commands/pushpull.rs at line 602
    [11.854][4.203:236](),[4.236][11.2859:2937](),[11.2859][11.2859:2937]()
    original: &[libpijul::Hash],
    now: &[libpijul::Hash],
    ) -> Result<Vec<libpijul::Hash>, anyhow::Error> {
    [11.854]
    [4.237]
    original: &[CS],
    now: &[CS],
    ) -> Result<Vec<CS>, anyhow::Error> {
  • replacement in pijul/src/commands/pushpull.rs at line 612
    [4.567][11.1171:1214](),[11.1171][11.1171:1214](),[11.1214][4.568:638]()
    for d in c.get_dependencies(&h)? {
    if original.get(&d).is_some() && now_.get(&d).is_none() {
    [4.567]
    [4.638]
    let hh = if let CS::Change(h) = h {
    h
    } else {
    stack.pop();
    result.push(h);
    continue;
    };
    for d in c.get_dependencies(&hh)? {
    if original.get(&CS::Change(d)).is_some() && now_.get(&CS::Change(d)).is_none() {
  • replacement in pijul/src/commands/pushpull.rs at line 622
    [4.680][4.680:711]()
    stack.push(d);
    [4.680]
    [11.1390]
    stack.push(CS::Change(d));
  • replacement in pijul/src/commands/pushpull.rs at line 636
    [11.1487][11.122682:122724](),[11.122682][11.122682:122724](),[11.122724][11.2938:2999](),[11.2999][11.122805:122838](),[11.122805][11.122805:122838]()
    fn check_deps<C: ChangeStore>(
    c: &C,
    original: &[libpijul::Hash],
    now: &[libpijul::Hash],
    ) -> Result<(), anyhow::Error> {
    [11.1487]
    [11.122838]
    fn check_deps<C: ChangeStore>(c: &C, original: &[CS], now: &[CS]) -> Result<(), anyhow::Error> {
  • edit in pijul/src/commands/pushpull.rs at line 641
    [11.123037]
    [11.123037]
    let n = if let CS::Change(n) = n { n } else { continue };
  • replacement in pijul/src/commands/pushpull.rs at line 643
    [11.123079][11.123079:123150]()
    if original_.get(&d).is_some() && now_.get(&d).is_none() {
    [11.123079]
    [11.11137]
    if original_.get(&CS::Change(d)).is_some() && now_.get(&CS::Change(d)).is_none() {
  • replacement in pijul/src/commands/pushpull.rs at line 651
    [11.22311][11.22311:22390]()
    fn notify_remote_unrecords(repo: &Repository, remote_unrecs: &[(u64, Hash)]) {
    [11.22311]
    [11.22390]
    fn notify_remote_unrecords(repo: &Repository, remote_unrecs: &[(u64, crate::remote::CS)]) {
  • replacement in pijul/src/commands/pushpull.rs at line 660
    [11.22751][11.22751:22824]()
    let header = &repo.changes.get_change(hash).unwrap().header;
    [11.22751]
    [11.22824]
    let header = match hash {
    CS::Change(hash) => repo.changes.get_header(hash).unwrap(),
    CS::State(hash) => repo.changes.get_tag_header(hash).unwrap(),
    };
  • replacement in pijul/src/commands/pushpull.rs at line 665
    [11.22855][11.22855:23141]()
    writeln!(&mut s, "# {}", header.message).expect("Infallible write to String");
    writeln!(&mut s, "# {}", header.timestamp).expect("Infallible write to String");
    writeln!(&mut s, "# {}", hash.to_base32()).expect("Infallible write to String");
    [11.22855]
    [11.23141]
    writeln!(&mut s, "# {}", header.message).unwrap();
    writeln!(&mut s, "# {}", header.timestamp).unwrap();
    match hash {
    CS::Change(hash) => {
    writeln!(&mut s, "# {}", hash.to_base32()).unwrap();
    }
    CS::State(hash) => {
    writeln!(&mut s, "# {}", hash.to_base32()).unwrap();
    }
    }
  • replacement in pijul/src/commands/pushpull.rs at line 685
    [11.23354][11.23354:23408]()
    fn notify_unknown_changes(unknown_changes: &[Hash]) {
    [11.23354]
    [11.23408]
    fn notify_unknown_changes(unknown_changes: &[crate::remote::CS]) {
  • replacement in pijul/src/commands/pushpull.rs at line 695
    [11.23767][11.23767:23864]()
    writeln!(&mut s, "# {}", hash.to_base32()).expect("Infallible write to String");
    [11.23767]
    [11.23864]
    let hash = match hash {
    CS::Change(hash) => hash.to_base32(),
    CS::State(hash) => hash.to_base32(),
    };
    writeln!(&mut s, "# {}", hash).expect("Infallible write to String");
  • replacement in pijul/src/commands/protocol.rs at line 34
    [11.124152][8.0:90]()
    static ref TAG: Regex = Regex::new(r#"^tag\s+(\S+)\s+(\S+)\s+([0-9]+)\s+"#).unwrap();
    [11.124152]
    [11.0]
    static ref TAG: Regex = Regex::new(r#"^tag\s+(\S+)\s+"#).unwrap();
    static ref TAGUP: Regex = Regex::new(r#"^tagup\s+(\S+)\s+(\S+)\s+([0-9]+)\s+"#).unwrap();
  • replacement in pijul/src/commands/protocol.rs at line 81
    [11.125737][11.11597:11667]()
    for x in txn.read().log(&*channel.read(), pos)? {
    [11.125737]
    [11.15402]
    let txn = txn.read();
    for x in txn.log(&*channel.read(), pos)? {
  • replacement in pijul/src/commands/protocol.rs at line 92
    [11.12250][11.1272:1345](),[11.1272][11.1272:1345]()
    writeln!(o, "{} {}", n, m.to_base32())?;
    [11.12250]
    [11.1345]
    let m2 = if let Some(x) = txn
    .rev_iter_tags(txn.tags(&*channel.read()), Some(n))?
    .next()
    {
    x?.1.b.into()
    } else {
    Merkle::zero()
    };
    writeln!(o, "{} {} {}", n, m.to_base32(), m2.to_base32())?;
  • edit in pijul/src/commands/protocol.rs at line 105
    [11.126196][11.11668:11765](),[11.11765][11.15540:15582](),[11.17836][11.15540:15582](),[11.15540][11.15540:15582](),[11.15582][11.12251:12297](),[11.12297][11.1515:1575](),[11.15582][11.1515:1575](),[11.1515][11.1515:1575]()
    } else if let Some(x) = txn.read().reverse_log(&*channel.read(), None)?.next() {
    let (n, (_, m)) = x?;
    let m: Merkle = m.into();
    writeln!(o, "{} {}", n, m.to_base32())?
  • replacement in pijul/src/commands/protocol.rs at line 106
    [11.126221][11.1576:1615]()
    writeln!(o, "-")?;
    [11.126221]
    [11.126476]
    let txn = txn.read();
    if let Some(x) = txn.reverse_log(&*channel.read(), None)?.next() {
    let (n, (_, m)) = x?;
    let m: Merkle = m.into();
    let m2 = if let Some(x) = txn
    .rev_iter_tags(txn.tags(&*channel.read()), Some(n))?
    .next()
    {
    x?.1.b.into()
    } else {
    Merkle::zero()
    };
    writeln!(o, "{} {} {}", n, m.to_base32(), m2.to_base32())?
    } else {
    writeln!(o, "-")?;
    }
  • edit in pijul/src/commands/protocol.rs at line 150
    [11.11929]
    [11.11974]
    let tags: Vec<u64> = txn
    .iter_tags(txn.tags(&*channel.read()), from)?
    .map(|k| (*k.unwrap().0).into())
    .collect();
    let mut tagsi = 0;
  • replacement in pijul/src/commands/protocol.rs at line 166
    [11.12631][11.3172:3328]()
    if txn.is_tagged(&channel.read().tags, n)? {
    writeln!(o, "{}.{}.{}.", n, h.to_base32(), m.to_base32())?
    [11.12631]
    [11.3328]
    if paths.is_empty() && tags.get(tagsi) == Some(&n) {
    writeln!(o, "{}.{}.{}.", n, h.to_base32(), m.to_base32(),)?;
    tagsi += 1;
  • replacement in pijul/src/commands/protocol.rs at line 170
    [11.3361][11.3361:3447]()
    writeln!(o, "{}.{}.{}", n, h.to_base32(), m.to_base32())?
    [11.3361]
    [11.3447]
    writeln!(o, "{}.{}.{}", n, h.to_base32(), m.to_base32())?;
  • edit in pijul/src/commands/protocol.rs at line 178
    [11.137]
    [11.137]
    let mut tag_path = repo.changes_dir.clone();
    libpijul::changestore::filesystem::push_tag_filename(&mut tag_path, &state);
    let mut tag = libpijul::tag::OpenTagFile::open(&tag_path, &state)?;
    let mut buf = Vec::new();
    tag.short(&mut buf)?;
    o.write_u64::<BigEndian>(buf.len() as u64)?;
    o.write_all(&buf)?;
    o.flush()?;
    }
    } else if let Some(cap) = TAGUP.captures(&buf) {
    if let Some(state) = Merkle::from_base32(cap[1].as_bytes()) {
  • edit in pijul/src/commands/protocol.rs at line 192
    [11.341]
    [11.341]
    let mut tag_path = repo.changes_dir.clone();
    libpijul::changestore::filesystem::push_tag_filename(&mut tag_path, &m);
    if std::fs::metadata(&tag_path).is_ok() {
    bail!("Tag for state {} already exists", m.to_base32());
    }
  • edit in pijul/src/commands/protocol.rs at line 209
    [11.848][11.848:1162]()
    let mut tag_path = repo.changes_dir.clone();
    std::fs::create_dir_all(&tag_path)?;
    let mut temp_path = tag_path.clone();
    temp_path.push("tmp");
    let mut w = std::fs::File::create(&temp_path)?;
  • replacement in pijul/src/commands/protocol.rs at line 213
    [11.1332][11.1332:1398]()
    let header = bincode::deserialize(&buf)?;
    [11.1332]
    [11.1398]
    let header = libpijul::tag::read_short(std::io::Cursor::new(&buf[..]), &m)?;
    let temp_path = tag_path.with_extension("tmp");
    std::fs::create_dir_all(temp_path.parent().unwrap())?;
    let mut w = std::fs::File::create(&temp_path)?;
  • replacement in pijul/src/commands/protocol.rs at line 220
    [11.1492][11.1492:1667]()
    libpijul::changestore::filesystem::push_tag_filename(&mut tag_path, &m);
    std::fs::create_dir_all(tag_path.parent().unwrap())?;
    [11.1492]
    [11.1667]
  • edit in pijul/src/commands/mod.rs at line 151
    [11.204]
    [11.2970]
    use crate::remote::CS;
  • replacement in pijul/src/commands/mod.rs at line 158
    [11.3136][11.3136:3169]()
    pullable: &[libpijul::Hash],
    [11.3136]
    [11.3169]
    pullable: &[CS],
  • replacement in pijul/src/commands/mod.rs at line 180
    [11.3733][11.3733:4003]()
    writeln!(v, "{}\n", p.to_base32()).unwrap();
    let deps = changes.get_dependencies(&p)?;
    if !deps.is_empty() {
    write!(v, " Dependencies:").unwrap();
    for d in deps {
    write!(v, " {}", d.to_base32()).unwrap();
    [11.3733]
    [11.4003]
    let header = match p {
    CS::Change(p) => {
    writeln!(v, "{}\n", p.to_base32()).unwrap();
    let deps = changes.get_dependencies(&p)?;
    if !deps.is_empty() {
    write!(v, " Dependencies:").unwrap();
    for d in deps {
    write!(v, " {}", d.to_base32()).unwrap();
    }
    writeln!(v).unwrap();
    }
    changes.get_header(&p)?
    }
    CS::State(p) => {
    writeln!(v, "t{}\n", p.to_base32()).unwrap();
    changes.get_tag_header(&p)?
  • replacement in pijul/src/commands/mod.rs at line 197
    [11.4017][11.4017:4107]()
    writeln!(v).unwrap();
    }
    let change = changes.get_header(&p)?;
    [11.4017]
    [11.4107]
    };
  • replacement in pijul/src/commands/mod.rs at line 200
    [11.4180][11.4180:4221]()
    for a in change.authors.iter() {
    [11.4180]
    [11.4221]
    for a in header.authors.iter() {
  • replacement in pijul/src/commands/mod.rs at line 212
    [11.4414][11.4414:4520]()
    writeln!(v, " Date: {}\n", change.timestamp).unwrap();
    for l in change.message.lines() {
    [11.4414]
    [11.4520]
    writeln!(v, " Date: {}\n", header.timestamp).unwrap();
    for l in header.message.lines() {
  • replacement in pijul/src/commands/mod.rs at line 216
    [11.4577][11.4577:4626]()
    if let Some(desc) = change.description {
    [11.4577]
    [11.4626]
    if let Some(desc) = header.description {
  • replacement in pijul/src/commands/mod.rs at line 229
    [11.4940][11.4940:4995]()
    fn parse_changelist(o: &[u8]) -> Vec<libpijul::Hash> {
    [11.4940]
    [11.4995]
    fn parse_changelist(o: &[u8]) -> Vec<crate::remote::CS> {
  • replacement in pijul/src/commands/mod.rs at line 233
    [11.5083][11.5083:5154]()
    .filter_map(|l| libpijul::Hash::from_base32(l.as_bytes()))
    [11.5083]
    [11.5154]
    .filter_map(|l| {
    ::log::debug!(
    "l = {:?} {:?}",
    l,
    libpijul::Merkle::from_base32(l.as_bytes())
    );
    if l.starts_with("t") {
    libpijul::Merkle::from_base32(&l.as_bytes()[1..]).map(crate::remote::CS::State)
    } else {
    libpijul::Hash::from_base32(l.as_bytes()).map(crate::remote::CS::Change)
    }
    })
  • edit in libpijul/src/tag.rs at line 100
    [103.1742]
    [11.8014]
    pub fn short<W: std::io::Write>(&mut self, mut w: W) -> Result<(), TagError> {
    let mut header_buf = vec![0u8; (self.header.channel - self.header.header) as usize];
    self.file.seek(SeekFrom::Start(self.header.header))?;
    self.file.read_exact(&mut header_buf)?;
    debug!("header_buf = {:?}", header_buf);
    let mut off = FileHeader {
    version: VERSION,
    header: 0,
    channel: 0,
    unhashed: 0,
    total: 0,
    offsets: DbOffsets::default(),
    state: self.header.state.clone(),
    };
    off.header = bincode::serialized_size(&off)?;
    off.channel = off.header + header_buf.len() as u64;
    off.total = off.channel;
    let mut off_buf = Vec::with_capacity(off.header as usize);
    bincode::serialize_into(&mut off_buf, &off)?;
    w.write_all(&off_buf)?;
    w.write_all(&header_buf)?;
    Ok(())
    }
    }
    pub fn read_short<R: std::io::Read + std::io::Seek>(mut file: R, expected: &Merkle) -> Result<crate::change::ChangeHeader, TagError> {
    let mut off = [0u8; std::mem::size_of::<FileHeader>() as usize];
    file.seek(SeekFrom::Start(0))?;
    file.read_exact(&mut off)?;
    let header: FileHeader = bincode::deserialize(&off).map_err(TagError::BincodeDe)?;
    debug!("header = {:?}", header);
    if &header.state == expected {
    file.seek(SeekFrom::Start(header.header))?;
    Ok(bincode::deserialize_from(file).map_err(TagError::BincodeDe)?)
    } else {
    Err(TagError::WrongHash {
    expected: *expected,
    got: header.state,
    })
    }
  • replacement in libpijul/src/tag.rs at line 520
    [11.19425][10.0:124]()
    let tags = copy::<L64, Pair<SerializedMerkle, SerializedMerkle>, UP<L64, Pair<SerializedMerkle, SerializedMerkle>>, _>(
    [11.19425]
    [11.19497]
    debug!("copying tags");
    let tags = copy::<L64, Pair<SerializedMerkle, SerializedMerkle>, P<L64, Pair<SerializedMerkle, SerializedMerkle>>, _>(
  • replacement in libpijul/src/tag/txn.rs at line 227
    [11.6778][11.6778:6952]()
    type Changeset = u64; // Db<ChangeId, L64>;
    type RevChangeset = u64; // UDb<L64, Pair<ChangeId, SerializedMerkle>>;
    type Tags = u64; // UDb<L64, SerializedHash>;
    [11.6778]
    [11.6952]
    type Changeset = u64;
    type RevChangeset = u64;
    type Tags = u64;
  • replacement in libpijul/src/tag/txn.rs at line 231
    [11.6953][11.6953:7007]()
    type States = u64; // UDb<SerializedMerkle, L64>;
    [11.6953]
    [11.7007]
    type States = u64;
  • replacement in libpijul/src/tag/txn.rs at line 406
    [11.2335][11.2335:2400]()
    ::sanakirja::btree::cursor::Cursor<L64, (), P<L64, ()>>;
    [11.2335]
    [11.2400]
    ::sanakirja::btree::cursor::Cursor<L64, Pair<SerializedMerkle, SerializedMerkle>, P<L64, Pair<SerializedMerkle, SerializedMerkle>>>;
  • replacement in libpijul/src/tag/txn.rs at line 410
    [11.2540][11.2540:2592]()
    let db: Db<L64, ()> = Db::from_page(*tags);
    [11.2540]
    [11.2592]
    let db: Db<L64, Pair<SerializedMerkle, SerializedMerkle>> = Db::from_page(*tags);
  • replacement in libpijul/src/tag/txn.rs at line 423
    [11.13339][11.2754:2832]()
    crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, ()>,
    [11.13339]
    [11.13429]
    crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>,
  • replacement in libpijul/src/tag/txn.rs at line 427
    [11.2877][11.2877:2932]()
    let db: Db<L64, ()> = Db::from_page(*channel);
    [11.2877]
    [11.13585]
    let db: Db<L64, Pair<SerializedMerkle, SerializedMerkle>> = Db::from_page(*channel);
  • replacement in libpijul/src/tag/txn.rs at line 443
    [11.14025][11.2933:2991]()
    ) -> Result<Option<&L64>, TxnErr<Self::GraphError>> {
    [11.14025]
    [11.14102]
    ) -> Result<Option<(&L64, &Pair<SerializedMerkle, SerializedMerkle>)>, TxnErr<Self::GraphError>> {
  • replacement in libpijul/src/tag/txn.rs at line 445
    [11.14145][11.2992:3026]()
    Ok(x.map(|(a, _)| a))
    [11.14145]
    [11.14163]
    Ok(x)
  • replacement in libpijul/src/tag/txn.rs at line 454
    [11.14340][11.3027:3085]()
    ) -> Result<Option<&L64>, TxnErr<Self::GraphError>> {
    [11.14340]
    [11.14417]
    ) -> Result<Option<(&L64, &Pair<SerializedMerkle, SerializedMerkle>)>, TxnErr<Self::GraphError>> {
  • replacement in libpijul/src/tag/txn.rs at line 456
    [11.14460][11.3086:3120]()
    Ok(x.map(|(a, _)| a))
    [11.14460]
    [11.14478]
    Ok(x)
  • replacement in libpijul/src/tag/txn.rs at line 467
    [11.14675][11.3121:3194]()
    crate::pristine::Cursor<Self, &Self, Self::TagsCursor, L64, ()>,
    [11.14675]
    [11.14760]
    crate::pristine::Cursor<Self, &Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>,
  • replacement in libpijul/src/tag/txn.rs at line 478
    [11.14973][11.3195:3271]()
    crate::pristine::RevCursor<Self, &Self, Self::TagsCursor, L64, ()>,
    [11.14973]
    [11.15061]
    crate::pristine::RevCursor<Self, &Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>,
  • replacement in libpijul/src/tag/txn.rs at line 482
    [11.3316][11.3316:3371]()
    let db: Db<L64, ()> = Db::from_page(*channel);
    [11.3316]
    [11.15217]
    let db: Db<L64, Pair<SerializedMerkle, SerializedMerkle>> = Db::from_page(*channel);
  • replacement in libpijul/src/tag/txn.rs at line 752
    [11.23017][11.3511:3589]()
    crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, ()>,
    [11.23017]
    [11.23107]
    crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>,
  • replacement in libpijul/src/tag/txn.rs at line 760
    [11.23298][11.3590:3648]()
    ) -> Result<Option<&L64>, TxnErr<Self::GraphError>> {
    [11.23298]
    [11.23375]
    ) -> Result<Option<(&L64, &Pair<SerializedMerkle, SerializedMerkle>)>, TxnErr<Self::GraphError>> {
  • replacement in libpijul/src/tag/txn.rs at line 767
    [11.23503][11.3649:3707]()
    ) -> Result<Option<&L64>, TxnErr<Self::GraphError>> {
    [11.23503]
    [11.23580]
    ) -> Result<Option<(&L64, &Pair<SerializedMerkle, SerializedMerkle>)>, TxnErr<Self::GraphError>> {
  • replacement in libpijul/src/tag/txn.rs at line 776
    [11.23728][11.3708:3781]()
    crate::pristine::Cursor<Self, &Self, Self::TagsCursor, L64, ()>,
    [11.23728]
    [11.23813]
    crate::pristine::Cursor<Self, &Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>,
  • replacement in libpijul/src/tag/txn.rs at line 787
    [11.24038][11.3782:3858]()
    crate::pristine::RevCursor<Self, &Self, Self::TagsCursor, L64, ()>,
    [11.24038]
    [11.24126]
    crate::pristine::RevCursor<Self, &Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>,
  • replacement in libpijul/src/pristine/sanakirja.rs at line 947
    [11.23676][11.4233:4311]()
    crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, ()>,
    [11.23676]
    [11.23766]
    crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>,
  • replacement in libpijul/src/pristine/sanakirja.rs at line 965
    [11.24249][11.4312:4370]()
    ) -> Result<Option<&L64>, TxnErr<Self::GraphError>> {
    [11.24249]
    [11.24326]
    ) -> Result<Option<(&L64, &Pair<SerializedMerkle, SerializedMerkle>)>, TxnErr<Self::GraphError>> {
  • replacement in libpijul/src/pristine/sanakirja.rs at line 967
    [11.24374][11.4371:4405]()
    Ok(x.map(|(a, _)| a))
    [11.24374]
    [11.24392]
    Ok(x)
  • replacement in libpijul/src/pristine/sanakirja.rs at line 976
    [11.24562][11.4406:4464]()
    ) -> Result<Option<&L64>, TxnErr<Self::GraphError>> {
    [11.24562]
    [11.24639]
    ) -> Result<Option<(&L64, &Pair<SerializedMerkle, SerializedMerkle>)>, TxnErr<Self::GraphError>> {
  • replacement in libpijul/src/pristine/sanakirja.rs at line 978
    [11.24687][11.4465:4499]()
    Ok(x.map(|(a, _)| a))
    [11.24687]
    [11.24705]
    Ok(x)
  • replacement in libpijul/src/pristine/sanakirja.rs at line 988
    [11.2167][9.809:906]()
    ) -> Result<super::Cursor<Self, &Self, Self::TagsCursor, L64, ()>, TxnErr<Self::GraphError>>
    [11.2167]
    [9.906]
    ) -> Result<super::Cursor<Self, &Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>, TxnErr<Self::GraphError>>
  • replacement in libpijul/src/pristine/sanakirja.rs at line 997
    [11.2455][9.913:1013]()
    ) -> Result<super::RevCursor<Self, &Self, Self::TagsCursor, L64, ()>, TxnErr<Self::GraphError>>
    [11.2455]
    [9.1013]
    ) -> Result<super::RevCursor<Self, &Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>, TxnErr<Self::GraphError>>
  • edit in libpijul/src/pristine/sanakirja.rs at line 1231
    [11.549083]
    [11.45839]
    fn state_from_prefix(
    &self,
    channel: &Self::Channel,
    s: &str,
    ) -> Result<(Merkle, L64), super::HashPrefixError<Self::GraphError>> {
    let h: SerializedMerkle = if let Some(ref h) = Merkle::from_prefix(s) {
    h.into()
    } else {
    return Err(super::HashPrefixError::Parse(s.to_string()));
    };
    let mut result = None;
    debug!("h = {:?}", h);
    for x in btree::iter(&self.txn, &channel.states, Some((&h, None)))
    .map_err(|e| super::HashPrefixError::Txn(e.into()))?
    {
    let (e, i) = x.map_err(|e| super::HashPrefixError::Txn(e.into()))?;
    debug!("{:?} {:?}", e, i);
    if e < &h {
    continue;
    } else {
    let e: Merkle = e.into();
    let b32 = e.to_base32();
    debug!("{:?}", b32);
    let (b32, _) = b32.split_at(s.len().min(b32.len()));
    if b32 != s {
    break;
    } else if result.is_none() {
    result = Some((e, *i))
    } else {
    return Err(super::HashPrefixError::Ambiguous(s.to_string()));
    }
    }
    }
    if let Some(result) = result {
    Ok(result)
    } else {
    Err(super::HashPrefixError::NotFound(s.to_string()))
    }
    }
  • edit in libpijul/src/pristine/sanakirja.rs at line 1431
    [11.554746][9.1095:1457]()
    sanakirja_cursor!(remotetags, L64, Pair<SerializedMerkle, SerializedMerkle>);
    sanakirja_rev_cursor!(remotetags, L64, Pair<SerializedMerkle, SerializedMerkle>);
    type RemotetagsCursor = ::sanakirja::btree::cursor::Cursor<
    L64,
    Pair<SerializedMerkle, SerializedMerkle>,
    UP<L64, Pair<SerializedMerkle, SerializedMerkle>>,
    >;
  • edit in libpijul/src/pristine/sanakirja.rs at line 1498
    [11.81489]
    [11.81489]
    debug!("last_remote: {:?}", remote);
  • replacement in libpijul/src/pristine/sanakirja.rs at line 1509
    [9.1497][9.1497:1532]()
    remote: &Self::Remotetags,
    [9.1497]
    [9.1532]
    remote: &Self::Tags,
  • edit in libpijul/src/pristine/sanakirja.rs at line 1533
    [11.49322]
    [11.556591]
    }
    fn get_remote_tag(
    &self,
    remote: &Self::Tags,
    n: u64,
    ) -> Result<Option<(u64, &Pair<SerializedMerkle, SerializedMerkle>)>, TxnErr<Self::GraphError>>
    {
    let n = n.into();
    if let Some(x) = btree::rev_iter(&self.txn, remote, Some((&n, None)))?.next() {
    let (&k, m) = x?;
    Ok(Some((k.into(), m)))
    } else {
    Ok(None)
    }
  • replacement in libpijul/src/pristine/sanakirja.rs at line 1564
    [11.82186][11.49635:49685](),[11.49635][11.49635:49685]()
    ) -> Result<bool, TxnErr<Self::GraphError>> {
    [11.82186]
    [11.98958]
    ) -> Result<Option<u64>, TxnErr<Self::GraphError>> {
  • replacement in libpijul/src/pristine/sanakirja.rs at line 1566
    [11.63625][11.82263:82311](),[11.99032][11.82263:82311](),[11.82263][11.82263:82311](),[11.82311][11.10272:10300]()
    Some((k, _)) if k == m => Ok(true),
    _ => Ok(false),
    [11.99032]
    [11.82338]
    Some((k, v)) if k == m => Ok(Some((*v).into())),
    _ => Ok(None),
  • replacement in libpijul/src/pristine/sanakirja.rs at line 1856
    [9.3270][9.3270:3318]()
    debug!("del_changes {:?} {:?}", t_, p);
    [9.3270]
    [9.3318]
    debug!("del_tags {:?} {:?}", t_, p);
  • replacement in libpijul/src/pristine/sanakirja.rs at line 1904
    [11.562292][11.3610:3643]()
    v: (Hash, Merkle, bool),
    [11.562292]
    [9.3542]
    v: (Hash, Merkle),
  • edit in libpijul/src/pristine/sanakirja.rs at line 1915
    [11.85930]
    [11.85930]
    debug!("remote.remote after put: {:?}", remote.remote);
  • replacement in libpijul/src/pristine/sanakirja.rs at line 1917
    [11.86001][11.3644:3661](),[11.3661][9.3593:3648](),[9.3648][11.3735:3745](),[11.3735][11.3735:3745]()
    if v.2 {
    self.put_tags(&mut remote.tags, k, &v.1)?;
    }
    [11.86001]
    [11.86001]
    // if v.2 {
    // self.put_tags(&mut remote.tags, k, &v.1)?;
    // }
  • edit in libpijul/src/pristine/sanakirja.rs at line 2369
    [11.32833]
    [11.32833]
    _tags: r.tags.db.into(),
  • edit in libpijul/src/pristine/sanakirja.rs at line 2518
    [11.33344]
    [11.33344]
    const REMOTE_LEN: usize = 40;
  • replacement in libpijul/src/pristine/sanakirja.rs at line 2525
    [11.33448][11.33448:33477]()
    33 + self.path.len()
    [11.33448]
    [11.33477]
    REMOTE_LEN + 1 + self.path.len()
  • replacement in libpijul/src/pristine/sanakirja.rs at line 2528
    [11.33534][11.33534:33569]()
    33 + (*p.add(32)) as usize
    [11.33534]
    [11.33569]
    REMOTE_LEN + 1 + (*p.add(REMOTE_LEN)) as usize
  • replacement in libpijul/src/pristine/sanakirja.rs at line 2531
    [11.33644][11.33644:33683]()
    let len = *p.add(32) as usize;
    [11.33644]
    [11.33683]
    let len = *p.add(REMOTE_LEN) as usize;
  • replacement in libpijul/src/pristine/sanakirja.rs at line 2540
    [11.33957][11.33957:33991]()
    33 + self.path.len(),
    [11.33957]
    [11.33991]
    REMOTE_LEN + 1 + self.path.len(),
  • replacement in libpijul/src/pristine/sanakirja.rs at line 2544
    [11.34053][11.34053:34117]()
    std::slice::from_raw_parts(p, 33 + self.path.len())
    [11.34053]
    [11.34117]
    std::slice::from_raw_parts(p, REMOTE_LEN + 1 + self.path.len())
  • edit in libpijul/src/pristine/sanakirja.rs at line 2555
    [11.34254]
    [11.34254]
    _tags: L64,
  • replacement in libpijul/src/pristine/sanakirja.rs at line 2562
    [11.34405][11.34405:34455]()
    let len = 33 + self._path.len() as usize;
    [11.34405]
    [11.34455]
    let len = REMOTE_LEN + 1 + self._path.len() as usize;
  • replacement in libpijul/src/pristine/mod.rs at line 257
    [11.35468][11.35468:35536]()
    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
    [11.35468]
    [11.35536]
    #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
  • edit in libpijul/src/pristine/mod.rs at line 292
    [11.36263]
    [11.36263]
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
    write!(fmt, "{}", data_encoding::BASE32_NOPAD.encode(&self.0))
    }
    }
    impl std::fmt::Debug for RemoteId {
  • replacement in libpijul/src/pristine/mod.rs at line 467
    [11.26829][11.5033:5111]()
    crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, ()>,
    [11.26829]
    [11.26919]
    crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>,
  • replacement in libpijul/src/pristine/mod.rs at line 474
    [11.27039][11.5112:5169]()
    ) -> Result<Option<&L64>, TxnErr<Self::GraphError>>;
    [11.27039]
    [11.27115]
    ) -> Result<Option<(&L64, &Pair<SerializedMerkle, SerializedMerkle>)>, TxnErr<Self::GraphError>>;
  • replacement in libpijul/src/pristine/mod.rs at line 479
    [11.27195][11.5170:5227]()
    ) -> Result<Option<&L64>, TxnErr<Self::GraphError>>;
    [11.27195]
    [11.3106]
    ) -> Result<Option<(&L64, &Pair<SerializedMerkle, SerializedMerkle>)>, TxnErr<Self::GraphError>>;
  • replacement in libpijul/src/pristine/mod.rs at line 485
    [11.3189][11.5228:5319]()
    ) -> Result<Cursor<Self, &Self, Self::TagsCursor, L64, ()>, TxnErr<Self::GraphError>>;
    [11.3189]
    [11.3315]
    ) -> Result<Cursor<Self, &Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>, TxnErr<Self::GraphError>>;
  • replacement in libpijul/src/pristine/mod.rs at line 492
    [11.3427][11.5320:5379]()
    RevCursor<Self, &Self, Self::TagsCursor, L64, ()>,
    [11.3427]
    [11.3498]
    RevCursor<Self, &Self, Self::TagsCursor, L64, Pair<SerializedMerkle, SerializedMerkle>>,
  • edit in libpijul/src/pristine/mod.rs at line 652
    [11.58422]
    [11.591226]
    fn state_from_prefix(
    &self,
    channel: &Self::Channel,
    s: &str,
    ) -> Result<(Merkle, L64), HashPrefixError<Self::GraphError>>;
  • edit in libpijul/src/pristine/mod.rs at line 695
    [11.103300][9.3725:3873]()
    cursor!(remotetags, L64, Pair<SerializedMerkle, SerializedMerkle>);
    rev_cursor!(remotetags, L64, Pair<SerializedMerkle, SerializedMerkle>);
  • replacement in libpijul/src/pristine/mod.rs at line 732
    [9.3913][9.3913:3948]()
    remote: &Self::Remotetags,
    [9.3913]
    [9.3948]
    remote: &Self::Tags,
  • edit in libpijul/src/pristine/mod.rs at line 735
    [9.4045]
    [11.59531]
    /// Find the last state greater than or equal to n.
  • edit in libpijul/src/pristine/mod.rs at line 741
    [11.103728]
    [11.965]
    /// Find the last tag less than or equal to n (opposite of get_remote_state).
    fn get_remote_tag(
    &self,
    remote: &Self::Tags,
    n: u64,
    ) -> Result<Option<(u64, &Pair<SerializedMerkle, SerializedMerkle>)>, TxnErr<Self::GraphError>>;
  • replacement in libpijul/src/pristine/mod.rs at line 758
    [11.103794][11.60067:60116](),[11.60067][11.60067:60116]()
    ) -> Result<bool, TxnErr<Self::GraphError>>;
    [11.103794]
    [11.7533]
    ) -> Result<Option<u64>, TxnErr<Self::GraphError>>;
  • edit in libpijul/src/pristine/mod.rs at line 1487
    [11.68035]
    [11.22252]
    initialized_cursor!(tags, L64, Pair<SerializedMerkle, SerializedMerkle>, ChannelTxnT, GraphError);
    initialized_rev_cursor!(tags, L64, Pair<SerializedMerkle, SerializedMerkle>, ChannelTxnT, GraphError);
  • edit in libpijul/src/pristine/mod.rs at line 1532
    [11.22745][11.5380:5769]()
    impl<'a, T: ChannelTxnT> Iterator for crate::pristine::RevCursor<T, &'a T, T::TagsCursor, L64, ()>
    {
    type Item = Result<&'a L64, TxnErr<T::GraphError>>;
    fn next(&mut self) -> Option<Self::Item> {
    match self.txn.cursor_tags_prev(&mut self.cursor) {
    Ok(Some(x)) => Some(Ok(x)),
    Ok(None) => None,
    Err(e) => Some(Err(e)),
    }
    }
    }
  • edit in libpijul/src/pristine/mod.rs at line 1533
    [11.5770][11.5770:6520](),[11.1515][11.621548:621549](),[11.3690][11.621548:621549](),[11.6520][11.621548:621549](),[11.68729][11.621548:621549](),[11.621548][11.621548:621549]()
    impl<'a, T: ChannelTxnT>
    crate::pristine::Cursor<T, &'a T, T::TagsCursor, L64, ()>
    {
    pub fn prev(&mut self) -> Option<Result<u64, TxnErr<T::GraphError>>> {
    match self.txn.cursor_tags_prev(&mut self.cursor) {
    Ok(Some(x)) => Some(Ok((*x).into())),
    Ok(None) => None,
    Err(e) => Some(Err(e)),
    }
    }
    }
    impl<'a, T: ChannelTxnT> Iterator for crate::pristine::Cursor<T, &'a T, T::TagsCursor, L64, ()>
    {
    type Item = Result<u64, TxnErr<T::GraphError>>;
    fn next(&mut self) -> Option<Self::Item> {
    match self.txn.cursor_tags_next(&mut self.cursor) {
    Ok(Some(x)) => Some(Ok((*x).into())),
    Ok(None) => None,
    Err(e) => Some(Err(e)),
    }
    }
    }
  • replacement in libpijul/src/pristine/mod.rs at line 1868
    [11.638332][11.3929:3962]()
    v: (Hash, Merkle, bool),
    [11.638332]
    [9.4168]
    v: (Hash, Merkle),
  • edit in libpijul/src/pristine/merkle.rs at line 3
    [11.638816]
    [11.638816]
    pub(crate) const BASE32_BYTES: usize = 53;
  • edit in libpijul/src/pristine/merkle.rs at line 31
    [104.9]
    [104.9]
    impl std::fmt::Debug for SerializedMerkle {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
    Merkle::from(self).fmt(fmt)
    }
    }
  • edit in libpijul/src/pristine/merkle.rs at line 96
    [11.639957]
    [11.639957]
    }
    }
    pub fn from_prefix(s: &str) -> Option<Self> {
    let mut b32 = [b'A'; BASE32_BYTES];
    if s.len() > BASE32_BYTES {
    return None;
  • edit in libpijul/src/pristine/merkle.rs at line 104
    [11.639967]
    [11.639967]
    (&mut b32[..s.len()]).clone_from_slice(s.as_bytes());
    let bytes = if let Ok(bytes) = data_encoding::BASE32_NOPAD.decode(&b32) {
    bytes
    } else {
    return None;
    };
    curve25519_dalek::edwards::CompressedEdwardsY::from_slice(&bytes[..32])
    .decompress()
    .map(Merkle::Ed25519)
  • replacement in libpijul/src/pristine/merkle.rs at line 156
    [11.112517][11.101552:101614]()
    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
    [11.112517]
    [11.112573]
    #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
  • edit in libpijul/src/changestore/mod.rs at line 39
    [11.818398]
    [11.818398]
    fn get_tag_header(&self, h: &crate::Merkle) -> Result<ChangeHeader, Self::Error>;
  • replacement in libpijul/src/changestore/memory.rs at line 2
    [11.820772][11.820772:820799]()
    use crate::change::Change;
    [11.820772]
    [11.820799]
    use crate::change::{Change, ChangeHeader};
  • edit in libpijul/src/changestore/memory.rs at line 11
    [11.821071]
    [11.821071]
    tags: Arc<RwLock<HashMap<crate::Merkle, ChangeHeader>>>,
  • edit in libpijul/src/changestore/memory.rs at line 41
    [11.821445]
    [11.821445]
    fn get_tag_header(&self, h: &crate::Merkle) -> Result<ChangeHeader, Self::Error> {
    let changes = self.tags.read().unwrap();
    Ok(changes.get(&h).unwrap().clone())
    }
  • edit in libpijul/src/changestore/filesystem.rs at line 33
    [11.35449]
    [11.824519]
    #[error(transparent)]
    Tag(#[from] crate::tag::TagError),
  • edit in libpijul/src/changestore/filesystem.rs at line 62
    [11.825005]
    [11.825005]
    path
    }
    pub fn tag_filename(&self, hash: &Merkle) -> PathBuf {
    let mut path = self.changes_dir.clone();
    push_tag_filename(&mut path, hash);
  • edit in libpijul/src/changestore/filesystem.rs at line 166
    [11.828467]
    [11.828467]
    fn get_tag_header(&self, h: &Merkle) -> Result<ChangeHeader, Self::Error> {
    let path = self.tag_filename(h);
    let mut p = crate::tag::OpenTagFile::open(&path, h)?;
    Ok(p.header()?)
    }