fix(vcs): hide tracked changes of ignored names from Git status (#408)

Names in Settings › Ignored files and folders were hidden only when untracked; their tracked or staged changes still showed in the change list. They are now filtered too, except conflicts, so a merge can't stall on a hidden file.

Co-authored-by: a-rookie-of-C-language <[email protected]>
This commit is contained in:
arookieofcanda-rookie-of-C-language authored and GitHub committed 2026-10-30 19:00:42 +08:00
1 parent 924446279b
commit c3252d43c3
2 files changed
+15

No files matched your search

+4
View File
@@ -105,6 +105,10 @@ pub(crate) fn status(r: &Repo) -> IdeResult<Vec<FileStatus>> {
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;
+11
View File
@@ -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();