diff --git a/commit.go b/commit.go index 4e91d3c29..5e8c91d30 100644 --- a/commit.go +++ b/commit.go @@ -34,14 +34,18 @@ type CommitGPGSignature struct { } // similar to https://github.com/git/git/blob/3bc53220cb2dcf709f7a027a3f526befd021d858/commit.c#L1128 -func newGPGSignatureFromCommitline(data []byte, signatureStart int) (*CommitGPGSignature, error) { +func newGPGSignatureFromCommitline(data []byte, signatureStart int, tag bool) (*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:]) + if tag { + sig.Payload = string(data[:signatureStart-1]) + } else { + sig.Payload = string(data[:signatureStart-8]) + string(data[signatureEnd+27:]) + } return sig, nil } diff --git a/repo_commit.go b/repo_commit.go index 1acdfffb3..d5cab8f87 100644 --- a/repo_commit.go +++ b/repo_commit.go @@ -78,7 +78,7 @@ l: } commit.Committer = sig case "gpgsig": - sig, err := newGPGSignatureFromCommitline(data, nextline+spacepos+1) + sig, err := newGPGSignatureFromCommitline(data, nextline+spacepos+1, false) if err != nil { return nil, err } @@ -86,7 +86,20 @@ l: } nextline += eol + 1 case eol == 0: - commit.CommitMessage = string(data[nextline+1:]) + cm := string(data[nextline+1:]) + + // Tag GPG signatures are stored below the commit message + sigindex := strings.Index(cm, "-----BEGIN PGP SIGNATURE-----") + if sigindex != -1 { + sig, err := newGPGSignatureFromCommitline(data, (nextline+1)+sigindex, true) + if err == nil && sig != nil { + // remove signature from commit message + cm = cm[:sigindex-1] + commit.Signature = sig + } + } + + commit.CommitMessage = cm break l default: break l diff --git a/repo_commit_test.go b/repo_commit_test.go index db37135e7..307c6d466 100644 --- a/repo_commit_test.go +++ b/repo_commit_test.go @@ -35,3 +35,15 @@ func TestRepository_GetBranches(t *testing.T) { assert.Equal(t, testCase.ExpectedBranches, branches) } } + +func TestGetTagCommitWithSignature(t *testing.T) { + bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") + bareRepo1, err := OpenRepository(bareRepo1Path) + commit, err := bareRepo1.GetCommit("3ad28a9149a2864384548f3d17ed7f38014c9e8a") + + assert.NoError(t, err) + assert.NotNil(t, commit) + assert.NotNil(t, commit.Signature) + // test that signature is not in message + assert.Equal(t, "tag", commit.CommitMessage) +} diff --git a/tests/repos/repo1_bare/objects/3a/d28a9149a2864384548f3d17ed7f38014c9e8a b/tests/repos/repo1_bare/objects/3a/d28a9149a2864384548f3d17ed7f38014c9e8a new file mode 100644 index 000000000..ee2652b1c Binary files /dev/null and b/tests/repos/repo1_bare/objects/3a/d28a9149a2864384548f3d17ed7f38014c9e8a differ diff --git a/tests/repos/repo1_bare/refs/tags/test b/tests/repos/repo1_bare/refs/tags/test new file mode 100644 index 000000000..ee311722e --- /dev/null +++ b/tests/repos/repo1_bare/refs/tags/test @@ -0,0 +1 @@ +3ad28a9149a2864384548f3d17ed7f38014c9e8a