Merge branch 'maint' of git://repo.or.cz/git-gui into maint
authorJunio C Hamano <gitster@pobox.com>
Tue, 18 Sep 2007 06:50:17 +0000 (23:50 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 18 Sep 2007 06:50:17 +0000 (23:50 -0700)
* 'maint' of git://repo.or.cz/git-gui:
  git-gui: Disable native platform text selection in "lists"
  git-gui: Paper bag fix "Commit->Revert" format arguments
  git-gui: Provide 'uninstall' Makefile target to undo an installation
  git-gui: Font chooser to handle a large number of font families
  git-gui: Make backporting changes from i18n version easier
  git-gui: Don't delete send on Windows as it doesn't exist
  git-gui: Trim trailing slashes from untracked submodule names
  git-gui: Assume untracked directories are Git submodules
  git-gui: handle "deleted symlink" diff marker
  git-gui: show unstaged symlinks in diff viewer
  git-gui: Avoid use of libdir in Makefile
  git-gui: Disable Tk send in all git-gui sessions
  git-gui: lib/index.tcl: handle files with % in the filename properly
  git-gui: Properly set the state of "Stage/Unstage Hunk" action
  git-gui: Fix detaching current branch during checkout
  git-gui: Correct starting of git-remote to handle -w option

git-gui/Makefile
git-gui/git-gui.sh
git-gui/lib/browser.tcl
git-gui/lib/checkout_op.tcl
git-gui/lib/choose_font.tcl [new file with mode: 0644]
git-gui/lib/diff.tcl
git-gui/lib/index.tcl
git-gui/lib/option.tcl

index 1bac6fe..18e6750 100644 (file)
@@ -31,6 +31,9 @@ ifndef INSTALL
        INSTALL = install
 endif
 
+RM_F      ?= rm -f
+RMDIR     ?= rmdir
+
 INSTALL_D0 = $(INSTALL) -d -m755 # space is required here
 INSTALL_D1 =
 INSTALL_R0 = $(INSTALL) -m644 # space is required here
@@ -42,6 +45,12 @@ INSTALL_L1 = && ln # space is required here
 INSTALL_L2 =
 INSTALL_L3 =
 
+REMOVE_D0  = $(RMDIR) # space is required here
+REMOVE_D1  = || true
+REMOVE_F0  = $(RM_F) # space is required here
+REMOVE_F1  =
+CLEAN_DST  = true
+
 ifndef V
        QUIET          = @
        QUIET_GEN      = $(QUIET)echo '   ' GEN $@ &&
@@ -60,6 +69,12 @@ ifndef V
        INSTALL_L1 = && src=
        INSTALL_L2 = && dst=
        INSTALL_L3 = && echo '   ' 'LINK       ' `basename "$$dst"` '->' `basename "$$src"` && rm -f "$$dst" && ln "$$src" "$$dst"
+
+       CLEAN_DST = echo ' ' UNINSTALL
+       REMOVE_D0 = dir=
+       REMOVE_D1 = && echo ' ' REMOVE $$dir && test -d "$$dir" && $(RMDIR) "$$dir" || true
+       REMOVE_F0 = dst=
+       REMOVE_F1 = && echo '   ' REMOVE `basename "$$dst"` && $(RM_F) "$$dst"
 endif
 
 TCL_PATH   ?= tclsh
@@ -76,8 +91,8 @@ SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
 TCL_PATH_SQ = $(subst ','\'',$(TCL_PATH))
 TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
 
-libdir   ?= $(sharedir)/git-gui/lib
-libdir_SQ = $(subst ','\'',$(libdir))
+gg_libdir ?= $(sharedir)/git-gui/lib
+libdir_SQ  = $(subst ','\'',$(gg_libdir))
 
 exedir    = $(dir $(gitexecdir))share/git-gui/lib
 exedir_SQ = $(subst ','\'',$(exedir))
@@ -126,7 +141,7 @@ TRACK_VARS = \
        $(subst ','\'',TCL_PATH='$(TCL_PATH_SQ)') \
        $(subst ','\'',TCLTK_PATH='$(TCLTK_PATH_SQ)') \
        $(subst ','\'',gitexecdir='$(gitexecdir_SQ)') \
-       $(subst ','\'',libdir='$(libdir_SQ)') \
+       $(subst ','\'',gg_libdir='$(libdir_SQ)') \
 #end TRACK_VARS
 
 GIT-GUI-VARS: .FORCE-GIT-GUI-VARS
@@ -146,6 +161,17 @@ install: all
        $(QUIET)$(INSTALL_R0)lib/tclIndex $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)'
        $(QUIET)$(foreach p,$(ALL_LIBFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' &&) true
 
+uninstall:
+       $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
+       $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui $(REMOVE_F1)
+       $(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/$p $(REMOVE_F1) &&) true
+       $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(libdir_SQ)'
+       $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/tclIndex $(REMOVE_F1)
+       $(QUIET)$(foreach p,$(ALL_LIBFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true
+       $(QUIET)$(REMOVE_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(REMOVE_D1)
+       $(QUIET)$(REMOVE_D0)'$(DESTDIR_SQ)$(libdir_SQ)' $(REMOVE_D1)
+       $(QUIET)$(REMOVE_D0)`dirname '$(DESTDIR_SQ)$(libdir_SQ)'` $(REMOVE_D1)
+
 dist-version:
        @mkdir -p $(TARDIR)
        @echo $(GITGUI_VERSION) > $(TARDIR)/version
@@ -154,6 +180,6 @@ clean::
        rm -f $(ALL_PROGRAMS) lib/tclIndex
        rm -f GIT-VERSION-FILE GIT-GUI-VARS
 
-.PHONY: all install dist-version clean
+.PHONY: all install uninstall dist-version clean
 .PHONY: .FORCE-GIT-VERSION-FILE
 .PHONY: .FORCE-GIT-GUI-VARS
index fa30ccc..f789e91 100755 (executable)
@@ -42,6 +42,8 @@ if {[catch {package require Tcl 8.4} err]
        exit 1
 }
 
+catch {rename send {}} ; # What an evil concept...
+
 ######################################################################
 ##
 ## enable verbose loading?
@@ -60,6 +62,18 @@ if {![catch {set _verbose $env(GITGUI_VERBOSE)}]} {
        }
 }
 
+######################################################################
+##
+## Fake internationalization to ease backporting of changes.
+
+proc mc {fmt args} {
+       set cmk [string first @@ $fmt]
+       if {$cmk > 0} {
+               set fmt [string range $fmt 0 [expr {$cmk - 1}]]
+       }
+       return [eval [list format $fmt] $args]
+}
+
 ######################################################################
 ##
 ## read only globals
@@ -261,7 +275,7 @@ proc _git_cmd {name} {
                        set s [gets $f]
                        close $f
 
-                       switch -glob -- $s {
+                       switch -glob -- [lindex $s 0] {
                        #!*sh     { set i sh     }
                        #!*perl   { set i perl   }
                        #!*python { set i python }
@@ -275,7 +289,7 @@ proc _git_cmd {name} {
                        if {$interp eq {}} {
                                error "git-$name requires $i (not in PATH)"
                        }
-                       set v [list $interp $p]
+                       set v [concat [list $interp] [lrange $s 1 end] [list $p]]
                } else {
                        # Assume it is builtin to git somehow and we
                        # aren't actually able to see a file for it.
@@ -467,6 +481,16 @@ proc tk_optionMenu {w varName args} {
        return $m
 }
 
+proc rmsel_tag {text} {
+       $text tag conf sel \
+               -background [$text cget -background] \
+               -foreground [$text cget -foreground] \
+               -borderwidth 0
+       $text tag conf in_sel -background lightgray
+       bind $text <Motion> break
+       return $text
+}
+
 ######################################################################
 ##
 ## find git
@@ -1008,7 +1032,11 @@ proc read_ls_others {fd after} {
        set pck [split $buf_rlo "\0"]
        set buf_rlo [lindex $pck end]
        foreach p [lrange $pck 0 end-1] {
-               merge_state [encoding convertfrom $p] ?O
+               set p [encoding convertfrom $p]
+               if {[string index $p end] eq {/}} {
+                       set p [string range $p 0 end-1]
+               }
+               merge_state $p ?O
        }
        rescan_done $fd buf_rlo $after
 }
@@ -2133,8 +2161,8 @@ pack $ui_workdir -side left -fill both -expand 1
 .vpane.files add .vpane.files.workdir -sticky nsew
 
 foreach i [list $ui_index $ui_workdir] {
-       $i tag conf in_diff -background lightgray
-       $i tag conf in_sel  -background lightgray
+       rmsel_tag $i
+       $i tag conf in_diff -background [$i tag cget in_sel -background]
 }
 unset i
 
@@ -2441,20 +2469,17 @@ proc popup_diff_menu {ctxm x y X Y} {
        set ::cursorX $x
        set ::cursorY $y
        if {$::ui_index eq $::current_diff_side} {
-               set s normal
                set l "Unstage Hunk From Commit"
        } else {
-               if {$current_diff_path eq {}
-                       || ![info exists file_states($current_diff_path)]
-                       || {_O} eq [lindex $file_states($current_diff_path) 0]} {
-                       set s disabled
-               } else {
-                       set s normal
-               }
                set l "Stage Hunk For Commit"
        }
-       if {$::is_3way_diff} {
+       if {$::is_3way_diff
+               || $current_diff_path eq {}
+               || ![info exists file_states($current_diff_path)]
+               || {_O} eq [lindex $file_states($current_diff_path) 0]} {
                set s disabled
+       } else {
+               set s normal
        }
        $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l
        tk_popup $ctxm $X $Y
index 888db3c..3134900 100644 (file)
@@ -47,9 +47,7 @@ constructor new {commit {path {}}} {
                -width 70 \
                -xscrollcommand [list $w.list.sbx set] \
                -yscrollcommand [list $w.list.sby set]
-       $w_list tag conf in_sel \
-               -background [$w_list cget -foreground] \
-               -foreground [$w_list cget -background]
+       rmsel_tag $w_list
        scrollbar $w.list.sbx -orient h -command [list $w_list xview]
        scrollbar $w.list.sby -orient v -command [list $w_list yview]
        pack $w.list.sbx -side bottom -fill x
index 170f737..76f04f2 100644 (file)
@@ -396,7 +396,7 @@ method _after_readtree {} {
                        set is_detached 0
                }
        } else {
-               if {$new_hash ne $HEAD} {
+               if {!$is_detached || $new_hash ne $HEAD} {
                        append log " to $new_expr"
                        if {[catch {
                                        _detach_HEAD $log $new_hash
diff --git a/git-gui/lib/choose_font.tcl b/git-gui/lib/choose_font.tcl
new file mode 100644 (file)
index 0000000..0c4051b
--- /dev/null
@@ -0,0 +1,166 @@
+# git-gui font chooser
+# Copyright (C) 2007 Shawn Pearce
+
+class choose_font {
+
+field w
+field w_family    ; # UI widget of all known family names
+field w_example   ; # Example to showcase the chosen font
+
+field f_family    ; # Currently chosen family name
+field f_size      ; # Currently chosen point size
+
+field v_family    ; # Name of global variable for family
+field v_size      ; # Name of global variable for size
+
+variable all_families [list]  ; # All fonts known to Tk
+
+constructor pick {path title a_family a_size} {
+       variable all_families
+
+       set v_family $a_family
+       set v_size $a_size
+
+       upvar #0 $v_family pv_family
+       upvar #0 $v_size pv_size
+
+       set f_family $pv_family
+       set f_size $pv_size
+
+       make_toplevel top w
+       wm title $top "[appname] ([reponame]): $title"
+       wm geometry $top "+[winfo rootx $path]+[winfo rooty $path]"
+
+       label $w.header -text $title -font font_uibold
+       pack $w.header -side top -fill x
+
+       frame $w.buttons
+       button $w.buttons.select \
+               -text [mc Select] \
+               -default active \
+               -command [cb _select]
+       button $w.buttons.cancel \
+               -text [mc Cancel] \
+               -command [list destroy $w]
+       pack $w.buttons.select -side right
+       pack $w.buttons.cancel -side right -padx 5
+       pack $w.buttons -side bottom -fill x -pady 10 -padx 10
+
+       frame $w.inner
+
+       frame $w.inner.family
+       label $w.inner.family.l \
+               -text [mc "Font Family"] \
+               -anchor w
+       set w_family $w.inner.family.v
+       text $w_family \
+               -background white \
+               -borderwidth 1 \
+               -relief sunken \
+               -cursor $::cursor_ptr \
+               -wrap none \
+               -width 30 \
+               -height 10 \
+               -yscrollcommand [list $w.inner.family.sby set]
+       rmsel_tag $w_family
+       scrollbar $w.inner.family.sby -command [list $w_family yview]
+       pack $w.inner.family.l -side top -fill x
+       pack $w.inner.family.sby -side right -fill y
+       pack $w_family -fill both -expand 1
+
+       frame $w.inner.size
+       label $w.inner.size.l \
+               -text [mc "Font Size"] \
+               -anchor w
+       spinbox $w.inner.size.v \
+               -textvariable @f_size \
+               -from 2 -to 80 -increment 1 \
+               -width 3
+       bind $w.inner.size.v <FocusIn> {%W selection range 0 end}
+       pack $w.inner.size.l -fill x -side top
+       pack $w.inner.size.v -fill x -padx 2
+
+       grid configure $w.inner.family $w.inner.size -sticky nsew
+       grid rowconfigure $w.inner 0 -weight 1
+       grid columnconfigure $w.inner 0 -weight 1
+       pack $w.inner -fill both -expand 1 -padx 5 -pady 5
+
+       frame $w.example
+       label $w.example.l \
+               -text [mc "Font Example"] \
+               -anchor w
+       set w_example $w.example.t
+       text $w_example \
+               -background white \
+               -borderwidth 1 \
+               -relief sunken \
+               -height 3 \
+               -width 40
+       rmsel_tag $w_example
+       $w_example tag conf example -justify center
+       $w_example insert end [mc "This is example text.\nIf you like this text, it can be your font."] example
+       $w_example conf -state disabled
+       pack $w.example.l -fill x
+       pack $w_example -fill x
+       pack $w.example -fill x -padx 5
+
+       if {$all_families eq {}} {
+               set all_families [lsort [font families]]
+       }
+
+       $w_family tag conf pick
+       $w_family tag bind pick <Button-1> [cb _pick_family %x %y]\;break
+       foreach f $all_families {
+               set sel [list pick]
+               if {$f eq $f_family} {
+                       lappend sel in_sel
+               }
+               $w_family insert end "$f\n" $sel
+       }
+       $w_family conf -state disabled
+       _update $this
+
+       trace add variable @f_size write [cb _update]
+       bind $w <Key-Escape> [list destroy $w]
+       bind $w <Key-Return> [cb _select]\;break
+       bind $w <Visibility> "
+               grab $w
+               focus $w
+       "
+       tkwait window $w
+}
+
+method _select {} {
+       upvar #0 $v_family pv_family
+       upvar #0 $v_size pv_size
+
+       set pv_family $f_family
+       set pv_size $f_size
+
+       destroy $w
+}
+
+method _pick_family {x y} {
+       variable all_families
+
+       set i [lindex [split [$w_family index @$x,$y] .] 0]
+       set n [lindex $all_families [expr {$i - 1}]]
+       if {$n ne {}} {
+               $w_family tag remove in_sel 0.0 end
+               $w_family tag add in_sel $i.0 [expr {$i + 1}].0
+               set f_family $n
+               _update $this
+       }
+}
+
+method _update {args} {
+       variable all_families
+
+       set i [lsearch -exact $all_families $f_family]
+       if {$i < 0} return
+
+       $w_example tag conf example -font [list $f_family $f_size]
+       $w_family see [expr {$i + 1}].0
+}
+
+}
index e09e125..694834a 100644 (file)
@@ -84,12 +84,30 @@ proc show_diff {path w {lno {}}} {
        #
        if {$m eq {_O}} {
                set max_sz [expr {128 * 1024}]
+               set type unknown
                if {[catch {
-                               set fd [open $path r]
-                               fconfigure $fd -eofchar {}
-                               set content [read $fd $max_sz]
-                               close $fd
-                               set sz [file size $path]
+                               set type [file type $path]
+                               switch -- $type {
+                               directory {
+                                       set type submodule
+                                       set content {}
+                                       set sz 0
+                               }
+                               link {
+                                       set content [file readlink $path]
+                                       set sz [string length $content]
+                               }
+                               file {
+                                       set fd [open $path r]
+                                       fconfigure $fd -eofchar {}
+                                       set content [read $fd $max_sz]
+                                       close $fd
+                                       set sz [file size $path]
+                               }
+                               default {
+                                       error "'$type' not supported"
+                               }
+                               }
                        } err ]} {
                        set diff_active 0
                        unlock_index
@@ -98,7 +116,9 @@ proc show_diff {path w {lno {}}} {
                        return
                }
                $ui_diff conf -state normal
-               if {![catch {set type [exec file $path]}]} {
+               if {$type eq {submodule}} {
+                       $ui_diff insert end "* Git Repository (subproject)\n" d_@
+               } elseif {![catch {set type [exec file $path]}]} {
                        set n [string length $path]
                        if {[string equal -length $n $path $type]} {
                                set type [string range $type $n end]
@@ -198,6 +218,7 @@ proc read_diff {fd} {
                if {[string match {mode *} $line]
                        || [string match {new file *} $line]
                        || [string match {deleted file *} $line]
+                       || [string match {deleted symlink} $line]
                        || [string match {Binary files * and * differ} $line]
                        || $line eq {\ No newline at end of file}
                        || [regexp {^\* Unmerged path } $line]} {
index f47f929..44689ab 100644 (file)
@@ -13,7 +13,8 @@ proc update_indexinfo {msg pathList after} {
        if {$batch > 25} {set batch 25}
 
        ui_status [format \
-               "$msg... %i/%i files (%.2f%%)" \
+               "%s... %i/%i files (%.2f%%)" \
+               $msg \
                $update_index_cp \
                $totalCnt \
                0.0]
@@ -68,7 +69,8 @@ proc write_update_indexinfo {fd pathList totalCnt batch msg after} {
        }
 
        ui_status [format \
-               "$msg... %i/%i files (%.2f%%)" \
+               "%s... %i/%i files (%.2f%%)" \
+               $msg \
                $update_index_cp \
                $totalCnt \
                [expr {100.0 * $update_index_cp / $totalCnt}]]
@@ -86,7 +88,8 @@ proc update_index {msg pathList after} {
        if {$batch > 25} {set batch 25}
 
        ui_status [format \
-               "$msg... %i/%i files (%.2f%%)" \
+               "%s... %i/%i files (%.2f%%)" \
+               $msg \
                $update_index_cp \
                $totalCnt \
                0.0]
@@ -145,7 +148,8 @@ proc write_update_index {fd pathList totalCnt batch msg after} {
        }
 
        ui_status [format \
-               "$msg... %i/%i files (%.2f%%)" \
+               "%s... %i/%i files (%.2f%%)" \
+               $msg \
                $update_index_cp \
                $totalCnt \
                [expr {100.0 * $update_index_cp / $totalCnt}]]
@@ -163,7 +167,8 @@ proc checkout_index {msg pathList after} {
        if {$batch > 25} {set batch 25}
 
        ui_status [format \
-               "$msg... %i/%i files (%.2f%%)" \
+               "%s... %i/%i files (%.2f%%)" \
+               $msg \
                $update_index_cp \
                $totalCnt \
                0.0]
@@ -218,7 +223,8 @@ proc write_checkout_index {fd pathList totalCnt batch msg after} {
        }
 
        ui_status [format \
-               "$msg... %i/%i files (%.2f%%)" \
+               "%s... %i/%i files (%.2f%%)" \
+               $msg \
                $update_index_cp \
                $totalCnt \
                [expr {100.0 * $update_index_cp / $totalCnt}]]
index aa9f783..063f5df 100644 (file)
@@ -255,17 +255,23 @@ proc do_options {} {
 
                frame $w.global.$name
                label $w.global.$name.l -text "$text:"
-               pack $w.global.$name.l -side left -anchor w -fill x
-               eval tk_optionMenu $w.global.$name.family \
-                       global_config_new(gui.$font^^family) \
-                       $all_fonts
-               spinbox $w.global.$name.size \
-                       -textvariable global_config_new(gui.$font^^size) \
-                       -from 2 -to 80 -increment 1 \
-                       -width 3
-               bind $w.global.$name.size <FocusIn> {%W selection range 0 end}
-               pack $w.global.$name.size -side right -anchor e
-               pack $w.global.$name.family -side right -anchor e
+               button $w.global.$name.b \
+                       -text [mc "Change Font"] \
+                       -command [list \
+                               choose_font::pick \
+                               $w \
+                               [mc "Choose %s" $text] \
+                               global_config_new(gui.$font^^family) \
+                               global_config_new(gui.$font^^size) \
+                               ]
+               label $w.global.$name.f -textvariable global_config_new(gui.$font^^family)
+               label $w.global.$name.s -textvariable global_config_new(gui.$font^^size)
+               label $w.global.$name.pt -text [mc "pt."]
+               pack $w.global.$name.l -side left -anchor w
+               pack $w.global.$name.b -side right -anchor e
+               pack $w.global.$name.pt -side right -anchor w
+               pack $w.global.$name.s -side right -anchor w
+               pack $w.global.$name.f -side right -anchor w
                pack $w.global.$name -side top -anchor w -fill x
        }