提交 392f1300 编写于 作者: J Junio C Hamano

Merge git://repo.or.cz/git-gui

* git://repo.or.cz/git-gui:
  git-gui: "Stage Line": Treat independent changes in adjacent lines better
  git-gui: Fix "Stage/Unstage Line" with one line of context.
  git-gui: Correct 'Visualize Branches' on Mac OS X to start gitk
  git-gui: Look for gitk in $PATH, not $LIBEXEC/git-core
  Add a menu item to invoke full copy detection in blame.
  Kill the blame back-end on window close.
  Add options to control the search for copies in blame.
  Fix pre-commit hooks under MinGW/MSYS
......@@ -473,10 +473,10 @@ proc githook_read {hook_name args} {
set pchook [gitdir hooks $hook_name]
lappend args 2>@1
# On Cygwin [file executable] might lie so we need to ask
# On Windows [file executable] might lie so we need to ask
# the shell if the hook is executable. Yes that's annoying.
#
if {[is_Cygwin]} {
if {[is_Windows]} {
upvar #0 _sh interp
if {![info exists interp]} {
set interp [_which sh]
......@@ -497,6 +497,20 @@ proc githook_read {hook_name args} {
return {}
}
proc kill_file_process {fd} {
set process [pid $fd]
catch {
if {[is_Windows]} {
# Use a Cygwin-specific flag to allow killing
# native Windows processes
exec kill -f $process
} else {
exec kill $process
}
}
}
proc sq {value} {
regsub -all ' $value "'\\''" value
return "'$value'"
......@@ -642,6 +656,8 @@ set default_config(user.email) {}
set default_config(gui.matchtrackingbranch) false
set default_config(gui.pruneduringfetch) false
set default_config(gui.trustmtime) false
set default_config(gui.fastcopyblame) false
set default_config(gui.copyblamethreshold) 40
set default_config(gui.diffcontext) 5
set default_config(gui.commitmsgwidth) 75
set default_config(gui.newbranchtemplate) {}
......@@ -1670,10 +1686,10 @@ proc do_gitk {revs} {
# -- Always start gitk through whatever we were loaded with. This
# lets us bypass using shell process on Windows systems.
#
set exe [file join [file dirname $::_git] gitk]
set exe [_which gitk]
set cmd [list [info nameofexecutable] $exe]
if {! [file exists $exe]} {
error_popup [mc "Unable to start gitk:\n\n%s does not exist" $exe]
if {$exe eq {}} {
error_popup [mc "Couldn't find gitk in PATH"]
} else {
global env
......
......@@ -33,13 +33,6 @@ variable group_colors {
#ececec
}
# Switches for original location detection
#
variable original_options [list -C -C]
if {[git-version >= 1.5.3]} {
lappend original_options -w ; # ignore indentation changes
}
# Current blame data; cleared/reset on each load
#
field commit ; # input commit to blame
......@@ -263,6 +256,9 @@ constructor new {i_commit i_path} {
$w.ctxm add command \
-label [mc "Copy Commit"] \
-command [cb _copycommit]
$w.ctxm add command \
-label [mc "Do Full Copy Detection"] \
-command [cb _fullcopyblame]
foreach i $w_columns {
for {set g 0} {$g < [llength $group_colors]} {incr g} {
......@@ -333,19 +329,27 @@ constructor new {i_commit i_path} {
bind $w.file_pane <Configure> \
"if {{$w.file_pane} eq {%W}} {[cb _resize %h]}"
wm protocol $top WM_DELETE_WINDOW "destroy $top"
bind $top <Destroy> [cb _kill]
_load $this {}
}
method _kill {} {
if {$current_fd ne {}} {
kill_file_process $current_fd
catch {close $current_fd}
set current_fd {}
}
}
method _load {jump} {
variable group_colors
_hide_tooltip $this
if {$total_lines != 0 || $current_fd ne {}} {
if {$current_fd ne {}} {
catch {close $current_fd}
set current_fd {}
}
_kill $this
foreach i $w_columns {
$i conf -state normal
......@@ -511,7 +515,6 @@ method _exec_blame {cur_w cur_d options cur_s} {
method _read_blame {fd cur_w cur_d} {
upvar #0 $cur_d line_data
variable group_colors
variable original_options
if {$fd ne $current_fd} {
catch {close $fd}
......@@ -684,6 +687,18 @@ method _read_blame {fd cur_w cur_d} {
if {[eof $fd]} {
close $fd
if {$cur_w eq $w_asim} {
# Switches for original location detection
set threshold [get_config gui.copyblamethreshold]
set original_options [list "-C$threshold"]
if {![is_config_true gui.fastcopyblame]} {
# thorough copy search; insert before the threshold
set original_options [linsert $original_options 0 -C]
}
if {[git-version >= 1.5.3]} {
lappend original_options -w ; # ignore indentation changes
}
_exec_blame $this $w_amov @amov_data \
$original_options \
[mc "Loading original location annotations..."]
......@@ -696,6 +711,72 @@ method _read_blame {fd cur_w cur_d} {
}
} ifdeleted { catch {close $fd} }
method _find_commit_bound {data_list start_idx delta} {
upvar #0 $data_list line_data
set pos $start_idx
set limit [expr {[llength $line_data] - 1}]
set base_commit [lindex $line_data $pos 0]
while {$pos > 0 && $pos < $limit} {
set new_pos [expr {$pos + $delta}]
if {[lindex $line_data $new_pos 0] ne $base_commit} {
return $pos
}
set pos $new_pos
}
return $pos
}
method _fullcopyblame {} {
if {$current_fd ne {}} {
tk_messageBox \
-icon error \
-type ok \
-title [mc "Busy"] \
-message [mc "Annotation process is already running."]
return
}
# Switches for original location detection
set threshold [get_config gui.copyblamethreshold]
set original_options [list -C -C "-C$threshold"]
if {[git-version >= 1.5.3]} {
lappend original_options -w ; # ignore indentation changes
}
# Find the line range
set pos @$::cursorX,$::cursorY
set lno [lindex [split [$::cursorW index $pos] .] 0]
set min_amov_lno [_find_commit_bound $this @amov_data $lno -1]
set max_amov_lno [_find_commit_bound $this @amov_data $lno 1]
set min_asim_lno [_find_commit_bound $this @asim_data $lno -1]
set max_asim_lno [_find_commit_bound $this @asim_data $lno 1]
if {$min_asim_lno < $min_amov_lno} {
set min_amov_lno $min_asim_lno
}
if {$max_asim_lno > $max_amov_lno} {
set max_amov_lno $max_asim_lno
}
lappend original_options -L "$min_amov_lno,$max_amov_lno"
# Clear lines
for {set i $min_amov_lno} {$i <= $max_amov_lno} {incr i} {
lset amov_data $i [list ]
}
# Start the back-end process
_exec_blame $this $w_amov @amov_data \
$original_options \
[mc "Running thorough copy detection..."]
}
method _click {cur_w pos} {
set lno [lindex [split [$cur_w index $pos] .] 0]
_showcommit $this $cur_w $lno
......
......@@ -411,6 +411,53 @@ proc apply_line {x y} {
set hh [lindex [split $hh ,] 0]
set hln [lindex [split $hh -] 1]
# There is a special situation to take care of. Consider this hunk:
#
# @@ -10,4 +10,4 @@
# context before
# -old 1
# -old 2
# +new 1
# +new 2
# context after
#
# We used to keep the context lines in the order they appear in the
# hunk. But then it is not possible to correctly stage only
# "-old 1" and "+new 1" - it would result in this staged text:
#
# context before
# old 2
# new 1
# context after
#
# (By symmetry it is not possible to *un*stage "old 2" and "new 2".)
#
# We resolve the problem by introducing an asymmetry, namely, when
# a "+" line is *staged*, it is moved in front of the context lines
# that are generated from the "-" lines that are immediately before
# the "+" block. That is, we construct this patch:
#
# @@ -10,4 +10,5 @@
# context before
# +new 1
# old 1
# old 2
# context after
#
# But we do *not* treat "-" lines that are *un*staged in a special
# way.
#
# With this asymmetry it is possible to stage the change
# "old 1" -> "new 1" directly, and to stage the change
# "old 2" -> "new 2" by first staging the entire hunk and
# then unstaging the change "old 1" -> "new 1".
# This is non-empty if and only if we are _staging_ changes;
# then it accumulates the consecutive "-" lines (after converting
# them to context lines) in order to be moved after the "+" change
# line.
set pre_context {}
set n 0
set i_l [$ui_diff index "$i_l + 1 lines"]
set patch {}
......@@ -422,16 +469,27 @@ proc apply_line {x y} {
[$ui_diff compare $the_l < $next_l]} {
# the line to stage/unstage
set ln [$ui_diff get $i_l $next_l]
set patch "$patch$ln"
if {$c1 eq {-}} {
set n [expr $n+1]
set patch "$patch$pre_context$ln"
} else {
set patch "$patch$ln$pre_context"
}
set pre_context {}
} elseif {$c1 ne {-} && $c1 ne {+}} {
# context line
set ln [$ui_diff get $i_l $next_l]
set patch "$patch$ln"
set patch "$patch$pre_context$ln"
set n [expr $n+1]
set pre_context {}
} elseif {$c1 eq $to_context} {
# turn change line into context line
set ln [$ui_diff get "$i_l + 1 chars" $next_l]
set patch "$patch $ln"
if {$c1 eq {-}} {
set pre_context "$pre_context $ln"
} else {
set patch "$patch $ln"
}
set n [expr $n+1]
}
set i_l $next_l
......
......@@ -123,6 +123,8 @@ proc do_options {} {
{b gui.trustmtime {mc "Trust File Modification Timestamps"}}
{b gui.pruneduringfetch {mc "Prune Tracking Branches During Fetch"}}
{b gui.matchtrackingbranch {mc "Match Tracking Branches"}}
{b gui.fastcopyblame {mc "Blame Copy Only On Changed Files"}}
{i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}}
{i-0..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
{i-0..99 gui.commitmsgwidth {mc "Commit Message Text Width"}}
{t gui.newbranchtemplate {mc "New Branch Name Template"}}
......
......@@ -7,7 +7,7 @@ if {[string first -psn [lindex $argv 0]] == 0} {
}
if {[file tail [lindex $argv 0]] eq {gitk}} {
set argv0 [file join $gitexecdir gitk]
set argv0 [lindex $argv 0]
set AppMain_source $argv0
} else {
set argv0 [file join $gitexecdir [file tail [lindex $argv 0]]]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册