aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/object/commit.go
diff options
context:
space:
mode:
authorAditya Sirish <aditya@saky.in>2023-09-27 11:54:31 -0400
committerAditya Sirish <aditya@saky.in>2023-09-27 16:28:43 -0400
commitcbfd0c5005523b131449c6fdd7fa0c0bc84012a9 (patch)
tree0559b309115cec0e6536661dca8c7ae938cd6357 /plumbing/object/commit.go
parent809f9df1b76258a311a20c76d346e86aca0a08f8 (diff)
downloadgo-git-cbfd0c5005523b131449c6fdd7fa0c0bc84012a9.tar.gz
plumbing/object: Support mergetag in merge commits
When a merge commit is created from merging a signed tag, the tag object is embedded in the commit object. This commit adds support for this tag data when encoding and decoding a commit object. Signed-off-by: Aditya Sirish <aditya@saky.in>
Diffstat (limited to 'plumbing/object/commit.go')
-rw-r--r--plumbing/object/commit.go38
1 files changed, 38 insertions, 0 deletions
diff --git a/plumbing/object/commit.go b/plumbing/object/commit.go
index 8a0f35c..508e93c 100644
--- a/plumbing/object/commit.go
+++ b/plumbing/object/commit.go
@@ -20,6 +20,11 @@ const (
beginpgp string = "-----BEGIN PGP SIGNATURE-----"
endpgp string = "-----END PGP SIGNATURE-----"
headerpgp string = "gpgsig"
+
+ // https://github.com/git/git/blob/bcb6cae2966cc407ca1afc77413b3ef11103c175/Documentation/gitformat-signature.txt#L153
+ // When a merge commit is created from a signed tag, the tag is embedded in
+ // the commit with the "mergetag" header.
+ headermergetag string = "mergetag"
)
// Hash represents the hash of an object
@@ -38,6 +43,9 @@ type Commit struct {
// Committer is the one performing the commit, might be different from
// Author.
Committer Signature
+ // MergeTag is the embedded tag object when a merge commit is created by
+ // merging a signed tag.
+ MergeTag string
// PGPSignature is the PGP signature of the commit.
PGPSignature string
// Message is the commit message, contains arbitrary text.
@@ -184,6 +192,7 @@ func (c *Commit) Decode(o plumbing.EncodedObject) (err error) {
defer sync.PutBufioReader(r)
var message bool
+ var mergetag bool
var pgpsig bool
var msgbuf bytes.Buffer
for {
@@ -192,6 +201,16 @@ func (c *Commit) Decode(o plumbing.EncodedObject) (err error) {
return err
}
+ if mergetag {
+ if len(line) > 0 && line[0] == ' ' {
+ line = bytes.TrimLeft(line, " ")
+ c.MergeTag += string(line)
+ continue
+ } else {
+ mergetag = false
+ }
+ }
+
if pgpsig {
if len(line) > 0 && line[0] == ' ' {
line = bytes.TrimLeft(line, " ")
@@ -225,6 +244,9 @@ func (c *Commit) Decode(o plumbing.EncodedObject) (err error) {
c.Author.Decode(data)
case "committer":
c.Committer.Decode(data)
+ case headermergetag:
+ c.MergeTag += string(data) + "\n"
+ mergetag = true
case headerpgp:
c.PGPSignature += string(data) + "\n"
pgpsig = true
@@ -286,6 +308,22 @@ func (c *Commit) encode(o plumbing.EncodedObject, includeSig bool) (err error) {
return err
}
+ if c.MergeTag != "" {
+ if _, err = fmt.Fprint(w, "\n"+headermergetag+" "); err != nil {
+ return err
+ }
+
+ // Split tag information lines and re-write with a left padding and
+ // newline. Use join for this so it's clear that a newline should not be
+ // added after this section. The newline will be added either as part of
+ // the PGP signature or the commit message.
+ mergetag := strings.TrimSuffix(c.MergeTag, "\n")
+ lines := strings.Split(mergetag, "\n")
+ if _, err = fmt.Fprint(w, strings.Join(lines, "\n ")); err != nil {
+ return err
+ }
+ }
+
if c.PGPSignature != "" && includeSig {
if _, err = fmt.Fprint(w, "\n"+headerpgp+" "); err != nil {
return err