2020-01-15 08:32:57 +00:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2022-11-27 13:20:29 -05:00
// SPDX-License-Identifier: MIT
2020-01-15 08:32:57 +00:00
package git
import (
"bufio"
"bytes"
"io"
"strings"
)
// CommitFromReader will generate a Commit from a provided reader
2020-12-17 14:00:47 +00: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
2023-12-13 21:02:00 +00:00
func CommitFromReader ( gitRepo * Repository , objectID ObjectID , reader io . Reader ) ( * Commit , error ) {
2020-01-15 08:32:57 +00:00
commit := & Commit {
2023-12-13 21:02:00 +00:00
ID : objectID ,
2021-05-12 06:11:42 +01:00
Author : & Signature { } ,
Committer : & Signature { } ,
2020-01-15 08:32:57 +00:00
}
payloadSB := new ( strings . Builder )
signatureSB := new ( strings . Builder )
messageSB := new ( strings . Builder )
message := false
pgpsig := false
2020-12-17 14:00:47 +00:00
bufReader , ok := reader . ( * bufio . Reader )
if ! ok {
bufReader = bufio . NewReader ( reader )
}
2020-01-15 08:32:57 +00:00
2020-12-17 14:00:47 +00:00
readLoop :
for {
line , err := bufReader . ReadBytes ( '\n' )
if err != nil {
if err == io . EOF {
2020-12-17 20:42:33 +00:00
if message {
_ , _ = messageSB . Write ( line )
}
_ , _ = payloadSB . Write ( line )
2020-12-17 14:00:47 +00:00
break readLoop
}
return nil , err
}
2020-01-15 08:32:57 +00:00
if pgpsig {
if len ( line ) > 0 && line [ 0 ] == ' ' {
_ , _ = signatureSB . Write ( line [ 1 : ] )
continue
}
2024-04-22 13:48:42 +02:00
pgpsig = false
2020-01-15 08:32:57 +00:00
}
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" :
2023-12-19 15:20:47 +08:00
commit . Tree = * NewTree ( gitRepo , MustIDFromString ( string ( data ) ) )
2020-01-15 08:32:57 +00:00
_ , _ = payloadSB . Write ( line )
case "parent" :
2023-12-19 15:20:47 +08:00
commit . Parents = append ( commit . Parents , MustIDFromString ( string ( data ) ) )
2020-01-15 08:32:57 +00: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 )
2024-03-29 22:55:10 +01:00
case "encoding" :
_ , _ = payloadSB . Write ( line )
2020-01-15 08:32:57 +00:00
case "gpgsig" :
2024-01-19 16:05:02 +00:00
fallthrough
case "gpgsig-sha256" : // FIXME: no intertop, so only 1 exists at present.
2020-01-15 08:32:57 +00:00
_ , _ = signatureSB . Write ( data )
_ = signatureSB . WriteByte ( '\n' )
pgpsig = true
}
} else {
_ , _ = messageSB . Write ( line )
2020-12-17 20:42:33 +00:00
_ , _ = payloadSB . Write ( line )
2020-01-15 08:32:57 +00:00
}
}
commit . CommitMessage = messageSB . String ( )
2024-04-02 04:23:17 +08:00
commit . Signature = & CommitSignature {
2020-01-15 08:32:57 +00:00
Signature : signatureSB . String ( ) ,
Payload : payloadSB . String ( ) ,
}
if len ( commit . Signature . Signature ) == 0 {
commit . Signature = nil
}
2020-12-17 14:00:47 +00:00
return commit , nil
2020-01-15 08:32:57 +00:00
}