]> asedeno.scripts.mit.edu Git - git.git/blobdiff - git-gui.sh
git-gui: handle "deleted symlink" diff marker
[git.git] / git-gui.sh
index f87b955fdb98bdd0591c9c02c52075e245cc2e19..6d676097a6a3aeecfda3a752b7344dc88094956c 100755 (executable)
@@ -42,6 +42,8 @@ if {[catch {package require Tcl 8.4} err]
        exit 1
 }
 
+rename send {} ; # What an evil concept...
+
 ######################################################################
 ##
 ## enable verbose loading?
@@ -60,54 +62,6 @@ if {![catch {set _verbose $env(GITGUI_VERBOSE)}]} {
        }
 }
 
-######################################################################
-##
-## configure our library
-
-set oguilib {@@GITGUI_LIBDIR@@}
-set oguirel {@@GITGUI_RELATIVE@@}
-if {$oguirel eq {1}} {
-       set oguilib [file dirname [file dirname [file normalize $argv0]]]
-       set oguilib [file join $oguilib share git-gui lib]
-} elseif {[string match @@* $oguirel]} {
-       set oguilib [file join [file dirname [file normalize $argv0]] lib]
-}
-
-set idx [file join $oguilib tclIndex]
-if {[catch {set fd [open $idx r]} err]} {
-       catch {wm withdraw .}
-       tk_messageBox \
-               -icon error \
-               -type ok \
-               -title "git-gui: fatal error" \
-               -message $err
-       exit 1
-}
-if {[gets $fd] eq {# Autogenerated by git-gui Makefile}} {
-       set idx [list]
-       while {[gets $fd n] >= 0} {
-               if {$n ne {} && ![string match #* $n]} {
-                       lappend idx $n
-               }
-       }
-} else {
-       set idx {}
-}
-close $fd
-
-if {$idx ne {}} {
-       set loaded [list]
-       foreach p $idx {
-               if {[lsearch -exact $loaded $p] >= 0} continue
-               source [file join $oguilib $p]
-               lappend loaded $p
-       }
-       unset loaded p
-} else {
-       set auto_path [concat [list $oguilib] $auto_path]
-}
-unset -nocomplain oguirel idx fd
-
 ######################################################################
 ##
 ## read only globals
@@ -309,7 +263,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 }
@@ -323,7 +277,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.
@@ -532,7 +486,11 @@ if {$_git eq {}} {
 
 if {[catch {set _git_version [git --version]} err]} {
        catch {wm withdraw .}
-       error_popup "Cannot determine Git version:
+       tk_messageBox \
+               -icon error \
+               -type ok \
+               -title "git-gui: fatal error" \
+               -message "Cannot determine Git version:
 
 $err
 
@@ -541,7 +499,11 @@ $err
 }
 if {![regsub {^git version } $_git_version {} _git_version]} {
        catch {wm withdraw .}
-       error_popup "Cannot parse Git version string:\n\n$_git_version"
+       tk_messageBox \
+               -icon error \
+               -type ok \
+               -title "git-gui: fatal error" \
+               -message "Cannot parse Git version string:\n\n$_git_version"
        exit 1
 }
 
@@ -619,7 +581,11 @@ proc git-version {args} {
 
 if {[git-version < 1.5]} {
        catch {wm withdraw .}
-       error_popup "[appname] requires Git 1.5.0 or later.
+       tk_messageBox \
+               -icon error \
+               -type ok \
+               -title "git-gui: fatal error" \
+               -message "[appname] requires Git 1.5.0 or later.
 
 You are using [git-version]:
 
@@ -627,6 +593,54 @@ You are using [git-version]:
        exit 1
 }
 
+######################################################################
+##
+## configure our library
+
+set oguilib {@@GITGUI_LIBDIR@@}
+set oguirel {@@GITGUI_RELATIVE@@}
+if {$oguirel eq {1}} {
+       set oguilib [file dirname [file dirname [file normalize $argv0]]]
+       set oguilib [file join $oguilib share git-gui lib]
+} elseif {[string match @@* $oguirel]} {
+       set oguilib [file join [file dirname [file normalize $argv0]] lib]
+}
+
+set idx [file join $oguilib tclIndex]
+if {[catch {set fd [open $idx r]} err]} {
+       catch {wm withdraw .}
+       tk_messageBox \
+               -icon error \
+               -type ok \
+               -title "git-gui: fatal error" \
+               -message $err
+       exit 1
+}
+if {[gets $fd] eq {# Autogenerated by git-gui Makefile}} {
+       set idx [list]
+       while {[gets $fd n] >= 0} {
+               if {$n ne {} && ![string match #* $n]} {
+                       lappend idx $n
+               }
+       }
+} else {
+       set idx {}
+}
+close $fd
+
+if {$idx ne {}} {
+       set loaded [list]
+       foreach p $idx {
+               if {[lsearch -exact $loaded $p] >= 0} continue
+               source [file join $oguilib $p]
+               lappend loaded $p
+       }
+       unset loaded p
+} else {
+       set auto_path [concat [list $oguilib] $auto_path]
+}
+unset -nocomplain oguirel idx fd
+
 ######################################################################
 ##
 ## feature option selection
@@ -691,7 +705,15 @@ if {![file isdirectory $_gitdir]} {
        error_popup "Git directory not found:\n\n$_gitdir"
        exit 1
 }
-if {![is_enabled bare]} {
+if {$_prefix ne {}} {
+       regsub -all {[^/]+/} $_prefix ../ cdup
+       if {[catch {cd $cdup} err]} {
+               catch {wm withdraw .}
+               error_popup "Cannot move to top of working directory:\n\n$err"
+               exit 1
+       }
+       unset cdup
+} elseif {![is_enabled bare]} {
        if {[lindex [file split $_gitdir] end] ne {.git}} {
                catch {wm withdraw .}
                error_popup "Cannot use funny .git directory:\n\n$_gitdir"
@@ -726,6 +748,7 @@ set empty_tree {}
 set current_branch {}
 set is_detached 0
 set current_diff_path {}
+set is_3way_diff 0
 set selected_commit_type new
 
 ######################################################################
@@ -872,6 +895,10 @@ proc rescan_stage2 {fd after} {
        if {[file readable $info_exclude]} {
                lappend ls_others "--exclude-from=$info_exclude"
        }
+       set user_exclude [get_config core.excludesfile]
+       if {$user_exclude ne {} && [file readable $user_exclude]} {
+               lappend ls_others "--exclude-from=$user_exclude"
+       }
 
        set buf_rdi {}
        set buf_rdf {}
@@ -1292,32 +1319,6 @@ static unsigned char file_merge_bits[] = {
    0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
 } -maskdata $filemask
 
-set file_dir_data {
-#define file_width 18
-#define file_height 18
-static unsigned char file_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00,
-  0x0c, 0x03, 0x00, 0x04, 0xfe, 0x00, 0x06, 0x80, 0x00, 0xff, 0x9f, 0x00,
-  0x03, 0x98, 0x00, 0x02, 0x90, 0x00, 0x06, 0xb0, 0x00, 0x04, 0xa0, 0x00,
-  0x0c, 0xe0, 0x00, 0x08, 0xc0, 0x00, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-}
-image create bitmap file_dir -background white -foreground blue \
-       -data $file_dir_data -maskdata $file_dir_data
-unset file_dir_data
-
-set file_uplevel_data {
-#define up_width 15
-#define up_height 15
-static unsigned char up_bits[] = {
-  0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,
-  0xfe, 0x3f, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
-  0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00};
-}
-image create bitmap file_uplevel -background white -foreground red \
-       -data $file_uplevel_data -maskdata $file_uplevel_data
-unset file_uplevel_data
-
 set ui_index .vpane.files.index.list
 set ui_workdir .vpane.files.workdir.list
 
@@ -1370,6 +1371,9 @@ unset i
 proc bind_button3 {w cmd} {
        bind $w <Any-Button-3> $cmd
        if {[is_MacOSX]} {
+               # Mac OS X sends Button-2 on right click through three-button mouse,
+               # or through trackpad right-clicking (two-finger touch + click).
+               bind $w <Any-Button-2> $cmd
                bind $w <Control-Button-1> $cmd
        }
 }
@@ -1827,12 +1831,12 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
 
-       .mbar.commit add command -label {Add To Commit} \
+       .mbar.commit add command -label {Stage To Commit} \
                -command do_add_selection
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
 
-       .mbar.commit add command -label {Add Tracked Files To Commit} \
+       .mbar.commit add command -label {Stage Changed Files To Commit} \
                -command do_add_all \
                -accelerator $M1T-I
        lappend disable_on_lock \
@@ -1955,6 +1959,12 @@ if {$browser ne {}} {
 }
 unset browser doc_path doc_url
 
+set root_exists 0
+bind . <Visibility> {
+       bind . <Visibility> {}
+       set root_exists 1
+}
+
 # -- Standard bindings
 #
 wm protocol . WM_DELETE_WINDOW do_quit
@@ -2154,7 +2164,7 @@ pack .vpane.lower.commarea.buttons.rescan -side top -fill x
 lappend disable_on_lock \
        {.vpane.lower.commarea.buttons.rescan conf -state}
 
-button .vpane.lower.commarea.buttons.incall -text {Add Tracked} \
+button .vpane.lower.commarea.buttons.incall -text {Stage Changed} \
        -command do_add_all
 pack .vpane.lower.commarea.buttons.incall -side top -fill x
 lappend disable_on_lock \
@@ -2429,15 +2439,23 @@ $ctxm add separator
 $ctxm add command -label {Options...} \
        -command do_options
 proc popup_diff_menu {ctxm x y X Y} {
+       global current_diff_path file_states
        set ::cursorX $x
        set ::cursorY $y
        if {$::ui_index eq $::current_diff_side} {
-               $ctxm entryconf $::ui_diff_applyhunk \
-                       -label {Unstage Hunk From Commit}
+               set l "Unstage Hunk From Commit"
+       } else {
+               set l "Stage Hunk For Commit"
+       }
+       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 {
-               $ctxm entryconf $::ui_diff_applyhunk \
-                       -label {Stage Hunk For Commit}
+               set s normal
        }
+       $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l
        tk_popup $ctxm $X $Y
 }
 bind_button3 $ui_diff [list popup_diff_menu $ctxm %x %y %X %Y]