Override ignore patterns if a file is tracked#53751
Override ignore patterns if a file is tracked#53751mchisolm0 wants to merge 11 commits intozed-industries:mainfrom
Conversation
- Introduce tracked_paths on GitRepository and implement for fake and real backends - FakeGitRepository now returns tracked paths from head and index contents - RealGitRepository tracks files by invoking `git ls-files -z --cached` and parsing null-delimited output - Add git_tracked_paths_args helper to build the command - Fall back to the "git" binary when no system/bundled binary is available - Update tests to reflect tracked paths behavior for nested bin paths
- Introduce tracked_paths on GitRepository and implement for fake and real backends - FakeGitRepository now returns tracked paths from head and index contents - RealGitRepository tracks files by invoking `git ls-files -z --cached` and parsing null-delimited output - Add git_tracked_paths_args helper to build the command - Fall back to the "git" binary when no system/bundled binary is available
…m0/zed into ignored-vs-tracked-file-coloring
|
The test I am removing this test from the current PR since it is actually only somewhat related and currently fails in CI for Windows. The test checks if tracked files refresh correctly when a previously ignored file is added to tracked files. Test being dropped from this PR#[gpui::test]
async fn test_tracking_nested_path_updates_ignored_bin_dir(cx: &mut TestAppContext) {
init_test(cx);
let fs = FakeFs::new(cx.background_executor.clone());
fs.insert_tree(
path!("/root"),
json!({
".git": {},
".gitignore": "bin/\n",
"bin": {
"ignored-file": "",
},
"images": {
"simple-bridge": {
"src": {
"rootfs": {
"bin": {
"simple-bridge": "#!/bin/sh\n",
}
}
}
}
}
}),
)
.await;
fs.set_head_and_index_for_repo(
path!("/root/.git").as_ref(),
&[(".gitignore", "bin/\n".into())],
);
let worktree = Worktree::local(
Path::new("/root"),
true,
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
.unwrap();
cx.read(|cx| worktree.read(cx).as_local().unwrap().scan_complete())
.await;
worktree.flush_fs_events(cx).await;
worktree
.update(cx, |tree, cx| {
tree.load_file(rel_path("bin/ignored-file"), cx)
})
.await
.unwrap();
worktree.read_with(cx, |worktree, _| {
let root_bin = worktree.entry_for_path(rel_path("bin")).unwrap();
let nested_bin = worktree
.entry_for_path(rel_path("images/simple-bridge/src/rootfs/bin"))
.unwrap();
assert!(root_bin.is_ignored);
assert!(nested_bin.is_ignored);
assert!(
worktree
.entry_for_path(rel_path(
"images/simple-bridge/src/rootfs/bin/simple-bridge"
))
.is_none(),
"tracked file should not be visible before the repository starts tracking it"
);
});
fs.set_head_and_index_for_repo(
path!("/root/.git").as_ref(),
&[
(".gitignore", "bin/\n".into()),
(
"images/simple-bridge/src/rootfs/bin/simple-bridge",
"#!/bin/sh\n".into(),
),
],
);
worktree.flush_fs_events(cx).await;
cx.read(|cx| worktree.read(cx).as_local().unwrap().scan_complete())
.await;
worktree.flush_fs_events(cx).await;
worktree.update(cx, |worktree, _cx| {
check_worktree_entries(
worktree,
&[],
&["bin", "bin/ignored-file"],
&[
".gitignore",
"images/simple-bridge/src/rootfs/bin",
"images/simple-bridge/src/rootfs/bin/simple-bridge",
],
&[],
);
});
}I have tested this manually on Linux, and the previously ignored file gets correctly shown as tracked once it is added as a tracked file. |
|
I had also added this test. I am removing it since I feel Project Panel Hides Ignored Files Test#[gpui::test]
async fn test_tracked_nested_bin_path_stays_visible_when_hide_gitignore_is_enabled(
cx: &mut gpui::TestAppContext,
) {
init_test(cx);
let fs = FakeFs::new(cx.background_executor.clone());
fs.insert_tree(
"/project_root",
json!({
".git": {},
".gitignore": "bin/\n",
"bin": {
"ignored-file": "",
},
"images": {
"simple-bridge": {
"src": {
"rootfs": {
"bin": {
"simple-bridge": "#!/bin/sh\n",
}
}
}
}
},
}),
)
.await;
fs.set_head_and_index_for_repo(
path!("/project_root/.git").as_ref(),
&[
(".gitignore", "bin/\n".into()),
(
"images/simple-bridge/src/rootfs/bin/simple-bridge",
"#!/bin/sh\n".into(),
),
],
);
let project = Project::test(fs.clone(), ["/project_root".as_ref()], cx).await;
let window = cx.add_window(|window, cx| MultiWorkspace::test_new(project.clone(), window, cx));
let workspace = window
.read_with(cx, |mw, _| mw.workspace().clone())
.unwrap();
let cx = &mut VisualTestContext::from_window(window.into(), cx);
cx.update(|_, cx| {
let settings = *ProjectPanelSettings::get_global(cx);
ProjectPanelSettings::override_global(
ProjectPanelSettings {
hide_gitignore: true,
..settings
},
cx,
);
});
let panel = workspace.update_in(cx, ProjectPanel::new);
cx.run_until_parked();
let initial_entries = visible_entries_as_strings(&panel, 0..20, cx);
assert!(
!initial_entries.iter().any(|entry| entry == " > bin"),
"root ignored bin directory should stay hidden when hide_gitignore is enabled: {initial_entries:?}"
);
for path in [
"project_root/images",
"project_root/images/simple-bridge",
"project_root/images/simple-bridge/src",
"project_root/images/simple-bridge/src/rootfs",
] {
toggle_expand_dir(&panel, path, cx);
}
let expanded_entries = visible_entries_as_strings(&panel, 0..20, cx);
assert!(
expanded_entries.iter().any(|entry| entry.trim() == "> bin"),
"tracked nested bin directory should be visible before it is expanded: {expanded_entries:?}"
);
toggle_expand_dir(
&panel,
"project_root/images/simple-bridge/src/rootfs/bin",
cx,
);
let expanded_entries = visible_entries_as_strings(&panel, 0..20, cx);
assert!(
expanded_entries
.iter()
.any(|entry| entry == " simple-bridge"),
"tracked nested file should remain visible in the project panel: {expanded_entries:?}"
);
}Project Test Checking Ignore with Real FS#[gpui::test]
async fn test_tracked_nested_bin_path_is_not_ignored_with_real_fs(cx: &mut gpui::TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let root = TempTree::new(json!({
".gitignore": "bin/\n",
"bin": {
"ignored-root-file": "ignored"
},
"images": {
"simple-bridge": {
"src": {
"rootfs": {
"bin": {
"simple-bridge": "tracked"
}
}
}
}
}
}));
let work_dir = root.path();
let repo = git_init(work_dir);
git_add(".gitignore", &repo);
git_add("images/simple-bridge/src/rootfs/bin/simple-bridge", &repo);
git_commit("Initial commit", &repo);
let project = Project::test(Arc::new(RealFs::new(None, cx.executor())), [work_dir], cx).await;
let tree = project.read_with(cx, |project, cx| project.worktrees(cx).next().unwrap());
tree.flush_fs_events(cx).await;
project
.update(cx, |project, cx| project.git_scans_complete(cx))
.await;
cx.executor().run_until_parked();
let repository = project.read_with(cx, |project, cx| {
project.repositories(cx).values().next().unwrap().clone()
});
cx.read(|cx| {
assert_entry_git_state(
tree.read(cx),
repository.read(cx),
"images/simple-bridge/src/rootfs/bin/simple-bridge",
None,
false,
);
assert!(
!tree
.read(cx)
.entry_for_path(&rel_path("images/simple-bridge/src/rootfs/bin"))
.unwrap()
.is_ignored,
"tracked nested bin directory should not be ignored"
);
});
} |
| @@ -10599,7 +10592,7 @@ async fn test_update_gitignore(cx: &mut gpui::TestAppContext) { | |||
|
|
|||
| cx.executor().run_until_parked(); | |||
| cx.read(|cx| { | |||
| assert_entry_git_state(tree.read(cx), repository.read(cx), "a.xml", None, true); | |||
| assert_entry_git_state(tree.read(cx), repository.read(cx), "a.xml", None, false); | |||
There was a problem hiding this comment.
Based on the linked issue, a tracked file that matches a .gitignore pattern should be treated as tracked.
Since...
crates/project/tests/integration/project_tests.rs line 10553
fs.set_head_and_index_for_repo(
path!("/root/.git").as_ref(),
&[
(".gitignore", "*.txt\n".into()),
("a.xml", "<a></a>".into()),
],
);The test's assertion here should be "a.xml" is not ignored, but I wonder if that means I need to update the test to make sure it still checks the originally intended behavior.
Current implementation for
.gitignorelogic fails to respect explicitly tracked files if they match ignore patterns. This is true for repository scoped.gitignorefiles or one defined globally withcore.excludesfile.The linked issues surfaced the problem when the user tracked a nested file but part of the path matched a
.gitignorepattern. This caused the project panel to show the directory/file as ignored even though the file was tracked.These changes use tracked files to override the list of ignored files/paths.
Self-Review Checklist:
Closes #51662 and Closes #53208
Release Notes: