From: Alexander Gavrilov <angavrilov@gmail.com>
To: git@vger.kernel.org
Cc: "Shawn O. Pearce" <spearce@spearce.org>
Subject: [PATCH (GIT-GUI) v2 2/5] git-gui: Fix the after callback execution in rescan.
Date: Sun, 16 Nov 2008 21:46:48 +0300 [thread overview]
Message-ID: <1226861211-16995-3-git-send-email-angavrilov@gmail.com> (raw)
In-Reply-To: <1226861211-16995-2-git-send-email-angavrilov@gmail.com>
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>
---
git-gui.sh | 41 ++++++++++++++++++++++++++++-------------
lib/diff.tcl | 6 +++---
2 files changed, 31 insertions(+), 16 deletions(-)
diff --git a/git-gui.sh b/git-gui.sh
index 34214b6..2709f6e 100755
--- a/git-gui.sh
+++ b/git-gui.sh
@@ -1469,10 +1469,8 @@ proc rescan_done {fd buf after} {
prune_selection
unlock_index
display_all_files
- if {$current_diff_path ne {}} reshow_diff
- if {$current_diff_path eq {}} select_first_diff
-
- uplevel #0 $after
+ if {$current_diff_path ne {}} { reshow_diff $after }
+ if {$current_diff_path eq {}} { select_first_diff $after }
}
proc prune_selection {} {
@@ -1984,16 +1982,16 @@ proc do_rescan {} {
}
proc ui_do_rescan {} {
- rescan {force_first_diff; ui_ready}
+ rescan {force_first_diff ui_ready}
}
proc do_commit {} {
commit_tree
}
-proc next_diff {} {
+proc next_diff {{after {}}} {
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} {
@@ -2078,25 +2076,42 @@ proc next_diff_after_action {w path {lno {}} {mmask {}}} {
}
}
-proc select_first_diff {} {
+proc select_first_diff {after} {
global ui_workdir
if {[find_next_diff $ui_workdir {} 1 {^_?U}] ||
[find_next_diff $ui_workdir {} 1 {[^O]$}]} {
- next_diff
+ next_diff $after
+ } else {
+ uplevel #0 $after
}
}
-proc force_first_diff {} {
- global current_diff_path
+proc force_first_diff {after} {
+ global ui_workdir current_diff_path file_states
if {[info exists file_states($current_diff_path)]} {
set state [lindex $file_states($current_diff_path) 0]
+ } else {
+ set state {OO}
+ }
- if {[string index $state 1] ne {O}} return
+ 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
}
- select_first_diff
+ if {$reselect} {
+ next_diff $after
+ } else {
+ uplevel #0 $after
+ }
}
proc toggle_or_diff {w x y} {
diff --git a/lib/diff.tcl b/lib/diff.tcl
index 94ee38c..bbbf15c 100644
--- a/lib/diff.tcl
+++ b/lib/diff.tcl
@@ -16,7 +16,7 @@ proc clear_diff {} {
$ui_workdir tag remove in_diff 0.0 end
}
-proc reshow_diff {} {
+proc reshow_diff {{after {}}} {
global file_states file_lists
global current_diff_path current_diff_side
global ui_diff
@@ -30,13 +30,13 @@ proc reshow_diff {} {
|| [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} {
if {[find_next_diff $current_diff_side $p {} {[^O]}]} {
- next_diff
+ next_diff $after
} else {
clear_diff
}
} else {
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
}
}
--
1.6.0.3.15.gb8d36
next prev parent reply other threads:[~2008-11-16 18:50 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-16 18:46 [PATCH (GIT-GUI) v2 0/5] Add a customizable Tools menu Alexander Gavrilov
2008-11-16 18:46 ` [PATCH (GIT-GUI) v2 1/5] git-gui: Implement system-wide configuration handling Alexander Gavrilov
2008-11-16 18:46 ` Alexander Gavrilov [this message]
2008-11-16 18:46 ` [PATCH (GIT-GUI) v2 3/5] git-gui: Add a Tools menu for arbitrary commands Alexander Gavrilov
2008-11-16 18:46 ` [PATCH (GIT-GUI) v2 4/5] git-gui: Allow Tools request arguments from the user Alexander Gavrilov
2008-11-16 18:46 ` [PATCH (GIT-GUI) v2 5/5] git-gui: Implement automatic rescan after Tool execution Alexander Gavrilov
2008-11-16 21:56 ` [PATCH (GIT-GUI) v2 0/5] Add a customizable Tools menu Shawn O. Pearce
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1226861211-16995-3-git-send-email-angavrilov@gmail.com \
--to=angavrilov@gmail.com \
--cc=git@vger.kernel.org \
--cc=spearce@spearce.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).