X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-gui%2Fgit-gui.sh;h=94067cc5f73388f33722d52ae02f44692bc07490;hb=2de00bf9e8815970c61cefaef35efeacd8a7d6de;hp=f5010dd47a0416eb18d823f257f4748fec621074;hpb=ea44949605781d1947ba1422ee541867e7ce9b81;p=git.git diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index f5010dd47..94067cc5f 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -4,7 +4,7 @@ exec wish "$0" -- "$@" set appvers {@@GITGUI_VERSION@@} set copyright { -Copyright © 2006, 2007 Shawn Pearce, Paul Mackerras. +Copyright © 2006, 2007 Shawn Pearce, et. al. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,7 +46,7 @@ proc gitdir {args} { proc gitexec {args} { global _gitexec if {$_gitexec eq {}} { - if {[catch {set _gitexec [exec git --exec-path]} err]} { + if {[catch {set _gitexec [git --exec-path]} err]} { error "Git not installed?\n\n$err" } } @@ -202,14 +202,14 @@ proc save_config {} { set value $global_config_new($name) if {$value ne $global_config($name)} { if {$value eq $default_config($name)} { - catch {exec git config --global --unset $name} + catch {git config --global --unset $name} } else { regsub -all "\[{}\]" $value {"} value - exec git config --global $name $value + git config --global $name $value } set global_config($name) $value if {$value eq $repo_config($name)} { - catch {exec git config --unset $name} + catch {git config --unset $name} set repo_config($name) $value } } @@ -219,21 +219,31 @@ proc save_config {} { set value $repo_config_new($name) if {$value ne $repo_config($name)} { if {$value eq $global_config($name)} { - catch {exec git config --unset $name} + catch {git config --unset $name} } else { regsub -all "\[{}\]" $value {"} value - exec git config $name $value + git config $name $value } set repo_config($name) $value } } } +###################################################################### +## +## handy utils + +proc git {args} { + return [eval exec git $args] +} + proc error_popup {msg} { set title [appname] if {[reponame] ne {}} { append title " ([reponame])" } + option add *Dialog.msg.font font_ui + option add *Button.font font_ui set cmd [list tk_messageBox \ -icon error \ -type ok \ @@ -250,6 +260,8 @@ proc warn_popup {msg} { if {[reponame] ne {}} { append title " ([reponame])" } + option add *Dialog.msg.font font_ui + option add *Button.font font_ui set cmd [list tk_messageBox \ -icon warning \ -type ok \ @@ -266,6 +278,8 @@ proc info_popup {msg {parent .}} { if {[reponame] ne {}} { append title " ([reponame])" } + option add *Dialog.msg.font font_ui + option add *Button.font font_ui tk_messageBox \ -parent $parent \ -icon info \ @@ -279,6 +293,8 @@ proc ask_popup {msg} { if {[reponame] ne {}} { append title " ([reponame])" } + option add *Dialog.msg.font font_ui + option add *Button.font font_ui return [tk_messageBox \ -parent . \ -icon question \ @@ -287,12 +303,49 @@ proc ask_popup {msg} { -message $msg] } +###################################################################### +## +## 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]} { + catch {wm withdraw .} + error_popup "Cannot determine Git version: + +$err + +[appname] requires Git $req_maj.$req_min or later." + 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. + +You are using $v." + exit 1 + } +} else { + catch {wm withdraw .} + error_popup "Cannot parse Git version string:\n\n$v" + 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 [exec git rev-parse --git-dir]} err]} { + && [catch {set _gitdir [git rev-parse --git-dir]} err]} { catch {wm withdraw .} error_popup "Cannot find the git directory:\n\n$err" exit 1 @@ -319,6 +372,24 @@ set _reponame [lindex [file split \ [file normalize [file dirname $_gitdir]]] \ end] +###################################################################### +## +## global init + +set current_diff_path {} +set current_diff_side {} +set diff_actions [list] +set ui_status_value {Initializing...} + +set HEAD {} +set PARENT {} +set MERGE_HEAD [list] +set commit_type {} +set empty_tree {} +set current_branch {} +set current_diff_path {} +set selected_commit_type new + ###################################################################### ## ## task management @@ -365,7 +436,7 @@ proc repository_state {ctvar hdvar mhvar} { set mh [list] - if {[catch {set current_branch [exec git symbolic-ref HEAD]}]} { + if {[catch {set current_branch [git symbolic-ref HEAD]}]} { set current_branch {} } else { regsub ^refs/((heads|tags|remotes)/)? \ @@ -374,7 +445,7 @@ proc repository_state {ctvar hdvar mhvar} { current_branch } - if {[catch {set hd [exec git rev-parse --verify HEAD]}]} { + if {[catch {set hd [git rev-parse --verify HEAD]}]} { set hd {} set ct initial return @@ -402,7 +473,7 @@ proc PARENT {} { return $p } if {$empty_tree eq {}} { - set empty_tree [exec git mktree << {}] + set empty_tree [git mktree << {}] } return $empty_tree } @@ -642,8 +713,9 @@ proc reshow_diff {} { global current_diff_path current_diff_side set p $current_diff_path - if {$p eq {} - || $current_diff_side eq {} + if {$p eq {}} { + # No diff is being shown. + } elseif {$current_diff_side eq {} || [catch {set s $file_states($p)}] || [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} { clear_diff @@ -663,12 +735,9 @@ proc handle_empty_diff {} { [short_path $path] has no changes. -The modification date of this file was updated -by another application, but the content within -the file was not changed. +The modification date of this file was updated by another application, but the content within the file was not changed. -A rescan will be automatically started to find -other files which may have the same state." +A rescan will be automatically started to find other files which may have the same state." clear_diff display_file $path __ @@ -969,8 +1038,7 @@ proc load_last_commit {} { if {[llength $PARENT] == 0} { error_popup {There is nothing to amend. -You are about to create the initial commit. -There is no commit before this to amend. +You are about to create the initial commit. There is no commit before this to amend. } return } @@ -979,10 +1047,7 @@ There is no commit before this to amend. if {$curType eq {merge}} { error_popup {Cannot amend while merging. -You are currently in the middle of a merge that -has not been fully completed. You cannot amend -the prior commit unless you first abort the -current merge activity. +You are currently in the middle of a merge that has not been fully completed. You cannot amend the prior commit unless you first abort the current merge activity. } return } @@ -1042,7 +1107,7 @@ proc committer_ident {} { global GIT_COMMITTER_IDENT if {$GIT_COMMITTER_IDENT eq {}} { - if {[catch {set me [exec git var GIT_COMMITTER_IDENT]} err]} { + if {[catch {set me [git var GIT_COMMITTER_IDENT]} err]} { error_popup "Unable to obtain your identity:\n\n$err" return {} } @@ -1072,9 +1137,7 @@ proc commit_tree {} { } elseif {$commit_type ne $curType || $HEAD ne $curHEAD} { info_popup {Last scanned state does not match repository state. -Another Git program has modified this repository -since the last scan. A rescan must be performed -before another commit can be created. +Another Git program has modified this repository since the last scan. A rescan must be performed before another commit can be created. The rescan will be automatically started now. } @@ -1095,8 +1158,7 @@ The rescan will be automatically started now. U? { error_popup "Unmerged files cannot be committed. -File [short_path $path] has merge conflicts. -You must resolve them and add the file before committing. +File [short_path $path] has merge conflicts. You must resolve them and add the file before committing. " unlock_index return @@ -1109,7 +1171,7 @@ File [short_path $path] cannot be committed by this program. } } } - if {!$files_ready} { + if {!$files_ready && ![string match *merge $curType]} { info_popup {No changes to commit. You must add at least 1 file before you can commit. @@ -1205,6 +1267,23 @@ proc commit_committree {fd_wt curHEAD msg} { return } + # -- Verify this wasn't an empty change. + # + if {$commit_type eq {normal}} { + set old_tree [git rev-parse "$PARENT^{tree}"] + if {$tree_id eq $old_tree} { + info_popup {No changes to commit. + +No files were modified by this commit and it was not a merge commit. + +A rescan will be automatically started now. +} + unlock_index + rescan {set ui_status_value {No changes to commit.}} + return + } + } + # -- Build the message. # set msg_p [gitdir COMMIT_EDITMSG] @@ -1219,14 +1298,8 @@ proc commit_committree {fd_wt curHEAD msg} { # -- Create the commit. # set cmd [list git commit-tree $tree_id] - set parents [concat $PARENT $MERGE_HEAD] - if {[llength $parents] > 0} { - foreach p $parents { - lappend cmd -p $p - } - } else { - # git commit-tree writes to stderr during initial commit. - lappend cmd 2>/dev/null + foreach p [concat $PARENT $MERGE_HEAD] { + lappend cmd -p $p } lappend cmd <$msg_p if {[catch {set cmt_id [eval exec $cmd]} err]} { @@ -1256,14 +1329,6 @@ proc commit_committree {fd_wt curHEAD msg} { return } - # -- Make sure our current branch exists. - # - if {$commit_type eq {initial}} { - lappend all_heads $current_branch - set all_heads [lsort -unique $all_heads] - populate_branch_menu - } - # -- Cleanup after ourselves. # catch {file delete $msg_p} @@ -1275,7 +1340,7 @@ proc commit_committree {fd_wt curHEAD msg} { # -- Let rerere do its thing. # if {[file isdirectory [gitdir rr-cache]]} { - catch {exec git rerere} + catch {git rerere} } # -- Run the post-commit hook. @@ -1299,6 +1364,14 @@ proc commit_committree {fd_wt curHEAD msg} { if {[is_enabled singlecommit]} do_quit + # -- Make sure our current branch exists. + # + if {$commit_type eq {initial}} { + lappend all_heads $current_branch + set all_heads [lsort -unique $all_heads] + populate_branch_menu + } + # -- Update in memory status # set selected_commit_type new @@ -1876,11 +1949,24 @@ proc all_tracking_branches {} { return [lsort -unique $all_trackings] } +proc load_all_tags {} { + set all_tags [list] + set fd [open "| git for-each-ref --format=%(refname) refs/tags" r] + while {[gets $fd line] > 0} { + if {![regsub ^refs/tags/ $line {} name]} continue + lappend all_tags $name + } + close $fd + + return [lsort $all_tags] +} + proc do_create_branch_action {w} { global all_heads null_sha1 repo_config global create_branch_checkout create_branch_revtype global create_branch_head create_branch_trackinghead global create_branch_name create_branch_revexp + global create_branch_tag set newbranch $create_branch_name if {$newbranch eq {} @@ -1894,7 +1980,7 @@ proc do_create_branch_action {w} { focus $w.desc.name_t return } - if {![catch {exec git show-ref --verify -- "refs/heads/$newbranch"}]} { + if {![catch {git show-ref --verify -- "refs/heads/$newbranch"}]} { tk_messageBox \ -icon error \ -type ok \ @@ -1904,7 +1990,7 @@ proc do_create_branch_action {w} { focus $w.desc.name_t return } - if {[catch {exec git check-ref-format "heads/$newbranch"}]} { + if {[catch {git check-ref-format "heads/$newbranch"}]} { tk_messageBox \ -icon error \ -type ok \ @@ -1919,9 +2005,10 @@ proc do_create_branch_action {w} { switch -- $create_branch_revtype { head {set rev $create_branch_head} tracking {set rev $create_branch_trackinghead} + tag {set rev $create_branch_tag} expression {set rev $create_branch_revexp} } - if {[catch {set cmt [exec git rev-parse --verify "${rev}^0"]}]} { + if {[catch {set cmt [git rev-parse --verify "${rev}^0"]}]} { tk_messageBox \ -icon error \ -type ok \ @@ -1964,6 +2051,8 @@ trace add variable create_branch_head write \ [list radio_selector create_branch_revtype head] trace add variable create_branch_trackinghead write \ [list radio_selector create_branch_revtype tracking] +trace add variable create_branch_tag write \ + [list radio_selector create_branch_revtype tag] trace add variable delete_branch_head write \ [list radio_selector delete_branch_checktype head] @@ -1975,6 +2064,7 @@ proc do_create_branch {} { global create_branch_checkout create_branch_revtype global create_branch_head create_branch_trackinghead global create_branch_name create_branch_revexp + global create_branch_tag set w .branch_editor toplevel $w @@ -2023,7 +2113,10 @@ proc do_create_branch {} { -value head \ -variable create_branch_revtype \ -font font_ui - eval tk_optionMenu $w.from.head_m create_branch_head $all_heads + set lbranchm [eval tk_optionMenu $w.from.head_m create_branch_head \ + $all_heads] + $lbranchm configure -font font_ui + $w.from.head_m configure -font font_ui grid $w.from.head_r $w.from.head_m -sticky w set all_trackings [all_tracking_branches] if {$all_trackings ne {}} { @@ -2033,11 +2126,28 @@ proc do_create_branch {} { -value tracking \ -variable create_branch_revtype \ -font font_ui - eval tk_optionMenu $w.from.tracking_m \ + set tbranchm [eval tk_optionMenu $w.from.tracking_m \ create_branch_trackinghead \ - $all_trackings + $all_trackings] + $tbranchm configure -font font_ui + $w.from.tracking_m configure -font font_ui grid $w.from.tracking_r $w.from.tracking_m -sticky w } + set all_tags [load_all_tags] + if {$all_tags ne {}} { + set create_branch_tag [lindex $all_tags 0] + radiobutton $w.from.tag_r \ + -text {Tag:} \ + -value tag \ + -variable create_branch_revtype \ + -font font_ui + set tagsm [eval tk_optionMenu $w.from.tag_m \ + create_branch_tag \ + $all_tags] + $tagsm configure -font font_ui + $w.from.tag_m configure -font font_ui + grid $w.from.tag_r $w.from.tag_m -sticky w + } radiobutton $w.from.exp_r \ -text {Revision Expression:} \ -value expression \ @@ -2100,7 +2210,7 @@ proc do_delete_branch_action {w} { } if {$check_rev eq {:none}} { set check_cmt {} - } elseif {[catch {set check_cmt [exec git rev-parse --verify "${check_rev}^0"]}]} { + } elseif {[catch {set check_cmt [git rev-parse --verify "${check_rev}^0"]}]} { tk_messageBox \ -icon error \ -type ok \ @@ -2114,10 +2224,10 @@ proc do_delete_branch_action {w} { set not_merged [list] foreach i [$w.list.l curselection] { set b [$w.list.l get $i] - if {[catch {set o [exec git rev-parse --verify $b]}]} continue + if {[catch {set o [git rev-parse --verify $b]}]} continue if {$check_cmt ne {}} { if {$b eq $check_rev} continue - if {[catch {set m [exec git merge-base $o $check_cmt]}]} continue + if {[catch {set m [git merge-base $o $check_cmt]}]} continue if {$o ne $m} { lappend not_merged $b continue @@ -2155,7 +2265,7 @@ Delete the selected branches?} foreach i $to_delete { set b [lindex $i 0] set o [lindex $i 1] - if {[catch {exec git update-ref -d "refs/heads/$b" $o} err]} { + if {[catch {git update-ref -d "refs/heads/$b" $o} err]} { append failed " - $b: $err\n" } else { set x [lsearch -sorted -exact $all_heads $b] @@ -2229,7 +2339,11 @@ proc do_delete_branch {} { -value head \ -variable delete_branch_checktype \ -font font_ui - eval tk_optionMenu $w.validate.head_m delete_branch_head $all_heads + set mergedlocalm [eval tk_optionMenu $w.validate.head_m \ + delete_branch_head \ + $all_heads] + $mergedlocalm configure -font font_ui + $w.validate.head_m configure -font font_ui grid $w.validate.head_r $w.validate.head_m -sticky w set all_trackings [all_tracking_branches] if {$all_trackings ne {}} { @@ -2239,9 +2353,11 @@ proc do_delete_branch {} { -value tracking \ -variable delete_branch_checktype \ -font font_ui - eval tk_optionMenu $w.validate.tracking_m \ + set mergedtrackm [eval tk_optionMenu $w.validate.tracking_m \ delete_branch_trackinghead \ - $all_trackings + $all_trackings] + $mergedtrackm configure -font font_ui + $w.validate.tracking_m configure -font font_ui grid $w.validate.tracking_r $w.validate.tracking_m -sticky w } radiobutton $w.validate.always_r \ @@ -2276,9 +2392,7 @@ proc switch_branch {new_branch} { } elseif {$commit_type ne $curType || $HEAD ne $curHEAD} { info_popup {Last scanned state does not match repository state. -Another Git program has modified this repository -since the last scan. A rescan must be performed -before the current branch can be changed. +Another Git program has modified this repository since the last scan. A rescan must be performed before the current branch can be changed. The rescan will be automatically started now. } @@ -2366,15 +2480,12 @@ Staying on branch '$current_branch'." # here, it Just Works(tm). If it doesn't we are in some really ugly # state that is difficult to recover from within git-gui. # - if {[catch {exec git symbolic-ref HEAD "refs/heads/$new_branch"} err]} { + if {[catch {git symbolic-ref HEAD "refs/heads/$new_branch"} err]} { error_popup "Failed to set current branch. -This working directory is only partially switched. -We successfully updated your files, but failed to -update an internal Git file. +This working directory is only partially switched. We successfully updated your files, but failed to update an internal Git file. -This should not have occurred. [appname] will now -close and give up. +This should not have occurred. [appname] will now close and give up. $err" do_quit @@ -2578,10 +2689,12 @@ proc do_push_anywhere {} { frame $w.buttons button $w.buttons.create -text Push \ -font font_ui \ + -default active \ -command [list start_push_anywhere_action $w] pack $w.buttons.create -side right button $w.buttons.cancel -text {Cancel} \ -font font_ui \ + -default normal \ -command [list destroy $w] pack $w.buttons.cancel -side right -padx 5 pack $w.buttons -side bottom -fill x -pady 10 -padx 10 @@ -2615,7 +2728,10 @@ proc do_push_anywhere {} { -value remote \ -variable push_urltype \ -font font_ui - eval tk_optionMenu $w.dest.remote_m push_remote $all_remotes + set remmenu [eval tk_optionMenu $w.dest.remote_m push_remote \ + $all_remotes] + $remmenu configure -font font_ui + $w.dest.remote_m configure -font font_ui grid $w.dest.remote_r $w.dest.remote_m -sticky w if {[lsearch -sorted -exact $all_remotes origin] != -1} { set push_remote origin @@ -2669,8 +2785,9 @@ proc do_push_anywhere {} { set push_thin 0 set push_tags 0 - bind $w "grab $w" + bind $w "grab $w; focus $w.buttons.create" bind $w "destroy $w" + bind $w [list start_push_anywhere_action $w] wm title $w "[appname] ([reponame]): Push" tkwait window $w } @@ -2685,8 +2802,7 @@ proc can_merge {} { if {[string match amend* $commit_type]} { info_popup {Cannot merge while amending. -You must finish amending this commit before -starting any type of merge. +You must finish amending this commit before starting any type of merge. } return 0 } @@ -2700,9 +2816,7 @@ starting any type of merge. if {$commit_type ne $curType || $HEAD ne $curHEAD} { info_popup {Last scanned state does not match repository state. -Another Git program has modified this repository -since the last scan. A rescan must be performed -before a merge can be performed. +Another Git program has modified this repository since the last scan. A rescan must be performed before a merge can be performed. The rescan will be automatically started now. } @@ -2721,9 +2835,7 @@ The rescan will be automatically started now. File [short_path $path] has merge conflicts. -You must resolve them, add the file, and commit to -complete the current merge. Only then can you -begin another merge. +You must resolve them, add the file, and commit to complete the current merge. Only then can you begin another merge. " unlock_index return 0 @@ -2733,9 +2845,7 @@ begin another merge. File [short_path $path] is modified. -You should complete the current commit before -starting a merge. Doing so will help you abort -a failed merge, should the need arise. +You should complete the current commit before starting a merge. Doing so will help you abort a failed merge, should the need arise. " unlock_index return 0 @@ -2811,13 +2921,11 @@ proc finish_merge {revcnt w ok} { Your merge of $revcnt branches has failed. -There are file-level conflicts between the -branches which must be resolved manually. +There are file-level conflicts between the branches which must be resolved manually. The working directory will now be reset. -You can attempt this merge again -by merging only one branch at a time." $w +You can attempt this merge again by merging only one branch at a time." $w set fd [open "| git read-tree --reset -u HEAD" r] fconfigure $fd -blocking 0 -translation binary @@ -2876,14 +2984,16 @@ proc do_local_merge {} { pack $w.source -fill both -expand 1 -pady 5 -padx 5 set cmd [list git for-each-ref] - lappend cmd {--format=%(objectname) %(refname)} + lappend cmd {--format=%(objectname) %(*objectname) %(refname)} lappend cmd refs/heads lappend cmd refs/remotes + lappend cmd refs/tags set fr_fd [open "| $cmd" r] fconfigure $fr_fd -translation binary while {[gets $fr_fd line] > 0} { set line [split $line { }] - set sha1([lindex $line 0]) [lindex $line 1] + set sha1([lindex $line 0]) [lindex $line 2] + set sha1([lindex $line 1]) [lindex $line 2] } close $fr_fd @@ -2891,7 +3001,7 @@ proc do_local_merge {} { set fr_fd [open "| git rev-list --all --not HEAD"] while {[gets $fr_fd line] > 0} { if {[catch {set ref $sha1($line)}]} continue - regsub ^refs/(heads|remotes)/ $ref {} ref + regsub ^refs/(heads|remotes|tags)/ $ref {} ref lappend to_show $ref } close $fr_fd @@ -2928,8 +3038,7 @@ You must finish amending this commit. if {[ask_popup "Abort $op? -Aborting the current $op will cause -*ALL* uncommitted changes to be lost. +Aborting the current $op will cause *ALL* uncommitted changes to be lost. Continue with aborting the current $op?"] eq {yes}} { set fd [open "| git read-tree --reset -u HEAD" r] @@ -2972,7 +3081,14 @@ proc new_browser {commit} { global next_browser_id cursor_ptr M1B global browser_commit browser_status browser_stack browser_path browser_busy - set w .browser[incr next_browser_id] + if {[winfo ismapped .]} { + set w .browser[incr next_browser_id] + set tl $w + toplevel $w + } else { + set w {} + set tl . + } set w_list $w.list.l set browser_commit($w_list) $commit set browser_status($w_list) {Starting...} @@ -2980,7 +3096,6 @@ proc new_browser {commit} { set browser_path($w_list) $browser_commit($w_list): set browser_busy($w_list) 1 - toplevel $w label $w.path -textvariable browser_path($w_list) \ -anchor w \ -justify left \ @@ -3030,8 +3145,8 @@ proc new_browser {commit} { bind $w_list break bind $w_list break - bind $w "focus $w" - bind $w " + bind $tl "focus $w" + bind $tl " array unset browser_buffer $w_list array unset browser_files $w_list array unset browser_status $w_list @@ -3040,7 +3155,7 @@ proc new_browser {commit} { array unset browser_commit $w_list array unset browser_busy $w_list " - wm title $w "[appname] ([reponame]): File Browser" + wm title $tl "[appname] ([reponame]): File Browser" ls_tree $w_list $browser_commit($w_list) {} } @@ -3490,12 +3605,14 @@ proc read_blame_incremental {fd w w_load w_cmit w_line w_file} { proc blame_incremental_status {w} { global blame_status blame_data + set have $blame_data($w,blame_lines) + set total $blame_data($w,total_lines) + set pdone 0 + if {$total} {set pdone [expr {100 * $have / $total}]} + set blame_status($w) [format \ "Loading annotations... %i of %i lines annotated (%2i%%)" \ - $blame_data($w,blame_lines) \ - $blame_data($w,total_lines) \ - [expr {100 * $blame_data($w,blame_lines) - / $blame_data($w,total_lines)}]] + $have $total $pdone] } proc blame_click {w w_cmit w_line w_file cur_w pos} { @@ -3993,6 +4110,7 @@ proc console_done {args} { if {[winfo exists $w]} { $w.m.s conf -background green -text {Success} $w.ok conf -state normal + focus $w.ok } } else { if {![winfo exists $w]} { @@ -4000,6 +4118,7 @@ proc console_done {args} { } $w.m.s conf -background red -text {Error: Command Failed} $w.ok conf -state normal + focus $w.ok } array unset console_cr $w @@ -4067,9 +4186,11 @@ proc do_stats {} { frame $w.buttons -border 1 button $w.buttons.close -text Close \ -font font_ui \ + -default active \ -command [list destroy $w] button $w.buttons.gc -text {Compress Database} \ -font font_ui \ + -default normal \ -command "destroy $w;do_gc" pack $w.buttons.close -side right pack $w.buttons.gc -side left @@ -4098,7 +4219,7 @@ proc do_stats {} { } pack $w.stat -pady 10 -padx 10 - bind $w "grab $w; focus $w" + bind $w "grab $w; focus $w.buttons.close" bind $w [list destroy $w] bind $w [list destroy $w] wm title $w "[appname] ([reponame]): Database Statistics" @@ -4161,7 +4282,7 @@ proc do_quit {} { set rc_geometry {} } if {$cfg_geometry ne $rc_geometry} { - catch {exec git config gui.geometry $cfg_geometry} + catch {git config gui.geometry $cfg_geometry} } } @@ -4395,12 +4516,13 @@ proc do_about {} { frame $w.buttons button $w.buttons.close -text {Close} \ -font font_ui \ + -default active \ -command [list destroy $w] pack $w.buttons.close -side right pack $w.buttons -side bottom -fill x -pady 10 -padx 10 label $w.desc \ - -text "[appname] - a commit creation tool for Git. + -text "git-gui - a graphical user interface for Git. $copyright" \ -padx 5 -pady 5 \ -justify left \ @@ -4411,8 +4533,8 @@ $copyright" \ pack $w.desc -side top -fill x -padx 5 -pady 5 set v {} - append v "[appname] version $appvers\n" - append v "[exec git version]\n" + append v "git-gui version $appvers\n" + append v "[git version]\n" append v "\n" if {$tcl_patchLevel eq $tk_patchLevel} { append v "Tcl/Tk version $tcl_patchLevel" @@ -4440,8 +4562,9 @@ $copyright" \ clipboard append -format STRING -type STRING -- \[$w.vers cget -text\] " - bind $w "grab $w; focus $w" + bind $w "grab $w; focus $w.buttons.close" bind $w "destroy $w" + bind $w "destroy $w" bind_button3 $w.vers "tk_popup $w.ctxm %X %Y; grab $w; focus $w" wm title $w "About [appname]" tkwait window $w @@ -4471,21 +4594,24 @@ proc do_options {} { toplevel $w wm geometry $w "+[winfo rootx .]+[winfo rooty .]" - label $w.header -text "[appname] Options" \ + label $w.header -text "Options" \ -font font_uibold pack $w.header -side top -fill x frame $w.buttons button $w.buttons.restore -text {Restore Defaults} \ -font font_ui \ + -default normal \ -command do_restore_defaults pack $w.buttons.restore -side left button $w.buttons.save -text Save \ -font font_ui \ + -default active \ -command [list do_save_config $w] pack $w.buttons.save -side right button $w.buttons.cancel -text {Cancel} \ -font font_ui \ + -default normal \ -command [list destroy $w] pack $w.buttons.cancel -side right -padx 5 pack $w.buttons -side bottom -fill x -pady 10 -padx 10 @@ -4572,9 +4698,11 @@ proc do_options {} { frame $w.global.$name label $w.global.$name.l -text "$text:" -font font_ui pack $w.global.$name.l -side left -anchor w -fill x - eval tk_optionMenu $w.global.$name.family \ + set fontmenu [eval tk_optionMenu $w.global.$name.family \ global_config_new(gui.$font^^family) \ - $all_fonts + $all_fonts] + $w.global.$name.family configure -font font_ui + $fontmenu configure -font font_ui spinbox $w.global.$name.size \ -textvariable global_config_new(gui.$font^^size) \ -from 2 -to 80 -increment 1 \ @@ -4586,8 +4714,9 @@ proc do_options {} { pack $w.global.$name -side top -anchor w -fill x } - bind $w "grab $w; focus $w" + bind $w "grab $w; focus $w.buttons.save" bind $w "destroy $w" + bind $w [list do_save_config $w] wm title $w "[appname] ([reponame]): Options" tkwait window $w } @@ -4945,6 +5074,7 @@ enable_option branch enable_option transport switch -- $subcommand { +browser - blame { disable_option multicommit disable_option branch @@ -4968,18 +5098,18 @@ set ui_comm {} # -- Menu Bar # menu .mbar -tearoff 0 -.mbar add cascade -label Repository -menu .mbar.repository -.mbar add cascade -label Edit -menu .mbar.edit +.mbar add cascade -label Repository -menu .mbar.repository -font font_ui +.mbar add cascade -label Edit -menu .mbar.edit -font font_ui if {[is_enabled branch]} { - .mbar add cascade -label Branch -menu .mbar.branch + .mbar add cascade -label Branch -menu .mbar.branch -font font_ui } if {[is_enabled multicommit] || [is_enabled singlecommit]} { - .mbar add cascade -label Commit -menu .mbar.commit + .mbar add cascade -label Commit -menu .mbar.commit -font font_ui } if {[is_enabled transport]} { - .mbar add cascade -label Merge -menu .mbar.merge - .mbar add cascade -label Fetch -menu .mbar.fetch - .mbar add cascade -label Push -menu .mbar.push + .mbar add cascade -label Merge -menu .mbar.merge -font font_ui + .mbar add cascade -label Fetch -menu .mbar.fetch -font font_ui + .mbar add cascade -label Push -menu .mbar.push -font font_ui } . configure -menu .mbar @@ -5094,6 +5224,12 @@ if {[is_enabled branch]} { -font font_ui lappend disable_on_lock [list .mbar.branch entryconf \ [.mbar.branch index last] -state] + + .mbar.branch add command -label {Reset...} \ + -command do_reset_hard \ + -font font_ui + lappend disable_on_lock [list .mbar.branch entryconf \ + [.mbar.branch index last] -state] } # -- Commit Menu @@ -5168,6 +5304,34 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} { [list .mbar.commit entryconf [.mbar.commit index last] -state] } +# -- Merge Menu +# +if {[is_enabled branch]} { + menu .mbar.merge + .mbar.merge add command -label {Local Merge...} \ + -command do_local_merge \ + -font font_ui + lappend disable_on_lock \ + [list .mbar.merge entryconf [.mbar.merge index last] -state] + .mbar.merge add command -label {Abort Merge...} \ + -command do_reset_hard \ + -font font_ui + lappend disable_on_lock \ + [list .mbar.merge entryconf [.mbar.merge index last] -state] + +} + +# -- Transport Menu +# +if {[is_enabled transport]} { + menu .mbar.fetch + + menu .mbar.push + .mbar.push add command -label {Push...} \ + -command do_push_anywhere \ + -font font_ui +} + if {[is_MacOSX]} { # -- Apple Menu (Mac OS X only) # @@ -5177,7 +5341,7 @@ if {[is_MacOSX]} { .mbar.apple add command -label "About [appname]" \ -command do_about \ -font font_ui - .mbar.apple add command -label "[appname] Options..." \ + .mbar.apple add command -label "Options..." \ -command do_options \ -font font_ui } else { @@ -5221,7 +5385,7 @@ if {[is_MacOSX]} { # -- Help Menu # -.mbar add cascade -label Help -menu .mbar.help +.mbar add cascade -label Help -menu .mbar.help -font font_ui menu .mbar.help if {![is_MacOSX]} { @@ -5236,7 +5400,7 @@ set doc_path [file dirname [gitexec]] set doc_path [file join $doc_path Documentation index.html] if {[is_Cygwin]} { - set doc_path [exec cygpath --windows $doc_path] + set doc_path [exec cygpath --mixed $doc_path] } if {$browser eq {}} { @@ -5280,6 +5444,15 @@ bind all <$M1B-Key-W> {destroy [winfo toplevel %W]} # -- 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 current_branch [lindex $argv 0] + new_browser $current_branch + return +} blame { if {[llength $argv] != 2} { puts stderr "usage: $argv0 blame commit path" @@ -5302,7 +5475,7 @@ gui { # fall through to setup UI for commits } default { - puts stderr "usage: $argv0 \[{blame|citool}\]" + puts stderr "usage: $argv0 \[{blame|browser|citool}\]" exit 1 } } @@ -5326,28 +5499,6 @@ pack .branch.l1 -side left pack .branch.cb -side left -fill x pack .branch -side top -fill x -if {[is_enabled branch]} { - menu .mbar.merge - .mbar.merge add command -label {Local Merge...} \ - -command do_local_merge \ - -font font_ui - lappend disable_on_lock \ - [list .mbar.merge entryconf [.mbar.merge index last] -state] - .mbar.merge add command -label {Abort Merge...} \ - -command do_reset_hard \ - -font font_ui - lappend disable_on_lock \ - [list .mbar.merge entryconf [.mbar.merge index last] -state] - - - menu .mbar.fetch - - menu .mbar.push - .mbar.push add command -label {Push...} \ - -command do_push_anywhere \ - -font font_ui -} - # -- Main Window Layout # panedwindow .vpane -orient vertical @@ -5552,9 +5703,6 @@ bind_button3 $ui_comm "tk_popup $ctxm %X %Y" # -- Diff Header # -set current_diff_path {} -set current_diff_side {} -set diff_actions [list] proc trace_current_diff_path {varname args} { global current_diff_path diff_actions file_states if {$current_diff_path eq {}} { @@ -5747,7 +5895,6 @@ unset ui_diff_applyhunk # -- Status Bar # -set ui_status_value {Initializing...} label .status -textvariable ui_status_value \ -anchor w \ -justify left \ @@ -5821,16 +5968,7 @@ unset i set file_lists($ui_index) [list] set file_lists($ui_workdir) [list] -set HEAD {} -set PARENT {} -set MERGE_HEAD [list] -set commit_type {} -set empty_tree {} -set current_branch {} -set current_diff_path {} -set selected_commit_type new - -wm title . "[appname] ([file normalize [file dirname [gitdir]]])" +wm title . "[appname] ([reponame]) [file normalize [file dirname [gitdir]]]" focus -force $ui_comm # -- Warn the user about environmental problems. Cygwin's Tcl @@ -5904,14 +6042,12 @@ if {[is_enabled transport]} { if {[is_enabled multicommit]} { set object_limit 2000 if {[is_Windows]} {set object_limit 200} - regexp {^([0-9]+) objects,} [exec git count-objects] _junk objects_current + regexp {^([0-9]+) objects,} [git count-objects] _junk objects_current if {$objects_current >= $object_limit} { if {[ask_popup \ "This repository currently has $objects_current loose objects. -To maintain optimal performance it is strongly -recommended that you compress the database -when more than $object_limit loose objects exist. +To maintain optimal performance it is strongly recommended that you compress the database when more than $object_limit loose objects exist. Compress the database now?"] eq yes} { do_gc