2020-01-15 11:32:57 +03:00
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package git
import (
"bufio"
"bytes"
"io"
"strings"
)
// CommitFromReader will generate a Commit from a provided reader
2020-12-17 17:00:47 +03:00
// We need this to interpret commits from cat-file or cat-file --batch
//
// If used as part of a cat-file --batch stream you need to limit the reader to the correct size
func CommitFromReader ( gitRepo * Repository , sha SHA1 , reader io . Reader ) ( * Commit , error ) {
2020-01-15 11:32:57 +03:00
commit := & Commit {
2021-05-12 08:11:42 +03:00
ID : sha ,
Author : & Signature { } ,
Committer : & Signature { } ,
2020-01-15 11:32:57 +03:00
}
payloadSB := new ( strings . Builder )
signatureSB := new ( strings . Builder )
messageSB := new ( strings . Builder )
message := false
pgpsig := false
2020-12-17 17:00:47 +03:00
bufReader , ok := reader . ( * bufio . Reader )
if ! ok {
bufReader = bufio . NewReader ( reader )
}
2020-01-15 11:32:57 +03:00
2020-12-17 17:00:47 +03:00
readLoop :
for {
line , err := bufReader . ReadBytes ( '\n' )
if err != nil {
if err == io . EOF {
2020-12-17 23:42:33 +03:00
if message {
_ , _ = messageSB . Write ( line )
}
_ , _ = payloadSB . Write ( line )
2020-12-17 17:00:47 +03:00
break readLoop
}
return nil , err
}
2020-01-15 11:32:57 +03:00
if pgpsig {
if len ( line ) > 0 && line [ 0 ] == ' ' {
_ , _ = signatureSB . Write ( line [ 1 : ] )
continue
} else {
pgpsig = false
}
}
if ! message {
// This is probably not correct but is copied from go-gits interpretation...
trimmed := bytes . TrimSpace ( line )
if len ( trimmed ) == 0 {
message = true
_ , _ = payloadSB . Write ( line )
continue
}
split := bytes . SplitN ( trimmed , [ ] byte { ' ' } , 2 )
var data [ ] byte
if len ( split ) > 1 {
data = split [ 1 ]
}
switch string ( split [ 0 ] ) {
case "tree" :
2020-12-17 17:00:47 +03:00
commit . Tree = * NewTree ( gitRepo , MustIDFromString ( string ( data ) ) )
2020-01-15 11:32:57 +03:00
_ , _ = payloadSB . Write ( line )
case "parent" :
2020-12-17 17:00:47 +03:00
commit . Parents = append ( commit . Parents , MustIDFromString ( string ( data ) ) )
2020-01-15 11:32:57 +03:00
_ , _ = payloadSB . Write ( line )
case "author" :
commit . Author = & Signature { }
commit . Author . Decode ( data )
_ , _ = payloadSB . Write ( line )
case "committer" :
commit . Committer = & Signature { }
commit . Committer . Decode ( data )
_ , _ = payloadSB . Write ( line )
case "gpgsig" :
_ , _ = signatureSB . Write ( data )
_ = signatureSB . WriteByte ( '\n' )
pgpsig = true
}
} else {
_ , _ = messageSB . Write ( line )
2020-12-17 23:42:33 +03:00
_ , _ = payloadSB . Write ( line )
2020-01-15 11:32:57 +03:00
}
}
commit . CommitMessage = messageSB . String ( )
commit . Signature = & CommitGPGSignature {
Signature : signatureSB . String ( ) ,
Payload : payloadSB . String ( ) ,
}
if len ( commit . Signature . Signature ) == 0 {
commit . Signature = nil
}
2020-12-17 17:00:47 +03:00
return commit , nil
2020-01-15 11:32:57 +03:00
}