On Mon, Feb 3, 2014 at 5:41 PM, Max Kirillov <[email protected]> wrote:
> For requesting a region blame, it is necessary to parse a hunk and
> find the region in the parent file corresponding to the selected region.
> There is already hunk parsin functionality in the find_hunk_blamespec{},
s/parsin/parsing/
s/in the/in/
> but returns only information for a single line.
s/but/but it/
> The new function, resolve_hunk_lines{}, scans the hunk once and returns
> for all hunk lines between $start_diffline and $end_diffline, in which parent
> each of them exists and which is its number there.
>
> Signed-off-by: Max Kirillov <[email protected]>
> ---
> gitk | 93
> ++++++++++++++++++++++++++++++++++++++++++--------------------------
> 1 file changed, 57 insertions(+), 36 deletions(-)
>
> diff --git a/gitk b/gitk
> index dfac4fd..7699a66 100755
> --- a/gitk
> +++ b/gitk
> @@ -3590,11 +3590,11 @@ proc external_diff {} {
> }
> }
>
> -proc find_hunk_blamespec {base line} {
> +proc resolve_hunk_lines {base start_diffline end_diffline} {
> global ctext
>
> # Find and parse the hunk header
> - set s_lix [$ctext search -backwards -regexp ^@@ "$line.0 lineend"
> $base.0]
> + set s_lix [$ctext search -backwards -regexp ^@@ "$start_diffline.0
> lineend" $base.0]
> if {$s_lix eq {}} return
>
> set s_line [$ctext get $s_lix "$s_lix + 1 lines"]
> @@ -3614,49 +3614,70 @@ proc find_hunk_blamespec {base line} {
> }
>
> # Now scan the lines to determine offset within the hunk
> - set max_parent [expr {[llength $base_lines]-2}]
> - set dline 0
> + set max_parent [expr {[llength $base_lines]-1}]
> set s_lno [lindex [split $s_lix "."] 0]
>
> - # Determine if the line is removed
> - set chunk [$ctext get $line.0 "$line.1 + $max_parent chars"]
> - if {[string match {[-+ ]*} $chunk]} {
> - set removed_idx [string first "-" $chunk]
> - # Choose a parent index
> - if {$removed_idx >= 0} {
> - set parent $removed_idx
> + set commitlines_by_diffline {}
> + array unset commit_lines
> + for {set p 0} {$p <= $max_parent} {incr p} {
> + set commit_lines($p) [expr [lindex $base_lines $p] - 1]
> + }
> + for {set diffline [expr $s_lno + 1]} {$diffline <= $end_diffline} {incr
> diffline} {
> + set chunk [$ctext get $diffline.0 "$diffline.0 + $max_parent chars"]
> + if {$chunk eq {} || [string match "\[\n@\]*" $chunk]} {
> + # region is larger than hunk
> + return {}
> + }
> + set is_removed [expr [string first "-" $chunk] >= 0]
> + if {!$is_removed} {
> + incr commit_lines(0)
> + set commitlines [list [list 0 $commit_lines(0)]]
> } else {
> - set unchanged_idx [string first " " $chunk]
> - if {$unchanged_idx >= 0} {
> - set parent $unchanged_idx
> - } else {
> - # blame the current commit
> - set parent -1
> - }
> - }
> - # then count other lines that belong to it
> - for {set i $line} {[incr i -1] > $s_lno} {} {
> - set chunk [$ctext get $i.0 "$i.1 + $max_parent chars"]
> - # Determine if the line is removed
> - set removed_idx [string first "-" $chunk]
> - if {$parent >= 0} {
> - set code [string index $chunk $parent]
> - if {$code eq "-" || ($removed_idx < 0 && $code ne "+")} {
> - incr dline
> + set commitlines {}
> + }
> + for {set p 1} {$p <= $max_parent} {incr p} {
> + switch -- [string index $chunk "$p-1"] {
> + "+" {
> }
> - } else {
> - if {$removed_idx < 0} {
> - incr dline
> + "-" {
> + incr commit_lines($p)
> + lappend commitlines [list $p $commit_lines($p)]
> + }
> + " " {
> + if {!$is_removed} {
> + incr commit_lines($p)
> + lappend commitlines [list $p $commit_lines($p)]
> + }
> + }
> + default {
> + error_popup "resolve_hunk_lines: unexpected diff
> line($diffline): $chunk"
> + break
> }
> }
> }
> - incr parent
> - } else {
> - set parent 0
> + if {$diffline >= $start_diffline} {
> + lappend commitlines_by_diffline [list $diffline $commitlines]
> + }
> }
> + return $commitlines_by_diffline
> +}
>
> - incr dline [lindex $base_lines $parent]
> - return [list $parent $dline]
> +proc find_hunk_blamespec {base line} {
> + foreach cl_spec [resolve_hunk_lines $base $line $line] {
> + if {[lindex $cl_spec 0] == $line} {
> + set commitlines [lindex $cl_spec 1]
> + if {[llength $commitlines] > 0} {
> + if {[llength $commitlines] > 1 && [lindex $commitlines 0 0]
> eq 0} {
> + return [lindex $commitlines 1]
> + } else {
> + return [lindex $commitlines 0]
> + }
> + } else {
> + error_popup "find_hunk_blamespec: invalid commitlines:
> $commitlines"
> + }
> + }
> + }
> + return {}
> }
>
> proc external_blame_diff {} {
> --
> 1.8.5.2.421.g4cdf8d0
>
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html