allow to compare local with remote records

tzemanovic
Mar 30, 2026, 1:05 PM
DNTMUCMOH4BRNMQAVCHDM2XESAJIKWTZW344CVHOQIJBWXJWCOMAC

Dependencies

  • [2] YBJRDOTC make all repo actions async
  • [3] 23SFYK4Q big view refactor into a new crate
  • [4] 3QVNMRNM test non-empty repo app view
  • [5] XSZZB47U refactor stuff into lib
  • [6] I2AG42PA new cols layout
  • [7] KWTBNTO3 diffs selection and scrolling
  • [8] 5MUEECMJ smooth scrolling nav
  • [9] PTWZYQFR use nav-scrollable for repo status
  • [10] UR4J677R nav for log changes and refactors
  • [11] K63JN6CR refactor out non-view field from cursor
  • [12] A6Z4O6RC actions menu
  • [13] JZXYSIYD channel selection!
  • [14] OJPGHVC3 entire log!
  • [15] WAOGSCOJ very nice refactor, wip adding channels logs
  • [16] WH57EHNM update tests
  • [17] EJPSD5XO shared allowed actions conditions between update and view
  • [18] YK3MOJJL chonky refactor, wip other channels logs & diffs
  • [19] TQEZQJV4 finish other channels logs selection
  • [20] EGJG2KPD refactor
  • [21] 7WCB5YQJ refactor msgs and modules
  • [22] PKLUHYE4 allow to copy change hash
  • [23] CULHFNIV add error report view
  • [24] IFQPVMBD error handling for repo actions
  • [25] LFEMJYYD start of to_record selection
  • [26] 5O4FWCFP add tests to_record selection and improve it
  • [27] N256FH74 improve views
  • [28] 2SLTGWP6 add change files diffs to-record selection
  • [29] YGZ3VCW4 add push
  • [30] ODCT4QJN add pull
  • [31] UTDTZCTX pull+push status, add info reports
  • [32] TEDT26JQ add push and pull sub-menus
  • [33] C4V7DNBN only show overall toggle if there is more than one changed file
  • [34] TWULZ43V improve the changed files header
  • [35] 3CM5KELT improve headers when there are no untracked/changed file
  • [36] BJ3CYLUT allow to reset changed file
  • [37] YRGDFHAB project dir picker
  • [38] LPSUBGUB add projects picker
  • [39] IMJQ4PML fix and refactor action bindings
  • [40] TMDH7GPV dir picker scrollables handling + confirmation
  • [41] IOXNOVX2 allow to initiate a new repo
  • [42] XQDYES5M add support for git import
  • [43] MWQ7NABX suppress error when temp file is deleted
  • [44] 6E6MSENZ allow to add untracked files recursively
  • [45] E7HE2UFT handle multiple or no pijul identity
  • [46] 3XRG4BB6 rewritten nav-scrollable!
  • [47] NZD56PVB fix mouse selection
  • [48] AZ5D2LQU allow to set record description
  • [49] 5ZRDYL6K fork channel, fix recording esc key
  • [50] 3BK22XE5 add a test for hover btn and more refactors
  • [51] BGOQFXP7 update pijul
  • [52] ACDXXAX2 refactor main's updates into smaller fns
  • [53] RDRBP7AL auto-scroll status selection
  • [*] SWWE2R6M display basic repo stuff
  • [*] UF5NJKAS test load repo
  • [*] OPXFZKEB view tests setup
  • [*] WT3GA27P add cursor with selection
  • [*] 6YZAVBWU Initial commit

