allow to reset changed file

tzemanovic
Jan 28, 2026, 6:06 PM
BJ3CYLUTYL3ODCU7XIQ2YIBQ6GMHP4IQ7HYMD4YCOPFRYEIYNWKQC

Dependencies

  • [2] WT3GA27P add cursor with selection
  • [3] D7A7MSIH allow to defer or abandon record, add buttons
  • [4] ACDXXAX2 refactor main's updates into smaller fns
  • [5] WXQBBQ2A update nightly
  • [6] PTWZYQFR use nav-scrollable for repo status
  • [7] 3XRG4BB6 rewritten nav-scrollable!
  • [8] WAOGSCOJ very nice refactor, wip adding channels logs
  • [9] EJPSD5XO shared allowed actions conditions between update and view
  • [10] YK3MOJJL chonky refactor, wip other channels logs & diffs
  • [11] 7WCB5YQJ refactor msgs and modules
  • [12] PKLUHYE4 allow to copy change hash
  • [13] LFEMJYYD start of to_record selection
  • [14] FU6P5QLG indicate when a file is a dir with appended '/'
  • [15] YGZ3VCW4 add push
  • [16] ODCT4QJN add pull
  • [17] UTDTZCTX pull+push status, add info reports
  • [18] TEDT26JQ add push and pull sub-menus
  • [19] UR4J677R nav for log changes and refactors
  • [20] JZXYSIYD channel selection!
  • [21] 5O4FWCFP add tests to_record selection and improve it
  • [22] A5YBC77V record!
  • [23] AZ5D2LQU allow to set record description
  • [24] U3EAZKHR allow to copy error report
  • [25] YBJRDOTC make all repo actions async
  • [26] KWTBNTO3 diffs selection and scrolling
  • [27] CULHFNIV add error report view
  • [28] 23SFYK4Q big view refactor into a new crate
  • [29] 5CYU7UT7 test: rm added file
  • [*] SWWE2R6M display basic repo stuff
  • [*] VCNKFNUF app init test
  • [*] 6YZAVBWU Initial commit

