diff options
Diffstat (limited to 'internal/git/catfile/parser.go')
-rw-r--r-- | internal/git/catfile/parser.go | 92 |
1 files changed, 1 insertions, 91 deletions
diff --git a/internal/git/catfile/parser.go b/internal/git/catfile/parser.go index 5df14954d..b64fe16eb 100644 --- a/internal/git/catfile/parser.go +++ b/internal/git/catfile/parser.go @@ -11,14 +11,13 @@ import ( "time" "gitlab.com/gitlab-org/gitaly/v16/internal/git" - "gitlab.com/gitlab-org/gitaly/v16/internal/helper" "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb" "google.golang.org/protobuf/types/known/timestamppb" ) // Parser parses Git objects into their gitalypb representations. type Parser interface { - ParseCommit(object git.Object) (*gitalypb.GitCommit, error) + ParseCommit(object git.Object) (*Commit, error) ParseTag(object git.Object) (*gitalypb.Tag, error) } @@ -37,95 +36,6 @@ func newParser() *parser { } } -// ParseCommit parses the commit data from the Reader. -func (p *parser) ParseCommit(object git.Object) (*gitalypb.GitCommit, error) { - commit := &gitalypb.GitCommit{Id: object.ObjectID().String()} - - var lastLine bool - p.bufferedReader.Reset(object) - - bytesRemaining := object.ObjectSize() - for !lastLine { - line, err := p.bufferedReader.ReadString('\n') - if errors.Is(err, io.EOF) { - lastLine = true - } else if err != nil { - return nil, fmt.Errorf("parse raw commit: header: %w", err) - } - bytesRemaining -= int64(len(line)) - - if len(line) == 0 || line[0] == ' ' { - continue - } - // A blank line indicates the start of the commit body - if line == "\n" { - break - } - - // There might not be a final line break if there was an EOF - if line[len(line)-1] == '\n' { - line = line[:len(line)-1] - } - - key, value, ok := strings.Cut(line, " ") - if !ok { - continue - } - - switch key { - case "parent": - commit.ParentIds = append(commit.ParentIds, value) - case "author": - commit.Author = parseCommitAuthor(value) - case "committer": - commit.Committer = parseCommitAuthor(value) - case "gpgsig", "gpgsig-sha256": - commit.SignatureType = detectSignatureType(value) - case "tree": - commit.TreeId = value - case "encoding": - commit.Encoding = value - } - } - - if !lastLine { - body := make([]byte, bytesRemaining) - if _, err := io.ReadFull(p.bufferedReader, body); err != nil { - return nil, fmt.Errorf("reading commit message: %w", err) - } - - // After we have copied the body, we must make sure that there really is no - // additional data. For once, this is to detect bugs in our implementation where we - // would accidentally have truncated the commit message. On the other hand, we also - // need to do this such that we observe the EOF, which we must observe in order to - // unblock reading the next object. - // - // This all feels a bit complicated, where it would be much easier to just read into - // a preallocated `bytes.Buffer`. But this complexity is indeed required to optimize - // allocations. So if you want to change this, please make sure to execute the - // `BenchmarkListAllCommits` benchmark. - if n, err := io.Copy(io.Discard, p.bufferedReader); err != nil { - return nil, fmt.Errorf("reading commit message: %w", err) - } else if n != 0 { - return nil, fmt.Errorf( - "commit message exceeds expected length %v by %v bytes", - object.ObjectSize(), n, - ) - } - - if len(body) > 0 { - commit.Subject = subjectFromBody(body) - commit.BodySize = int64(len(body)) - commit.Body = body - if max := helper.MaxCommitOrTagMessageSize; len(body) > max { - commit.Body = commit.Body[:max] - } - } - } - - return commit, nil -} - const maxUnixCommitDate = 1 << 53 // fallbackTimeValue is the value returned in case there is a parse error. It's the maximum |