@matheusbsbs / matheus-bagliano / commits / 584fa9ccf4
Fork 0

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 <angavrilov@gmail.com> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>

Alexander Gavrilov committed Feb 7, 2009 at 19:24 UTC 584fa9ccf4b467e7633c100333cadf92e0c07894
1 file changed +9
lib/diff.tcl
+9
@@ -51,11 +51,16 @@ proc force_diff_encoding {enc} {
51
52 proc handle_empty_diff {} {
53 global current_diff_path file_states file_lists
54 + global diff_empty_count
55
56 set path $current_diff_path
57 set s $file_states($path)
58 if {[lindex $s 0] ne {_M}} return
59
60 + # Prevent infinite rescan loops
61 + incr diff_empty_count
62 + if {$diff_empty_count > 1} return
63 +
64 info_popup [mc "No differences detected.
65
66 %s has no changes.
@@ -310,6 +315,7 @@ proc read_diff {fd cont_info} {
315 global ui_diff diff_active
316 global is_3way_diff is_conflict_diff current_diff_header
317 global current_diff_queue
318 + global diff_empty_count
319
320 $ui_diff conf -state normal
321 while {[gets $fd line] >= 0} {
@@ -415,7 +421,10 @@ proc read_diff {fd cont_info} {
421
422 if {[$ui_diff index end] eq {2.0}} {
423 handle_empty_diff
424 + } else {
425 + set diff_empty_count 0
426 }
427 +
428 set callback [lindex $cont_info 1]
429 if {$callback ne {}} {
430 eval $callback