diff --git a/cmd/dehub/cmd_commit.go b/cmd/dehub/cmd_commit.go index 38e11bf..91d0f82 100644 --- a/cmd/dehub/cmd_commit.go +++ b/cmd/dehub/cmd_commit.go @@ -13,7 +13,7 @@ import ( func cmdCommit(ctx context.Context, cmd *dcmd.Cmd) { flag := cmd.FlagSet() - accountID := flag.String("account-id", "", "Account to sign commit as") + accountID := flag.String("account-id", "", "Account to accredit commit with") repo := ctxRepo(ctx) accreditAndCommit := func(commit dehub.Commit) error { @@ -99,7 +99,7 @@ func cmdCommit(ctx context.Context, cmd *dcmd.Cmd) { }, ) - cmd.SubCmd("credential", "Commit credential of a different commit", + cmd.SubCmd("credential", "Commit credential of one or more change commits", func(ctx context.Context, cmd *dcmd.Cmd) { flag := cmd.FlagSet() startRev := flag.String("start", "", "Revision of the starting commit to accredit (when accrediting a range of changes)") @@ -117,7 +117,10 @@ func cmdCommit(ctx context.Context, cmd *dcmd.Cmd) { gitCommit, err := repo.GetGitRevision(plumbing.Revision(*rev)) if err != nil { return nil, fmt.Errorf("resolving revision %q: %w", *rev, err) - } else if credCommit, err = repo.NewCommitCredential(gitCommit.Interface.GetHash()); err != nil { + } + + gitCommits := []dehub.GitCommit{gitCommit} + if credCommit, err = repo.NewCommitCredentialFromChanges(gitCommits); err != nil { return nil, fmt.Errorf("constructing credential commit: %w", err) } } else { diff --git a/commit.go b/commit.go index 4bcd7c1..932dced 100644 --- a/commit.go +++ b/commit.go @@ -441,7 +441,7 @@ func (r *Repo) verifyCommit(branch plumbing.ReferenceName, gitCommit GitCommit, } type changeRangeInfo struct { - lastChangeCommit GitCommit + changeCommits []GitCommit authors map[string]struct{} msg string startTree, endTree *object.Tree @@ -455,17 +455,15 @@ func (r *Repo) changeRangeInfo(commits []GitCommit) (changeRangeInfo, error) { authors: map[string]struct{}{}, } - var lastChangeCommitOk bool for _, commit := range commits { if _, ok := commit.Interface.(*CommitChange); ok { - info.lastChangeCommit = commit - lastChangeCommitOk = true + info.changeCommits = append(info.changeCommits, commit) for _, cred := range commit.Commit.Common.Credentials { info.authors[cred.AccountID] = struct{}{} } } } - if !lastChangeCommitOk { + if len(info.changeCommits) == 0 { return changeRangeInfo{}, errors.New("no change commits found") } @@ -477,8 +475,9 @@ func (r *Repo) changeRangeInfo(commits []GitCommit) (changeRangeInfo, error) { commits[0].GitCommit.Hash, err) } - info.msg = info.lastChangeCommit.Commit.Change.Message - info.endTree = info.lastChangeCommit.GitTree + lastChangeCommit := info.changeCommits[len(info.changeCommits)-1] + info.msg = lastChangeCommit.Commit.Change.Message + info.endTree = lastChangeCommit.GitTree info.changeHash = genChangeHash(nil, info.msg, info.startTree, info.endTree) return info, nil } diff --git a/commit_credential.go b/commit_credential.go index 6224e8c..7df6ffa 100644 --- a/commit_credential.go +++ b/commit_credential.go @@ -12,6 +12,11 @@ import ( // CommitCredential describes the structure of a credential commit message. type CommitCredential struct { CredentialedHash yamlutil.Blob `yaml:"credentialed_hash"` + + // CommitHashes represents the commits which this credential is accrediting. + // It is only present for informational purposes, as commits don't not have + // any bearing on the CredentialedHash itself. + CommitHashes []string `yaml:"commits,omitempty"` } var _ CommitInterface = CommitCredential{} @@ -36,7 +41,19 @@ func (r *Repo) NewCommitCredentialFromChanges(commits []GitCommit) (Commit, erro if err != nil { return Commit{}, err } - return r.NewCommitCredential(info.changeHash) + + commitCred, err := r.NewCommitCredential(info.changeHash) + if err != nil { + return Commit{}, err + } + + for _, commit := range info.changeCommits { + commitCred.Credential.CommitHashes = append( + commitCred.Credential.CommitHashes, + commit.GitCommit.Hash.String(), + ) + } + return commitCred, nil } // MessageHead implements the method for the CommitInterface interface.