Change contents

  • edit in libflorescence/src/repo.rs at line 57
    [15.94]
    [15.94]
    pub remotes: Remotes,
  • edit in libflorescence/src/repo.rs at line 59
    [15.96]
    [15.96]
    #[derive(Clone, Debug, Default)]
    pub struct Remotes {
    pub default: Option<String>,
    pub other: Vec<String>,
    }
    /// Records that are only present locally xor remotely
    #[derive(Clone, Debug, Default)]
    pub struct RecordDichotomy {
    /// Added records only. Removed local records that are present on remote
    /// show as unpulled added records.
    pub local_records: Log,
    /// Remote records that haven't been pulled
    pub remote_records: Log,
    /// Remote unrecords
    pub remote_unrecords: Log,
    }
    impl RecordDichotomy {
    pub fn is_empty(&self) -> bool {
    let Self {
    local_records,
    remote_records,
    remote_unrecords,
    } = self;
    remote_records.is_empty()
    && remote_unrecords.is_empty()
    && local_records.is_empty()
    }
  • edit in libflorescence/src/repo.rs at line 90
    [15.97]
    [15.97]
    pub fn len(&self) -> usize {
    let Self {
    local_records,
    remote_records,
    remote_unrecords,
    } = self;
    remote_records.len() + remote_unrecords.len() + local_records.len()
    }
    pub fn get(&self, ix: usize) -> Option<&LogEntry> {
    let Self {
    local_records,
    remote_records,
    remote_unrecords,
    } = self;
    if ix < local_records.len() {
    return local_records.get(ix);
    }
    let ix = ix - local_records.len();
    if ix < remote_records.len() {
    return remote_records.get(ix);
    }
    let ix = ix - remote_records.len();
    remote_unrecords.get(ix)
    }
    }
  • edit in libflorescence/src/repo.rs at line 153
    [36.52]
    [31.86]
    },
    CompareRemote {
    remote: String,
    channel: String,
  • edit in libflorescence/src/repo.rs at line 198
    [29.226]
    [31.224]
    ComparedRemote {
    result: anyhow::Result<ComparedRemote>,
    remote: String,
    channel: String,
    },
    }
    #[derive(Debug)]
    pub struct ComparedRemote {
    pub record_dichotomy: RecordDichotomy,
    pub remote: String,
    pub channel: String,
  • edit in libflorescence/src/repo.rs at line 616
    [29.2032]
    [2.3040]
    MsgIn::CompareRemote { remote, channel } => {
    let result =
    compare_remote(&mut internal_state, &remote, &channel).await;
    let _ = msg_out_tx.send(MsgOut::ComparedRemote {
    result,
    remote,
    channel,
    });
    }
  • edit in libflorescence/src/repo.rs at line 662
    [43.516]
    [24.3112]
    let config = PijulConfig::load(Some(&repo.path), vec![])
    .context("getting Pijul config")?;
    let remotes = Remotes {
    default: config.default_remote,
    other: config
    .remotes
    .into_iter()
    .map(|conf| match conf {
    pijul_config::remote::RemoteConfig::Ssh { name, .. } => name,
    pijul_config::remote::RemoteConfig::Http { name, .. } => name,
    })
    .collect(),
    };
  • edit in libflorescence/src/repo.rs at line 683
    [15.2544]
    [24.3128]
    remotes,
  • replacement in libflorescence/src/repo.rs at line 1553
    [30.1240][30.1240:1266]()
    remote_unrecs: _,
    [30.1240]
    [30.1266]
    remote_unrecs,
  • edit in libflorescence/src/repo.rs at line 1766
    [36.1765]
    [36.1765]
    }
    #[allow(
    clippy::await_holding_lock,
    reason = "imposed by sanakirja API for txn"
    )]
    async fn compare_remote(
    internal_state: &mut InternalState,
    remote_name: &str,
    channel_name: &str,
    ) -> anyhow::Result<ComparedRemote> {
    let txn = internal_state
    .repo
    .pristine
    .arc_txn_begin()
    .context("Begin txn")?;
    let mut channel = txn
    .write()
    .open_or_create_channel(channel_name)
    .context("Loading current channel")?;
    let config = PijulConfig::load(Some(&internal_state.repo.path), vec![])?;
    let from_channel = libpijul::DEFAULT_CHANNEL;
    let no_cert_check = false;
    let mut remote = pijul_remote::repository(
    &config,
    Some(&internal_state.repo.path),
    None,
    remote_name,
    from_channel,
    no_cert_check,
    true,
    )
    .await?;
    let PushDelta {
    to_upload,
    remote_unrecs: _,
    unknown_changes: _,
    ..
    } = to_upload(
    &mut txn.write(),
    &mut channel,
    &internal_state.repo,
    &mut remote,
    )
    .await?;
    let RemoteDelta {
    inodes: _,
    remote_ref: _,
    to_download,
    remote_unrecs,
    ..
    } = to_download(
    &mut txn.write(),
    &mut channel,
    &mut internal_state.repo,
    &mut remote,
    )
    .await?;
    let remote_records = to_download
    .into_iter()
    .filter_map(|cs| match cs {
    pijul_remote::CS::Change(hash) => Some(hash),
    pijul_remote::CS::State(_) => None,
    })
    .map(|hash| mk_log_entry(&internal_state.repo, hash))
    .collect::<anyhow::Result<Log>>()?;
    let remote_unrecords = remote_unrecs
    .into_iter()
    .filter_map(|(_, cs)| match cs {
    pijul_remote::CS::Change(hash) => Some(hash),
    pijul_remote::CS::State(_) => None,
    })
    .map(|hash| mk_log_entry(&internal_state.repo, hash))
    .collect::<anyhow::Result<Log>>()?;
    let local_records = to_upload
    .into_iter()
    .filter_map(|cs| match cs {
    pijul_remote::CS::Change(hash) => Some(hash),
    pijul_remote::CS::State(_) => None,
    })
    .map(|hash| mk_log_entry(&internal_state.repo, hash))
    .collect::<anyhow::Result<Log>>()?;
    let record_dichotomy = RecordDichotomy {
    remote_records,
    remote_unrecords,
    local_records,
    };
    Ok(ComparedRemote {
    record_dichotomy,
    remote: remote_name.to_string(),
    channel: channel_name.to_string(),
    })
  • edit in libflorescence/src/repo/test.rs at line 68
    [16.27]
    [24.10146]
    remotes: _,
  • edit in inflorescence_view/src/view.rs at line 345
    [15.4551]
    [10.2870]
    remotes,
  • edit in inflorescence_view/src/view.rs at line 354
    [31.3497]
    [15.4655]
    record_dichotomy,
  • edit in inflorescence_view/src/view.rs at line 683
    [18.3416]
    [18.3416]
    selection::Unified::CompareRemote(Some(
    selection::CompareRemote { file, .. },
    )) => {
    if file.is_none() {
    1
    } else {
    2
    }
    }
  • replacement in inflorescence_view/src/view.rs at line 694
    [18.3509][18.3509:3565]()
    | selection::Unified::EntireLog(None) => 0,
    [18.3509]
    [6.1343]
    | selection::Unified::EntireLog(None)
    | selection::Unified::CompareRemote(None) => 0,
  • replacement in inflorescence_view/src/view.rs at line 721
    [34.451][34.451:501]()
    .padding(Padding::ZERO.top(SPACING * 2)))
    [34.451]
    [33.278]
    .padding(Padding::ZERO.top(SPACING)))
  • replacement in inflorescence_view/src/view.rs at line 732
    [35.339][35.339:390]()
    .padding(Padding::ZERO.top(SPACING * 2)))]
    [35.339]
    [27.321]
    .padding(Padding::ZERO.top(SPACING)))]
  • replacement in inflorescence_view/src/view.rs at line 737
    [27.647][27.647:761]()
    .chain([el(container(el(text("Recent changes:")))
    .padding(Padding::ZERO.top(SPACING * 2)))])
    [27.647]
    [27.761]
    .chain([el(container(el(text("Recent records:")))
    .padding(Padding::ZERO.top(SPACING)))])
  • edit in inflorescence_view/src/view.rs at line 753
    [15.11109]
    [15.11109]
    selection::Unified::CompareRemote(Some(
    selection::CompareRemote { file, .. },
    )) => file.is_none(),
  • replacement in inflorescence_view/src/view.rs at line 758
    [15.11206][15.11206:11263]()
    | selection::Unified::EntireLog(_) => false,
    [15.11206]
    [15.11263]
    | selection::Unified::EntireLog(_)
    | selection::Unified::CompareRemote(_) => false,
  • edit in inflorescence_view/src/view.rs at line 1337
    [18.15815]
    [28.2577]
    diff::view(
    state,
    nav,
    file,
    None,
    *diff_selected,
    false,
    to_record,
    )
    }
    None => el(text("Loading diff..")),
    },
    ])
    .spacing(SPACING)),
    // NOTE: This is currently never true - there are only up to 3
    // cols
    if hidden_cols == 2 {
    el(button(row([el(
    text("← Files").shaping(text::Shaping::Advanced)
    )]))
    .on_press(Msg::Action(
    action::FilteredMsg::Selection(
    selection::Msg::PressDir(selection::Dir::Left),
    ),
    )))
    } else {
    el(row([]))
    },
    ])
    .width(Length::Fill)
    .height(Length::Fill)
    .spacing(SPACING))
    }
    _ => el(column([])),
    };
    let compare_remote_nav_children = || {
    if let Some(record_dichotomy) =
    remotes.default.as_ref().and_then(|default_remote| {
    model::get_record_dichotomy(
    record_dichotomy,
    default_remote,
    channel,
    )
    })
    {
    let repo::RecordDichotomy {
    local_records,
    remote_records,
    remote_unrecords,
    } = record_dichotomy;
    let count = |records: &[_]| {
    records.len() + if records.is_empty() { 0 } else { 1 } // account for a header if non-empty
    };
    let row_count = count(local_records)
    + count(remote_records)
    + count(remote_unrecords);
    if row_count == 0 {
    vec![el(text("Local and remote are the same!"))]
    } else {
    let mut rows = Vec::with_capacity(row_count);
    let view = |rows: &mut Vec<_>, ix, entry: &repo::LogEntry| {
    let selection = match selection {
    selection::Unified::CompareRemote(Some(
    selection::CompareRemote {
    ix: Some(selected_ix),
    hash: _,
    file,
    remote: _,
    channel: _,
    },
    )) if &ix == selected_ix => {
    if file.is_some() {
    HierarchicalSelection::ChildSelected
    } else {
    HierarchicalSelection::Selected
    }
    }
    _ => HierarchicalSelection::NotSelected,
    };
    rows.push(el(button(el(text(display_short_hash(
    &entry.hash,
    ))))
    .on_press(Msg::UnfilteredSelection(
    selection::UnfilteredMsg::Select(
    selection::Select::CompareRemote { ix },
    ),
    ))
    .class(hierarchical_button_class(selection))));
    };
    if !local_records.is_empty() {
    rows.push(el(container(el(text("Local records:")))
    .padding(Padding::ZERO.top(SPACING))));
    }
    let ix_offset = 0;
    record_dichotomy.local_records.iter().enumerate().for_each(
    |(ix, entry)| view(&mut rows, ix + ix_offset, entry),
    );
    if !remote_records.is_empty() {
    rows.push(el(container(el(text("Remote records:")))
    .padding(Padding::ZERO.top(SPACING))));
    }
    let ix_offset = local_records.len();
    record_dichotomy.remote_records.iter().enumerate().for_each(
    |(ix, entry)| view(&mut rows, ix + ix_offset, entry),
    );
    if !remote_unrecords.is_empty() {
    rows.push(el(container(el(text("Remote unrecords:")))
    .padding(Padding::ZERO.top(SPACING))));
    }
    let ix_offset = ix_offset + remote_records.len();
    record_dichotomy
    .remote_unrecords
    .iter()
    .enumerate()
    .for_each(|(ix, entry)| {
    view(&mut rows, ix + ix_offset, entry)
    });
    rows
    }
    } else {
    vec![]
    }
    };
    // Compare remote records dichotomy
    let compare_remote_col_0 = || {
    el(column([el(nav_scrollable(
    &navigation.status_nav,
    compare_remote_nav_children(),
    )
    .class(if status_selected() {
    theme::Scrollable::Selected
    } else {
    theme::Scrollable::Normal
    })
    .width(Length::Fill)
    .height(Length::Fill))])
    .width(Length::Fill)
    .height(Length::Fill))
    };
    // Compare remote file selection in selected change
    let compare_remote_col_1 = || match selection {
    selection::Unified::CompareRemote(Some(selection::CompareRemote {
    ix: Some(ix),
    hash: _,
    file,
    remote: _,
    channel: _,
    })) => {
    let files_view = if let Some(record_dichotomy) =
    remotes.default.as_ref().and_then(|default_remote| {
    model::get_record_dichotomy(
    record_dichotomy,
    default_remote,
    channel,
    )
    }) {
    let nav = &navigation.compare_remote_navs.files_nav;
    let entry = record_dichotomy.get(*ix).unwrap();
    let files =
    entry.file_paths.iter().enumerate().map(|(ix, path)| {
    let selection = match file {
    Some(selection::LogChangeFileSelection {
    path: selected_path,
    diff_selected,
    ..
    }) if selected_path == path => {
    if *diff_selected {
    HierarchicalSelection::ChildSelected
    } else {
    HierarchicalSelection::Selected
    }
    }
    _ => HierarchicalSelection::NotSelected,
    };
    el(button(text(path))
    .on_press_with(move || {
    Msg::UnfilteredSelection(
    selection::UnfilteredMsg::Select(
    selection::Select::CompareRemoteFile {
    ix,
    path: path.clone(),
    },
    ),
    )
    })
    .class(hierarchical_button_class(selection)))
    });
    el(column([
    view_log_change_header(entry),
    el(nav_scrollable(nav, files)
    .class(if entire_log_change_selected() {
    theme::Scrollable::Selected
    } else {
    theme::Scrollable::Normal
    })
    .width(Length::Fill)
    .height(Length::Fill)),
    ]))
    } else {
    el(text("Loading..."))
    };
    el(column([
    files_view,
    if hidden_cols == 1 {
    el(button(row([el(
    text("← Records").shaping(text::Shaping::Advanced)
    )]))
    .on_press(Msg::Action(
    action::FilteredMsg::Selection(
    selection::Msg::PressDir(selection::Dir::Left),
    ),
    )))
    } else {
    el(row([]))
    },
    ])
    .width(Length::Fill)
    .height(Length::Fill)
    .spacing(SPACING))
    }
    _ => el(row([])),
    };
    // TODO more re-use with status_col_2
    // Compare remote log diff selection in selected change's file
    let compare_remote_col_2 = || match selection {
    selection::Unified::CompareRemote(Some(selection::CompareRemote {
    ix: _,
    hash: Some(hash),
    file:
    Some(selection::LogChangeFileSelection {
    ix: _,
    path,
    diff_selected,
    }),
    remote: _,
    channel: _,
    })) => {
    let file_id = file::log_id_parts_hash(*hash, path);
    let state = navigation.log_diffs.diffs.get(&file_id);
    el(column([
    el(column([
    view_header(format!(
    "{path} changes in {}:",
    display_short_hash(hash)
    )),
    match state {
    Some(diff::FileAndState { file, state }) => {
    let nav = &navigation.compare_remote_navs.diffs_nav;
  • edit in inflorescence_view/src/view.rs at line 1680
    [15.20013]
    [12.1959]
    selection::Unified::CompareRemote(_) => {
    let cols = [
    compare_remote_col_0(),
    compare_remote_col_1(),
    compare_remote_col_2(),
    ]
    .into_iter()
    .skip(hidden_cols);
    el(row(cols)
    .spacing(SPACING)
    .width(Length::Fill)
    .height(Length::Fill))
    }
  • edit in inflorescence_view/src/view.rs at line 1855
    [31.4692]
    [31.4692]
    Job::CompareRemote { remote, channel } => el(text(format!(
    "Fetching from remote {remote}, channel {channel}",
    ))),
  • edit in inflorescence_view/src/view/test.rs at line 83
    [16.936]
    [16.936]
    remotes: default(),
  • edit in inflorescence_view/src/view/test.rs at line 95
    [31.4726]
    [9.2372]
    record_dichotomy: default(),
  • edit in inflorescence_view/src/view/test.rs at line 142
    [4.1560]
    [9.2651]
    remotes: default(),
  • edit in inflorescence_view/src/view/test.rs at line 154
    [31.4752]
    [16.1666]
    record_dichotomy: default(),
  • edit in inflorescence_view/src/view/test.rs at line 206
    [31.4778]
    [16.2477]
    record_dichotomy: default(),
  • edit in inflorescence_view/src/view/test.rs at line 237
    [23.3308]
    [23.3308]
    remotes: default(),
  • edit in inflorescence_view/src/view/test.rs at line 249
    [31.4849]
    [23.3567]
    record_dichotomy: default(),
  • edit in inflorescence_view/src/view/test.rs at line 310
    [32.531227]
    [32.531227]
    remotes: default(),
  • edit in inflorescence_view/src/view/test.rs at line 322
    [32.531541]
    [32.531541]
    record_dichotomy: default(),
  • edit in inflorescence_model/src/selection.rs at line 44
    [14.542]
    [15.30088]
    /// Sub-selection in [`Primary::CompareRemote`] state
    pub compare_remote: Option<CompareRemote>,
  • edit in inflorescence_model/src/selection.rs at line 55
    [15.30333]
    [15.30333]
    CompareRemote(Option<&'a CompareRemote>),
  • edit in inflorescence_model/src/selection.rs at line 64
    [15.30449]
    [8.359]
    CompareRemote,
  • edit in inflorescence_model/src/selection.rs at line 117
    [19.322]
    [5.4435]
    },
    CompareRemote {
    ix: usize,
    },
    CompareRemoteFile {
    ix: usize,
    path: String,
  • edit in inflorescence_model/src/selection.rs at line 139
    [14.705]
    [14.705]
    pub file: Option<LogChangeFileSelection>,
    }
    #[derive(Debug)]
    pub struct CompareRemote {
    pub ix: Option<usize>,
    pub hash: Option<repo::ChangeHash>,
  • edit in inflorescence_model/src/selection.rs at line 147
    [14.751]
    [15.30483]
    pub remote: String,
    pub channel: String,
  • edit in inflorescence_model/src/selection.rs at line 157
    [15.30617]
    [15.30617]
    compare_remote,
  • edit in inflorescence_model/src/selection.rs at line 164
    [15.30869]
    [15.30869]
    Primary::CompareRemote => {
    Unified::CompareRemote(compare_remote.as_ref())
    }
  • replacement in inflorescence_model/src/model.rs at line 87
    [36.1829][41.1086:1118](),[41.1118][42.30476:30513](),[42.30513][44.1328:1357]()
    InitRepo { path: PathBuf },
    ImportFromGit { path: PathBuf },
    Add { recursive: bool },
    [36.1829]
    [32.531968]
    InitRepo {
    path: PathBuf,
    },
    ImportFromGit {
    path: PathBuf,
    },
    Add {
    recursive: bool,
    },
    CompareRemote {
    remote: Option<String>,
    channel: Option<String>,
    },
  • edit in inflorescence_model/src/model.rs at line 138
    [31.5181]
    [21.5171]
    // Outer key is remote name, inner key is channel name
    pub record_dichotomy:
    HashMap<String, HashMap<String, repo::RecordDichotomy>>,
    }
    pub fn get_record_dichotomy<'a>(
    record_dichotomy: &'a HashMap<
    String,
    HashMap<String, repo::RecordDichotomy>,
    >,
    remote: &str,
    channel: &str,
    ) -> Option<&'a repo::RecordDichotomy> {
    record_dichotomy
    .get(remote)
    .and_then(|map| map.get(channel))
  • edit in inflorescence_model/src/model.rs at line 156
    [21.5174]
    [21.5174]
    pub fn get_record_dichotomy_mut<'a>(
    record_dichotomy: &'a mut HashMap<
    String,
    HashMap<String, repo::RecordDichotomy>,
    >,
    remote: &str,
    channel: &str,
    ) -> Option<&'a mut repo::RecordDichotomy> {
    record_dichotomy
    .get_mut(remote)
    .and_then(|map| map.get_mut(channel))
    }
  • edit in inflorescence_model/src/model.rs at line 201
    [21.6141]
    [21.6141]
    /// Nav for comparing remote with local
    pub compare_remote_nav: nav_scrollable::State,
    /// Navs for logs comparing remote with local
    pub compare_remote_navs: log::Navs,
  • replacement in inflorescence_model/src/model.rs at line 207
    [21.6247][21.6247:6336]()
    /// Diffs of status log changes, entire log changes and other channels'
    /// logs
    [21.6247]
    [21.6336]
    /// Diffs of status log changes, entire log changes, other channels' logs
    /// and changes from comparing remote
  • edit in inflorescence_model/src/model.rs at line 231
    [31.5318]
    [21.6686]
    CompareRemote { remote: String, channel: String },
  • edit in inflorescence_model/src/action.rs at line 248
    [44.1706]
    [32.532531]
    model::SubMenu::CompareRemote {
    remote: _,
    channel: _,
    } => {
    // TODO select remote name
    // TODO select local and remote channel
    vec![
    Binding {
    keys_str: "Enter | S-c",
    keys: ModKeys::Two(
    ModKey {
    key: Key::Named(Named::Enter),
    mods: Mods::NONE,
    },
    ModKey {
    key: Key::Character("c".into()),
    mods: Mods::SHIFT,
    },
    ),
    label: "compare default remote",
    msg: Some(FilteredMsg::Confirm),
    },
    cancel(),
    ]
    }
  • edit in inflorescence_model/src/action.rs at line 506
    [17.5974]
    [17.5974]
    has_default_remote,
  • edit in inflorescence_model/src/action.rs at line 764
    [40.1307]
    [39.1019]
    }
    };
    let compare_remote = || -> Binding {
    Binding {
    keys_str: "S-c",
    keys: ModKeys::One(ModKey {
    key: Key::Character("c".into()),
    mods: Mods::SHIFT,
    }),
    label: "compare remote",
    msg: Some(FilteredMsg::EnterSubMenu(
    model::SubMenu::CompareRemote {
    remote: None,
    channel: None,
    },
    )),
  • edit in inflorescence_model/src/action.rs at line 826
    [40.1418]
    [17.10048]
    push_if(has_default_remote, compare_remote, ma);
  • edit in inflorescence_model/src/action.rs at line 842
    [39.1807]
    [17.10450]
    push_if(has_default_remote, compare_remote, ma);
  • edit in inflorescence_model/src/action.rs at line 881
    [26.16877]
    [17.10821]
    push_if(has_default_remote, compare_remote, ma);
  • edit in inflorescence_model/src/action.rs at line 889
    [39.2235]
    [17.10979]
    push_if(has_default_remote, compare_remote, ma);
  • edit in inflorescence_model/src/action.rs at line 993
    [17.13064]
    [17.13064]
    SubState::CompareRemote {
    can_select_right,
    has_any_diff,
    } => {
    push_if(has_any_diff, down, ma);
    push_if(has_any_diff, up, ma);
    push_if(has_any_diff && can_select_right, right, ma);
    push_if(has_any_diff, clipboard_copy_change_hash, ma);
    push(cancel, ma);
    }
    SubState::CompareRemoteChange { can_select_right } => {
    push(left, ma);
    push(down, ma);
    push(up, ma);
    push_if(can_select_right, right, ma);
    push(clipboard_copy_change_hash, ma);
    push(cancel, ma);
    }
    SubState::CompareRemoteChangeDiff => {
    push(left, ma);
    push(down, ma);
    push(up, ma);
    push(clipboard_copy_change_hash, ma);
    push(cancel, ma);
    }
  • edit in inflorescence_model/src/action.rs at line 1057
    [17.13405]
    [17.13405]
    has_default_remote: bool,
  • edit in inflorescence_model/src/action.rs at line 1113
    [17.14302]
    [17.14302]
    /// Comparing records in local vs. remote
    CompareRemote {
    can_select_right: bool,
    has_any_diff: bool,
    },
    /// Viewing a change in comparing records in local vs. remote
    CompareRemoteChange {
    can_select_right: bool,
    },
    /// Viewing a file diff of a change in comparing records in local vs.
    /// remote
    CompareRemoteChangeDiff,
  • edit in inflorescence_model/src/action.rs at line 1148
    [17.14709]
    [17.14709]
    let has_default_remote = state.repo.remotes.default.is_some();
  • edit in inflorescence_model/src/action.rs at line 1152
    [17.14788]
    [17.14788]
    has_default_remote,
  • edit in inflorescence_model/src/action.rs at line 1169
    [17.15165]
    [17.15165]
    remotes,
  • edit in inflorescence_model/src/action.rs at line 1178
    [31.6238]
    [17.15286]
    record_dichotomy,
  • edit in inflorescence_model/src/action.rs at line 1185
    [17.15457]
    [17.15457]
    compare_remote: compare_remote_selection,
  • edit in inflorescence_model/src/action.rs at line 1206
    [31.6411]
    [31.6411]
    model::Job::CompareRemote { .. } => true,
  • edit in inflorescence_model/src/action.rs at line 1443
    [17.23194]
    [17.23194]
    selection::Primary::CompareRemote => {
    let has_any_diff = remotes
    .default
    .as_ref()
    .and_then(|default_remote| {
    model::get_record_dichotomy(
    record_dichotomy,
    default_remote,
    channel,
    )
    })
    .map(|d| !d.is_empty())
    .unwrap_or(false);
    if let Some(selection::CompareRemote { file, .. }) =
    compare_remote_selection
    {
    match file {
    Some(selection::LogChangeFileSelection {
    diff_selected,
    ..
    }) => {
    if *diff_selected {
    SubState::CompareRemoteChangeDiff
    } else {
    let diffs_nav =
    &navigation.compare_remote_navs.diffs_nav;
    let can_select_right =
    nav_scrollable::needs_scrolling(diffs_nav);
    SubState::CompareRemoteChange { can_select_right }
    }
    }
    None => {
    let files_nav =
    &navigation.compare_remote_navs.files_nav;
    let can_select_right =
    nav_scrollable::has_sections(files_nav);
    SubState::CompareRemote {
    can_select_right,
    has_any_diff,
    }
    }
    }
    } else {
    SubState::CompareRemote {
    has_any_diff,
    can_select_right: false,
    }
    }
    }
  • replacement in inflorescence/src/selection.rs at line 3
    [15.39344][15.39344:39418](),[15.39418][21.10925:10985]()
    unify, Channel, Dir, HeldKey, LogChange, LogChangeFileSelection, Msg,
    Primary, Select, State, Status, UnfilteredMsg, Unified,
    [15.39344]
    [3.29306]
    unify, Channel, CompareRemote, Dir, HeldKey, LogChange,
    LogChangeFileSelection, Msg, Primary, Select, State, Status, UnfilteredMsg,
    Unified,
  • edit in inflorescence/src/selection.rs at line 26
    [15.39969]
    [11.992]
    pub record_dichotomy: Option<&'a repo::RecordDichotomy>,
  • edit in inflorescence/src/selection.rs at line 36
    [15.40044]
    [37.3601141]
    record_dichotomy: Option<&repo::RecordDichotomy>,
  • edit in inflorescence/src/selection.rs at line 44
    [15.40147]
    [15.40147]
    record_dichotomy,
  • edit in inflorescence/src/selection.rs at line 123
    [21.11261]
    [37.3601178]
    record_dichotomy: Option<&repo::RecordDichotomy>,
  • edit in inflorescence/src/selection.rs at line 131
    [21.11387]
    [21.11387]
    record_dichotomy,
  • edit in inflorescence/src/selection.rs at line 149
    [15.41116]
    [13.13770]
    Primary::CompareRemote => select_down_compare_remote(ctx, delta),
  • edit in inflorescence/src/selection.rs at line 551
    [15.46280]
    [14.26575]
    fn select_down_compare_remote(
    ctx: &mut Ctx<'_>,
    delta: Option<Duration>,
    ) -> Task<crate::ManagingRepoMsg> {
    if let Some(record_dichotomy) = ctx.record_dichotomy {
    let len = record_dichotomy.len();
    if len > 0
    && let Some(CompareRemote {
    ix,
    hash,
    file,
    remote,
    channel,
    }) = ctx.state.compare_remote.take()
    {
    let (selection, task) = if let (Some(change_ix), Some(hash)) =
    (ix, hash)
    {
    if let Some(LogChangeFileSelection {
    ix: file_ix,
    path,
    diff_selected,
    }) = file
    {
    if diff_selected {
    let selection = CompareRemote {
    ix: Some(change_ix),
    hash: Some(hash),
    file: Some(LogChangeFileSelection {
    ix: file_ix,
    path,
    diff_selected,
    }),
    remote,
    channel,
    };
  • edit in inflorescence/src/selection.rs at line 589
    [14.26576]
    [37.3601431]
    nav_scrollable::scroll_down(
    &mut ctx.navigation.compare_remote_navs.diffs_nav,
    delta,
    );
    (selection, Task::none())
    } else {
    let log_entry =
    record_dichotomy.get(change_ix).unwrap();
    let file_ix =
    if log_entry.file_paths.len().saturating_sub(1)
    == file_ix
    {
    0
    } else {
    file_ix + 1
    };
    let (file, selection_task) =
    compare_remote_file_selection(
    file_ix,
    hash,
    VDir::Down,
    ctx.navigation,
    log_entry,
    );
    let selection = CompareRemote {
    ix: Some(change_ix),
    hash: Some(hash),
    file: Some(file),
    remote,
    channel,
    };
    (selection, selection_task)
    }
    } else {
    if change_ix + 1 == len {
    let ix = 0;
    compare_remote_selection(
    ix,
    VDir::Up,
    ctx,
    record_dichotomy,
    remote,
    channel,
    )
    } else {
    let ix = change_ix + 1;
    compare_remote_selection(
    ix,
    VDir::Down,
    ctx,
    record_dichotomy,
    remote,
    channel,
    )
    }
    }
    } else {
    let ix = 0;
    compare_remote_selection(
    ix,
    VDir::Down,
    ctx,
    record_dichotomy,
    remote,
    channel,
    )
    };
    ctx.state.compare_remote = Some(selection);
    return task;
    }
    }
    Task::none()
    }
  • edit in inflorescence/src/selection.rs at line 676
    [15.46563]
    [15.46563]
    Primary::CompareRemote => select_up_compare_remote(ctx, delta),
  • edit in inflorescence/src/selection.rs at line 1069
    [15.54205]
    [15.54205]
    fn select_up_compare_remote(
    ctx: &mut Ctx<'_>,
    delta: Option<Duration>,
    ) -> Task<crate::ManagingRepoMsg> {
    if let Some(record_dichotomy) = ctx.record_dichotomy {
    let len = record_dichotomy.len();
    if len > 0
    && let Some(CompareRemote {
    ix,
    hash,
    file,
    remote,
    channel,
    }) = ctx.state.compare_remote.take()
    {
    let (selection, task) = if let (Some(change_ix), Some(hash)) =
    (ix, hash)
    {
    if let Some(LogChangeFileSelection {
    ix: file_ix,
    path,
    diff_selected,
    }) = file
    {
    if diff_selected {
    let selection = CompareRemote {
    ix: Some(change_ix),
    hash: Some(hash),
    file: Some(LogChangeFileSelection {
    ix: file_ix,
    path,
    diff_selected,
    }),
    remote,
    channel,
    };
    nav_scrollable::scroll_up(
    &mut ctx.navigation.compare_remote_navs.diffs_nav,
    delta,
    );
    (selection, Task::none())
    } else {
    let log_entry =
    record_dichotomy.get(change_ix).unwrap();
    let file_ix = if 0 == file_ix {
    log_entry.file_paths.len().saturating_sub(1)
    } else {
    file_ix - 1
    };
    let (file, selection_task) =
    compare_remote_file_selection(
    file_ix,
    hash,
    VDir::Up,
    ctx.navigation,
    log_entry,
    );
    let selection = CompareRemote {
    ix: Some(change_ix),
    hash: Some(hash),
    file: Some(file),
    remote,
    channel,
    };
    (selection, selection_task)
    }
    } else {
    if change_ix == 0 {
    let ix = len.saturating_sub(1);
    compare_remote_selection(
    ix,
    VDir::Up,
    ctx,
    record_dichotomy,
    remote,
    channel,
    )
    } else {
    let ix = change_ix - 1;
    compare_remote_selection(
    ix,
    VDir::Up,
    ctx,
    record_dichotomy,
    remote,
    channel,
    )
    }
    }
    } else {
    let ix = len.saturating_sub(1);
    compare_remote_selection(
    ix,
    VDir::Down,
    ctx,
    record_dichotomy,
    remote,
    channel,
    )
    };
    ctx.state.compare_remote = Some(selection);
    return task;
    }
    }
    Task::none()
    }
  • edit in inflorescence/src/selection.rs at line 1461
    [15.59712]
    [14.34132]
    Primary::CompareRemote => {
    let (selection, task) = match ctx.state.compare_remote.take() {
    Some(CompareRemote {
    ix,
    hash,
    file:
    Some(LogChangeFileSelection {
    ix: file_ix,
    path,
    diff_selected,
    }),
    remote,
    channel,
    }) => {
    if diff_selected {
    (
    Some(CompareRemote {
    ix,
    hash,
    file: Some(LogChangeFileSelection {
    ix: file_ix,
    path,
    diff_selected: false,
    }),
    remote,
    channel,
    }),
    Task::none(),
    )
    } else {
    let selection = CompareRemote {
    ix,
    hash,
    file: None,
    remote,
    channel,
    };
    (Some(selection), Task::none())
    }
    }
    selection @ (Some(CompareRemote { file: None, .. }) | None) => {
    (selection, Task::none())
    }
    };
    ctx.state.compare_remote = selection;
    task
    }
  • edit in inflorescence/src/selection.rs at line 1516
    [18.42335]
    [18.42335]
    Primary::CompareRemote => select_right_compare_remote(ctx),
  • edit in inflorescence/src/selection.rs at line 1869
    [18.53241]
    [15.68894]
    }
    Task::none()
    }
    fn select_right_compare_remote(
    ctx: &mut Ctx<'_>,
    ) -> Task<crate::ManagingRepoMsg> {
    if let Some(record_dichotomy) = ctx.record_dichotomy {
    let len = record_dichotomy.len();
    if len > 0
    && let Some(CompareRemote {
    ix: Some(change_ix),
    hash: Some(hash),
    file,
    remote,
    channel,
    }) = ctx.state.compare_remote.take()
    {
    let (selection, task) = match file {
    None => {
    let log_entry = record_dichotomy.get(change_ix).unwrap();
    let (file, task) =
    if let Some(path) = log_entry.file_paths.first() {
    let file_id =
    file::log_id_parts_hash(log_entry.hash, path);
    // If the log is not loaded yet, the nav will be
    // initialized once it's
    // loaded (`repo::MsgOut::GotChangeDiffs`)
    if let Some(log) =
    ctx.navigation.log_diffs.diffs.get(&file_id)
    {
    let unchanged_sections =
    diff::unchanged_sections(&log.file);
    log::init_diffs_nav(
    &mut ctx.navigation.compare_remote_navs,
    file_id,
    )
    .set_skip_sections(unchanged_sections);
    };
    (
    Some(LogChangeFileSelection {
    ix: 0,
    path: path.clone(),
    diff_selected: false,
    }),
    Task::none(),
    )
    } else {
    (None, Task::none())
    };
    (
    Some(CompareRemote {
    ix: Some(change_ix),
    hash: Some(hash),
    file,
    remote,
    channel,
    }),
    task,
    )
    }
    Some(LogChangeFileSelection {
    ix: file_ix,
    path,
    diff_selected: false,
    }) => {
    let is_diff_scrollable = log::diff_needs_scrolling(
    &ctx.navigation.compare_remote_navs,
    );
    (
    Some(CompareRemote {
    ix: Some(change_ix),
    hash: Some(hash),
    file: Some(LogChangeFileSelection {
    ix: file_ix,
    path,
    diff_selected: is_diff_scrollable,
    }),
    remote,
    channel,
    }),
    Task::none(),
    )
    }
    file => (
    Some(CompareRemote {
    ix: Some(change_ix),
    hash: Some(hash),
    file,
    remote,
    channel,
    }),
    Task::none(),
    ),
    };
    ctx.state.compare_remote = selection;
    return task;
    }
  • edit in inflorescence/src/selection.rs at line 1979
    [15.69076]
    [15.69076]
    record_dichotomy: _,
  • replacement in inflorescence/src/selection.rs at line 2099
    [15.72796][19.5153:5211]()
    Select::Channel { .. } => unreachable!(),
    [15.72796]
    [7.46480]
    Select::Channel { .. }
    | Select::CompareRemote { .. }
    | Select::CompareRemoteFile { .. } => {
    unreachable!()
    }
  • replacement in inflorescence/src/selection.rs at line 2208
    [20.2306][19.9598:9677](),[19.9598][19.9598:9677]()
    Select::UntrackedFile { .. } | Select::ChangedFile { .. } => {
    [20.2306]
    [19.9677]
    Select::UntrackedFile { .. }
    | Select::ChangedFile { .. }
    | Select::CompareRemote { .. }
    | Select::CompareRemoteFile { .. } => {
  • replacement in inflorescence/src/selection.rs at line 2243
    [15.73963][15.73963:74022]()
    status_log_file_selection(
    [15.73963]
    [15.74022]
    entire_log_file_selection(
  • replacement in inflorescence/src/selection.rs at line 2263
    [19.9912][19.9912:9976]()
    | Select::Channel { .. } => unreachable!(),
    [19.9912]
    [15.74815]
    | Select::Channel { .. }
    | Select::CompareRemote { .. }
    | Select::CompareRemoteFile { .. } => unreachable!(),
  • edit in inflorescence/src/selection.rs at line 2268
    [15.74884]
    [15.74884]
    return task;
    }
    }
    Primary::CompareRemote => {
    if let Some((
    record_dichotomy,
    CompareRemote {
    ix: record_ix,
    hash,
    file: _,
    remote,
    channel,
    },
    )) = ctx.record_dichotomy.zip(ctx.state.compare_remote.take())
    {
    let (selection, task) = match select {
    Select::CompareRemote { ix } => {
    let (selection, task) = compare_remote_selection(
    ix,
    VDir::Down,
    ctx,
    record_dichotomy,
    remote,
    channel,
    );
    (Some(selection), task)
    }
    Select::CompareRemoteFile {
    ix: file_ix,
    path: _,
    } => {
    let record_ix = record_ix.unwrap();
    let entry = record_dichotomy.get(record_ix).unwrap();
    let (file, task) = compare_remote_file_selection(
    file_ix,
    hash.unwrap(),
    VDir::Down,
    ctx.navigation,
    entry,
    );
    let selection = Some(CompareRemote {
    ix: Some(record_ix),
    hash,
    file: Some(file),
    remote,
    channel,
    });
    (selection, task)
    }
    Select::UntrackedFile { .. }
    | Select::ChangedFile { .. }
    | Select::LogChange { .. }
    | Select::LogChangeFile { .. }
    | Select::Channel { .. } => unreachable!(),
    };
    ctx.state.compare_remote = selection;
  • edit in inflorescence/src/selection.rs at line 2328
    [15.74930][15.74930:74931]()
  • edit in inflorescence/src/selection.rs at line 2369
    [15.75103]
    [15.75103]
    record_dichotomy: _,
  • edit in inflorescence/src/selection.rs at line 2427
    [15.75526]
    [15.75526]
    record_dichotomy: _,
  • edit in inflorescence/src/selection.rs at line 2492
    [18.54675]
    [18.54675]
    record_dichotomy: _,
  • edit in inflorescence/src/selection.rs at line 2573
    [15.76078]
    [15.76078]
    record_dichotomy: _,
  • edit in inflorescence/src/selection.rs at line 2622
    [15.76923]
    [15.76923]
    record_dichotomy: _,
  • edit in inflorescence/src/selection.rs at line 2704
    [15.77535]
    [15.77535]
    record_dichotomy: _,
  • edit in inflorescence/src/selection.rs at line 2759
    [18.58230]
    [18.58230]
    match dir {
    VDir::Up => nav_scrollable::scroll_up_to_section(nav, ix),
    VDir::Down => nav_scrollable::scroll_down_to_section(nav, ix),
    }
    (
    LogChangeFileSelection {
    ix,
    path,
    diff_selected: false,
    },
    Task::none(),
    )
    }
    fn compare_remote_selection(
    ix: usize,
    dir: VDir,
    ctx: &mut Ctx<'_>,
    record_dichotomy: &repo::RecordDichotomy,
    remote: String,
    channel: String,
    ) -> (CompareRemote, Task<crate::ManagingRepoMsg>) {
    let Ctx {
    state: _,
    files: _,
    navigation,
    repo: _,
    logs: _,
    record_dichotomy: _,
    } = ctx;
    let entry = record_dichotomy.get(ix).unwrap();
    let hash = entry.hash;
    let task = if !navigation
    .log_diffs
    .changes_with_loaded_diffs
    .contains(&hash)
    {
    Task::done(crate::ManagingRepoMsg::ToRepo(
    repo::MsgIn::GetChangeDiffs { hash },
    ))
    } else {
    Task::none()
    };
    log::init_files_nav(&mut navigation.compare_remote_navs, hash);
  • edit in inflorescence/src/selection.rs at line 2808
    [18.58246]
    [18.58246]
    VDir::Up => nav_scrollable::scroll_up_to_section(
    &mut navigation.compare_remote_nav,
    ix,
    ),
    VDir::Down => nav_scrollable::scroll_down_to_section(
    &mut navigation.compare_remote_nav,
    ix,
    ),
    }
    let selection = CompareRemote {
    ix: Some(ix),
    hash: Some(hash),
    file: None,
    remote,
    channel,
    };
    (selection, task)
    }
    fn compare_remote_file_selection(
    ix: usize,
    hash: repo::ChangeHash,
    dir: VDir,
    navigation: &mut Navigation,
    log_entry: &repo::LogEntry,
    ) -> (LogChangeFileSelection, Task<crate::ManagingRepoMsg>) {
    let path = log_entry.file_paths.get(ix).unwrap().clone();
    log::init_diffs_nav(
    &mut navigation.compare_remote_navs,
    file::log_id_parts_hash(hash, &path),
    );
    let nav = &mut navigation.compare_remote_navs.files_nav;
    match dir {
  • edit in inflorescence/src/main.rs at line 618
    [45.5702]
    [45.5702]
    record_dichotomy: default(),
  • edit in inflorescence/src/main.rs at line 649
    [45.7335]
    [45.7335]
    record_dichotomy: default(),
  • replacement in inflorescence/src/main.rs at line 959
    [44.3105][44.3105:3159]()
    | model::SubMenu::Add { .. },
    [44.3105]
    [42.34282]
    | model::SubMenu::Add { .. }
    | model::SubMenu::CompareRemote { .. },
  • edit in inflorescence/src/main.rs at line 1073
    [21.12265]
    [21.12265]
    record_dichotomy,
  • edit in inflorescence/src/main.rs at line 1077
    [21.12351]
    [21.12351]
    let record_dichotomy =
    selection.compare_remote.as_ref().and_then(
    |selection::CompareRemote {
    ix: _,
    hash: _,
    file: _,
    remote,
    channel,
    }| {
    model::get_record_dichotomy(
    record_dichotomy,
    remote,
    channel,
    )
    },
    );
  • edit in inflorescence/src/main.rs at line 1101
    [21.12575]
    [21.12575]
    record_dichotomy,
  • edit in inflorescence/src/main.rs at line 1138
    [45.9790]
    [45.9790]
    record_dichotomy: default(),
  • edit in inflorescence/src/main.rs at line 1170
    [44.3397]
    [44.3397]
    }
    Some(model::SubMenu::CompareRemote { remote, channel }) => {
    if let Some(ReadyState {
    repo,
    selection,
    jobs,
    ..
    }) = model::is_ready_mut(model)
    {
    let remote = remote
    .as_ref()
    .or(repo.remotes.default.as_ref())
    .cloned();
    if let Some(remote) = remote {
    let channel = channel
    .clone()
    .unwrap_or_else(|| repo.channel.clone());
    jobs.insert(model::Job::CompareRemote {
    remote: remote.clone(),
    channel: channel.clone(),
    });
    selection.primary = selection::Primary::CompareRemote;
    selection.compare_remote =
    Some(selection::CompareRemote {
    ix: None,
    hash: None,
    file: None,
    remote: remote.clone(),
    channel: channel.clone(),
    });
    state
    .repo_tx_in
    .send(repo::MsgIn::CompareRemote {
    remote,
    channel,
    })
    .unwrap();
    } else {
    report::show_err(
    report,
    "No default remote configured".to_string(),
    );
    }
    *sub_menu = None;
    }
    Task::none()
  • edit in inflorescence/src/main.rs at line 1287
    [45.10975]
    [45.10975]
    record_dichotomy: default(),
  • replacement in inflorescence/src/main.rs at line 1323
    [15.84598][15.84598:84655]()
    | selection::Primary::EntireLog => {
    [15.84598]
    [15.84655]
    | selection::Primary::EntireLog
    | selection::Primary::CompareRemote => {
  • edit in inflorescence/src/main.rs at line 1337
    [15.84927]
    [15.84927]
    record_dichotomy,
  • edit in inflorescence/src/main.rs at line 1341
    [15.85010]
    [18.60454]
    let record_dichotomy =
    selection.compare_remote.as_ref().and_then(
    |selection::CompareRemote {
    ix: _,
    hash: _,
    file: _,
    remote,
    channel,
    }| {
    model::get_record_dichotomy(
    record_dichotomy,
    remote,
    channel,
    )
    },
    );
  • edit in inflorescence/src/main.rs at line 1365
    [15.85230]
    [18.60490]
    record_dichotomy,
  • edit in inflorescence/src/main.rs at line 1527
    [25.18195][45.12603:12604]()
  • replacement in inflorescence/src/main.rs at line 1534
    [18.60867][18.60867:60935]()
    // Check that selection coreesponds to the navigation state
    [18.60867]
    [18.60935]
    // Check that selection corresponds to the navigation state
  • edit in inflorescence/src/main.rs at line 1546
    [18.61221]
    [18.61221]
    compare_remote,
  • edit in inflorescence/src/main.rs at line 1636
    [18.64615]
    [18.64615]
    Some(*hash)
    );
    }
    }
    if let Some(selection::CompareRemote {
    ix: _,
    hash: Some(hash),
    file,
    remote: _,
    channel: _,
    }) = compare_remote
    {
    assert_eq!(
    navigation.compare_remote_navs.change_hash,
    Some(*hash)
    );
    if let Some(selection::LogChangeFileSelection {
    path, ..
    }) = file
    {
    assert_eq!(
    navigation.compare_remote_navs.change_hash,
    Some(*hash)
    );
    let file_id = file::log_id_parts_hash(*hash, path);
    if navigation.log_diffs.diffs.contains_key(&file_id) {
    assert_eq!(
    navigation.compare_remote_navs.file_id,
    Some(file_id)
    );
    }
    } else {
    assert_eq!(
    navigation.compare_remote_navs.change_hash,
  • edit in inflorescence/src/main.rs at line 1786
    [22.3001]
    [22.3001]
    selection::Unified::CompareRemote(Some(
    selection::CompareRemote {
    hash: Some(hash), ..
    },
    )) => Some(repo::hash_to_string(hash)),
  • replacement in inflorescence/src/main.rs at line 1793
    [22.3088][22.3088:3144]()
    | selection::Unified::EntireLog(_) => None,
    [22.3088]
    [22.3144]
    | selection::Unified::EntireLog(_)
    | selection::Unified::CompareRemote(_) => None,
  • edit in inflorescence/src/main.rs at line 1899
    [38.25382]
    [38.25382]
    if let Some(ReadyState {
    repo,
    record_dichotomy,
    ..
    }) = model::is_ready_mut(model)
    && let Some(record_dichotomy) =
    repo.remotes.default.as_ref().and_then(
    |default_remote| {
    model::get_record_dichotomy_mut(
    record_dichotomy,
    default_remote,
    &channel,
    )
    },
    )
    {
    let repo::RecordDichotomy {
    local_records,
    remote_records,
    remote_unrecords,
    } = record_dichotomy;
    // Remove remote unrecords that were re-pushed
    remote_unrecords.retain(|entry| {
    local_records
    .iter()
    .all(|local| local.hash != entry.hash)
    });
    // Move local records into remote records
    remote_records.extend(mem::take(local_records));
    }
  • edit in inflorescence/src/main.rs at line 1950
    [38.26007]
    [38.26007]
    if let Some(ReadyState {
    repo,
    record_dichotomy,
    ..
    }) = model::is_ready_mut(model)
    && let Some(record_dichotomy) =
    repo.remotes.default.as_ref().and_then(
    |default_remote| {
    model::get_record_dichotomy_mut(
    record_dichotomy,
    default_remote,
    &channel,
    )
    },
    )
    {
    let repo::RecordDichotomy {
    local_records: _,
    remote_records,
    remote_unrecords: _,
    } = record_dichotomy;
    // Remove remote records as they were pulled
    *remote_records = default();
    }
  • edit in inflorescence/src/main.rs at line 1992
    [38.26527]
    [38.26527]
    repo::MsgOut::ComparedRemote {
    result,
    channel,
    remote,
    } => {
    match result {
    Ok(repo::ComparedRemote {
    record_dichotomy: d,
    remote,
    channel,
    }) => {
    if let Some(ReadyState {
    record_dichotomy, ..
    }) = model::is_ready_mut(model)
    {
    record_dichotomy
    .entry(remote)
    .or_default()
    .insert(channel, d);
    }
    }
    Err(err) => {
    let msg =
    format!("Failed to compare with remote with {err:?}. Remote {remote:?}, channel: {channel:?}");
    report::show_err(report, msg);
    }
    }
    if let Some(ReadyState { jobs, .. }) = model::is_ready_mut(model) {
    jobs.swap_remove(&Job::CompareRemote { remote, channel });
    }
    Task::none()
    }
  • edit in inflorescence/src/main.rs at line 2093
    [15.87419]
    [15.87419]
    record_dichotomy: None,
  • edit in inflorescence/src/main.rs at line 2181
    [15.88411]
    [15.88411]
    record_dichotomy: None,
  • edit in inflorescence/src/main.rs at line 2388
    [45.13554]
    [45.13554]
    record_dichotomy: default(),
  • edit in inflorescence/src/main.rs at line 2503
    [31.9184]
    [15.92314]
    record_dichotomy: _,
  • edit in inflorescence/src/main.rs at line 2816
    [18.65855]
    [18.65855]
    selection::Unified::CompareRemote(Some(
    selection::CompareRemote {
    hash: Some(selected_hash),
    file,
    ..
    },
    )) if *selected_hash == hash => file
    .as_ref()
    .map(|file| (file, &mut navigation.compare_remote_navs)),
  • replacement in inflorescence/src/main.rs at line 2827
    [18.65942][18.65942:65998]()
    | selection::Unified::EntireLog(_) => None,
    [18.65942]
    [18.65998]
    | selection::Unified::EntireLog(_)
    | selection::Unified::CompareRemote(_) => None,