@@ -199,19 +199,32 @@ fn source_diff_for_path(
199199 path : & str ,
200200 cached : bool ,
201201 ignore_whitespace_changes : bool ,
202+ is_untracked_worktree_file : bool ,
202203) -> Option < String > {
203204 let git_bin = resolve_git_binary ( ) . ok ( ) ?;
204205 let mut args = vec ! [ "diff" ] ;
205- if cached {
206- args. push ( "--cached" ) ;
207- }
208- args. push ( "--no-color" ) ;
209- args. push ( "-U0" ) ;
210- if ignore_whitespace_changes {
211- args. push ( "-w" ) ;
206+ if is_untracked_worktree_file && !cached {
207+ args. push ( "--no-index" ) ;
208+ args. push ( "--no-color" ) ;
209+ args. push ( "-U0" ) ;
210+ if ignore_whitespace_changes {
211+ args. push ( "-w" ) ;
212+ }
213+ args. push ( "--" ) ;
214+ args. push ( if cfg ! ( windows) { "NUL" } else { "/dev/null" } ) ;
215+ args. push ( path) ;
216+ } else {
217+ if cached {
218+ args. push ( "--cached" ) ;
219+ }
220+ args. push ( "--no-color" ) ;
221+ args. push ( "-U0" ) ;
222+ if ignore_whitespace_changes {
223+ args. push ( "-w" ) ;
224+ }
225+ args. push ( "--" ) ;
226+ args. push ( path) ;
212227 }
213- args. push ( "--" ) ;
214- args. push ( path) ;
215228
216229 let output = std_command ( git_bin)
217230 . args ( args)
@@ -370,7 +383,7 @@ fn map_new_to_old_line_clamped(hunks: &[ParsedPatchHunk], new_line: usize) -> us
370383 if new_line < insertion_point {
371384 break ;
372385 }
373- delta - = hunk. old_count as isize ;
386+ delta + = hunk. old_count as isize ;
374387 continue ;
375388 }
376389
@@ -719,6 +732,42 @@ mod display_hunk_tests {
719732
720733 assert ! ( display_hunks[ 0 ] . start_display_line_index < display_hunks[ 1 ] . start_display_line_index) ;
721734 }
735+
736+ #[ test]
737+ fn build_display_hunks_maps_unstaged_hunks_after_staged_deletions ( ) {
738+ let diff = concat ! (
739+ "@@ -2,1 +2,0 @@\n " ,
740+ "-line two\n " ,
741+ "@@ -5,1 +4,1 @@\n " ,
742+ "-line five\n " ,
743+ "+line five updated\n "
744+ ) ;
745+ let staged_diff = concat ! (
746+ "diff --git a/example.txt b/example.txt\n " ,
747+ "index 1111111..2222222 100644\n " ,
748+ "--- a/example.txt\n " ,
749+ "+++ b/example.txt\n " ,
750+ "@@ -2,1 +2,0 @@\n " ,
751+ "-line two\n "
752+ ) ;
753+ let unstaged_diff = concat ! (
754+ "diff --git a/example.txt b/example.txt\n " ,
755+ "index 2222222..3333333 100644\n " ,
756+ "--- a/example.txt\n " ,
757+ "+++ b/example.txt\n " ,
758+ "@@ -4,1 +4,1 @@\n " ,
759+ "-line five\n " ,
760+ "+line five updated\n "
761+ ) ;
762+
763+ let display_hunks = build_display_hunks ( diff, Some ( staged_diff) , Some ( unstaged_diff) ) ;
764+
765+ assert_eq ! ( display_hunks. len( ) , 2 ) ;
766+ assert_eq ! ( display_hunks[ 0 ] . id, "staged:2:1:2:0" ) ;
767+ assert_eq ! ( display_hunks[ 1 ] . id, "unstaged:4:1:4:1" ) ;
768+ assert_eq ! ( display_hunks[ 1 ] . start_display_line_index, 3 ) ;
769+ assert_eq ! ( display_hunks[ 1 ] . end_display_line_index, 4 ) ;
770+ }
722771}
723772
724773fn has_ignored_parent_directory ( repo : & Repository , path : & Path ) -> bool {
@@ -1132,11 +1181,15 @@ pub(super) async fn get_git_diffs_inner(
11321181 let is_image = old_image_mime. is_some ( ) || new_image_mime. is_some ( ) ;
11331182 let is_deleted = delta. status ( ) == git2:: Delta :: Deleted ;
11341183 let is_added = delta. status ( ) == git2:: Delta :: Added ;
1184+ let file_status = repo. status_file ( display_path) . unwrap_or ( Status :: empty ( ) ) ;
1185+ let is_untracked_worktree_file =
1186+ file_status. contains ( Status :: WT_NEW ) && !file_status. contains ( Status :: INDEX_NEW ) ;
11351187 let staged_diff = source_diff_for_path (
11361188 & repo_root,
11371189 normalized_path. as_str ( ) ,
11381190 true ,
11391191 ignore_whitespace_changes,
1192+ is_untracked_worktree_file,
11401193 )
11411194 . and_then ( |diff| {
11421195 if diff. trim ( ) . is_empty ( ) {
@@ -1150,6 +1203,7 @@ pub(super) async fn get_git_diffs_inner(
11501203 normalized_path. as_str ( ) ,
11511204 false ,
11521205 ignore_whitespace_changes,
1206+ is_untracked_worktree_file,
11531207 )
11541208 . and_then ( |diff| {
11551209 if diff. trim ( ) . is_empty ( ) {
0 commit comments