diff options
Diffstat (limited to 'git-gui/git-gui.sh')
-rwxr-xr-x | git-gui/git-gui.sh | 175 |
1 files changed, 148 insertions, 27 deletions
diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index fd6a43d0a2..b186329d28 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -137,6 +137,20 @@ unset oguimsg ###################################################################### ## +## On Mac, bring the current Wish process window to front + +if {[tk windowingsystem] eq "aqua"} { + catch { + exec osascript -e [format { + tell application "System Events" + set frontmost of processes whose unix id is %d to true + end tell + } [pid]] + } +} + +###################################################################### +## ## read only globals set _appname {Git Gui} @@ -154,6 +168,7 @@ set _trace [lsearch -exact $argv --trace] if {$_trace >= 0} { set argv [lreplace $argv $_trace $_trace] set _trace 1 + if {[tk windowingsystem] eq "win32"} { console show } } else { set _trace 0 } @@ -299,7 +314,9 @@ proc is_config_true {name} { global repo_config if {[catch {set v $repo_config($name)}]} { return 0 - } elseif {$v eq {true} || $v eq {1} || $v eq {yes}} { + } + set v [string tolower $v] + if {$v eq {} || $v eq {true} || $v eq {1} || $v eq {yes} || $v eq {on}} { return 1 } else { return 0 @@ -310,7 +327,9 @@ proc is_config_false {name} { global repo_config if {[catch {set v $repo_config($name)}]} { return 0 - } elseif {$v eq {false} || $v eq {0} || $v eq {no}} { + } + set v [string tolower $v] + if {$v eq {false} || $v eq {0} || $v eq {no} || $v eq {off}} { return 1 } else { return 0 @@ -460,6 +479,35 @@ proc _which {what args} { return {} } +# Test a file for a hashbang to identify executable scripts on Windows. +proc is_shellscript {filename} { + if {![file exists $filename]} {return 0} + set f [open $filename r] + fconfigure $f -encoding binary + set magic [read $f 2] + close $f + return [expr {$magic eq "#!"}] +} + +# Run a command connected via pipes on stdout. +# This is for use with textconv filters and uses sh -c "..." to allow it to +# contain a command with arguments. On windows we must check for shell +# scripts specifically otherwise just call the filter command. +proc open_cmd_pipe {cmd path} { + global env + if {![file executable [shellpath]]} { + set exe [auto_execok [lindex $cmd 0]] + if {[is_shellscript [lindex $exe 0]]} { + set run [linsert [auto_execok sh] end -c "$cmd \"\$0\"" $path] + } else { + set run [concat $exe [lrange $cmd 1 end] $path] + } + } else { + set run [list [shellpath] -c "$cmd \"\$0\"" $path] + } + return [open |$run r] +} + proc _lappend_nice {cmd_var} { global _nice upvar $cmd_var cmd @@ -725,7 +773,10 @@ if {[is_Windows]} { gitlogo put gray26 -to 5 15 11 16 gitlogo redither - wm iconphoto . -default gitlogo + image create photo gitlogo32 -width 32 -height 32 + gitlogo32 copy gitlogo -zoom 2 2 + + wm iconphoto . -default gitlogo gitlogo32 } } @@ -843,9 +894,11 @@ set default_config(gui.textconv) true set default_config(gui.pruneduringfetch) false set default_config(gui.trustmtime) false set default_config(gui.fastcopyblame) false +set default_config(gui.maxrecentrepo) 10 set default_config(gui.copyblamethreshold) 40 set default_config(gui.blamehistoryctx) 7 set default_config(gui.diffcontext) 5 +set default_config(gui.diffopts) {} set default_config(gui.commitmsgwidth) 75 set default_config(gui.newbranchtemplate) {} set default_config(gui.spellingdictionary) {} @@ -854,10 +907,13 @@ set default_config(gui.fontdiff) [font configure font_diff] # TODO: this option should be added to the git-config documentation set default_config(gui.maxfilesdisplayed) 5000 set default_config(gui.usettk) 1 +set default_config(gui.warndetachedcommit) 1 set font_descs { {fontui font_ui {mc "Main Font"}} {fontdiff font_diff {mc "Diff/Console Font"}} } +set default_config(gui.stageuntracked) ask +set default_config(gui.displayuntracked) true ###################################################################### ## @@ -1059,6 +1115,10 @@ git-version proc _parse_config {arr_name args} { } else { set arr($name) $value } + } elseif {[regexp {^([^\n]+)$} $line line name]} { + # no value given, but interpreting them as + # boolean will be handled as true + set arr($name) {} } } } @@ -1074,6 +1134,10 @@ git-version proc _parse_config {arr_name args} { } else { set arr($name) $value } + } elseif {[regexp {^([^=]+)$} $line line name]} { + # no value given, but interpreting them as + # boolean will be handled as true + set arr($name) {} } } close $fd_rc @@ -1219,8 +1283,12 @@ load_config 0 apply_config # v1.7.0 introduced --show-toplevel to return the canonical work-tree -if {[package vsatisfies $_git_version 1.7.0]} { - set _gitworktree [git rev-parse --show-toplevel] +if {[package vsatisfies $_git_version 1.7.0-]} { + if { [is_Cygwin] } { + catch {set _gitworktree [exec cygpath --windows [git rev-parse --show-toplevel]]} + } else { + set _gitworktree [git rev-parse --show-toplevel] + } } else { # try to set work tree from environment, core.worktree or use # cdup to obtain a relative path to the top of the worktree. If @@ -1416,7 +1484,7 @@ proc rescan {after {honor_trustmtime 1}} { (![$ui_comm edit modified] || [string trim [$ui_comm get 0.0 end]] eq {})} { if {[string match amend* $commit_type]} { - } elseif {[load_message GITGUI_MSG]} { + } elseif {[load_message GITGUI_MSG utf-8]} { } elseif {[run_prepare_commit_msg_hook]} { } elseif {[load_message MERGE_MSG]} { } elseif {[load_message SQUASH_MSG]} { @@ -1471,7 +1539,7 @@ proc rescan_stage2 {fd after} { close $fd } - if {[package vsatisfies $::_git_version 1.6.3]} { + if {[package vsatisfies $::_git_version 1.6.3-]} { set ls_others [list --exclude-standard] } else { set ls_others [list --exclude-per-directory=.gitignore] @@ -1488,21 +1556,30 @@ proc rescan_stage2 {fd after} { set buf_rdf {} set buf_rlo {} - set rescan_active 3 + set rescan_active 2 ui_status [mc "Scanning for modified files ..."] - set fd_di [git_read diff-index --cached -z [PARENT]] + if {[git-version >= "1.7.2"]} { + set fd_di [git_read diff-index --cached --ignore-submodules=dirty -z [PARENT]] + } else { + set fd_di [git_read diff-index --cached -z [PARENT]] + } set fd_df [git_read diff-files -z] - set fd_lo [eval git_read ls-files --others -z $ls_others] fconfigure $fd_di -blocking 0 -translation binary -encoding binary fconfigure $fd_df -blocking 0 -translation binary -encoding binary - fconfigure $fd_lo -blocking 0 -translation binary -encoding binary + fileevent $fd_di readable [list read_diff_index $fd_di $after] fileevent $fd_df readable [list read_diff_files $fd_df $after] - fileevent $fd_lo readable [list read_ls_others $fd_lo $after] + + if {[is_config_true gui.displayuntracked]} { + set fd_lo [eval git_read ls-files --others -z $ls_others] + fconfigure $fd_lo -blocking 0 -translation binary -encoding binary + fileevent $fd_lo readable [list read_ls_others $fd_lo $after] + incr rescan_active + } } -proc load_message {file} { +proc load_message {file {encoding {}}} { global ui_comm set f [gitdir $file] @@ -1511,6 +1588,9 @@ proc load_message {file} { return 0 } fconfigure $fd -eofchar {} + if {$encoding ne {}} { + fconfigure $fd -encoding $encoding + } set content [string trim [read $fd]] close $fd regsub -all -line {[ \r\t]+$} $content {} content @@ -1526,7 +1606,7 @@ proc run_prepare_commit_msg_hook {} { # prepare-commit-msg requires PREPARE_COMMIT_MSG exist. From git-gui # it will be .git/MERGE_MSG (merge), .git/SQUASH_MSG (squash), or an - # empty file but existant file. + # empty file but existent file. set fd_pcm [open [gitdir PREPARE_COMMIT_MSG] a] @@ -2219,6 +2299,7 @@ proc do_quit {{rc {1}}} { && $msg ne {}} { catch { set fd [open $save w] + fconfigure $fd -encoding utf-8 puts -nonewline $fd $msg close $fd } @@ -2473,6 +2554,7 @@ proc toggle_or_diff {w x y} { [concat $after [list ui_ready]] } } else { + set selected_paths($path) 1 show_diff $path $w $lno } } @@ -2587,6 +2669,16 @@ if {![is_bare]} { .mbar.repository add command \ -label [mc "Explore Working Copy"] \ -command {do_explore} +} + +if {[is_Windows]} { + .mbar.repository add command \ + -label [mc "Git Bash"] \ + -command {eval exec [auto_execok start] \ + [list "Git Bash" bash --login -l &]} +} + +if {[is_Windows] || ![is_bare]} { .mbar.repository add separator } @@ -2950,9 +3042,11 @@ blame { set jump_spec {} set is_path 0 foreach a $argv { - if {$is_path || [file exists $_prefix$a]} { + set p [file join $_prefix $a] + + if {$is_path || [file exists $p]} { if {$path ne {}} usage - set path [normalize_relpath $_prefix$a] + set path [normalize_relpath $p] break } elseif {$a eq {--}} { if {$path ne {}} { @@ -2975,8 +3069,13 @@ blame { unset is_path if {$head ne {} && $path eq {}} { - set path [normalize_relpath $_prefix$head] - set head {} + if {[string index $head 0] eq {/}} { + set path [normalize_relpath $head] + set head {} + } else { + set path [normalize_relpath $_prefix$head] + set head {} + } } if {$head eq {}} { @@ -3129,13 +3228,29 @@ unset i # -- Diff and Commit Area # -${NS}::frame .vpane.lower -height 300 -width 400 -${NS}::frame .vpane.lower.commarea -${NS}::frame .vpane.lower.diff -relief sunken -borderwidth 1 -pack .vpane.lower.diff -fill both -expand 1 -pack .vpane.lower.commarea -side bottom -fill x -.vpane add .vpane.lower -if {!$use_ttk} {.vpane paneconfigure .vpane.lower -sticky nsew} +if {$have_tk85} { + ${NS}::panedwindow .vpane.lower -orient vertical + ${NS}::frame .vpane.lower.commarea + ${NS}::frame .vpane.lower.diff -relief sunken -borderwidth 1 -height 500 + .vpane.lower add .vpane.lower.diff + .vpane.lower add .vpane.lower.commarea + .vpane add .vpane.lower + if {$use_ttk} { + .vpane.lower pane .vpane.lower.diff -weight 1 + .vpane.lower pane .vpane.lower.commarea -weight 0 + } else { + .vpane.lower paneconfigure .vpane.lower.diff -stretch always + .vpane.lower paneconfigure .vpane.lower.commarea -stretch never + } +} else { + frame .vpane.lower -height 300 -width 400 + frame .vpane.lower.commarea + frame .vpane.lower.diff -relief sunken -borderwidth 1 + pack .vpane.lower.diff -fill both -expand 1 + pack .vpane.lower.commarea -side bottom -fill x + .vpane add .vpane.lower + .vpane paneconfigure .vpane.lower -sticky nsew +} # -- Commit Area Buttons # @@ -3361,6 +3476,7 @@ foreach {n c} {0 black 1 red4 2 green4 3 yellow4 4 blue4 5 magenta4 6 cyan4 7 gr $ui_diff tag configure clri3$n -background $c } $ui_diff tag configure clr1 -font font_diffbold +$ui_diff tag configure clr4 -underline 1 $ui_diff tag conf d_info -foreground blue -font font_diffbold @@ -3661,6 +3777,8 @@ bind $ui_diff <$M1B-Key-v> {break} bind $ui_diff <$M1B-Key-V> {break} bind $ui_diff <$M1B-Key-a> {%W tag add sel 0.0 end;break} bind $ui_diff <$M1B-Key-A> {%W tag add sel 0.0 end;break} +bind $ui_diff <$M1B-Key-j> {do_revert_selection;break} +bind $ui_diff <$M1B-Key-J> {do_revert_selection;break} bind $ui_diff <Key-Up> {catch {%W yview scroll -1 units};break} bind $ui_diff <Key-Down> {catch {%W yview scroll 1 units};break} bind $ui_diff <Key-Left> {catch {%W xview scroll -1 units};break} @@ -3693,6 +3811,8 @@ bind . <$M1B-Key-s> do_signoff bind . <$M1B-Key-S> do_signoff bind . <$M1B-Key-t> do_add_selection bind . <$M1B-Key-T> do_add_selection +bind . <$M1B-Key-u> do_unstage_selection +bind . <$M1B-Key-U> do_unstage_selection bind . <$M1B-Key-j> do_revert_selection bind . <$M1B-Key-J> do_revert_selection bind . <$M1B-Key-i> do_add_all @@ -3786,7 +3906,7 @@ if {[is_enabled transport]} { } if {[winfo exists $ui_comm]} { - set GITGUI_BCK_exists [load_message GITGUI_BCK] + set GITGUI_BCK_exists [load_message GITGUI_BCK utf-8] # -- If both our backup and message files exist use the # newer of the two files to initialize the buffer. @@ -3823,6 +3943,7 @@ if {[winfo exists $ui_comm]} { } elseif {$m} { catch { set fd [open [gitdir GITGUI_BCK] w] + fconfigure $fd -encoding utf-8 puts -nonewline $fd $msg close $fd set GITGUI_BCK_exists 1 @@ -3877,7 +3998,7 @@ after 1 { $ui_comm configure -state disabled -background gray } } -if {[is_enabled multicommit]} { +if {[is_enabled multicommit] && ![is_config_false gui.gcwarning]} { after 1000 hint_gc } if {[is_enabled retcode]} { |