mirror of
https://github.com/harness/drone.git
synced 2025-05-05 04:11:53 +08:00
optimized get branch (#912)
This commit is contained in:
parent
cb817bf2ad
commit
ee7b2775c1
@ -16,9 +16,9 @@ package adapter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/harness/gitness/errors"
|
|
||||||
"github.com/harness/gitness/git/types"
|
"github.com/harness/gitness/git/types"
|
||||||
|
|
||||||
gitea "code.gitea.io/gitea/modules/git"
|
gitea "code.gitea.io/gitea/modules/git"
|
||||||
@ -37,30 +37,15 @@ func (a Adapter) GetBranch(
|
|||||||
return nil, ErrBranchNameEmpty
|
return nil, ErrBranchNameEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
giteaRepo, err := gitea.OpenRepository(ctx, repoPath)
|
ref := GetReferenceFromBranchName(branchName)
|
||||||
|
commit, err := getCommit(ctx, repoPath, ref, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, processGiteaErrorf(err, "failed to open repository")
|
return nil, fmt.Errorf("failed to find the commit for the branch: %w", err)
|
||||||
}
|
|
||||||
defer giteaRepo.Close()
|
|
||||||
|
|
||||||
giteaBranch, err := giteaRepo.GetBranch(branchName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, processGiteaErrorf(err, "failed to get branch '%s'", branchName)
|
|
||||||
}
|
|
||||||
|
|
||||||
giteaCommit, err := giteaBranch.GetCommit()
|
|
||||||
if err != nil {
|
|
||||||
return nil, processGiteaErrorf(err, "failed to get commit '%s'", branchName)
|
|
||||||
}
|
|
||||||
|
|
||||||
commit, err := mapGiteaCommit(giteaCommit)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Internal("failed to map gitea commit", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &types.Branch{
|
return &types.Branch{
|
||||||
Name: giteaBranch.Name,
|
Name: branchName,
|
||||||
SHA: giteaCommit.ID.String(),
|
SHA: commit.SHA,
|
||||||
Commit: commit,
|
Commit: commit,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/harness/gitness/errors"
|
"github.com/harness/gitness/errors"
|
||||||
"github.com/harness/gitness/git/types"
|
"github.com/harness/gitness/git/types"
|
||||||
@ -27,16 +28,11 @@ import (
|
|||||||
gitea "code.gitea.io/gitea/modules/git"
|
gitea "code.gitea.io/gitea/modules/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// GetLatestCommit gets the latest commit of a path relative from the provided revision.
|
||||||
giteaPrettyLogFormat = `--pretty=format:` + fmtCommitHash
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetLatestCommit gets the latest commit of a path relative from the provided reference.
|
|
||||||
// Note: ref can be Branch / Tag / CommitSHA.
|
|
||||||
func (a Adapter) GetLatestCommit(
|
func (a Adapter) GetLatestCommit(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
repoPath string,
|
repoPath string,
|
||||||
ref string,
|
rev string,
|
||||||
treePath string,
|
treePath string,
|
||||||
) (*types.Commit, error) {
|
) (*types.Commit, error) {
|
||||||
if repoPath == "" {
|
if repoPath == "" {
|
||||||
@ -44,45 +40,7 @@ func (a Adapter) GetLatestCommit(
|
|||||||
}
|
}
|
||||||
treePath = cleanTreePath(treePath)
|
treePath = cleanTreePath(treePath)
|
||||||
|
|
||||||
giteaRepo, err := gitea.OpenRepository(ctx, repoPath)
|
return getCommit(ctx, repoPath, rev, treePath)
|
||||||
if err != nil {
|
|
||||||
return nil, processGiteaErrorf(err, "failed to open repository")
|
|
||||||
}
|
|
||||||
defer giteaRepo.Close()
|
|
||||||
|
|
||||||
giteaCommit, err := giteaGetCommitByPath(giteaRepo, ref, treePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, processGiteaErrorf(err, "error getting latest commit for '%s'", treePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
return mapGiteaCommit(giteaCommit)
|
|
||||||
}
|
|
||||||
|
|
||||||
// giteaGetCommitByPath returns the latest commit per specific branch.
|
|
||||||
func giteaGetCommitByPath(
|
|
||||||
giteaRepo *gitea.Repository,
|
|
||||||
ref string,
|
|
||||||
treePath string,
|
|
||||||
) (*gitea.Commit, error) {
|
|
||||||
if treePath == "" {
|
|
||||||
treePath = "."
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: the difference to gitea implementation is passing `ref`.
|
|
||||||
stdout, _, runErr := gitea.NewCommand(giteaRepo.Ctx, "log", ref, "-1", giteaPrettyLogFormat, "--", treePath).
|
|
||||||
RunStdBytes(&gitea.RunOpts{Dir: giteaRepo.Path})
|
|
||||||
if runErr != nil {
|
|
||||||
return nil, fmt.Errorf("in giteaGetCommitByPath: failed to trigger log command: %w", runErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
lines := parseLinesToSlice(stdout)
|
|
||||||
|
|
||||||
giteaCommits, err := getGiteaCommits(giteaRepo, lines)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("in giteaGetCommitByPath: failed to get commits: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return giteaCommits[0], nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGiteaCommits(
|
func getGiteaCommits(
|
||||||
@ -324,28 +282,17 @@ func getFileChangeTypeFromLog(
|
|||||||
return nil, nil, nil, fmt.Errorf("could not parse change for the file '%s'", filePath)
|
return nil, nil, nil, fmt.Errorf("could not parse change for the file '%s'", filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCommit returns the (latest) commit for a specific ref.
|
// GetCommit returns the (latest) commit for a specific revision.
|
||||||
// Note: ref can be Branch / Tag / CommitSHA.
|
|
||||||
func (a Adapter) GetCommit(
|
func (a Adapter) GetCommit(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
repoPath string,
|
repoPath string,
|
||||||
ref string,
|
rev string,
|
||||||
) (*types.Commit, error) {
|
) (*types.Commit, error) {
|
||||||
if repoPath == "" {
|
if repoPath == "" {
|
||||||
return nil, ErrRepositoryPathEmpty
|
return nil, ErrRepositoryPathEmpty
|
||||||
}
|
}
|
||||||
giteaRepo, err := gitea.OpenRepository(ctx, repoPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, processGiteaErrorf(err, "failed to open repository")
|
|
||||||
}
|
|
||||||
defer giteaRepo.Close()
|
|
||||||
|
|
||||||
commit, err := giteaRepo.GetCommit(ref)
|
return getCommit(ctx, repoPath, rev, "")
|
||||||
if err != nil {
|
|
||||||
return nil, processGiteaErrorf(err, "error getting commit for ref '%s'", ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
return mapGiteaCommit(commit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a Adapter) GetFullCommitID(
|
func (a Adapter) GetFullCommitID(
|
||||||
@ -497,3 +444,79 @@ func parseLinesToSlice(output []byte) []string {
|
|||||||
|
|
||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getCommit(
|
||||||
|
ctx context.Context,
|
||||||
|
repoPath string,
|
||||||
|
rev string,
|
||||||
|
path string,
|
||||||
|
) (*types.Commit, error) {
|
||||||
|
const format = "" +
|
||||||
|
fmtCommitHash + fmtZero + // 0
|
||||||
|
fmtAuthorName + fmtZero + // 1
|
||||||
|
fmtAuthorEmail + fmtZero + // 2
|
||||||
|
fmtAuthorTime + fmtZero + // 3
|
||||||
|
fmtCommitterName + fmtZero + // 4
|
||||||
|
fmtCommitterEmail + fmtZero + // 5
|
||||||
|
fmtCommitterTime + fmtZero + // 6
|
||||||
|
fmtSubject + fmtZero + // 7
|
||||||
|
fmtBody // 8
|
||||||
|
|
||||||
|
args := []string{"log", "--max-count=1", "--format=" + format, rev}
|
||||||
|
if path != "" {
|
||||||
|
args = append(args, "--", path)
|
||||||
|
}
|
||||||
|
|
||||||
|
commitLine, stderr, err := gitea.NewCommand(ctx, args...).RunStdString(&gitea.RunOpts{Dir: repoPath})
|
||||||
|
if strings.Contains(stderr, "ambiguous argument") {
|
||||||
|
return nil, errors.NotFound("revision %q not found", rev)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to run git to get commit data: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if commitLine == "" {
|
||||||
|
return nil, errors.InvalidArgument("path %q not found in %s", path, rev)
|
||||||
|
}
|
||||||
|
|
||||||
|
const columnCount = 9
|
||||||
|
|
||||||
|
commitData := strings.Split(strings.TrimSpace(commitLine), separatorZero)
|
||||||
|
if len(commitData) != columnCount {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"unexpected git log formatted output, expected %d, but got %d columns", columnCount, len(commitData))
|
||||||
|
}
|
||||||
|
|
||||||
|
sha := commitData[0]
|
||||||
|
authorName := commitData[1]
|
||||||
|
authorEmail := commitData[2]
|
||||||
|
authorTimestamp := commitData[3]
|
||||||
|
committerName := commitData[4]
|
||||||
|
committerEmail := commitData[5]
|
||||||
|
committerTimestamp := commitData[6]
|
||||||
|
subject := commitData[7]
|
||||||
|
body := commitData[8]
|
||||||
|
|
||||||
|
authorTime, _ := time.Parse(time.RFC3339Nano, authorTimestamp)
|
||||||
|
committerTime, _ := time.Parse(time.RFC3339Nano, committerTimestamp)
|
||||||
|
|
||||||
|
return &types.Commit{
|
||||||
|
SHA: sha,
|
||||||
|
Title: subject,
|
||||||
|
Message: body,
|
||||||
|
Author: types.Signature{
|
||||||
|
Identity: types.Identity{
|
||||||
|
Name: authorName,
|
||||||
|
Email: authorEmail,
|
||||||
|
},
|
||||||
|
When: authorTime,
|
||||||
|
},
|
||||||
|
Committer: types.Signature{
|
||||||
|
Identity: types.Identity{
|
||||||
|
Name: committerName,
|
||||||
|
Email: committerEmail,
|
||||||
|
},
|
||||||
|
When: committerTime,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -28,7 +27,6 @@ import (
|
|||||||
"github.com/harness/gitness/errors"
|
"github.com/harness/gitness/errors"
|
||||||
"github.com/harness/gitness/git/types"
|
"github.com/harness/gitness/git/types"
|
||||||
|
|
||||||
gitea "code.gitea.io/gitea/modules/git"
|
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -123,57 +121,5 @@ func (c commitEntryGetter) Find(
|
|||||||
path = "."
|
path = "."
|
||||||
}
|
}
|
||||||
|
|
||||||
const format = "" +
|
return getCommit(ctx, repoPath, commitSHA, path)
|
||||||
fmtCommitHash + fmtZero + // 0
|
|
||||||
fmtAuthorName + fmtZero + // 1
|
|
||||||
fmtAuthorEmail + fmtZero + // 2
|
|
||||||
fmtAuthorUnix + fmtZero + // 3
|
|
||||||
fmtCommitterName + fmtZero + // 4
|
|
||||||
fmtCommitterEmail + fmtZero + // 5
|
|
||||||
fmtCommitterUnix + fmtZero + // 6
|
|
||||||
fmtSubject + fmtZero + // 7
|
|
||||||
fmtBody // 8
|
|
||||||
|
|
||||||
args := []string{"log", "--max-count=1", "--format=" + format, commitSHA, "--", path}
|
|
||||||
commitLine, _, err := gitea.NewCommand(ctx, args...).RunStdString(&gitea.RunOpts{Dir: repoPath})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to run git to get the last commit for path: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
const columnCount = 9
|
|
||||||
|
|
||||||
commitData := strings.Split(strings.TrimSpace(commitLine), separatorZero)
|
|
||||||
if len(commitData) != columnCount {
|
|
||||||
return nil, errors.InvalidArgument("path %q not found in commit %s", path, commitSHA)
|
|
||||||
}
|
|
||||||
|
|
||||||
sha := commitData[0]
|
|
||||||
authorName := commitData[1]
|
|
||||||
authorEmail := commitData[2]
|
|
||||||
authorTime, _ := strconv.ParseInt(commitData[3], 10, 64) // parse failure produces 01-01-1970
|
|
||||||
committerName := commitData[4]
|
|
||||||
committerEmail := commitData[5]
|
|
||||||
committerTime, _ := strconv.ParseInt(commitData[6], 10, 64) // parse failure produces 01-01-1970
|
|
||||||
subject := commitData[7]
|
|
||||||
body := commitData[8]
|
|
||||||
|
|
||||||
return &types.Commit{
|
|
||||||
SHA: sha,
|
|
||||||
Title: subject,
|
|
||||||
Message: body,
|
|
||||||
Author: types.Signature{
|
|
||||||
Identity: types.Identity{
|
|
||||||
Name: authorName,
|
|
||||||
Email: authorEmail,
|
|
||||||
},
|
|
||||||
When: time.Unix(authorTime, 0),
|
|
||||||
},
|
|
||||||
Committer: types.Signature{
|
|
||||||
Identity: types.Identity{
|
|
||||||
Name: committerName,
|
|
||||||
Email: committerEmail,
|
|
||||||
},
|
|
||||||
When: time.Unix(committerTime, 0),
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user