add pull
[?]
Dec 3, 2025, 8:10 PM
ODCT4QJNJLQTDNFPIF7HX4XCFTEXZBESG3PTD276O7TWB7MSGWMQCDependencies
- [2]
D7A7MSIHallow to defer or abandon record, add buttons - [3]
OQ6HSAWHshow record log - [4]
ACDXXAX2refactor main's updates into smaller fns - [5]
KWTBNTO3diffs selection and scrolling - [6]
WAOGSCOJvery nice refactor, wip adding channels logs - [7]
EJPSD5XOshared allowed actions conditions between update and view - [8]
YK3MOJJLchonky refactor, wip other channels logs & diffs - [9]
IFQPVMBDerror handling for repo actions - [10]
LFEMJYYDstart of to_record selection - [11]
YGZ3VCW4add push - [12]
UF5NJKAStest load repo - [*]
SWWE2R6Mdisplay basic repo stuff - [*]
6YZAVBWUInitial commit
Change contents
- replacement in libflorescence/src/repo.rs at line 8
use pijul_remote::{PushDelta, RemoteRepo};use pijul_remote::{PushDelta, RemoteDelta, RemoteRepo}; - edit in libflorescence/src/repo.rs at line 78
Pull, - edit in libflorescence/src/repo.rs at line 108
result: anyhow::Result<()>,},Pulled { - edit in libflorescence/src/repo.rs at line 459
}MsgIn::Pull => {let result = pull(&internal_state.path).await;let _ = msg_out_tx.send(MsgOut::Pulled { result }); - edit in libflorescence/src/repo.rs at line 1286
}}#[allow(clippy::await_holding_lock,reason = "imposed by sanakirja API for txn")]async fn pull(repo_path: &Path) -> Result<(), anyhow::Error> {let mut repo = pijul::Repository::find_root(Some(repo_path))?;let channel_name = current_channel(&repo)?;let txn = repo.pristine.arc_txn_begin()?;let mut channel = txn.write().open_or_create_channel(&channel_name)?;let remote_name = if let Some(ref def) = repo.config.default_remote {def} else {bail!("Missing remote")};// TODO why no same as current channel_name?let from_channel = libpijul::DEFAULT_CHANNEL;let no_cert_check = false;let mut remote = pijul_remote::repository(&repo,Some(&repo.path),None,remote_name,from_channel,no_cert_check,true,).await?;let RemoteDelta {inodes,remote_ref,to_download,remote_unrecs: _,..} = to_download(&mut txn.write(), &mut channel, &mut repo, &mut remote).await?;let hash = pending(txn.clone(), &channel, &mut repo)?;if let Some(ref r) = remote_ref {remote.update_identities(&mut repo, r).await?;}// TODO: Show remote unrecords// notify_remote_unrecords(&repo, remote_unrecs.as_slice());if to_download.is_empty() {if let Some(ref h) = hash {txn.write().unrecord(&repo.changes, &channel, h, 0)?;}txn.commit()?;bail!("Nothing to pull");}{// Now that .pull is always given `false` for `do_apply`...let mut ws = libpijul::ApplyWorkspace::new();debug!("to_download = {:#?}", to_download);let mut channel = channel.write();let mut txn = txn.write();for h in to_download.iter().rev() {match h {pijul_remote::CS::Change(h) => {txn.apply_change_rec_ws(&repo.changes,&mut channel,h,&mut ws,)?;}pijul_remote::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",libpijul::Base32::to_base32(s),channel.name)}}}}}let full = false;remote.complete_changes(&repo, &*txn.read(), &mut channel, &to_download, full).await?;remote.finish().await?;debug!("inodes = {:?}", inodes);debug!("to_download: {:?}", to_download.len());let mut touched = HashSet::new();let txn_ = txn.read();for d in to_download.iter() {debug!("to_download {:?}", d);match d {pijul_remote::CS::Change(d) => {use pijul::GraphTxnT;if let Some(int) = txn_.get_internal(&d.into())? {use pijul::DepsTxnT;for inode in txn_.iter_rev_touched(int)? {let (int_, inode) = inode?;if int_ < int {continue;} else if int_ > int {break;}use pijul::GraphTxnT;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);}}}}pijul_remote::CS::State(_) => {// No need to do anything for now here, we don't// output after downloading a tag.}}}std::mem::drop(txn_);let is_current_channel = true;if is_current_channel {let mut touched_paths = BTreeSet::new();{let txn_ = txn.read();for &i in touched.iter() {if let Some((path, _)) = libpijul::fs::find_path(&repo.changes,&*txn_,&*channel.read(),false,i,)? {touched_paths.insert(path);} else {touched_paths.clear();break;}}}if touched_paths.is_empty() {touched_paths.insert(String::from(""));}let mut last: Option<&str> = None;let mut conflicts = Vec::new();for path in touched_paths.iter() {if let Some(last_path) = last {// If `last_path` is a prefix (in the path sense) of `path`,// skip.if last_path.len() < path.len() {let (pre_last, post_last) = path.split_at(last_path.len());if pre_last == last_path && post_last.starts_with("/") {continue;}}}debug!("path = {:?}", path);conflicts.extend(libpijul::output::output_repository_no_pending(&repo.working_copy,&repo.changes,&txn,&channel,path,true,None,std::thread::available_parallelism()?.get(),0,)?.into_iter(),);last = Some(path)}// TODO: handle conflicts// print_conflicts(&conflicts)?;}if let Some(h) = hash {txn.write().unrecord(&repo.changes, &channel, &h, 0)?;repo.changes.del_change(&h)?; - edit in libflorescence/src/repo.rs at line 1484
txn.commit()?;Ok(()) - edit in libflorescence/src/repo.rs at line 1489
/// Gets the `to_download` vec and calculates any remote unrecords./// If the local remote cache can be auto-updated, it will be.async fn to_download(txn: &mut MutTxn<()>,channel: &mut ChannelRef<MutTxn<()>>,repo: &mut pijul::Repository,remote: &mut RemoteRepo,) -> Result<RemoteDelta<MutTxn<()>>, anyhow::Error> {let path = &[];let force_cache = None;let changes = &[];let delta = remote.update_changelist_pushpull(txn,path,channel,force_cache,repo,changes,true,).await?;let to_download = remote.pull(repo,txn,channel,delta.to_download.as_slice(),&delta.inodes,false,).await?;Ok(RemoteDelta {to_download,..delta})}/// Record the pending change (i.e. any unrecorded modifications in/// the working copy), returning its hash.fn pending<T: pijul::MutTxnTExt + pijul::TxnT + Send + Sync + 'static>(txn: pijul::ArcTxn<T>,channel: &pijul::ChannelRef<T>,repo: &mut pijul_repository::Repository,) -> anyhow::Result<Option<libpijul::Hash>> {use libpijul::changestore::ChangeStore;let mut builder = pijul::record::Builder::new();builder.record(txn.clone(),libpijul::Algorithm::default(),false,&libpijul::DEFAULT_SEPARATOR,channel.clone(),&repo.working_copy,&repo.changes,"",std::thread::available_parallelism()?.get(),)?;let recorded = builder.finish();if recorded.actions.is_empty() {return Ok(None);}let mut txn = txn.write();let actions = recorded.actions.into_iter().map(|rec| rec.globalize(&*txn).unwrap()).collect();let contents = if let Ok(c) = std::sync::Arc::try_unwrap(recorded.contents){c.into_inner()} else {unreachable!()};let mut pending_change = libpijul::change::Change::make_change(&*txn,channel,actions,contents,libpijul::change::ChangeHeader::default(),Vec::new(),)?;let (dependencies, extra_known) = libpijul::change::dependencies(&*txn,&*channel.read(),pending_change.changes.iter(),)?;pending_change.dependencies = dependencies;pending_change.extra_known = extra_known;let hash = repo.changes.save_change(&mut pending_change, |_, _| Ok::<_, anyhow::Error>(())).unwrap();txn.apply_local_change(channel,&pending_change,&hash,&recorded.updatables,)?;Ok(Some(hash))} - edit in inflorescence_model/src/action.rs at line 41
Pull, - edit in inflorescence_model/src/action.rs at line 104
(Pull, Pull) => true, - edit in inflorescence_model/src/action.rs at line 126
(Pull, _) => false, - edit in inflorescence_model/src/action.rs at line 347
let pull = || Binding {key: "F",label: "pull",msg: Some(FilteredMsg::Pull),}; - edit in inflorescence_model/src/action.rs at line 396
ma.push(pull()); - edit in inflorescence/src/main.rs at line 557
// TODO switch state while pushing to display progress - edit in inflorescence/src/main.rs at line 561
action::FilteredMsg::Pull => {// TODO switch state while pulling to display progressstate.repo_tx_in.send(repo::MsgIn::Pull).unwrap();Task::none()} - edit in inflorescence/src/main.rs at line 756
repo::MsgOut::Pulled { result } => match result {Ok(()) => Task::none(),Err(err) => report_err(state, err.to_string()),}, - edit in inflorescence/src/main.rs at line 1568
"f" if mods == Modifiers::SHIFT => {action(action::FilteredMsg::Pull)}