git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 1/3] gitk: refactor: separate generic hunk parsing out of find_hunk_blamespecs{}

From
Eric Sunshine <sunshine@sunshineco.com>
Date
Feb 3, 2014, 23:20 UTC
Message-ID
<CAPig+cRv6851TWgRU6sBorKYZ0ABXv+a3oi=hrGjxYz9P6T7mg@mail.gmail.com>
In-Reply-To
<20140203224152.GA14305@wheezy.local>
On Mon, Feb 3, 2014 at 5:41 PM, Max Kirillov <max@max630.net> 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/
Show 139 quoted lines
> 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 <max@max630.net>
> ---
>  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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous: Max KirillovNext: Max Kirillov
Message 4 of 8 in “gitk: use single blamestuff for all show_line_source{} calls”
  1. gitk: use single blamestuff for all show_line_source{} callsMax Kirillov, Feb 3, 2014
  2. 0/3 gitk: show latest change to regionMax Kirillov, Feb 3, 2014
  3. 1/3 gitk: refactor: separate generic hunk parsing out of find_hunk_blamespecs{}Max Kirillov, Feb 3, 2014
  4. Eric SunshineFeb 3, 2014
  5. Max KirillovJun 24, 2014
  6. 2/3 gitk: refactor: separate io from logic in the searching origin of lineMax Kirillov, Feb 3, 2014
  7. 3/3 gitk: pick selection for region blameMax Kirillov, Feb 3, 2014
  8. 3/3 gitk: show latest change to regionMax Kirillov, Feb 3, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.