X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=git-gui.sh;h=63b2045d96b87b414edfe04dd5f0d951c1f7b233;hb=79a060e477a743ad49508aec9a491fe1aa7d7c3b;hp=46358258bb65ceba68441c51fd69f212e9f817d3;hpb=a6c9b081b6860816615e84b75bbc7916aab184e9;p=git.git diff --git a/git-gui.sh b/git-gui.sh index 46358258b..63b2045d9 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1,6 +1,12 @@ #!/bin/sh # Tcl ignores the next line -*- tcl -*- \ -exec wish "$0" -- "$@" + if test "z$*" = zversion \ + || test "z$*" = z--version; \ + then \ + echo 'git-gui version @@GITGUI_VERSION@@'; \ + exit; \ + fi; \ + exec wish "$0" -- "$@" set appvers {@@GITGUI_VERSION@@} set copyright { @@ -22,13 +28,23 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA} ###################################################################### ## -## configure our library +## Tcl/Tk sanity check -set oguilib {@@GITGUI_LIBDIR@@} -if {[string match @@* $oguilib]} { - set oguilib [file join [file dirname [file normalize $argv0]] lib] +if {[catch {package require Tcl 8.4} err] + || [catch {package require Tk 8.4} err] +} { + catch {wm withdraw .} + tk_messageBox \ + -icon error \ + -type ok \ + -title "git-gui: fatal error" \ + -message $err + exit 1 } -set auto_path [concat [list $oguilib] $auto_path] + +###################################################################### +## +## enable verbose loading? if {![catch {set _verbose $env(GITGUI_VERBOSE)}]} { unset _verbose @@ -44,6 +60,54 @@ 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 @@ -158,6 +222,15 @@ proc is_config_true {name} { } } +proc get_config {name} { + global repo_config + if {[catch {set v $repo_config($name)}]} { + return {} + } else { + return $v + } +} + proc load_config {include_global} { global repo_config global_config default_config @@ -211,6 +284,17 @@ proc git {args} { return [eval exec git $args] } +proc current-branch {} { + set ref {} + set fd [open [gitdir HEAD] r] + if {[gets $fd ref] <16 + || ![regsub {^ref: refs/heads/} $ref {} ref]} { + set ref {} + } + close $fd + return $ref +} + auto_load tk_optionMenu rename tk_optionMenu real__tkOptionMenu proc tk_optionMenu {w varName args} { @@ -224,45 +308,89 @@ proc tk_optionMenu {w varName args} { ## ## version check -if {{--version} eq $argv || {version} eq $argv} { - puts "git-gui version $appvers" - exit -} - -set req_maj 1 -set req_min 5 - -if {[catch {set v [git --version]} err]} { +if {[catch {set _git_version [git --version]} err]} { catch {wm withdraw .} error_popup "Cannot determine Git version: $err -[appname] requires Git $req_maj.$req_min or later." +[appname] requires Git 1.5.0 or later." + exit 1 +} +if {![regsub {^git version } $_git_version {} _git_version]} { + catch {wm withdraw .} + error_popup "Cannot parse Git version string:\n\n$_git_version" exit 1 } -if {[regexp {^git version (\d+)\.(\d+)} $v _junk act_maj act_min]} { - if {$act_maj < $req_maj - || ($act_maj == $req_maj && $act_min < $req_min)} { - catch {wm withdraw .} - error_popup "[appname] requires Git $req_maj.$req_min or later. +regsub {\.[0-9]+\.g[0-9a-f]+$} $_git_version {} _git_version +regsub {\.rc[0-9]+$} $_git_version {} _git_version -You are using $v." - exit 1 +proc git-version {args} { + global _git_version + + switch [llength $args] { + 0 { + return $_git_version } -} else { + + 2 { + set op [lindex $args 0] + set vr [lindex $args 1] + set cm [package vcompare $_git_version $vr] + return [expr $cm $op 0] + } + + 4 { + set type [lindex $args 0] + set name [lindex $args 1] + set parm [lindex $args 2] + set body [lindex $args 3] + + if {($type ne {proc} && $type ne {method})} { + error "Invalid arguments to git-version" + } + if {[llength $body] < 2 || [lindex $body end-1] ne {default}} { + error "Last arm of $type $name must be default" + } + + foreach {op vr cb} [lrange $body 0 end-2] { + if {[git-version $op $vr]} { + return [uplevel [list $type $name $parm $cb]] + } + } + + return [uplevel [list $type $name $parm [lindex $body end]]] + } + + default { + error "git-version >= x" + } + + } +} + +if {[git-version < 1.5]} { catch {wm withdraw .} - error_popup "Cannot parse Git version string:\n\n$v" + error_popup "[appname] requires Git 1.5.0 or later. + +You are using [git-version]: + +[git --version]" exit 1 } -unset -nocomplain v _junk act_maj act_min req_maj req_min ###################################################################### ## ## repository setup -if { [catch {set _gitdir $env(GIT_DIR)}] - && [catch {set _gitdir [git rev-parse --git-dir]} err]} { +if {[catch { + set _gitdir $env(GIT_DIR) + set _prefix {} + }] + && [catch { + set _gitdir [git rev-parse --git-dir] + set _prefix [git rev-parse --show-prefix] + } err]} { catch {wm withdraw .} error_popup "Cannot find the git directory:\n\n$err" exit 1 @@ -353,15 +481,7 @@ proc repository_state {ctvar hdvar mhvar} { set mh [list] - if {[catch {set current_branch [git symbolic-ref HEAD]}]} { - set current_branch {} - } else { - regsub ^refs/((heads|tags|remotes)/)? \ - $current_branch \ - {} \ - current_branch - } - + set current_branch [current-branch] if {[catch {set hd [git rev-parse --verify HEAD]}]} { set hd {} set ct initial @@ -418,7 +538,8 @@ proc rescan {after {honor_trustmtime 1}} { if {![$ui_comm edit modified] || [string trim [$ui_comm get 0.0 end]] eq {}} { - if {[load_message GITGUI_MSG]} { + if {[string match amend* $commit_type]} { + } elseif {[load_message GITGUI_MSG]} { } elseif {[load_message MERGE_MSG]} { } elseif {[load_message SQUASH_MSG]} { } @@ -971,6 +1092,7 @@ proc incr_font_size {font {amt 1}} { incr sz $amt font configure $font -size $sz font configure ${font}bold -size $sz + font configure ${font}italic -size $sz } ###################################################################### @@ -986,15 +1108,17 @@ proc do_gitk {revs} { # lets us bypass using shell process on Windows systems. # set cmd [list [info nameofexecutable]] - lappend cmd [gitexec gitk] + set exe [gitexec gitk] + lappend cmd $exe if {$revs ne {}} { append cmd { } append cmd $revs } - if {[catch {eval exec $cmd &} err]} { - error_popup "Failed to start gitk:\n\n$err" + if {! [file exists $exe]} { + error_popup "Unable to start gitk:\n\n$exe does not exist" } else { + eval exec $cmd & set ui_status_value $starting_gitk_msg after 10000 { if {$ui_status_value eq $starting_gitk_msg} { @@ -1163,25 +1287,28 @@ catch { destroy .dummy } +font create font_uiitalic font create font_uibold font create font_diffbold +font create font_diffitalic foreach class {Button Checkbutton Entry Label Labelframe Listbox Menu Message - Radiobutton Text} { + Radiobutton Spinbox Text} { option add *$class.font font_ui } unset class -if {[is_Windows]} { - set M1B Control - set M1T Ctrl -} elseif {[is_MacOSX]} { +if {[is_Windows] || [is_MacOSX]} { + option add *Menu.tearOff 0 +} + +if {[is_MacOSX]} { set M1B M1 set M1T Cmd } else { - set M1B M1 - set M1T M1 + set M1B Control + set M1T Ctrl } proc apply_config {} { @@ -1199,16 +1326,20 @@ proc apply_config {} { } foreach {cn cv} [font configure $font] { font configure ${font}bold $cn $cv + font configure ${font}italic $cn $cv } font configure ${font}bold -weight bold + font configure ${font}italic -slant italic } } +set default_config(merge.diffstat) true set default_config(merge.summary) false set default_config(merge.verbosity) 2 set default_config(user.name) {} set default_config(user.email) {} +set default_config(gui.pruneduringfetch) false set default_config(gui.trustmtime) false set default_config(gui.diffcontext) 5 set default_config(gui.newbranchtemplate) {} @@ -1288,7 +1419,7 @@ menu .mbar.repository .mbar.repository add command \ -label {Browse Current Branch} \ - -command {new_browser $current_branch} + -command {browser::new $current_branch} trace add variable current_branch write ".mbar.repository entryconf [.mbar.repository index last] -label \"Browse \$current_branch\" ;#" .mbar.repository add separator @@ -1365,13 +1496,18 @@ if {[is_enabled branch]} { menu .mbar.branch .mbar.branch add command -label {Create...} \ - -command do_create_branch \ + -command branch_create::dialog \ -accelerator $M1T-N lappend disable_on_lock [list .mbar.branch entryconf \ [.mbar.branch index last] -state] + .mbar.branch add command -label {Rename...} \ + -command branch_rename::dialog + lappend disable_on_lock [list .mbar.branch entryconf \ + [.mbar.branch index last] -state] + .mbar.branch add command -label {Delete...} \ - -command do_delete_branch + -command branch_delete::dialog lappend disable_on_lock [list .mbar.branch entryconf \ [.mbar.branch index last] -state] @@ -1466,7 +1602,10 @@ if {[is_enabled transport]} { menu .mbar.push .mbar.push add command -label {Push...} \ - -command do_push_anywhere + -command do_push_anywhere \ + -accelerator $M1T-P + .mbar.push add command -label {Delete...} \ + -command remote_branch_delete::dialog } if {[is_MacOSX]} { @@ -1488,8 +1627,7 @@ if {[is_MacOSX]} { # -- Tools Menu # - if {[file exists /usr/local/miga/lib/gui-miga] - && [file exists .pvcsrc]} { + if {[is_Cygwin] && [file exists /usr/local/miga/lib/gui-miga]} { proc do_miga {} { global ui_status_value if {![lock_index update]} return @@ -1566,31 +1704,65 @@ unset browser doc_path doc_url # -- Standard bindings # -bind . do_quit +wm protocol . WM_DELETE_WINDOW do_quit 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]} +set subcommand_args {} +proc usage {} { + puts stderr "usage: $::argv0 $::subcommand $::subcommand_args" + exit 1 +} + # -- Not a normal commit type invocation? Do that instead! # switch -- $subcommand { browser { - if {[llength $argv] != 1} { - puts stderr "usage: $argv0 browser commit" - exit 1 + set subcommand_args {rev?} + switch [llength $argv] { + 0 { set current_branch [current-branch] } + 1 { set current_branch [lindex $argv 0] } + default usage } - set current_branch [lindex $argv 0] - new_browser $current_branch + browser::new $current_branch return } blame { - if {[llength $argv] != 2} { - puts stderr "usage: $argv0 blame commit path" - exit 1 + set subcommand_args {rev? path?} + set head {} + set path {} + set is_path 0 + foreach a $argv { + if {$is_path || [file exists $_prefix$a]} { + if {$path ne {}} usage + set path $_prefix$a + break + } elseif {$a eq {--}} { + if {$path ne {}} { + if {$head ne {}} usage + set head $path + set path {} + } + set is_path 1 + } elseif {$head eq {}} { + if {$head ne {}} usage + set head $a + } else { + usage + } + } + unset is_path + + if {$head eq {}} { + set current_branch [current-branch] + } else { + set current_branch $head } - set current_branch [lindex $argv 0] - show_blame $current_branch [lindex $argv 1] + + if {$path eq {}} usage + blame::new $head $path return } citool - @@ -1638,8 +1810,8 @@ pack .vpane -anchor n -side top -fill both -expand 1 # -- Index File List # frame .vpane.files.index -height 100 -width 200 -label .vpane.files.index.title -text {Changes To Be Committed} \ - -background green +label .vpane.files.index.title -text {Staged Changes (Will Be Committed)} \ + -background lightgreen text $ui_index -background white -borderwidth 0 \ -width 20 -height 10 \ -wrap none \ @@ -1658,8 +1830,8 @@ pack $ui_index -side left -fill both -expand 1 # -- Working Directory File List # frame .vpane.files.workdir -height 100 -width 200 -label .vpane.files.workdir.title -text {Changed But Not Updated} \ - -background red +label .vpane.files.workdir.title -text {Unstaged Changes (Will Not Be Committed)} \ + -background lightsalmon text $ui_workdir -background white -borderwidth 0 \ -width 20 -height 10 \ -wrap none \ @@ -1676,10 +1848,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 -font font_uibold - $i tag conf in_sel \ - -background [$i cget -foreground] \ - -foreground [$i cget -background] + $i tag conf in_diff -background lightgray + $i tag conf in_sel -background lightgray } unset i @@ -1723,6 +1893,10 @@ pack .vpane.lower.commarea.buttons.commit -side top -fill x lappend disable_on_lock \ {.vpane.lower.commarea.buttons.commit conf -state} +button .vpane.lower.commarea.buttons.push -text {Push} \ + -command do_push_anywhere +pack .vpane.lower.commarea.buttons.push -side top -fill x + # -- Commit Message Buffer # frame .vpane.lower.commarea.buffer @@ -1837,18 +2011,18 @@ proc trace_current_diff_path {varname args} { } trace add variable current_diff_path write trace_current_diff_path -frame .vpane.lower.diff.header -background orange +frame .vpane.lower.diff.header -background gold label .vpane.lower.diff.header.status \ - -background orange \ + -background gold \ -width $max_status_desc \ -anchor w \ -justify left label .vpane.lower.diff.header.file \ - -background orange \ + -background gold \ -anchor w \ -justify left label .vpane.lower.diff.header.path \ - -background orange \ + -background gold \ -anchor w \ -justify left pack .vpane.lower.diff.header.status -side left @@ -1962,17 +2136,17 @@ lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] $ctxm add separator $ctxm add command \ -label {Show Less Context} \ - -command {if {$repo_config(gui.diffcontext) >= 2} { + -command {if {$repo_config(gui.diffcontext) >= 1} { incr repo_config(gui.diffcontext) -1 reshow_diff }} lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] $ctxm add command \ -label {Show More Context} \ - -command { + -command {if {$repo_config(gui.diffcontext) < 99} { incr repo_config(gui.diffcontext) reshow_diff - } + }} lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] $ctxm add separator $ctxm add command -label {Options...} \ @@ -2047,13 +2221,17 @@ bind $ui_diff {catch {%W yview scroll 1 pages};break} bind $ui_diff {focus %W} if {[is_enabled branch]} { - bind . <$M1B-Key-n> do_create_branch - bind . <$M1B-Key-N> do_create_branch + bind . <$M1B-Key-n> branch_create::dialog + bind . <$M1B-Key-N> branch_create::dialog +} +if {[is_enabled transport]} { + bind . <$M1B-Key-p> do_push_anywhere + bind . <$M1B-Key-P> do_push_anywhere } -bind all do_rescan -bind all <$M1B-Key-r> do_rescan -bind all <$M1B-Key-R> do_rescan +bind . 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-i> do_add_all