aboutsummaryrefslogtreecommitdiffstats
path: root/worktree_commit.go
diff options
context:
space:
mode:
Diffstat (limited to 'worktree_commit.go')
-rw-r--r--worktree_commit.go53
1 files changed, 43 insertions, 10 deletions
diff --git a/worktree_commit.go b/worktree_commit.go
index 4d811f3..18002f2 100644
--- a/worktree_commit.go
+++ b/worktree_commit.go
@@ -2,7 +2,10 @@ package git
import (
"bytes"
+ "crypto"
+ "crypto/rand"
"errors"
+ "io"
"path"
"sort"
"strings"
@@ -14,6 +17,7 @@ import (
"github.com/go-git/go-git/v5/storage"
"github.com/ProtonMail/go-crypto/openpgp"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
"github.com/go-git/go-billy/v5"
)
@@ -125,12 +129,17 @@ func (w *Worktree) buildCommitObject(msg string, opts *CommitOptions, tree plumb
ParentHashes: opts.Parents,
}
- if opts.SignKey != nil {
- sig, err := w.buildCommitSignature(commit, opts.SignKey)
+ // Convert SignKey into a Signer if set. Existing Signer should take priority.
+ signer := opts.Signer
+ if signer == nil && opts.SignKey != nil {
+ signer = &gpgSigner{key: opts.SignKey}
+ }
+ if signer != nil {
+ sig, err := w.buildCommitSignature(commit, signer)
if err != nil {
return plumbing.ZeroHash, err
}
- commit.PGPSignature = sig
+ commit.PGPSignature = string(sig)
}
obj := w.r.Storer.NewEncodedObject()
@@ -140,20 +149,44 @@ func (w *Worktree) buildCommitObject(msg string, opts *CommitOptions, tree plumb
return w.r.Storer.SetEncodedObject(obj)
}
-func (w *Worktree) buildCommitSignature(commit *object.Commit, signKey *openpgp.Entity) (string, error) {
+type gpgSigner struct {
+ key *openpgp.Entity
+}
+
+func (s *gpgSigner) Public() crypto.PublicKey {
+ return s.key.PrimaryKey
+}
+
+func (s *gpgSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
+ var cfg *packet.Config
+ if opts != nil {
+ cfg = &packet.Config{
+ DefaultHash: opts.HashFunc(),
+ }
+ }
+
+ var b bytes.Buffer
+ if err := openpgp.ArmoredDetachSign(&b, s.key, bytes.NewReader(digest), cfg); err != nil {
+ return nil, err
+ }
+ return b.Bytes(), nil
+}
+
+func (w *Worktree) buildCommitSignature(commit *object.Commit, signer crypto.Signer) ([]byte, error) {
encoded := &plumbing.MemoryObject{}
if err := commit.Encode(encoded); err != nil {
- return "", err
+ return nil, err
}
r, err := encoded.Reader()
if err != nil {
- return "", err
+ return nil, err
}
- var b bytes.Buffer
- if err := openpgp.ArmoredDetachSign(&b, signKey, r, nil); err != nil {
- return "", err
+ b, err := io.ReadAll(r)
+ if err != nil {
+ return nil, err
}
- return b.String(), nil
+
+ return signer.Sign(rand.Reader, b, nil)
}
// buildTreeHelper converts a given index.Index file into multiple git objects