Skip to content

Commit f823de7

Browse files
committed
git-gui: Remove forced rescan of stat-dirty files.
It is possible that stat information of tracked files is modified without actually modifying the content. Plumbing commands would detect such files as modified, so that Git GUI runs `git update-info --refresh` in order to synchronize the cached stat info with the reality. However, this can be an expensive operation in large repositories. As remediation, e534f3a (git-gui: Allow the user to disable update-index --refresh during rescan, 2006-11-07) introduced an option to skip the expensive part. The option was named "trust file modification timestamp". But the catch is that sometimes file timestamps can't be trusted. In this case, a file would remain listed in Unstaged Changes although there are no changes. So 16403d0 (git-gui: Refresh a file if it has an empty diff, 2006-11-11) introduced a popup message informing the user about the situation and then removed the file from the Unstaged Changes list. Now users had to click away the message box for every file that was stat-dirty. Under the assumption that a file in such a state is not the only one, 124355d (git-gui: Always start a rescan on an empty diff, 2007-01-22) introduced a forced (potentially expensive) refresh that would de-list all stat-dirty files after the first notification was dismissed. Along came 6c510be (Lazy man's auto-CRLF, 2007-02-13) in Git. It introduced a new case where a file in the worktree can have no essential differences to the staged version, but still be detected as modified by plumbing commands. This time, however, the index cannot be synchronized fully by `git update-index --refresh`, so that the file remains listed in Unstaged Changes until it is staged manually. Needless to say that the message box now becomes an annoyance, because it must be dismissed every time an affected file is selected, and the file remains listed nevertheless. Remove the message box. Write the notice that no differences were found in the diff panel instead. Also include a link that, when clicked, initiates the rescan. With this scheme, the rescan does not happen automatically anymore, but requires an additional click. (This is now two clicks in total for users who encounter stat-dirty files after enabling the "trust file modification timestamps" option.) However, users whom the rescan does not help (autocrlf-related dirty files) save half the clicks because there is no message box to dismiss. Signed-off-by: Johannes Sixt <[email protected]>
1 parent 2864e85 commit f823de7

File tree

2 files changed

+8
-21
lines changed

2 files changed

+8
-21
lines changed

git-gui.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1357,7 +1357,6 @@ set current_diff_path {}
13571357
set is_3way_diff 0
13581358
set is_submodule_diff 0
13591359
set is_conflict_diff 0
1360-
set diff_empty_count 0
13611360
set last_revert {}
13621361
set last_revert_enc {}
13631362

@@ -3594,6 +3593,8 @@ $ui_diff tag configure clr1 -font font_diffbold
35943593
$ui_diff tag configure clr4 -underline 1
35953594

35963595
$ui_diff tag conf d_info -foreground blue -font font_diffbold
3596+
$ui_diff tag conf d_rescan -foreground blue -underline 1 -font font_diffbold
3597+
$ui_diff tag bind d_rescan <Button-1> { clear_diff; rescan ui_ready 0 }
35973598

35983599
$ui_diff tag conf d_cr -elide true
35993600
$ui_diff tag conf d_@ -font font_diffbold

lib/diff.tcl

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -63,28 +63,17 @@ proc force_diff_encoding {enc} {
6363
}
6464

6565
proc handle_empty_diff {} {
66-
global current_diff_path file_states file_lists
67-
global diff_empty_count
66+
global current_diff_path file_states
67+
global ui_diff
6868

6969
set path $current_diff_path
7070
set s $file_states($path)
7171
if {[lindex $s 0] ne {_M} || [has_textconv $path]} return
7272

73-
# Prevent infinite rescan loops
74-
incr diff_empty_count
75-
if {$diff_empty_count > 1} return
76-
77-
info_popup [mc "No differences detected.
78-
79-
%s has no changes.
80-
81-
The modification date of this file was updated by another application, but the content within the file was not changed.
82-
83-
A rescan will be automatically started to find other files which may have the same state." [short_path $path]]
84-
85-
clear_diff
86-
display_file $path __
87-
rescan ui_ready 0
73+
$ui_diff conf -state normal
74+
$ui_diff insert end [mc "* No differences detected; stage the file to de-list it from Unstaged Changes.\n"] d_info
75+
$ui_diff insert end [mc "* Click to find other files that may have the same state.\n"] d_rescan
76+
$ui_diff conf -state disabled
8877
}
8978

9079
proc show_diff {path w {lno {}} {scroll_pos {}} {callback {}}} {
@@ -387,7 +376,6 @@ proc read_diff {fd conflict_size cont_info} {
387376
global ui_diff diff_active is_submodule_diff
388377
global is_3way_diff is_conflict_diff current_diff_header
389378
global current_diff_queue
390-
global diff_empty_count
391379

392380
$ui_diff conf -state normal
393381
while {[gets $fd line] >= 0} {
@@ -559,8 +547,6 @@ proc read_diff {fd conflict_size cont_info} {
559547

560548
if {[$ui_diff index end] eq {2.0}} {
561549
handle_empty_diff
562-
} else {
563-
set diff_empty_count 0
564550
}
565551

566552
set callback [lindex $cont_info 1]

0 commit comments

Comments
 (0)