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 <angavrilov@gmail.com> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
153ad78b50
commit
7cf4566f48
43
git-gui.sh
43
git-gui.sh
@ -1491,10 +1491,8 @@ proc rescan_done {fd buf after} {
|
|||||||
prune_selection
|
prune_selection
|
||||||
unlock_index
|
unlock_index
|
||||||
display_all_files
|
display_all_files
|
||||||
if {$current_diff_path ne {}} reshow_diff
|
if {$current_diff_path ne {}} { reshow_diff $after }
|
||||||
if {$current_diff_path eq {}} select_first_diff
|
if {$current_diff_path eq {}} { select_first_diff $after }
|
||||||
|
|
||||||
uplevel #0 $after
|
|
||||||
}
|
}
|
||||||
|
|
||||||
proc prune_selection {} {
|
proc prune_selection {} {
|
||||||
@ -2006,16 +2004,16 @@ proc do_rescan {} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc ui_do_rescan {} {
|
proc ui_do_rescan {} {
|
||||||
rescan {force_first_diff; ui_ready}
|
rescan {force_first_diff ui_ready}
|
||||||
}
|
}
|
||||||
|
|
||||||
proc do_commit {} {
|
proc do_commit {} {
|
||||||
commit_tree
|
commit_tree
|
||||||
}
|
}
|
||||||
|
|
||||||
proc next_diff {} {
|
proc next_diff {{after {}}} {
|
||||||
global next_diff_p next_diff_w next_diff_i
|
global next_diff_p next_diff_w next_diff_i
|
||||||
show_diff $next_diff_p $next_diff_w {}
|
show_diff $next_diff_p $next_diff_w {} {} $after
|
||||||
}
|
}
|
||||||
|
|
||||||
proc find_anchor_pos {lst name} {
|
proc find_anchor_pos {lst name} {
|
||||||
@ -2100,25 +2098,42 @@ proc next_diff_after_action {w path {lno {}} {mmask {}}} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proc select_first_diff {} {
|
proc select_first_diff {after} {
|
||||||
global ui_workdir
|
global ui_workdir
|
||||||
|
|
||||||
if {[find_next_diff $ui_workdir {} 1 {^_?U}] ||
|
if {[find_next_diff $ui_workdir {} 1 {^_?U}] ||
|
||||||
[find_next_diff $ui_workdir {} 1 {[^O]$}]} {
|
[find_next_diff $ui_workdir {} 1 {[^O]$}]} {
|
||||||
next_diff
|
next_diff $after
|
||||||
|
} else {
|
||||||
|
uplevel #0 $after
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proc force_first_diff {} {
|
proc force_first_diff {after} {
|
||||||
global current_diff_path
|
global ui_workdir current_diff_path file_states
|
||||||
|
|
||||||
if {[info exists file_states($current_diff_path)]} {
|
if {[info exists file_states($current_diff_path)]} {
|
||||||
set state [lindex $file_states($current_diff_path) 0]
|
set state [lindex $file_states($current_diff_path) 0]
|
||||||
|
} else {
|
||||||
if {[string index $state 1] ne {O}} return
|
set state {OO}
|
||||||
}
|
}
|
||||||
|
|
||||||
select_first_diff
|
set reselect 0
|
||||||
|
if {[string first {U} $state] >= 0} {
|
||||||
|
# Already a conflict, do nothing
|
||||||
|
} elseif {[find_next_diff $ui_workdir $current_diff_path {} {^_?U}]} {
|
||||||
|
set reselect 1
|
||||||
|
} elseif {[string index $state 1] ne {O}} {
|
||||||
|
# Already a diff & no conflicts, do nothing
|
||||||
|
} elseif {[find_next_diff $ui_workdir $current_diff_path {} {[^O]$}]} {
|
||||||
|
set reselect 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if {$reselect} {
|
||||||
|
next_diff $after
|
||||||
|
} else {
|
||||||
|
uplevel #0 $after
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proc toggle_or_diff {w x y} {
|
proc toggle_or_diff {w x y} {
|
||||||
|
@ -16,7 +16,7 @@ proc clear_diff {} {
|
|||||||
$ui_workdir tag remove in_diff 0.0 end
|
$ui_workdir tag remove in_diff 0.0 end
|
||||||
}
|
}
|
||||||
|
|
||||||
proc reshow_diff {} {
|
proc reshow_diff {{after {}}} {
|
||||||
global file_states file_lists
|
global file_states file_lists
|
||||||
global current_diff_path current_diff_side
|
global current_diff_path current_diff_side
|
||||||
global ui_diff
|
global ui_diff
|
||||||
@ -30,13 +30,13 @@ proc reshow_diff {} {
|
|||||||
|| [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} {
|
|| [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} {
|
||||||
|
|
||||||
if {[find_next_diff $current_diff_side $p {} {[^O]}]} {
|
if {[find_next_diff $current_diff_side $p {} {[^O]}]} {
|
||||||
next_diff
|
next_diff $after
|
||||||
} else {
|
} else {
|
||||||
clear_diff
|
clear_diff
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
set save_pos [lindex [$ui_diff yview] 0]
|
set save_pos [lindex [$ui_diff yview] 0]
|
||||||
show_diff $p $current_diff_side {} $save_pos
|
show_diff $p $current_diff_side {} $save_pos $after
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user