Reload git index on file events to catch new contents

Julia created

Change summary

crates/editor/src/element.rs   |  4 +---
crates/git/src/repository.rs   | 16 +++++++++++++---
crates/project/src/project.rs  |  2 +-
crates/project/src/worktree.rs |  3 ++-
4 files changed, 17 insertions(+), 8 deletions(-)

Detailed changes

crates/editor/src/element.rs 🔗

@@ -630,9 +630,7 @@ impl EditorElement {
                     let new_hunk = get_hunk(diff_layout.buffer_row, &layout.diff_hunks);
 
                     let (is_ending, is_starting) = match (diff_layout.last_diff, new_hunk) {
-                        (Some(old_hunk), Some(new_hunk)) if new_hunk == old_hunk => {
-                            (false, false)
-                        }
+                        (Some(old_hunk), Some(new_hunk)) if new_hunk == old_hunk => (false, false),
                         (a, b) => (a.is_some(), b.is_some()),
                     };
 

crates/git/src/repository.rs 🔗

@@ -10,12 +10,20 @@ pub use git2::Repository as LibGitRepository;
 
 #[async_trait::async_trait]
 pub trait GitRepository: Send {
-    fn load_index(&self, relative_file_path: &Path) -> Option<String>;
+    fn reload_index(&self);
+
+    fn load_index_text(&self, relative_file_path: &Path) -> Option<String>;
 }
 
 #[async_trait::async_trait]
 impl GitRepository for LibGitRepository {
-    fn load_index(&self, relative_file_path: &Path) -> Option<String> {
+    fn reload_index(&self) {
+        if let Ok(mut index) = self.index() {
+            _ = index.read(false);
+        }
+    }
+
+    fn load_index_text(&self, relative_file_path: &Path) -> Option<String> {
         fn logic(repo: &LibGitRepository, relative_file_path: &Path) -> Result<Option<String>> {
             const STAGE_NORMAL: i32 = 0;
             let index = repo.index()?;
@@ -54,7 +62,9 @@ impl FakeGitRepository {
 
 #[async_trait::async_trait]
 impl GitRepository for FakeGitRepository {
-    fn load_index(&self, path: &Path) -> Option<String> {
+    fn reload_index(&self) {}
+
+    fn load_index_text(&self, path: &Path) -> Option<String> {
         let state = self.state.lock();
         state.index_contents.get(path).cloned()
     }

crates/project/src/project.rs 🔗

@@ -4684,7 +4684,7 @@ impl Project {
                 cx.spawn(|_, mut cx| async move {
                     let diff_base = cx
                         .background()
-                        .spawn(async move { repo.repo.lock().load_index(&relative_repo) })
+                        .spawn(async move { repo.repo.lock().load_index_text(&relative_repo) })
                         .await;
 
                     let buffer_id = buffer.update(&mut cx, |buffer, cx| {

crates/project/src/worktree.rs 🔗

@@ -671,7 +671,7 @@ impl LocalWorktree {
                 if let Ok(repo_relative) = path.strip_prefix(repo.content_path) {
                     let repo_relative = repo_relative.to_owned();
                     cx.background()
-                        .spawn(async move { repo.repo.lock().load_index(&repo_relative) })
+                        .spawn(async move { repo.repo.lock().load_index_text(&repo_relative) })
                         .await
                 } else {
                     None
@@ -2505,6 +2505,7 @@ impl BackgroundScanner {
 
                         let scan_id = snapshot.scan_id;
                         if let Some(repo) = snapshot.in_dot_git(&path) {
+                            repo.repo.lock().reload_index();
                             repo.scan_id = scan_id;
                         }