This patch sends the list of patches + all their dependencies that touch a path, instead of letting the client download the dependencies after the initial download.
OGJFEWHUMFIZYBS456FPNUN3KEUDZXIJNFGPEMJGQDC7INZMHQZQC R7X3PDL6ERX6POMBPIGHFCJVPG4QLA4LJYFDRPLXCAD45X772ASAC ABQDWHNGSBF2REQDCGXSBFAU4RUMXYAF2KHJ5O3D32M7Z3A3FEDAC PYTC7DPVCWKYDXXBY44BBNB4DHZ3N4OQW3EOEQ7H6Z5P5XBG2EIAC SXEYMYF7P4RZMZ46WPL4IZUTSQ2ATBWYZX7QNVMS3SGOYXYOHAGQC L2VH4BYK3IULLGBHXMZJWKRKDQY43QEMQRTXFJCNRDE7PODLXWTAC MU5GSJAW65PEG3BRYUKZ7O37BPHW3MOX3S5E2RFOXKGUOJEEDQ5AC TYAKEAJLABCZQDYAI4YBGIJNQ7HJS4DVULEGPCZOGJPJUYYNR6TAC DDJO7X2P2BAJSXPOE6ODKAJM7GRWKPT36WWTUZ373ZWQRYU4CFIAC S2B5MEWPPG4P6SL5NWTVAHPRJ6YPKX3VTRONYS267ZTTTPA6L3GAC CCLLB7OIFNFYJZTG3UCI7536TOCWSCSXR67VELSB466R24WLJSDAC DO2Y5TY5JQISUHCVNPI2FXO7WWZVJQ3LGPWF4DNADMGZRIO6PT2QC I24UEJQLCH2SOXA4UHIYWTRDCHSOPU7AFTRUOTX7HZIAV4AZKYEQC EUZFFJSOWV4PXDFFPDAFBHFUUMOFEU6ST7JH57YYRRR2SEOXLN6QC A3RM526Y7LUXNYW4TL56YKQ5GVOK2R5D7JJVTSQ6TT5MEXIR6YAAC ZWVYH7WPYOGDKWODFSAJ6R5U64DON2AVVJ2XZJKHAOMLJEFTYF3QC UDHP4ZVBQZT2VBURB2MDCU2IZDNMCAFSIUKWRBDQ5BWMFKSN2LYQC 4XLHUME7YLJV6XUZBOW7PX62TCJXIWW2CPITXO5GZOULWGXRVDZAC IBPVOKM5MXTGB2P7LCD75MISAYUNDPEKQAUEVCXJJWLWCX2TJZBAC C3L2TLQWREYOM3YHL37L7PS74YGLHBEDQRSCVMYIU6HKBEPNN2SAC L4JXJHWXYNCL4QGJXNKKTOKKTAXKKXBJUUY7HFZGEUZ5A2V5H34QC YN63NUZO4LVJ7XPMURDULTXBVJKW5MVCTZ24R7Z52QMHO3HPDUVQC RM225IDQR36MNBMN7OT2R562M4FUD6L34RY7A3WDBBETZIIDKZ5AC WZVCLZKY34KQBQU6YBGJLQCDADBQ67LQVDNRVCMQVY3O3C3EIWSQC self.download_changelist_(f, a, from, paths, &remote_txn, &remote_channel)}pub fn download_changelist_<A,T: libpijul::ChannelTxnT + libpijul::TxnTExt + libpijul::DepsTxnT + libpijul::GraphTxnT,F: FnMut(&mut A, u64, Hash, Merkle, bool) -> Result<(), anyhow::Error>,>(&mut self,mut f: F,a: &mut A,from: u64,paths: &[String],remote_txn: &T,remote_channel: &ChannelRef<T>,) -> Result<HashSet<Position<Hash>>, anyhow::Error> {let store = libpijul::changestore::filesystem::FileSystem::from_root(&self.root,pijul_repository::max_files()?,);
for x in remote_txn.log(&*rem, from)? {let (n, (h, m)) = x?;assert!(n >= from);let h_int = remote_txn.get_internal(h)?.unwrap();if paths_.is_empty()|| paths_.iter().any(|x| {remote_txn.get_touched_files(x, Some(h_int))
if paths_.is_empty() {for x in remote_txn.log(&*rem, from)? {debug!("log {:?}", x);let (n, (h, m)) = x?;assert!(n >= from);debug!("put_remote {:?} {:?} {:?}", n, h, m);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)?;}}} else {let mut hashes = HashMap::new();let mut stack = Vec::new();for x in remote_txn.log(&*rem, from)? {debug!("log {:?}", x);let (n, (h, m)) = x?;assert!(n >= from);let h_int = remote_txn.get_internal(h)?.unwrap();if paths_.is_empty()|| paths_.iter().any(|x| {let y = remote_txn.get_touched_files(x, Some(h_int)).unwrap();debug!("x {:?} {:?}", x, y);y == Some(h_int)}){stack.push((*h_int, *m, n));}}while let Some((h_int, m, n)) = stack.pop() {if hashes.insert(h_int, (m, n)).is_some() {continue;}for d in remote_txn.iter_dep(&h_int)? {let (&h_int_, &d) = d?;if h_int_ < h_int {continue;} else if h_int_ > h_int {break;}let n = remote_txn.get_changeset(remote_txn.changes(&*rem), &d)
.is_some()}){
.unwrap();let m = remote_txn.get_revchangeset(remote_txn.rev_changes(&*rem), &n).unwrap().unwrap().b;stack.push((d, m.into(), (*n).into()))}}let mut hashes: Vec<_> = hashes.into_iter().collect();hashes.sort_by_key(|(_, (_, n))| *n);for (h_int, (m, n)) in hashes {let h = remote_txn.get_external(&h_int)?.unwrap();
for r in CHANGELIST_PATHS.captures_iter(&cap[3]) {let s: String = r[1].replace("\\\"", "\"");if let Ok((p, ambiguous)) = txn.follow_oldest_path(&repo.changes, &channel, &s){if ambiguous {bail!("Ambiguous path")
{for r in CHANGELIST_PATHS.captures_iter(&cap[3]) {let s: String = r[1].replace("\\\"", "\"");if let Ok((p, ambiguous)) =txn.follow_oldest_path(&repo.changes, &channel, &s){if ambiguous {bail!("Ambiguous path")}let h: libpijul::Hash = txn.get_external(&p.change)?.unwrap().into();writeln!(o, "{}.{}", h.to_base32(), p.pos.0)?;paths.push(s);} else {debug!("protocol line: {:?}", buf);bail!("Protocol error")
let h: libpijul::Hash = txn.get_external(&p.change)?.unwrap().into();writeln!(o, "{}.{}", h.to_base32(), p.pos.0)?;paths.insert(p);paths.extend(libpijul::fs::iter_graph_descendants(&*txn, &channel.read(), p)?.map(|x| x.unwrap()),);} else {debug!("protocol line: {:?}", buf);bail!("Protocol error")
for x in txn.log(&*channel.read(), from)? {let (n, (h, m)) = x?;let h_int = txn.get_internal(h)?.unwrap();if paths.is_empty()|| paths.iter().any(|x| {x.change == *h_int|| txn.get_touched_files(x, Some(h_int)).unwrap().is_some()}){let h: Hash = h.into();let m: Merkle = m.into();if paths.is_empty() && tags.get(tagsi) == Some(&n) {
(pijul_remote::local::Local {channel: (&cap[1]).to_string(),root: PathBuf::new(),changes_dir: PathBuf::new(),pristine: pristine.clone(),name: String::new(),}).download_changelist_(|_, n, h, m, is_tag| {if is_tag {