Skip to content

Commit 584fa9c

Browse files
angavrilovspearce
authored andcommitted
git-gui: Avoid an infinite rescan loop in handle_empty_diff.
If the index update machinery and git diff happen to disagree on whether a particular file is modified, it may cause git-gui to enter an infinite index rescan loop, where an empty diff starts a rescan, which finds the same set of files modified, and tries to display the diff for the first one, which happens to be the empty one. A current example of a possible disagreement point is the autocrlf filter. This patch breaks the loop by using a global counter to track the auto-rescans. The variable is reset whenever a non-empty diff is displayed. Another suggested approach, which is based on giving the --exit-code argument to git diff, cannot be used, because diff-files seems to trust the timestamps in the index, and returns a non-zero code even if the file is actually unchanged, which essentially defeats the purpose of the auto-rescan logic. Signed-off-by: Alexander Gavrilov <[email protected]> Signed-off-by: Shawn O. Pearce <[email protected]>
1 parent 06569cd commit 584fa9c

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

lib/diff.tcl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,16 @@ proc force_diff_encoding {enc} {
5151

5252
proc handle_empty_diff {} {
5353
global current_diff_path file_states file_lists
54+
global diff_empty_count
5455

5556
set path $current_diff_path
5657
set s $file_states($path)
5758
if {[lindex $s 0] ne {_M}} return
5859

60+
# Prevent infinite rescan loops
61+
incr diff_empty_count
62+
if {$diff_empty_count > 1} return
63+
5964
info_popup [mc "No differences detected.
6065
6166
%s has no changes.
@@ -310,6 +315,7 @@ proc read_diff {fd cont_info} {
310315
global ui_diff diff_active
311316
global is_3way_diff is_conflict_diff current_diff_header
312317
global current_diff_queue
318+
global diff_empty_count
313319

314320
$ui_diff conf -state normal
315321
while {[gets $fd line] >= 0} {
@@ -415,7 +421,10 @@ proc read_diff {fd cont_info} {
415421

416422
if {[$ui_diff index end] eq {2.0}} {
417423
handle_empty_diff
424+
} else {
425+
set diff_empty_count 0
418426
}
427+
419428
set callback [lindex $cont_info 1]
420429
if {$callback ne {}} {
421430
eval $callback

0 commit comments

Comments
 (0)