Skip to content

Commit 7cf4566

Browse files
angavrilovspearce
authored andcommitted
git-gui: Fix the after callback execution in rescan.
The rescan function receives a callback command as its parameter, which is supposed to be executed after the scan finishes. It is generally used to update status. However, rescan may initiate a loading of a diff, which always calls ui_ready after completion. If the after handler is called before that, ui_ready will override the new status. This commit ensures that the after callback is properly threaded through the diff machinery. Since it uncovered the fact that force_first_diff actually didn't work due to an undeclared global variable, and the desired effects appeared only because of the race condition between the diff system and the rescan callback, I also reimplement this function to make it behave as originally intended. Signed-off-by: Alexander Gavrilov <[email protected]> Signed-off-by: Shawn O. Pearce <[email protected]>
1 parent 153ad78 commit 7cf4566

File tree

2 files changed

+31
-16
lines changed

2 files changed

+31
-16
lines changed

git-gui.sh

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,10 +1491,8 @@ proc rescan_done {fd buf after} {
14911491
prune_selection
14921492
unlock_index
14931493
display_all_files
1494-
if {$current_diff_path ne {}} reshow_diff
1495-
if {$current_diff_path eq {}} select_first_diff
1496-
1497-
uplevel #0 $after
1494+
if {$current_diff_path ne {}} { reshow_diff $after }
1495+
if {$current_diff_path eq {}} { select_first_diff $after }
14981496
}
14991497
15001498
proc prune_selection {} {
@@ -2006,16 +2004,16 @@ proc do_rescan {} {
20062004
}
20072005
20082006
proc ui_do_rescan {} {
2009-
rescan {force_first_diff; ui_ready}
2007+
rescan {force_first_diff ui_ready}
20102008
}
20112009
20122010
proc do_commit {} {
20132011
commit_tree
20142012
}
20152013
2016-
proc next_diff {} {
2014+
proc next_diff {{after {}}} {
20172015
global next_diff_p next_diff_w next_diff_i
2018-
show_diff $next_diff_p $next_diff_w {}
2016+
show_diff $next_diff_p $next_diff_w {} {} $after
20192017
}
20202018
20212019
proc find_anchor_pos {lst name} {
@@ -2100,25 +2098,42 @@ proc next_diff_after_action {w path {lno {}} {mmask {}}} {
21002098
}
21012099
}
21022100
2103-
proc select_first_diff {} {
2101+
proc select_first_diff {after} {
21042102
global ui_workdir
21052103
21062104
if {[find_next_diff $ui_workdir {} 1 {^_?U}] ||
21072105
[find_next_diff $ui_workdir {} 1 {[^O]$}]} {
2108-
next_diff
2106+
next_diff $after
2107+
} else {
2108+
uplevel #0 $after
21092109
}
21102110
}
21112111
2112-
proc force_first_diff {} {
2113-
global current_diff_path
2112+
proc force_first_diff {after} {
2113+
global ui_workdir current_diff_path file_states
21142114
21152115
if {[info exists file_states($current_diff_path)]} {
21162116
set state [lindex $file_states($current_diff_path) 0]
2117+
} else {
2118+
set state {OO}
2119+
}
21172120
2118-
if {[string index $state 1] ne {O}} return
2121+
set reselect 0
2122+
if {[string first {U} $state] >= 0} {
2123+
# Already a conflict, do nothing
2124+
} elseif {[find_next_diff $ui_workdir $current_diff_path {} {^_?U}]} {
2125+
set reselect 1
2126+
} elseif {[string index $state 1] ne {O}} {
2127+
# Already a diff & no conflicts, do nothing
2128+
} elseif {[find_next_diff $ui_workdir $current_diff_path {} {[^O]$}]} {
2129+
set reselect 1
21192130
}
21202131
2121-
select_first_diff
2132+
if {$reselect} {
2133+
next_diff $after
2134+
} else {
2135+
uplevel #0 $after
2136+
}
21222137
}
21232138
21242139
proc toggle_or_diff {w x y} {

lib/diff.tcl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ proc clear_diff {} {
1616
$ui_workdir tag remove in_diff 0.0 end
1717
}
1818

19-
proc reshow_diff {} {
19+
proc reshow_diff {{after {}}} {
2020
global file_states file_lists
2121
global current_diff_path current_diff_side
2222
global ui_diff
@@ -30,13 +30,13 @@ proc reshow_diff {} {
3030
|| [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} {
3131

3232
if {[find_next_diff $current_diff_side $p {} {[^O]}]} {
33-
next_diff
33+
next_diff $after
3434
} else {
3535
clear_diff
3636
}
3737
} else {
3838
set save_pos [lindex [$ui_diff yview] 0]
39-
show_diff $p $current_diff_side {} $save_pos
39+
show_diff $p $current_diff_side {} $save_pos $after
4040
}
4141
}
4242

0 commit comments

Comments
 (0)