Change contents

  • edit in libflorescence/src/repo.rs at line 82
    [17.86]
    [17.86]
    },
    ResetFile {
    path: String,
  • edit in libflorescence/src/repo.rs at line 488
    [17.875]
    [15.2022]
    }
    MsgIn::ResetFile { path } => {
    let state: anyhow::Result<State>;
    (internal_state, state) = spawn_blocking(move || {
    let state = |internal_state: &mut InternalState| {
    reset_file(internal_state, path)?;
    get_state(internal_state)
    };
    let state = state(&mut internal_state);
    (internal_state, state)
    })
    .await
    .unwrap();
    let _ = msg_out_tx.send(MsgOut::Refreshed {
    state,
    invalidate_logs: false,
    });
  • edit in libflorescence/src/repo.rs at line 1553
    [15.4674]
    [16.6804]
    fn reset_file(state: &mut InternalState, path: String) -> anyhow::Result<()> {
    let repo = &state.repo;
    let current_channel = current_channel(repo)?;
    let txn = repo.pristine.arc_txn_begin()?;
    let repo_path = CanonicalPathBuf::canonicalize(&repo.path)?;
    let channel = txn
    .read()
    .load_channel(&current_channel)?
    .context("Loading current channel")?;
    let mut conflicts = Vec::new();
    let root = std::fs::canonicalize(&path)?;
    let path = root.strip_prefix(&repo_path)?;
    use path_slash::PathExt;
    let path = path.to_slash_lossy();
    conflicts.extend(libpijul::output::output_repository_no_pending(
    &repo.working_copy,
    &repo.changes,
    &txn,
    &channel,
    &path,
    true,
    None,
    std::thread::available_parallelism()?.get(),
    0,
    )?);
    // TODO: handle conflicts - but why are there conflicts from file reset? Is
    // it for the case when reset removes conflict resolutions?
    // super::print_conflicts(&conflicts)?;
    txn.commit()?;
    Ok(())
    }
  • edit in inflorescence_model/src/model.rs at line 44
    [18.531968]
    [18.531968]
    ResetChange,
  • replacement in inflorescence_model/src/action.rs at line 24
    [9.4169][9.4169:4186]()
    RmAddedFile,
    [9.4169]
    [9.4186]
    RmChange,
  • replacement in inflorescence_model/src/action.rs at line 70
    [9.4855][9.4855:4899]()
    (RmAddedFile, RmAddedFile) => true,
    [9.4855]
    [9.4899]
    (RmChange, RmChange) => true,
  • replacement in inflorescence_model/src/action.rs at line 110
    [9.5373][9.5373:5408]()
    (RmAddedFile, _) => false,
    [9.5373]
    [9.5408]
    (RmChange, _) => false,
  • edit in inflorescence_model/src/action.rs at line 141
    [18.532517]
    [18.532517]
    }
    model::SubMenu::ResetChange => {
    vec![confirm("confirm reset selection"), cancel()]
  • edit in inflorescence_model/src/action.rs at line 232
    [11.8028]
    [9.7256]
    };
    let reset_changed_file = || Binding {
    key: "x",
    label: "reset file",
    msg: Some(FilteredMsg::RmChange),
    };
    let reset_changed_hunk = || Binding {
    key: "x",
    label: "reset hunk",
    msg: Some(FilteredMsg::RmChange),
  • replacement in inflorescence_model/src/action.rs at line 246
    [9.7349][11.8029:8074]()
    msg: Some(FilteredMsg::RmAddedFile),
    [9.7349]
    [9.7386]
    msg: Some(FilteredMsg::RmChange),
  • edit in inflorescence_model/src/action.rs at line 393
    [14.10232]
    [14.10294]
    ma.push(reset_changed_file());
  • edit in inflorescence_model/src/action.rs at line 432
    [13.14797]
    [13.14797]
    can_reset_hunk,
  • edit in inflorescence_model/src/action.rs at line 441
    [9.10669]
    [12.891]
    // TODO support reset of selected hunk
    {
    let _ = (can_reset_hunk, reset_changed_hunk);
    // push_if(can_reset_hunk, reset_changed_hunk, ma);
    }
  • edit in inflorescence_model/src/action.rs at line 630
    [9.13835]
    [13.15265]
    can_reset_hunk: bool,
  • edit in inflorescence_model/src/action.rs at line 756
    [13.15643]
    [13.15643]
    can_reset_hunk: false,
  • edit in inflorescence_model/src/action.rs at line 816
    [13.16170]
    [13.16170]
    can_reset_hunk: true,
  • edit in inflorescence_model/src/action.rs at line 849
    [13.16518]
    [13.16518]
    can_reset_hunk: false,
  • replacement in inflorescence/src/test.rs at line 617
    [10.29790][11.10755:10827]()
    Msg::View(view::Msg::Action(action::FilteredMsg::RmAddedFile)),
    [10.29790]
    [10.29853]
    Msg::View(view::Msg::Action(action::FilteredMsg::RmChange)),
  • edit in inflorescence/src/main.rs at line 348
    [18.533909]
    [18.533909]
    model::SubMenu::ResetChange => reset_change(state),
  • replacement in inflorescence/src/main.rs at line 456
    [11.13163][11.13163:13229]()
    action::FilteredMsg::RmAddedFile => rm_added_file(state),
    [11.13163]
    [11.13229]
    action::FilteredMsg::RmChange => rm_change(state),
  • edit in inflorescence/src/main.rs at line 726
    [18.535214]
    [12.2209]
    fn reset_change(state: &mut State) -> Task<Msg> {
    if let Some(ReadyState { selection, .. }) =
    model::is_ready_mut(&mut state.model)
    && let Some(selection::Status::ChangedFile {
    ix: _,
    path,
    diff_selected,
    }) = selection.status.as_ref()
    {
    if !diff_selected {
    state
    .repo_tx_in
    .send(repo::MsgIn::ResetFile {
    path: path.raw.clone(),
    })
    .unwrap();
    } else {
    todo!("reset selected hunk")
    }
    } else {
    report::show_err(
    &mut state.model.report,
    "Cannot reset the current selection. This should never happen, please report it! State: {state:?}"
    .to_string(),
    );
    }
    state.model.sub_menu = None;
    Task::none()
    }
  • replacement in inflorescence/src/main.rs at line 932
    [4.2322][4.2322:2373]()
    fn rm_added_file(state: &mut State) -> Task<Msg> {
    [4.2322]
    [8.87496]
    fn rm_change(state: &mut State) -> Task<Msg> {
  • edit in inflorescence/src/main.rs at line 948
    [8.87745]
    [5.1085]
    // See if the change is a previously untracked file
  • replacement in inflorescence/src/main.rs at line 1009
    [5.2037][6.6909:6910](),[6.6910][7.20558:20591]()
    return Task::none();
    [5.2037]
    [3.1813]
    } else {
    state.model.sub_menu = Some(model::SubMenu::ResetChange);
  • replacement in inflorescence/src/main.rs at line 1676
    [11.14008][11.14008:14077]()
    "x" => action(action::FilteredMsg::RmAddedFile),
    [11.14008]
    [2.3009]
    "x" => action(action::FilteredMsg::RmChange),