group diffs by file name

[?]
Mar 27, 2025, 8:40 PM
W4LFX7IHQ7SDX67ATSGWDB5IN6472ZJDBKY2XZ54SBJEYD5GAT5QC

Dependencies

  • [2] SWWE2R6M display basic repo stuff
  • [3] WT3GA27P add cursor with selection
  • [4] EC3TVL4X add untracked files
  • [5] KT5UYXGK fix selection after adding file, add changed file diffs
  • [6] YBJRDOTC make all repo actions async
  • [7] A5YBC77V record!
  • [8] D7A7MSIH allow to defer or abandon record, add buttons
  • [9] UCBNZULE make changed files paths optional (no path for root)
  • [10] 4WO3ZJM2 show untracked files' contents
  • [11] CFYW3HGZ wip: display changed files
  • [12] W7IUT3ZV start recording impl
  • [13] DVKSPF7R track selected file path together with an index
  • [14] UB2ITZJS refresh changed files on FS changes
  • [15] S2NVIFXR allow to enter record msg
  • [16] ELG3UDT6 allow to rm added files
  • [*] 6YZAVBWU Initial commit

Change contents

  • replacement in crates/libflowers_client/src/repo.rs at line 30
    [6.235][6.235:281]()
    pub changed_files: BTreeSet<ChangedFile>,
    [6.235]
    [6.281]
    pub changed_files: ChangedFiles,
  • replacement in crates/libflowers_client/src/repo.rs at line 39
    [4.281][5.77:123]()
    pub changed_files: BTreeSet<ChangedFile>,
    [4.281]
    [5.123]
    pub changed_files: ChangedFiles,
  • replacement in crates/libflowers_client/src/repo.rs at line 42
    [5.126][5.126:207](),[5.207][9.7:37](),[9.37][5.229:262](),[5.229][5.229:262]()
    #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
    pub struct ChangedFile {
    pub path: Option<String>,
    pub diff: ChangedFileDiff,
    }
    [5.126]
    [5.262]
    pub type ChangedFiles = BTreeMap<String, ChangedFile>;
    pub type ChangedFile = BTreeSet<ChangedFileDiff>;
    pub const ROOT_FILE: &str = ".";
  • replacement in crates/libflowers_client/src/repo.rs at line 89
    [6.670][6.670:716]()
    changed_files: BTreeSet<ChangedFile>,
    [6.670]
    [6.716]
    changed_files: ChangedFiles,
  • replacement in crates/libflowers_client/src/repo.rs at line 436
    [5.1700][10.396:491](),[10.491][2.2949:2982](),[5.1757][2.2949:2982](),[2.2949][2.2949:2982](),[2.2982][10.492:535]()
    fn changed_files(
    diff: &Diff,
    repo_changes: &FileSystem,
    ) -> BTreeSet<ChangedFile> {
    diff.changes
    .iter()
    .map(|change| match dbg!(change) {
    [5.1700]
    [5.1758]
    fn changed_files(diff: &Diff, repo_changes: &FileSystem) -> ChangedFiles {
    let mut changes: ChangedFiles = BTreeMap::new();
    for change in diff.changes.iter() {
    match dbg!(change) {
  • replacement in crates/libflowers_client/src/repo.rs at line 444
    [5.1861][5.1861:1892](),[5.1892][9.40:82](),[9.82][5.1928:1988](),[5.1928][5.1928:1988]()
    } => ChangedFile {
    path: Some(path.clone()),
    diff: ChangedFileDiff::Move,
    },
    [5.1861]
    [2.3081]
    } => {
    changes
    .entry(path.clone())
    .or_default()
    .insert(ChangedFileDiff::Move);
    }
  • replacement in crates/libflowers_client/src/repo.rs at line 455
    [5.2072][5.2072:2103](),[5.2103][9.83:125](),[9.125][5.2139:2198](),[5.2139][5.2139:2198]()
    } => ChangedFile {
    path: Some(path.clone()),
    diff: ChangedFileDiff::Del,
    },
    [5.2072]
    [2.3234]
    } => {
    changes
    .entry(path.clone())
    .or_default()
    .insert(ChangedFileDiff::Del);
    }
  • replacement in crates/libflowers_client/src/repo.rs at line 466
    [5.2284][5.2284:2315](),[5.2315][9.126:168](),[9.168][5.2351:2412](),[5.2351][5.2351:2412]()
    } => ChangedFile {
    path: Some(path.clone()),
    diff: ChangedFileDiff::Undel,
    },
    [5.2284]
    [2.3391]
    } => {
    changes
    .entry(path.clone())
    .or_default()
    .insert(ChangedFileDiff::Undel);
    }
  • replacement in crates/libflowers_client/src/repo.rs at line 478
    [5.2530][5.2530:2561](),[5.2561][9.169:211](),[9.211][5.2597:2731](),[5.2597][5.2597:2731](),[5.2731][9.212:254](),[9.254][5.2767:2917](),[5.2767][5.2767:2917](),[5.2917][9.255:297](),[9.297][5.2953:3028](),[5.2953][5.2953:3028]()
    } => ChangedFile {
    path: Some(path.clone()),
    diff: ChangedFileDiff::Add,
    },
    BaseHunk::SolveNameConflict { name: _, path } => ChangedFile {
    path: Some(path.clone()),
    diff: ChangedFileDiff::SolveNameConflict,
    },
    BaseHunk::UnsolveNameConflict { name: _, path } => ChangedFile {
    path: Some(path.clone()),
    diff: ChangedFileDiff::UnsolveNameConflict,
    },
    [5.2530]
    [2.3712]
    } => {
    changes
    .entry(path.clone())
    .or_default()
    .insert(ChangedFileDiff::Add);
    }
    BaseHunk::SolveNameConflict { name: _, path } => {
    changes
    .entry(path.clone())
    .or_default()
    .insert(ChangedFileDiff::SolveNameConflict);
    }
    BaseHunk::UnsolveNameConflict { name: _, path } => {
    changes
    .entry(path.clone())
    .or_default()
    .insert(ChangedFileDiff::UnsolveNameConflict);
    }
  • edit in crates/libflowers_client/src/repo.rs at line 501
    [10.580][10.580:633]()
    let path = Some(local.path.clone());
  • replacement in crates/libflowers_client/src/repo.rs at line 515
    [10.1203][10.1203:1309]()
    ChangedFile {
    path,
    diff: ChangedFileDiff::Edit {
    [10.1203]
    [10.1309]
    changes.entry(local.path.clone()).or_default().insert(
    ChangedFileDiff::Edit {
  • replacement in crates/libflowers_client/src/repo.rs at line 521
    [10.1429][10.1429:1447]()
    }
    [10.1429]
    [10.1447]
    );
  • replacement in crates/libflowers_client/src/repo.rs at line 528
    [5.3308][5.3308:3339](),[5.3339][9.347:395](),[9.395][5.3381:3527](),[5.3381][5.3381:3527](),[5.3527][9.396:444](),[9.444][5.3569:3643](),[5.3569][5.3569:3643]()
    } => ChangedFile {
    path: Some(local.path.clone()),
    diff: ChangedFileDiff::Replacement,
    },
    BaseHunk::SolveOrderConflict { change: _, local } => ChangedFile {
    path: Some(local.path.clone()),
    diff: ChangedFileDiff::SolveOrderConflict,
    },
    [5.3308]
    [5.3643]
    } => {
    changes
    .entry(local.path.clone())
    .or_default()
    .insert(ChangedFileDiff::Replacement);
    }
    BaseHunk::SolveOrderConflict { change: _, local } => {
    changes
    .entry(local.path.clone())
    .or_default()
    .insert(ChangedFileDiff::SolveOrderConflict);
    }
  • replacement in crates/libflowers_client/src/repo.rs at line 541
    [5.3712][5.3712:3742](),[5.3742][9.445:497](),[9.497][5.3788:3871](),[5.3788][5.3788:3871]()
    ChangedFile {
    path: Some(local.path.clone()),
    diff: ChangedFileDiff::UnsolveOrderConflict,
    }
    [5.3712]
    [5.3871]
    changes
    .entry(local.path.clone())
    .or_default()
    .insert(ChangedFileDiff::UnsolveOrderConflict);
  • replacement in crates/libflowers_client/src/repo.rs at line 550
    [5.3943][5.3943:3974](),[5.3974][9.498:546](),[9.546][5.4016:4215](),[5.4016][5.4016:4215](),[5.4215][9.547:575](),[9.575][5.4254:4443](),[5.4254][5.4254:4443](),[5.4443][9.576:604](),[9.604][5.4482:4545](),[5.4482][5.4482:4545](),[5.4545][4.544:574](),[2.4415][4.544:574]()
    } => ChangedFile {
    path: Some(local.path.clone()),
    diff: ChangedFileDiff::ResurrectZombines,
    },
    BaseHunk::AddRoot { name: _, inode: _ } => ChangedFile {
    // TODO: maybe they don't all have path?
    path: None,
    diff: ChangedFileDiff::AddRoot,
    },
    BaseHunk::DelRoot { name: _, inode: _ } => ChangedFile {
    // TODO: maybe they don't all have path?
    path: None,
    diff: ChangedFileDiff::DelRoot,
    },
    })
    .collect()
    [5.3943]
    [4.574]
    } => {
    changes
    .entry(local.path.clone())
    .or_default()
    .insert(ChangedFileDiff::ResurrectZombines);
    }
    BaseHunk::AddRoot { name: _, inode: _ } => {
    changes
    .entry(ROOT_FILE.to_string())
    .or_default()
    .insert(ChangedFileDiff::AddRoot);
    }
    BaseHunk::DelRoot { name: _, inode: _ } => {
    changes
    .entry(ROOT_FILE.to_string())
    .or_default()
    .insert(ChangedFileDiff::DelRoot);
    }
    }
    }
    changes
  • replacement in crates/libflowers_client/src/cursor.rs at line 9
    [4.1646][9.608:661]()
    ChangedFile { ix: usize, path: Option<String> },
    [4.1646]
    [3.188]
    ChangedFile { ix: usize, path: String },
  • edit in crates/flowers_ui/src/main.rs at line 16
    [5.4614][6.4676:4708]()
    use std::collections::BTreeSet;
  • replacement in crates/flowers_ui/src/main.rs at line 175
    [6.6621][6.6621:6701]()
    let path = repo.changed_files.iter().nth(ix).unwrap().path.clone();
    [6.6621]
    [5.5061]
    let path = repo
    .changed_files
    .iter()
    .nth(ix)
    .map(|(k, _v)| k)
    .unwrap()
    .clone();
  • replacement in crates/flowers_ui/src/main.rs at line 384
    [6.11860][6.11860:11911](),[6.11911][9.675:725](),[9.725][6.11955:12089](),[6.11955][6.11955:12089]()
    let file = repo::ChangedFile {
    path: Some(path.clone()),
    diff: repo::ChangedFileDiff::Add,
    };
    repo.changed_files.insert(file);
    [6.11860]
    [6.12089]
    repo.changed_files
    .entry(path.clone())
    .or_default()
    .insert(repo::ChangedFileDiff::Add);
  • replacement in crates/flowers_ui/src/main.rs at line 410
    [6.12618][6.12618:12763]()
    let file = repo.changed_files.iter().nth(*ix).unwrap();
    if let repo::ChangedFileDiff::Add = &file.diff {
    [6.12618]
    [7.4835]
    let diffs = repo.changed_files.get(path).unwrap();
    if diffs
    .iter()
    .any(|diff| matches!(diff, repo::ChangedFileDiff::Add))
    {
  • replacement in crates/flowers_ui/src/main.rs at line 418
    [7.4966][9.726:890]()
    path: path
    .clone()
    .expect("Added file must have a path"),
    [7.4966]
    [7.4967]
    path: path.clone(),
  • edit in crates/flowers_ui/src/main.rs at line 422
    [6.12957][6.12957:13006]()
    let file = file.clone();
  • replacement in crates/flowers_ui/src/main.rs at line 423
    [6.13059][6.13059:13131]()
    let removed = repo.changed_files.remove(&file);
    [6.13059]
    [6.13131]
    let removed = repo.changed_files.remove(path);
  • replacement in crates/flowers_ui/src/main.rs at line 425
    [6.13170][6.13170:13207]()
    removed,
    [6.13170]
    [6.13207]
    removed.is_some(),
  • replacement in crates/flowers_ui/src/main.rs at line 427
    [6.13261][6.13261:13314]()
    file, repo.changed_files
    [6.13261]
    [6.13314]
    path,
    repo.changed_files
  • replacement in crates/flowers_ui/src/main.rs at line 431
    [6.13391][9.891:1046]()
    if let Some(file_path) = file.path {
    repo.untracked_files.insert(file_path);
    }
    [6.13391]
    [6.13455]
    repo.untracked_files.insert(path.clone());
  • replacement in crates/flowers_ui/src/main.rs at line 499
    [6.14598][6.14598:14639]()
    BTreeSet::new();
    [6.14598]
    [7.5329]
    repo::ChangedFiles::default();
  • replacement in crates/flowers_ui/src/main.rs at line 649
    [6.16155][6.16155:16379]()
    .find(|(_ix, file)| &file.path == path)
    .map(|(ix, file)| cursor::Selection::ChangedFile {
    ix,
    path: file.path.clone(),
    [6.16155]
    [6.16379]
    .find(|(_ix, (file_path, _diffs))| file_path == &path)
    .map(|(ix, (file_path, _diffs))| {
    cursor::Selection::ChangedFile {
    ix,
    path: file_path.clone(),
    }
  • replacement in crates/flowers_ui/src/main.rs at line 740
    [8.2707][5.7599:7626](),[6.17039][5.7599:7626](),[3.3633][5.7599:7626]()
    |(ix, file)| {
    [8.2707]
    [3.3660]
    |(ix, (file_path, _diffs))| {
  • replacement in crates/flowers_ui/src/main.rs at line 746
    [9.1075][9.1075:1307]()
    match &file.path {
    Some(file_path) => text(format!("{}: {}", file.diff, file_path)),
    None => text(format!("{}", file.diff)),
    })
    [9.1075]
    [3.3911]
    text(format!("{}", file_path)))
  • replacement in crates/flowers_ui/src/main.rs at line 748
    [3.3968][5.7702:7791]()
    cursor::Selection::ChangedFile{ix, path: file.path.clone()},
    [3.3968]
    [3.4025]
    cursor::Selection::ChangedFile{ix, path: file_path.clone()},
  • edit in crates/flowers_ui/src/main.rs at line 791
    [11.170][11.170:329]()
    let path = if let Some(path) = path {
    path.as_str()
    } else {
    "root"
    };