From: Alexander Gavrilov <angavrilov@gmail.com>
To: git@vger.kernel.org
Cc: "Shawn O. Pearce" <spearce@spearce.org>,
Junio C Hamano <gitster@pobox.com>,
Andy Davey <as.davey@gmail.com>,
kbro <kevin.broadey@googlemail.com>
Subject: [RFC PATCH (GIT-GUI/CORE BUG)] git-gui: Avoid an infinite rescan loop in handle_empty_diff.
Date: Sat, 24 Jan 2009 00:52:57 +0300 [thread overview]
Message-ID: <200901240052.58259.angavrilov@gmail.com> (raw)
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 variable to track
the auto-rescans. The variable is reset whenever a non-empty
diff is displayed. As a way to work around the malfunctioning
index rescan command, it resurrects the pre-0.6.0 code that
directly updates only the affected file.
Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
---
Note that if the file is actually modified, and the bug is
either in git-diff or the way git-gui calls it, this patch
will stage the file without displaying it in the UI. Thus, it
may be better to simply do nothing if the loop prevention
logic triggers.
On Jan 22, 11:31 pm, kbro <kevin.broa...@googlemail.com> wrote:
> However, for me it was worse as the "No differences" message popped up
> as soon as I opened git-gui, and the dialog said it would run a rescan
> to find all files in a similar state. The rescan caused the same
> error to be detected again, so I could never get the dialog box to go
> away.
On Friday 23 January 2009 02:56:23 Andy Davey wrote:
> I had the exact same problem you described running git-1.6.1-
> preview20081227 on Windows XP as well. (the endless loop of dialog box
> is very frustrating).
P.S. Steps to reproduce the autocrlf handling mismatch on Linux:
$ git init
$ echo > foo
$ git add foo && git commit -m init
$ unix2dos -o foo
$ git config core.autocrlf true
$ git status
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: foo
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git diff foo
diff --git a/foo b/foo
It happens because git-status assumes that a change in
file size always means that the file contents have changed.
Content filters like autocrlf may invalidate this assumption.
lib/diff.tcl | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)
diff --git a/lib/diff.tcl b/lib/diff.tcl
index bbbf15c..e5abb49 100644
--- a/lib/diff.tcl
+++ b/lib/diff.tcl
@@ -51,6 +51,7 @@ proc force_diff_encoding {enc} {
proc handle_empty_diff {} {
global current_diff_path file_states file_lists
+ global last_empty_diff
set path $current_diff_path
set s $file_states($path)
@@ -66,7 +67,17 @@ A rescan will be automatically started to find other files which may have the sa
clear_diff
display_file $path __
- rescan ui_ready 0
+
+ if {![info exists last_empty_diff]} {
+ set last_empty_diff $path
+ rescan ui_ready 0
+ } else {
+ # We already tried rescanning recently, and it failed,
+ # so resort to updating this particular file.
+ if {[catch {git update-index -- $path} err]} {
+ error_popup [mc "Failed to refresh index:\n\n%s" $err]
+ }
+ }
}
proc show_diff {path w {lno {}} {scroll_pos {}} {callback {}}} {
@@ -310,6 +321,7 @@ proc read_diff {fd cont_info} {
global ui_diff diff_active
global is_3way_diff is_conflict_diff current_diff_header
global current_diff_queue
+ global last_empty_diff
$ui_diff conf -state normal
while {[gets $fd line] >= 0} {
@@ -415,6 +427,8 @@ proc read_diff {fd cont_info} {
if {[$ui_diff index end] eq {2.0}} {
handle_empty_diff
+ } else {
+ catch { unset last_empty_diff }
}
set callback [lindex $cont_info 1]
if {$callback ne {}} {
--
1.6.1.63.g950db
next reply other threads:[~2009-01-23 21:53 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-23 21:52 Alexander Gavrilov [this message]
2009-01-24 1:46 ` [RFC PATCH (GIT-GUI/CORE BUG)] git-gui: Avoid an infinite rescan loop in handle_empty_diff Keith Cascio
2009-01-24 3:29 ` Junio C Hamano
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=200901240052.58259.angavrilov@gmail.com \
--to=angavrilov@gmail.com \
--cc=as.davey@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=kevin.broadey@googlemail.com \
--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).