@@ -10,8 +10,6 @@ import (
1010 "fmt"
1111 "io"
1212 "os"
13- "regexp"
14- "strings"
1513
1614 "code.gitea.io/gitea/modules/log"
1715 "code.gitea.io/gitea/modules/util"
@@ -33,14 +31,13 @@ type BlameReader struct {
3331 done chan error
3432 lastSha * string
3533 ignoreRevsFile * string
34+ objectFormat ObjectFormat
3635}
3736
3837func (r * BlameReader ) UsesIgnoreRevs () bool {
3938 return r .ignoreRevsFile != nil
4039}
4140
42- var shaLineRegex = regexp .MustCompile ("^([a-z0-9]{40})" )
43-
4441// NextPart returns next part of blame (sequential code lines with the same commit)
4542func (r * BlameReader ) NextPart () (* BlamePart , error ) {
4643 var blamePart * BlamePart
@@ -52,6 +49,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
5249 }
5350 }
5451
52+ const previousHeader = "previous "
5553 var lineBytes []byte
5654 var isPrefix bool
5755 var err error
@@ -67,21 +65,22 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
6765 continue
6866 }
6967
70- line := string (lineBytes )
71-
72- lines := shaLineRegex .FindStringSubmatch (line )
73- if lines != nil {
74- sha1 := lines [1 ]
68+ var objectID string
69+ objectFormatLength := r .objectFormat .FullLength ()
7570
71+ if len (lineBytes ) > objectFormatLength && lineBytes [objectFormatLength ] == ' ' && r .objectFormat .IsValid (string (lineBytes [0 :objectFormatLength ])) {
72+ objectID = string (lineBytes [0 :objectFormatLength ])
73+ }
74+ if len (objectID ) > 0 {
7675 if blamePart == nil {
7776 blamePart = & BlamePart {
78- Sha : sha1 ,
77+ Sha : objectID ,
7978 Lines : make ([]string , 0 ),
8079 }
8180 }
8281
83- if blamePart .Sha != sha1 {
84- r .lastSha = & sha1
82+ if blamePart .Sha != objectID {
83+ r .lastSha = & objectID
8584 // need to munch to end of line...
8685 for isPrefix {
8786 _ , isPrefix , err = r .bufferedReader .ReadLine ()
@@ -91,12 +90,13 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
9190 }
9291 return blamePart , nil
9392 }
94- } else if line [0 ] == '\t' {
95- blamePart .Lines = append (blamePart .Lines , line [1 :])
96- } else if strings .HasPrefix (line , "previous " ) {
97- parts := strings .SplitN (line [len ("previous " ):], " " , 2 )
98- blamePart .PreviousSha = parts [0 ]
99- blamePart .PreviousPath = parts [1 ]
93+ } else if lineBytes [0 ] == '\t' {
94+ blamePart .Lines = append (blamePart .Lines , string (lineBytes [1 :]))
95+ } else if bytes .HasPrefix (lineBytes , []byte (previousHeader )) {
96+ offset := len (previousHeader ) // already includes a space
97+ blamePart .PreviousSha = string (lineBytes [offset : offset + objectFormatLength ])
98+ offset += objectFormatLength + 1 // +1 for space
99+ blamePart .PreviousPath = string (lineBytes [offset :])
100100 }
101101
102102 // need to munch to end of line...
@@ -126,7 +126,7 @@ func (r *BlameReader) Close() error {
126126}
127127
128128// CreateBlameReader creates reader for given repository, commit and file
129- func CreateBlameReader (ctx context.Context , repoPath string , commit * Commit , file string , bypassBlameIgnore bool ) (* BlameReader , error ) {
129+ func CreateBlameReader (ctx context.Context , objectFormat ObjectFormat , repoPath string , commit * Commit , file string , bypassBlameIgnore bool ) (* BlameReader , error ) {
130130 var ignoreRevsFile * string
131131 if CheckGitVersionAtLeast ("2.23" ) == nil && ! bypassBlameIgnore {
132132 ignoreRevsFile = tryCreateBlameIgnoreRevsFile (commit )
@@ -175,6 +175,7 @@ func CreateBlameReader(ctx context.Context, repoPath string, commit *Commit, fil
175175 bufferedReader : bufferedReader ,
176176 done : done ,
177177 ignoreRevsFile : ignoreRevsFile ,
178+ objectFormat : objectFormat ,
178179 }, nil
179180}
180181
0 commit comments