git: Handle git status output for deleted-in-index state (#23483)

When a file exists in HEAD, is deleted in the index, and exists again in
the working copy, git produces two lines for it, one reading `D `
(deleted in index, unmodified in working copy), and the other reading
`??` (untracked). Merge these two into the equivalent of `DA`.

Release Notes:

- Improved handling of files that are deleted in the git index but exist
in HEAD and the working copy
This commit is contained in:
Cole Miller 2025-01-22 15:28:25 -05:00 committed by GitHub
parent 08b3c03241
commit 55d99e0259
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 83 additions and 0 deletions

View file

@ -2639,6 +2639,62 @@ async fn test_git_repository_status(cx: &mut TestAppContext) {
});
}
#[gpui::test]
async fn test_git_status_postprocessing(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let root = temp_tree(json!({
"project": {
"sub": {},
"a.txt": "",
},
}));
let work_dir = root.path().join("project");
let repo = git_init(work_dir.as_path());
// a.txt exists in HEAD and the working copy but is deleted in the index.
git_add("a.txt", &repo);
git_commit("Initial commit", &repo);
git_remove_index("a.txt".as_ref(), &repo);
// `sub` is a nested git repository.
let _sub = git_init(&work_dir.join("sub"));
let tree = Worktree::local(
root.path(),
true,
Arc::new(RealFs::default()),
Default::default(),
&mut cx.to_async(),
)
.await
.unwrap();
tree.flush_fs_events(cx).await;
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
.await;
cx.executor().run_until_parked();
tree.read_with(cx, |tree, _cx| {
let snapshot = tree.snapshot();
let repo = snapshot.repositories().iter().next().unwrap();
let entries = repo.status().collect::<Vec<_>>();
// `sub` doesn't appear in our computed statuses.
assert_eq!(entries.len(), 1);
assert_eq!(entries[0].repo_path.as_ref(), Path::new("a.txt"));
// a.txt appears with a combined `DA` status.
assert_eq!(
entries[0].status,
TrackedStatus {
index_status: StatusCode::Deleted,
worktree_status: StatusCode::Added
}
.into()
);
});
}
#[gpui::test]
async fn test_repository_subfolder_git_status(cx: &mut TestAppContext) {
init_test(cx);