allow to add untracked files recursively

tzemanovic
Mar 6, 2026, 1:26 PM
6E6MSENZAZE7RGL4QBQD3MIAURXE5R3HINFWTNLOASJYVNHVOUMAC

Dependencies

  • [2] KT5UYXGK fix selection after adding file, add changed file diffs
  • [3] YBJRDOTC make all repo actions async
  • [4] I56UGW7U make record test, fix log update
  • [5] SWDPAGF6 test channel name
  • [6] QYDWH7KB test add and rm
  • [7] WAOGSCOJ very nice refactor, wip adding channels logs
  • [8] EJPSD5XO shared allowed actions conditions between update and view
  • [9] YK3MOJJL chonky refactor, wip other channels logs & diffs
  • [10] 7WCB5YQJ refactor msgs and modules
  • [11] IFQPVMBD error handling for repo actions
  • [12] FU6P5QLG indicate when a file is a dir with appended '/'
  • [13] TEDT26JQ add push and pull sub-menus
  • [14] BJ3CYLUT allow to reset changed file
  • [15] YRGDFHAB project dir picker
  • [16] 5BAPU7K6 dir picker key navigation
  • [17] T4UECD3S picking projects key nav and scrollable
  • [18] IOXNOVX2 allow to initiate a new repo
  • [19] XQDYES5M add support for git import
  • [20] AHWWRC73 navigate log entries
  • [21] LFEMJYYD start of to_record selection
  • [22] LPSUBGUB add projects picker
  • [23] MORKDJUE use allowed actions binding for key subs
  • [24] SEJXDXPW improve file watcher to respect .ignore file
  • [25] X6AK4QPX finish recording test
  • [26] AZ5D2LQU allow to set record description
  • [27] U3EAZKHR allow to copy error report
  • [28] PKLUHYE4 allow to copy change hash
  • [29] ELG3UDT6 allow to rm added files
  • [30] CULHFNIV add error report view
  • [31] ONRCENKT rm unnecessary state from repo's internal state
  • [32] 2LWMGRUM test diff
  • [33] YYKXNBFL test: add untracked file
  • [34] UF5NJKAS test load repo
  • [35] 3B75LKFN replace panics with bails
  • [36] YGZ3VCW4 add push
  • [37] ODCT4QJN add pull
  • [38] ACDXXAX2 refactor main's updates into smaller fns
  • [39] 5FVZF7XX test changed files
  • [*] VCNKFNUF app init test
  • [*] SWWE2R6M display basic repo stuff
  • [*] 6YZAVBWU Initial commit

Change contents

  • replacement in libflorescence/src/testing.rs at line 79
    [5.671][11.5:61]()
    repo::add(&mut repo, DEFAULT_IGNORE_FILE).unwrap();
    [5.671]
    [5.749]
    let recursive = false;
    repo::add(&mut repo, DEFAULT_IGNORE_FILE, recursive).unwrap();
  • edit in libflorescence/src/repo.rs at line 65
    [7.262]
    [7.262]
    recursive: bool,
  • replacement in libflorescence/src/repo.rs at line 391
    [3.2396][3.2396:2442]()
    MsgIn::AddUntrackedFile { path } => {
    [3.2396]
    [4.182]
    MsgIn::AddUntrackedFile { path, recursive } => {
  • replacement in libflorescence/src/repo.rs at line 395
    [11.968][11.968:1036]()
    let result = add(&mut internal_state, &path_clone);
    [11.968]
    [11.1036]
    let result = add(&mut internal_state, &path_clone, recursive);
  • edit in libflorescence/src/repo.rs at line 938
    [11.6917]
    [11.6917]
    recursive: bool,
  • replacement in libflorescence/src/repo.rs at line 957
    [2.1191][2.1191:1197]()
    {
    [2.1191]
    [2.1197]
    if recursive {
    let threads = std::thread::available_parallelism()?.get();
    use libpijul::working_copy::filesystem::*;
    let (full, _) = get_prefix(Some(repo_path.as_ref()), path.as_path())?;
    let full = CanonicalPathBuf::new(&full)?;
    repo.working_copy.add_prefix_rec(
    &txn,
    repo_path.clone(),
    full.clone(),
    false,
    threads,
    0,
    )?
    } else {
  • replacement in libflorescence/src/repo/test.rs at line 208
    [6.406][11.10967:11021]()
    repo::add(&mut internal.repo, new_file).unwrap();
    [6.406]
    [6.451]
    let recursive = false;
    repo::add(&mut internal.repo, new_file, recursive).unwrap();
  • edit in libflorescence/src/repo/test.rs at line 222
    [6.777]
    [5.3687]
    // Create a dir with a file inside it
    let new_dir = "a";
    std::fs::create_dir(repo_path.join(new_dir)).unwrap();
    let new_file = "new_file";
    std::fs::write(repo_path.join(new_dir).join(new_file), "some content")
    .unwrap();
    let recursive = true;
    repo::add(&mut internal.repo, new_dir, recursive).unwrap();
    let diff = repo::get_diff(&internal.repo).unwrap();
    assert_eq!(diff.changes.len(), 2);
  • edit in inflorescence_model/src/model.rs at line 89
    [19.30513]
    [13.531968]
    Add { recursive: bool },
  • replacement in inflorescence_model/src/action.rs at line 40
    [8.4147][8.4147:4169]()
    AddUntrackedFile,
    [8.4147]
    [14.1834]
    ToggleRecursive,
  • replacement in inflorescence_model/src/action.rs at line 86
    [8.4801][8.4801:4855]()
    (AddUntrackedFile, AddUntrackedFile) => true,
    [8.4801]
    [14.1849]
    (ToggleRecursive, ToggleRecursive) => true,
  • replacement in inflorescence_model/src/action.rs at line 126
    [8.5333][8.5333:5373]()
    (AddUntrackedFile, _) => false,
    [8.5333]
    [14.1888]
    (ToggleRecursive, _) => false,
  • edit in inflorescence_model/src/action.rs at line 238
    [18.1318]
    [13.532531]
    model::SubMenu::Add { recursive } => {
    vec![
    confirm("confirm add"),
    toggle_recursive(*recursive),
    cancel(),
    ]
    }
  • replacement in inflorescence_model/src/action.rs at line 511
    [8.7214][10.7978:8028]()
    msg: Some(FilteredMsg::AddUntrackedFile),
    [8.7214]
    [14.2048]
    msg: Some(FilteredMsg::EnterSubMenu(model::SubMenu::Add {
    recursive: false,
    })),
  • edit in inflorescence_model/src/action.rs at line 1437
    [13.533388]
    [13.533388]
    fn toggle_recursive(is_recursive: bool) -> Binding {
    Binding {
    keys_str: "r",
    keys: ModKeys::One(ModKey {
    key: Key::Character("r".into()),
    mods: Mods::NONE,
    }),
    label: if is_recursive {
    "add non-recursive"
    } else {
    "add recursive"
    },
    msg: Some(FilteredMsg::ToggleRecursive),
    }
    }
  • replacement in inflorescence/src/test.rs at line 152
    [9.26774][10.9028:9105]()
    Msg::View(view::Msg::Action(action::FilteredMsg::AddUntrackedFile)),
    [9.26774]
    [9.26842]
    Msg::View(view::Msg::Action(action::FilteredMsg::EnterSubMenu(
    model::SubMenu::Add { recursive: false },
    ))),
    );
    let _task = update(
    &mut state,
    Msg::View(view::Msg::Action(action::FilteredMsg::Confirm)),
  • replacement in inflorescence/src/test.rs at line 276
    [9.27820][10.9597:9674]()
    Msg::View(view::Msg::Action(action::FilteredMsg::AddUntrackedFile)),
    [9.27820]
    [9.27888]
    Msg::View(view::Msg::Action(action::FilteredMsg::EnterSubMenu(
    model::SubMenu::Add { recursive: false },
    ))),
    );
    let _task = update(
    &mut state,
    Msg::View(view::Msg::Action(action::FilteredMsg::Confirm)),
  • replacement in inflorescence/src/test.rs at line 594
    [9.29167][10.10535:10612]()
    Msg::View(view::Msg::Action(action::FilteredMsg::AddUntrackedFile)),
    [9.29167]
    [9.29235]
    Msg::View(view::Msg::Action(action::FilteredMsg::EnterSubMenu(
    model::SubMenu::Add { recursive: false },
    ))),
    );
    let _task = update(
    &mut state,
    Msg::View(view::Msg::Action(action::FilteredMsg::Confirm)),
  • replacement in inflorescence/src/main.rs at line 458
    [17.4156][17.4156:4208]()
    | action::FilteredMsg::AddUntrackedFile
    [17.4156]
    [17.4208]
    | action::FilteredMsg::ToggleRecursive
  • replacement in inflorescence/src/main.rs at line 879
    [19.34227][19.34227:34282]()
    | model::SubMenu::ResetChange,
    [19.34227]
    [19.34282]
    | model::SubMenu::ResetChange
    | model::SubMenu::Add { .. },
  • replacement in inflorescence/src/main.rs at line 903
    [16.18388][16.18388:18440]()
    | action::FilteredMsg::AddUntrackedFile
    [16.18388]
    [16.18440]
    | action::FilteredMsg::ToggleRecursive
  • edit in inflorescence/src/main.rs at line 1036
    [18.6227]
    [19.35057]
    Some(model::SubMenu::Add { recursive }) => {
    let task = add_untracked_file(state, model, *recursive);
    *sub_menu = None;
    task
    }
  • replacement in inflorescence/src/main.rs at line 1154
    [15.3618547][15.3618547:3618653]()
    action::FilteredMsg::AddUntrackedFile => {
    add_untracked_file(state, model)
    }
    [15.3618547]
    [15.3618653]
    action::FilteredMsg::ToggleRecursive => toggle_recursive(sub_menu),
  • edit in inflorescence/src/main.rs at line 1385
    [9.64717]
    [13.534299]
    }
    fn toggle_recursive(sub_menu: &mut Option<model::SubMenu>) -> Task<Msg> {
    if let Some(model::SubMenu::Add { recursive }) = sub_menu.as_mut() {
    *recursive = !*recursive;
    }
    Task::none()
  • edit in inflorescence/src/main.rs at line 1637
    [15.3622368]
    [18.8216]
    recursive: bool,
  • edit in inflorescence/src/main.rs at line 1657
    [12.13828]
    [12.13828]
    recursive,