git-gui: Limit display of large untracked files.
authorShawn O. Pearce <spearce@spearce.org>
Tue, 23 Jan 2007 07:33:58 +0000 (02:33 -0500)
committerShawn O. Pearce <spearce@spearce.org>
Tue, 23 Jan 2007 07:33:58 +0000 (02:33 -0500)
Our internal diff viewer displays untracked files to help users see if
they should become tracked, or not.  It is not meant as a full file
viewer that handles any sort of input.  Consequently it is rather
unreasonable for users to expect us to show them very large files.
Some users may click on a very big file (and not know its very big)
then get surprised when Tk takes a long time to load the content and
render it, especially if their memory is tight and their OS starts to
swap processes out.

Instead we now limit the amount of data we load to the first 128 KiB
of any untracked file.  If the file is larger than 128 KiB we display
a warning message at the top of our diff viewer to notify the user
that we are not going to load the entire thing.  Users should be able
to recognize a file just by its first 128 KiB and determine if it
should be added to the repository or not.

Since we are loading 128 KiB we may as well scan it to see if the
file is binary.  So I've removed the "first 8000 bytes" rule and
just allowed git-gui to scan the entire data chunk that it read in.
This is probably faster anyway if Tcl's [string range] command winds
up making a copy of the data.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui.sh

index 9136e7fe9844f57b106280e4d9e033adb7a9f64c..f71dabe68a684c3888c53d9fa9d9993910719674 100755 (executable)
@@ -626,10 +626,12 @@ proc show_diff {path w {lno {}}} {
        # - Git won't give us the diff, there's nothing to compare to!
        #
        if {$m eq {_O}} {
+               set max_sz [expr {128 * 1024}]
                if {[catch {
                                set fd [open $path r]
-                               set content [read $fd]
+                               set content [read $fd $max_sz]
                                close $fd
+                               set sz [file size $path]
                        } err ]} {
                        set diff_active 0
                        unlock_index
@@ -637,11 +639,27 @@ proc show_diff {path w {lno {}}} {
                        error_popup "Error loading file:\n\n$err"
                        return
                }
-               if {[string first "\0" [string range $content 0 8000]] != -1} {
-                       set content {* Binary file (not showing content).}
-               }
                $ui_diff conf -state normal
-               $ui_diff insert end $content
+               if {[string first "\0" $content] != -1} {
+                       $ui_diff insert end \
+                               "* Binary file (not showing content)." \
+                               d_@
+               } else {
+                       if {$sz > $max_sz} {
+                               $ui_diff insert end \
+"* Untracked file is $sz bytes.
+* Showing only first $max_sz bytes.
+
+" d_@
+                       }
+                       $ui_diff insert end $content
+                       if {$sz > $max_sz} {
+                               $ui_diff insert end "
+* Untracked file clipped here by [appname].
+* To see the entire file, use an external editor.
+" d_@
+                       }
+               }
                $ui_diff conf -state disabled
                set diff_active 0
                unlock_index