Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions plumbing/object/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import (
"gopkg.in/src-d/go-git.v4/utils/ioutil"
)

const (
beginpgp string = "-----BEGIN PGP SIGNATURE-----"
endpgp string = "-----END PGP SIGNATURE-----"
)

// Hash represents the hash of an object
type Hash plumbing.Hash

Expand All @@ -28,6 +33,8 @@ type Commit struct {
// Committer is the one performing the commit, might be different from
// Author.
Committer Signature
// PGPSignature is the PGP signature of the commit.
PGPSignature string
// Message is the commit message, contains arbitrary text.
Message string
// TreeHash is the hash of the root tree of the commit.
Expand Down Expand Up @@ -145,12 +152,33 @@ func (c *Commit) Decode(o plumbing.EncodedObject) (err error) {
r := bufio.NewReader(reader)

var message bool
var pgpsig bool
for {
line, err := r.ReadBytes('\n')
if err != nil && err != io.EOF {
return err
}

if pgpsig {
// Check if it's the end of a PGP signature.
if bytes.Contains(line, []byte(endpgp)) {
c.PGPSignature += endpgp + "\n"
pgpsig = false
} else {
// Trim the left padding.
line = bytes.TrimLeft(line, " ")
c.PGPSignature += string(line)
}
continue
}

// Check if it's the beginning of a PGP signature.
if bytes.Contains(line, []byte(beginpgp)) {
c.PGPSignature += beginpgp + "\n"
pgpsig = true
continue
}

if !message {
line = bytes.TrimSpace(line)
if len(line) == 0 {
Expand Down Expand Up @@ -215,6 +243,21 @@ func (b *Commit) Encode(o plumbing.EncodedObject) error {
return err
}

if b.PGPSignature != "" {
if _, err = fmt.Fprint(w, "pgpsig"); err != nil {
return err
}

// Split all the signature lines and write with a left padding and
// newline at the end.
lines := strings.Split(b.PGPSignature, "\n")
for _, line := range lines {
if _, err = fmt.Fprintf(w, " %s\n", line); err != nil {
return err
}
}
}

if _, err = fmt.Fprintf(w, "\n\n%s", b.Message); err != nil {
return err
}
Expand Down
26 changes: 26 additions & 0 deletions plumbing/object/commit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,29 @@ func (s *SuiteCommit) TestLongCommitMessageSerialization(c *C) {
c.Assert(err, IsNil)
c.Assert(decoded.Message, Equals, longMessage)
}

func (s *SuiteCommit) TestPGPSignatureSerialization(c *C) {
encoded := &plumbing.MemoryObject{}
decoded := &Commit{}
commit := *s.Commit

pgpsignature := `-----BEGIN PGP SIGNATURE-----

iQEcBAABAgAGBQJTZbQlAAoJEF0+sviABDDrZbQH/09PfE51KPVPlanr6q1v4/Ut
LQxfojUWiLQdg2ESJItkcuweYg+kc3HCyFejeDIBw9dpXt00rY26p05qrpnG+85b
hM1/PswpPLuBSr+oCIDj5GMC2r2iEKsfv2fJbNW8iWAXVLoWZRF8B0MfqX/YTMbm
ecorc4iXzQu7tupRihslbNkfvfciMnSDeSvzCpWAHl7h8Wj6hhqePmLm9lAYqnKp
8S5B/1SSQuEAjRZgI4IexpZoeKGVDptPHxLLS38fozsyi0QyDyzEgJxcJQVMXxVi
RUysgqjcpT8+iQM1PblGfHR4XAhuOqN5Fx06PSaFZhqvWFezJ28/CLyX5q+oIVk=
=EFTF
-----END PGP SIGNATURE-----
`
commit.PGPSignature = pgpsignature

err := commit.Encode(encoded)
c.Assert(err, IsNil)

err = decoded.Decode(encoded)
c.Assert(err, IsNil)
c.Assert(decoded.PGPSignature, Equals, pgpsignature)
}