diff --git a/crates/ide-vcs/src/status.rs b/crates/ide-vcs/src/status.rs index f87ccdf5..9a21ba09 100644 --- a/crates/ide-vcs/src/status.rs +++ b/crates/ide-vcs/src/status.rs @@ -105,6 +105,10 @@ pub(crate) fn status(r: &Repo) -> IdeResult> { Ok(map .into_iter() .filter(|(_, e)| e.staged.is_some() || e.unstaged.is_some()) + // Ignored names mean "the IDE treats these as nonexistent": hide their tracked + // changes too, not just untracked hits above. Conflicts stay visible so merges + // cannot stall on a file the user cannot see. + .filter(|(rel, _)| conflicts.contains(rel) || !ignored.is_ignored_path(rel)) .map(|(rel, mut e)| { if conflicts.contains(&rel) { e.staged = None; diff --git a/crates/ide-vcs/tests/repo.rs b/crates/ide-vcs/tests/repo.rs index 6b97eead..a2e97b41 100644 --- a/crates/ide-vcs/tests/repo.rs +++ b/crates/ide-vcs/tests/repo.rs @@ -175,6 +175,9 @@ fn status_matrix() { fx.write("staged_del.txt", "a\n"); fx.write("rename_me.txt", "some longer content\nthat is stable\nfor rename detection\n"); fx.write("both.txt", "a\n"); + // A committed file the IDE ignores keeps its history but drops out of the change list. + fx.write("tracked.pyc", "a\n"); + fx.git(&["add", "-f", "tracked.pyc"]); fx.commit_all("base"); fx.write("modified.txt", "b\n"); @@ -195,6 +198,10 @@ fn status_matrix() { fx.write(".DS_Store", "junk"); fx.write("dir/.DS_Store", "junk"); fx.write("pkg/__pycache__/m.pyc", "junk"); + fx.write("tracked.pyc", "b\n"); + // Contents differ from `staged_del.txt` so rename detection cannot pair them. + fx.write("staged_ignored.pyc", "cached\nbytecode\n"); + fx.git(&["add", "-f", "staged_ignored.pyc"]); let repo = fx.repo(); repo.set_ignored_names(ide_core::settings::Settings::default().ignored_names()); @@ -217,6 +224,10 @@ fn status_matrix() { assert_eq!(status_of(&st, "renamed.txt").renamed_from.as_deref(), Some("rename_me.txt")); assert!(!st.iter().any(|s| s.rel_path == "rename_me.txt"), "rename source listed: {st:#?}"); assert!(!st.iter().any(|s| s.rel_path.contains("debug.log") || s.rel_path.contains("build"))); + assert!( + !st.iter().any(|s| s.rel_path.contains("tracked.pyc") || s.rel_path.contains("staged_ignored.pyc")), + "{st:#?}" + ); assert!(!st.iter().any(|s| s.rel_path.contains(".DS_Store") || s.rel_path.contains("pkg")), "{st:#?}"); // Sorted by path. let paths: Vec<_> = st.iter().map(|s| s.rel_path.clone()).collect();