git-gui: Don't complain if no .git/remotes exist.
[gitweb.git] / git-gui
diff --git a/git-gui b/git-gui
index a43fb2f662f9ce1b0fc4f38a1158176ccb336b57..b8e7c8958639a54d57ac62fdb6099540fe7cbf7a 100755 (executable)
--- a/git-gui
+++ b/git-gui
@@ -92,7 +92,7 @@ proc update_status {{final Ready.}} {
        }
 
        if {![$ui_comm edit modified]
-           || [string trim [$ui_comm get 0.0 end]] == {}} {
+               || [string trim [$ui_comm get 0.0 end]] == {}} {
                if {[load_message GITGUI_MSG]} {
                } elseif {[load_message MERGE_MSG]} {
                } elseif {[load_message SQUASH_MSG]} {
@@ -591,25 +591,19 @@ proc commit_stage2 {fd_wt curHEAD msg} {
 proc fetch_from {remote} {
        set w [new_console "fetch $remote" \
                "Fetching new changes from $remote"]
-       set cmd [list git fetch]
-       lappend -v
+       set cmd [list git fetch]
+       lappend cmd -v
        lappend cmd $remote
-       lappend cmd |& cat
-       set fd_f [open $cmd r]
-       fconfigure $fd_f -blocking 0 -translation auto
-       fileevent $fd_f readable [list console_read $w $fd_f]
+       console_exec $w $cmd
 }
 
 proc push_to {remote} {
        set w [new_console "push $remote" \
                "Pushing changes to $remote"]
-       set cmd [list git push]
+       set cmd [list git push]
        lappend -v
        lappend cmd $remote
-       lappend cmd |& cat
-       set fd_f [open $cmd r]
-       fconfigure $fd_f -blocking 0 -translation auto
-       fileevent $fd_f readable [list console_read $w $fd_f]
+       console_exec $w $cmd
 }
 
 ######################################################################
@@ -803,8 +797,11 @@ proc load_all_remotes {} {
        set all_remotes [list]
        set rm_dir [file join $gitdir remotes]
        if {[file isdirectory $rm_dir]} {
-               set all_remotes [concat $all_remotes \
-                       [glob -types f -tails -directory $rm_dir * *]]
+               set all_remotes [concat $all_remotes [glob \
+                       -types f \
+                       -tails \
+                       -nocomplain \
+                       -directory $rm_dir *]]
        }
 
        set fd_rc [open "| git repo-config --list" r]
@@ -945,7 +942,7 @@ proc error_popup {msg} {
 }
 
 proc show_msg {w top msg} {
-       global gitdir appname
+       global gitdir appname mainfont
 
        message $w.m -text $msg -justify left -aspect 400
        pack $w.m -side top -fill x -padx 5 -pady 10
@@ -1008,9 +1005,11 @@ proc hook_failed_popup {hook msg} {
 set next_console_id 0
 
 proc new_console {short_title long_title} {
-       global next_console_id gitdir appname mainfont difffont
+       global next_console_id console_cr
+       global gitdir appname mainfont difffont
 
        set w .console[incr next_console_id]
+       set console_cr($w) 1.0
        toplevel $w
        frame $w.m
        label $w.m.l1 -text "$long_title:" \
@@ -1024,13 +1023,17 @@ proc new_console {short_title long_title} {
                -font $difffont \
                -state disabled \
                -yscrollcommand [list $w.m.sby set]
+       label $w.m.s -anchor w \
+               -justify left \
+               -font [concat $mainfont bold]
        scrollbar $w.m.sby -command [list $w.m.t yview]
        pack $w.m.l1 -side top -fill x
+       pack $w.m.s -side bottom -fill x
        pack $w.m.sby -side right -fill y
        pack $w.m.t -side left -fill both -expand 1
        pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10
 
-       button $w.ok -text {OK} \
+       button $w.ok -text {Running...} \
                -width 15 \
                -font $mainfont \
                -state disabled \
@@ -1043,18 +1046,68 @@ proc new_console {short_title long_title} {
        return $w
 }
 
+proc console_exec {w cmd} {
+       global tcl_platform
+
+       # -- Windows tosses the enviroment when we exec our child.
+       #    But most users need that so we have to relogin. :-(
+       #
+       if {$tcl_platform(platform) == {windows}} {
+               set cmd [list sh --login -c "cd \"[pwd]\" && [join $cmd { }]"]
+       }
+
+       # -- Tcl won't let us redirect both stdout and stderr to
+       #    the same pipe.  So pass it through cat...
+       #
+       set cmd [concat | $cmd |& cat]
+
+       set fd_f [open $cmd r]
+       fconfigure $fd_f -blocking 0 -translation binary
+       fileevent $fd_f readable [list console_read $w $fd_f]
+}
+
 proc console_read {w fd} {
+       global console_cr
+
        $w.m.t conf -state normal
-       while {[gets $fd line] >= 0} {
-               $w.m.t insert end $line
-               $w.m.t insert end "\n"
+       set buf [read $fd]
+       set c 0
+       set n [string length $buf]
+       while {$c < $n} {
+               set cr [string first "\r" $buf $c]
+               set lf [string first "\n" $buf $c]
+               if {$cr < 0} {set cr [expr $n + 1]}
+               if {$lf < 0} {set lf [expr $n + 1]}
+
+               if {$lf < $cr} {
+                       $w.m.t insert end [string range $buf $c $lf]
+                       set console_cr($w) [$w.m.t index {end -1c}]
+                       set c $lf
+                       incr c
+               } else {
+                       $w.m.t delete $console_cr($w) end
+                       $w.m.t insert end "\n"
+                       $w.m.t insert end [string range $buf $c $cr]
+                       set c $cr
+                       incr c
+               }
        }
        $w.m.t conf -state disabled
+       $w.m.t see end
 
+       fconfigure $fd -blocking 1
        if {[eof $fd]} {
-               close $fd
+               if {[catch {close $fd}]} {
+                       $w.m.s conf -background red -text {Error: Command Failed}
+               } else {
+                       $w.m.s conf -background green -text {Success}
+               }
+               $w.ok conf -text Close
                $w.ok conf -state normal
+               array unset console_cr $w
+               return
        }
+       fconfigure $fd -blocking 0
 }
 
 ######################################################################
@@ -1062,6 +1115,7 @@ proc console_read {w fd} {
 ## ui commands
 
 set starting_gitk_msg {Please wait... Starting gitk...}
+
 proc do_gitk {} {
        global tcl_platform ui_status_value starting_gitk_msg
 
@@ -1072,7 +1126,7 @@ proc do_gitk {} {
                }
        }
 
-    if {$tcl_platform(platform) == "windows"} {
+       if {$tcl_platform(platform) == {windows}} {
                exec sh -c gitk &
        } else {
                exec gitk &
@@ -1189,9 +1243,10 @@ set mainfont {Helvetica 10}
 set difffont {Courier 10}
 set maincursor [. cget -cursor]
 
-switch -- $tcl_platform(platform) {
-windows {set M1B Control; set M1T Ctrl}
-default {set M1B M1; set M1T M1}
+switch -glob -- "$tcl_platform(platform),$tcl_platform(os)" {
+windows,*   {set M1B Control; set M1T Ctrl}
+unix,Darwin {set M1B M1; set M1T Cmd}
+default     {set M1B M1; set M1T M1}
 }
 
 # -- Menu Bar
@@ -1427,17 +1482,19 @@ pack .status -anchor w -side bottom -fill x
 
 # -- Key Bindings
 bind $ui_comm <$M1B-Key-Return> {do_commit;break}
-bind . <Destroy> do_quit
-bind . <Key-F5> do_rescan
-bind . <$M1B-Key-r> do_rescan
-bind . <$M1B-Key-R> do_rescan
-bind . <$M1B-Key-s> do_signoff
-bind . <$M1B-Key-S> do_signoff
-bind . <$M1B-Key-u> do_checkin_all
-bind . <$M1B-Key-U> do_checkin_all
-bind . <$M1B-Key-Return> do_commit
-bind . <$M1B-Key-q> do_quit
-bind . <$M1B-Key-Q> do_quit
+bind .   <Destroy> do_quit
+bind all <Key-F5> do_rescan
+bind all <$M1B-Key-r> do_rescan
+bind all <$M1B-Key-R> do_rescan
+bind .   <$M1B-Key-s> do_signoff
+bind .   <$M1B-Key-S> do_signoff
+bind .   <$M1B-Key-u> do_checkin_all
+bind .   <$M1B-Key-U> do_checkin_all
+bind .   <$M1B-Key-Return> do_commit
+bind all <$M1B-Key-q> do_quit
+bind all <$M1B-Key-Q> do_quit
+bind all <$M1B-Key-w> {destroy [winfo toplevel %W]}
+bind all <$M1B-Key-W> {destroy [winfo toplevel %W]}
 foreach i [list $ui_index $ui_other] {
        bind $i <Button-1> {click %W %x %y 1 %X %Y; break}
        bind $i <Button-3> {click %W %x %y 3 %X %Y; break}
@@ -1449,17 +1506,23 @@ unset i M1B M1T
 ##
 ## main
 
-if {[catch {set gitdir [exec git rev-parse --git-dir]} err]} {
+set appname [lindex [file split $argv0] end]
+set gitdir {}
+
+if {[catch {set cdup [exec git rev-parse --show-cdup]} err]} {
        show_msg {} . "Cannot find the git directory: $err"
        exit 1
 }
-set cdup [exec git rev-parse --show-cdup]
 if {$cdup != ""} {
        cd $cdup
 }
 unset cdup
 
-set appname [lindex [file split $argv0] end]
+if {[catch {set gitdir [exec git rev-parse --git-dir]} err]} {
+       show_msg {} . "Cannot find the git directory: $err"
+       exit 1
+}
+
 if {$appname == {git-citool}} {
        set single_commit 1
 }