git: Don't load shallow HEAD text of symlinks (#25058)

Cole Miller created

For symlinks, return `None` from `load_committed_text` as we do from
`load_index_text` ever since #10037.

Release Notes:

- Fixed diff hunks appearing in unchanged symlinked files

Change summary

crates/git/src/repository.rs | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

Detailed changes

crates/git/src/repository.rs 🔗

@@ -84,12 +84,12 @@ pub trait GitRepository: Send + Sync {
 
     /// Returns the contents of an entry in the repository's index, or None if there is no entry for the given path.
     ///
-    /// Note that for symlink entries, this will return the contents of the symlink, not the target.
+    /// Also returns `None` for symlinks.
     fn load_index_text(&self, path: &RepoPath) -> Option<String>;
 
     /// Returns the contents of an entry in the repository's HEAD, or None if HEAD does not exist or has no entry for the given path.
     ///
-    /// Note that for symlink entries, this will return the contents of the symlink, not the target.
+    /// Also returns `None` for symlinks.
     fn load_committed_text(&self, path: &RepoPath) -> Option<String>;
 
     fn set_index_text(&self, path: &RepoPath, content: Option<String>) -> anyhow::Result<()>;
@@ -286,8 +286,11 @@ impl GitRepository for RealGitRepository {
     fn load_committed_text(&self, path: &RepoPath) -> Option<String> {
         let repo = self.repository.lock();
         let head = repo.head().ok()?.peel_to_tree().log_err()?;
-        let oid = head.get_path(path).ok()?.id();
-        let content = repo.find_blob(oid).log_err()?.content().to_owned();
+        let entry = head.get_path(path).ok()?;
+        if entry.filemode() == i32::from(git2::FileMode::Link) {
+            return None;
+        }
+        let content = repo.find_blob(entry.id()).log_err()?.content().to_owned();
         let content = String::from_utf8(content).log_err()?;
         Some(content)
     }