Don't save deleted files (#24171)

Conrad Irwin created

We now treat new files that have no content as not-dirty. This fixes the
git diff view when deleted files are present.

It also fixes a long-standing bug where `zed RAEDME` and then closing
the tab would prompt for "unsaved changes" when there were none.

Release Notes:

- Fixed a bug where closing an empty, named, file would warn about
unsaved content.

Change summary

crates/git_ui/src/project_diff.rs |  4 ++--
crates/language/src/buffer.rs     | 17 +++++++++++------
2 files changed, 13 insertions(+), 8 deletions(-)

Detailed changes

crates/git_ui/src/project_diff.rs 🔗

@@ -27,7 +27,7 @@ use workspace::{
 
 use crate::git_panel::GitPanel;
 
-actions!(git, [ShowUncommittedChanges]);
+actions!(git, [Diff]);
 
 pub(crate) struct ProjectDiff {
     multibuffer: Entity<MultiBuffer>,
@@ -63,7 +63,7 @@ impl ProjectDiff {
 
     fn deploy(
         workspace: &mut Workspace,
-        _: &ShowUncommittedChanges,
+        _: &Diff,
         window: &mut Window,
         cx: &mut Context<Workspace>,
     ) {

crates/language/src/buffer.rs 🔗

@@ -1914,12 +1914,17 @@ impl Buffer {
 
     /// Checks if the buffer has unsaved changes.
     pub fn is_dirty(&self) -> bool {
-        self.capability != Capability::ReadOnly
-            && (self.has_conflict
-                || self.file.as_ref().map_or(false, |file| {
-                    matches!(file.disk_state(), DiskState::New | DiskState::Deleted)
-                })
-                || self.has_unsaved_edits())
+        if self.capability == Capability::ReadOnly {
+            return false;
+        }
+        if self.has_conflict || self.has_unsaved_edits() {
+            return true;
+        }
+        match self.file.as_ref().map(|f| f.disk_state()) {
+            Some(DiskState::New) => !self.is_empty(),
+            Some(DiskState::Deleted) => true,
+            _ => false,
+        }
     }
 
     /// Checks if the buffer and its file have both changed since the buffer