diff options
Diffstat (limited to 'git-gui/lib')
| -rw-r--r-- | git-gui/lib/blame.tcl | 16 | ||||
| -rw-r--r-- | git-gui/lib/branch_delete.tcl | 4 | ||||
| -rw-r--r-- | git-gui/lib/checkout_op.tcl | 43 | ||||
| -rw-r--r-- | git-gui/lib/choose_repository.tcl | 37 | ||||
| -rw-r--r-- | git-gui/lib/commit.tcl | 35 | ||||
| -rw-r--r-- | git-gui/lib/database.tcl | 21 | ||||
| -rw-r--r-- | git-gui/lib/diff.tcl | 42 | ||||
| -rw-r--r-- | git-gui/lib/index.tcl | 34 | ||||
| -rw-r--r-- | git-gui/lib/mergetool.tcl | 4 | ||||
| -rw-r--r-- | git-gui/lib/remote_branch_delete.tcl | 26 | ||||
| -rw-r--r-- | git-gui/lib/shortcut.tcl | 2 | ||||
| -rw-r--r-- | git-gui/lib/tools.tcl | 2 |
12 files changed, 202 insertions, 64 deletions
diff --git a/git-gui/lib/blame.tcl b/git-gui/lib/blame.tcl index 1f3b08f9ef..8525b79aaa 100644 --- a/git-gui/lib/blame.tcl +++ b/git-gui/lib/blame.tcl @@ -1245,6 +1245,18 @@ method _open_tooltip {cur_w} { $tooltip_t conf -state disabled _position_tooltip $this + + # On MacOS raising a window causes it to acquire focus. + # Tk 8.5 on MacOS seems to properly support wm transient, + # so we can safely counter the effect there. + if {$::have_tk85 && [is_MacOSX]} { + update + if {$w eq {}} { + raise . + } else { + raise $w + } + } } method _position_tooltip {} { @@ -1268,7 +1280,9 @@ method _position_tooltip {} { append g $pos_y wm geometry $tooltip_wm $g - raise $tooltip_wm + if {![is_MacOSX]} { + raise $tooltip_wm + } } method _hide_tooltip {} { diff --git a/git-gui/lib/branch_delete.tcl b/git-gui/lib/branch_delete.tcl index ef1930b491..20d5e42307 100644 --- a/git-gui/lib/branch_delete.tcl +++ b/git-gui/lib/branch_delete.tcl @@ -51,7 +51,7 @@ constructor dialog {} { $w.check \ [mc "Delete Only If Merged Into"] \ ] - $w_check none [mc "Always (Do not perform merge test.)"] + $w_check none [mc "Always (Do not perform merge checks)"] pack $w.check -anchor nw -fill x -pady 5 -padx 5 foreach h [load_all_heads] { @@ -112,7 +112,7 @@ method _delete {} { } if {$to_delete eq {}} return if {$check_cmt eq {}} { - set msg [mc "Recovering deleted branches is difficult. \n\n Delete the selected branches?"] + set msg [mc "Recovering deleted branches is difficult.\n\nDelete the selected branches?"] if {[tk_messageBox \ -icon warning \ -type yesno \ diff --git a/git-gui/lib/checkout_op.tcl b/git-gui/lib/checkout_op.tcl index caca88831b..9e7412c446 100644 --- a/git-gui/lib/checkout_op.tcl +++ b/git-gui/lib/checkout_op.tcl @@ -9,6 +9,7 @@ field w_cons {}; # embedded console window object field new_expr ; # expression the user saw/thinks this is field new_hash ; # commit SHA-1 we are switching to field new_ref ; # ref we are updating/creating +field old_hash ; # commit SHA-1 that was checked out when we started field parent_w .; # window that started us field merge_type none; # type of merge to apply to existing branch @@ -280,11 +281,11 @@ method _start_checkout {} { # -- Our in memory state should match the repository. # - repository_state curType curHEAD curMERGE_HEAD + repository_state curType old_hash curMERGE_HEAD if {[string match amend* $commit_type] && $curType eq {normal} - && $curHEAD eq $HEAD} { - } elseif {$commit_type ne $curType || $HEAD ne $curHEAD} { + && $old_hash eq $HEAD} { + } elseif {$commit_type ne $curType || $HEAD ne $old_hash} { info_popup [mc "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. @@ -297,7 +298,7 @@ The rescan will be automatically started now. return } - if {$curHEAD eq $new_hash} { + if {$old_hash eq $new_hash} { _after_readtree $this } elseif {[is_config_true gui.trustmtime]} { _readtree $this @@ -453,13 +454,47 @@ method _after_readtree {} { If you wanted to be on a branch, create one now starting from 'This Detached Checkout'."] } + # -- Run the post-checkout hook. + # + set fd_ph [githook_read post-checkout $old_hash $new_hash 1] + if {$fd_ph ne {}} { + global pch_error + set pch_error {} + fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fileevent $fd_ph readable [cb _postcheckout_wait $fd_ph] + } else { + _update_repo_state $this + } +} + +method _postcheckout_wait {fd_ph} { + global pch_error + + append pch_error [read $fd_ph] + fconfigure $fd_ph -blocking 1 + if {[eof $fd_ph]} { + if {[catch {close $fd_ph}]} { + hook_failed_popup post-checkout $pch_error 0 + } + unset pch_error + _update_repo_state $this + return + } + fconfigure $fd_ph -blocking 0 +} + +method _update_repo_state {} { # -- Update our repository state. If we were previously in # amend mode we need to toss the current buffer and do a # full rescan to update our file lists. If we weren't in # amend mode our file lists are accurate and we can avoid # the rescan. # + global selected_commit_type commit_type HEAD MERGE_HEAD PARENT + global ui_comm + unlock_index + set name [_name $this] set selected_commit_type new if {[string match amend* $commit_type]} { $ui_comm delete 0.0 end diff --git a/git-gui/lib/choose_repository.tcl b/git-gui/lib/choose_repository.tcl index f9ff62a3b2..3f8f3030fa 100644 --- a/git-gui/lib/choose_repository.tcl +++ b/git-gui/lib/choose_repository.tcl @@ -235,6 +235,8 @@ proc _get_recentrepos {} { foreach p [get_config gui.recentrepo] { if {[_is_git [file join $p .git]]} { lappend recent $p + } else { + _unset_recentrepo $p } } return [lsort $recent] @@ -243,6 +245,7 @@ proc _get_recentrepos {} { proc _unset_recentrepo {p} { regsub -all -- {([()\[\]{}\.^$+*?\\])} $p {\\\1} p git config --global --unset gui.recentrepo "^$p\$" + load_config 1 } proc _append_recentrepos {path} { @@ -261,6 +264,7 @@ proc _append_recentrepos {path} { lappend recent $path git config --global --add gui.recentrepo $path + load_config 1 while {[llength $recent] > 10} { _unset_recentrepo [lindex $recent 0] @@ -398,6 +402,8 @@ method _do_new {} { grid $w_body.where.l $w_body.where.t $w_body.where.b -sticky ew pack $w_body.where -fill x + grid columnconfigure $w_body.where 1 -weight 1 + trace add variable @local_path write [cb _write_local_path] bind $w_body.h <Destroy> [list trace remove variable @local_path write [cb _write_local_path]] update @@ -964,7 +970,34 @@ method _readtree_wait {fd} { return } - set done 1 + # -- Run the post-checkout hook. + # + set fd_ph [githook_read post-checkout [string repeat 0 40] \ + [git rev-parse HEAD] 1] + if {$fd_ph ne {}} { + global pch_error + set pch_error {} + fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fileevent $fd_ph readable [cb _postcheckout_wait $fd_ph] + } else { + set done 1 + } +} + +method _postcheckout_wait {fd_ph} { + global pch_error + + append pch_error [read $fd_ph] + fconfigure $fd_ph -blocking 1 + if {[eof $fd_ph]} { + if {[catch {close $fd_ph}]} { + hook_failed_popup post-checkout $pch_error 0 + } + unset pch_error + set done 1 + return + } + fconfigure $fd_ph -blocking 0 } ###################################################################### @@ -998,6 +1031,8 @@ method _do_open {} { grid $w_body.where.l $w_body.where.t $w_body.where.b -sticky ew pack $w_body.where -fill x + grid columnconfigure $w_body.where 1 -weight 1 + trace add variable @local_path write [cb _write_local_path] bind $w_body.h <Destroy> [list trace remove variable @local_path write [cb _write_local_path]] update diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 9cc8410595..7f459cd564 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -115,6 +115,23 @@ proc create_new_commit {} { rescan ui_ready } +proc setup_commit_encoding {msg_wt {quiet 0}} { + global repo_config + + if {[catch {set enc $repo_config(i18n.commitencoding)}]} { + set enc utf-8 + } + set use_enc [tcl_encoding $enc] + if {$use_enc ne {}} { + fconfigure $msg_wt -encoding $use_enc + } else { + if {!$quiet} { + error_popup [mc "warning: Tcl does not support encoding '%s'." $enc] + } + fconfigure $msg_wt -encoding utf-8 + } +} + proc commit_tree {} { global HEAD commit_type file_states ui_comm repo_config global pch_error @@ -200,16 +217,7 @@ A good commit message has the following format: set msg_p [gitdir GITGUI_EDITMSG] set msg_wt [open $msg_p w] fconfigure $msg_wt -translation lf - if {[catch {set enc $repo_config(i18n.commitencoding)}]} { - set enc utf-8 - } - set use_enc [tcl_encoding $enc] - if {$use_enc ne {}} { - fconfigure $msg_wt -encoding $use_enc - } else { - error_popup [mc "warning: Tcl does not support encoding '%s'." $enc] - fconfigure $msg_wt -encoding utf-8 - } + setup_commit_encoding $msg_wt puts $msg_wt $msg close $msg_wt @@ -362,6 +370,7 @@ A rescan will be automatically started now. append reflogm " ($commit_type)" } set msg_fd [open $msg_p r] + setup_commit_encoding $msg_fd 1 gets $msg_fd subject close $msg_fd append reflogm {: } $subject @@ -398,8 +407,8 @@ A rescan will be automatically started now. # set fd_ph [githook_read post-commit] if {$fd_ph ne {}} { - upvar #0 pch_error$cmt_id pc_err - set pc_err {} + global pch_error + set pch_error {} fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} fileevent $fd_ph readable \ [list commit_postcommit_wait $fd_ph $cmt_id] @@ -461,7 +470,7 @@ A rescan will be automatically started now. } proc commit_postcommit_wait {fd_ph cmt_id} { - upvar #0 pch_error$cmt_id pch_error + global pch_error append pch_error [read $fd_ph] fconfigure $fd_ph -blocking 1 diff --git a/git-gui/lib/database.tcl b/git-gui/lib/database.tcl index a18ac8b430..d4e0bed0b6 100644 --- a/git-gui/lib/database.tcl +++ b/git-gui/lib/database.tcl @@ -89,27 +89,26 @@ proc do_fsck_objects {} { } proc hint_gc {} { - set object_limit 8 + set ndirs 1 + set limit 8 if {[is_Windows]} { - set object_limit 1 + set ndirs 4 + set limit 1 } - set objects_current [llength [glob \ - -directory [gitdir objects 42] \ + set count [llength [glob \ -nocomplain \ - -tails \ -- \ - *]] + [gitdir objects 4\[0-[expr {$ndirs-1}]\]/*]]] - if {$objects_current >= $object_limit} { - set objects_current [expr {$objects_current * 250}] - set object_limit [expr {$object_limit * 250}] + if {$count >= $limit * $ndirs} { + set objects_current [expr {$count * 256/$ndirs}] if {[ask_popup \ [mc "This repository currently has approximately %i loose objects. -To maintain optimal performance it is strongly recommended that you compress the database when more than %i loose objects exist. +To maintain optimal performance it is strongly recommended that you compress the database. -Compress the database now?" $objects_current $object_limit]] eq yes} { +Compress the database now?" $objects_current]] eq yes} { do_gc } } diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl index bbbf15c875..066755b864 100644 --- a/git-gui/lib/diff.tcl +++ b/git-gui/lib/diff.tcl @@ -51,11 +51,16 @@ proc force_diff_encoding {enc} { proc handle_empty_diff {} { global current_diff_path file_states file_lists + global diff_empty_count set path $current_diff_path set s $file_states($path) if {[lindex $s 0] ne {_M}} return + # Prevent infinite rescan loops + incr diff_empty_count + if {$diff_empty_count > 1} return + info_popup [mc "No differences detected. %s has no changes. @@ -250,7 +255,7 @@ proc show_other_diff {path w m cont_info} { proc start_show_diff {cont_info {add_opts {}}} { global file_states file_lists - global is_3way_diff diff_active repo_config + global is_3way_diff is_submodule_diff diff_active repo_config global ui_diff ui_index ui_workdir global current_diff_path current_diff_side current_diff_header @@ -260,6 +265,7 @@ proc start_show_diff {cont_info {add_opts {}}} { set s $file_states($path) set m [lindex $s 0] set is_3way_diff 0 + set is_submodule_diff 0 set diff_active 1 set current_diff_header {} @@ -290,6 +296,16 @@ proc start_show_diff {cont_info {add_opts {}}} { lappend cmd $path } + if {[string match {160000 *} [lindex $s 2]] + || [string match {160000 *} [lindex $s 3]]} { + set is_submodule_diff 1 + if {$w eq $ui_index} { + set cmd [list submodule summary --cached -- $path] + } else { + set cmd [list submodule summary --files -- $path] + } + } + if {[catch {set fd [eval git_read --nice $cmd]} err]} { set diff_active 0 unlock_index @@ -307,9 +323,10 @@ proc start_show_diff {cont_info {add_opts {}}} { } proc read_diff {fd cont_info} { - global ui_diff diff_active + global ui_diff diff_active is_submodule_diff global is_3way_diff is_conflict_diff current_diff_header global current_diff_queue + global diff_empty_count $ui_diff conf -state normal while {[gets $fd line] >= 0} { @@ -368,6 +385,23 @@ proc read_diff {fd cont_info} { set tags {} } } + } elseif {$is_submodule_diff} { + if {$line == ""} continue + if {[regexp {^\* } $line]} { + set line [string replace $line 0 1 {Submodule }] + set tags d_@ + } else { + set op [string range $line 0 2] + switch -- $op { + { <} {set tags d_-} + { >} {set tags d_+} + { W} {set tags {}} + default { + puts "error: Unhandled submodule diff marker: {$op}" + set tags {} + } + } + } } else { set op [string index $line 0] switch -- $op { @@ -415,7 +449,10 @@ proc read_diff {fd cont_info} { if {[$ui_diff index end] eq {2.0}} { handle_empty_diff + } else { + set diff_empty_count 0 } + set callback [lindex $cont_info 1] if {$callback ne {}} { eval $callback @@ -627,6 +664,7 @@ proc apply_line {x y} { } set i_l $next_l } + set patch "$patch$pre_context" set patch "@@ -$hln,$n +$hln,[eval expr $n $sign 1] @@\n$patch" if {[catch { diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl index d33896a0ce..0b58bd8876 100644 --- a/git-gui/lib/index.tcl +++ b/git-gui/lib/index.tcl @@ -14,29 +14,31 @@ proc _close_updateindex {fd after} { toplevel $w wm title $w [strcat "[appname] ([reponame]): " [mc "Index Error"]] wm geometry $w "+[winfo rootx .]+[winfo rooty .]" - pack [label $w.msg \ - -justify left \ - -anchor w \ - -text [strcat \ - [mc "Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui."] \ - "\n\n$err"] \ - ] -anchor w - - frame $w.buttons - button $w.buttons.continue \ + set s [mc "Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui."] + text $w.msg -yscrollcommand [list $w.vs set] \ + -width [string length $s] -relief flat \ + -borderwidth 0 -highlightthickness 0 \ + -background [$w cget -background] + $w.msg tag configure bold -font font_uibold -justify center + scrollbar $w.vs -command [list $w.msg yview] + $w.msg insert end $s bold \n\n$err {} + $w.msg configure -state disabled + + button $w.continue \ -text [mc "Continue"] \ -command [list destroy $w] - pack $w.buttons.continue -side right -padx 5 - button $w.buttons.unlock \ + button $w.unlock \ -text [mc "Unlock Index"] \ -command "destroy $w; _delete_indexlock" - pack $w.buttons.unlock -side right - pack $w.buttons -side bottom -fill x -pady 10 -padx 10 + grid $w.msg - $w.vs -sticky news + grid $w.unlock $w.continue - -sticky se -padx 2 -pady 2 + grid columnconfigure $w 0 -weight 1 + grid rowconfigure $w 0 -weight 1 wm protocol $w WM_DELETE_WINDOW update - bind $w.buttons.continue <Visibility> " + bind $w.continue <Visibility> " grab $w - focus $w.buttons.continue + focus %W " tkwait window $w diff --git a/git-gui/lib/mergetool.tcl b/git-gui/lib/mergetool.tcl index eb2b4b56a4..3fe90e6970 100644 --- a/git-gui/lib/mergetool.tcl +++ b/git-gui/lib/mergetool.tcl @@ -88,7 +88,7 @@ proc merge_load_stages {path cont} { set merge_stages(3) {} set merge_stages_buf {} - set merge_stages_fd [eval git_read ls-files -u -z -- $path] + set merge_stages_fd [eval git_read ls-files -u -z -- {$path}] fconfigure $merge_stages_fd -blocking 0 -translation binary -encoding binary fileevent $merge_stages_fd readable [list read_merge_stages $merge_stages_fd $cont] @@ -382,7 +382,7 @@ proc merge_tool_finish {fd} { delete_temp_files $mtool_tmpfiles ui_status [mc "Merge tool failed."] } else { - if {[is_config_true merge.keepbackup]} { + if {[is_config_true mergetool.keepbackup]} { file rename -force -- $backup "$mtool_target.orig" } diff --git a/git-gui/lib/remote_branch_delete.tcl b/git-gui/lib/remote_branch_delete.tcl index 89eb0f70f2..241642062e 100644 --- a/git-gui/lib/remote_branch_delete.tcl +++ b/git-gui/lib/remote_branch_delete.tcl @@ -208,15 +208,15 @@ method _delete {} { return } - if {[tk_messageBox \ - -icon warning \ - -type yesno \ - -title [wm title $w] \ - -parent $w \ - -message [mc "Recovering deleted branches is difficult. - -Delete the selected branches?"]] ne yes} { - return + if {$checktype ne {head}} { + if {[tk_messageBox \ + -icon warning \ + -type yesno \ + -title [wm title $w] \ + -parent $w \ + -message [mc "Recovering deleted branches is difficult.\n\nDelete the selected branches?"]] ne yes} { + return + } } destroy $w @@ -250,6 +250,8 @@ method _write_url {args} { set urltype url } method _write_check_head {args} { set checktype head } method _write_head_list {args} { + global current_branch + $head_m delete 0 end foreach abr $head_list { $head_m insert end radiobutton \ @@ -258,7 +260,11 @@ method _write_head_list {args} { -variable @check_head } if {[lsearch -exact -sorted $head_list $check_head] < 0} { - set check_head {} + if {[lsearch -exact -sorted $head_list $current_branch] < 0} { + set check_head {} + } else { + set check_head $current_branch + } } } diff --git a/git-gui/lib/shortcut.tcl b/git-gui/lib/shortcut.tcl index 38c3151b05..2f20eb39c0 100644 --- a/git-gui/lib/shortcut.tcl +++ b/git-gui/lib/shortcut.tcl @@ -54,7 +54,7 @@ proc do_cygwin_shortcut {} { $argv0] win32_create_lnk $fn [list \ $sh -c \ - "CHERE_INVOKING=1 source /etc/profile;[sq $me]" \ + "CHERE_INVOKING=1 source /etc/profile;[sq $me] &" \ ] \ [file dirname [file normalize [gitdir]]] } err]} { diff --git a/git-gui/lib/tools.tcl b/git-gui/lib/tools.tcl index 6ae63b6c7c..95e6e5553e 100644 --- a/git-gui/lib/tools.tcl +++ b/git-gui/lib/tools.tcl @@ -146,7 +146,7 @@ proc tools_complete {fullname w {ok 1}} { } if {$ok} { - set msg [mc "Tool completed succesfully: %s" $fullname] + set msg [mc "Tool completed successfully: %s" $fullname] } else { set msg [mc "Tool failed: %s" $fullname] } |
