diff --git a/commit.go b/commit.go index fa5e18561..28dd26483 100644 --- a/commit.go +++ b/commit.go @@ -6,6 +6,7 @@ package git import ( "bufio" + "bytes" "container/list" "fmt" "net/http" @@ -22,11 +23,30 @@ type Commit struct { Author *Signature Committer *Signature CommitMessage string + Signature *CommitGPGSignature parents []SHA1 // SHA1 strings submoduleCache *ObjectCache } +// CommitGPGSignature represents a git commit signature part. +type CommitGPGSignature struct { + Signature string + Payload string //TODO check if can be reconstruct from the rest of commit information to not have duplicate data +} + +// similar to https://github.com/git/git/blob/3bc53220cb2dcf709f7a027a3f526befd021d858/commit.c#L1128 +func newGPGSignatureFromCommitline(data []byte, signatureStart int) (*CommitGPGSignature, error) { + sig := new(CommitGPGSignature) + signatureEnd := bytes.LastIndex(data, []byte("-----END PGP SIGNATURE-----")) + if signatureEnd == -1 { + return nil, fmt.Errorf("end of commit signature not found") + } + sig.Signature = strings.Replace(string(data[signatureStart:signatureEnd+27]), "\n ", "\n", -1) + sig.Payload = string(data[:signatureStart-8]) + string(data[signatureEnd+27:]) + return sig, nil +} + // Message returns the commit message. Same as retrieving CommitMessage directly. func (c *Commit) Message() string { return c.CommitMessage diff --git a/repo_commit.go b/repo_commit.go index 97f44abda..37219734a 100644 --- a/repo_commit.go +++ b/repo_commit.go @@ -78,6 +78,12 @@ l: return nil, err } commit.Committer = sig + case "gpgsig": + sig, err := newGPGSignatureFromCommitline(data, nextline+spacepos+1) + if err != nil { + return nil, err + } + commit.Signature = sig } nextline += eol + 1 case eol == 0: