From 2f5339ece5718abe5cc1ecad9e8af49f81e34c09 Mon Sep 17 00:00:00 2001 From: Enver Bisevac Date: Tue, 10 Jan 2023 13:54:08 +0100 Subject: [PATCH] merge operation refactored (#172) --- gitrpc/internal/gitea/commit.go | 4 ++ gitrpc/internal/gitea/config.go | 28 +++++++++ gitrpc/internal/service/interface.go | 2 + gitrpc/internal/service/merge.go | 93 +++++----------------------- 4 files changed, 50 insertions(+), 77 deletions(-) create mode 100644 gitrpc/internal/gitea/config.go diff --git a/gitrpc/internal/gitea/commit.go b/gitrpc/internal/gitea/commit.go index 3dfe0ad0f..347c95118 100644 --- a/gitrpc/internal/gitea/commit.go +++ b/gitrpc/internal/gitea/commit.go @@ -166,6 +166,10 @@ func (g Adapter) GetCommit(ctx context.Context, repoPath string, ref string) (*t return mapGiteaCommit(commit) } +func (g Adapter) GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, error) { + return gitea.GetFullCommitID(ctx, repoPath, shortID) +} + // GetCommits returns the (latest) commits for a specific list of refs. // Note: ref can be Branch / Tag / CommitSHA. func (g Adapter) GetCommits(ctx context.Context, repoPath string, refs []string) ([]types.Commit, error) { diff --git a/gitrpc/internal/gitea/config.go b/gitrpc/internal/gitea/config.go new file mode 100644 index 000000000..2b449b2e2 --- /dev/null +++ b/gitrpc/internal/gitea/config.go @@ -0,0 +1,28 @@ +// Copyright 2022 Harness Inc. All rights reserved. +// Use of this source code is governed by the Polyform Free Trial License +// that can be found in the LICENSE.md file for this repository. + +package gitea + +import ( + "context" + "fmt" + "strings" + + "code.gitea.io/gitea/modules/git" +) + +// Config set local git key and value configuration. +func (g Adapter) Config(ctx context.Context, repoPath, key, value string) error { + var outbuf, errbuf strings.Builder + if err := git.NewCommand(ctx, "config", "--local").AddArguments(key, value). + Run(&git.RunOpts{ + Dir: repoPath, + Stdout: &outbuf, + Stderr: &errbuf, + }); err != nil { + return fmt.Errorf("git config [%s -> <%s> ]: %w\n%s\n%s", + key, value, err, outbuf.String(), errbuf.String()) + } + return nil +} diff --git a/gitrpc/internal/service/interface.go b/gitrpc/internal/service/interface.go index 644627789..d3e44d48a 100644 --- a/gitrpc/internal/service/interface.go +++ b/gitrpc/internal/service/interface.go @@ -13,6 +13,7 @@ import ( // GitAdapter for accessing git commands from gitea. type GitAdapter interface { InitRepository(ctx context.Context, path string, bare bool) error + Config(ctx context.Context, repoPath, key, value string) error SetDefaultBranch(ctx context.Context, repoPath string, defaultBranch string, allowEmpty bool) error Clone(ctx context.Context, from, to string, opts types.CloneRepoOptions) error AddFiles(repoPath string, all bool, files ...string) error @@ -30,6 +31,7 @@ type GitAdapter interface { ListCommits(ctx context.Context, repoPath string, ref string, afterRef string, page int, limit int) ([]types.Commit, error) GetLatestCommit(ctx context.Context, repoPath string, ref string, treePath string) (*types.Commit, error) + GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, error) GetAnnotatedTag(ctx context.Context, repoPath string, sha string) (*types.Tag, error) GetAnnotatedTags(ctx context.Context, repoPath string, shas []string) ([]types.Tag, error) CreateBranch(ctx context.Context, repoPath string, branchName string, target string) (*types.Branch, error) diff --git a/gitrpc/internal/service/merge.go b/gitrpc/internal/service/merge.go index 821bdc656..2542d1187 100644 --- a/gitrpc/internal/service/merge.go +++ b/gitrpc/internal/service/merge.go @@ -81,68 +81,26 @@ func (s MergeService) MergeBranch( return nil, fmt.Errorf("unable to write .git/info/sparse-checkout file in tmpBasePath: %w", err) } - gitConfigCommand := func() *git.Command { - return git.NewCommand(ctx, "config", "--local") - } - // Switch off LFS process (set required, clean and smudge here also) - if err = gitConfigCommand().AddArguments("filter.lfs.process", ""). - Run(&git.RunOpts{ - Dir: tmpBasePath, - Stdout: &outbuf, - Stderr: &errbuf, - }); err != nil { - return nil, fmt.Errorf("git config [filter.lfs.process -> <> ]: %w\n%s\n%s", - err, outbuf.String(), errbuf.String()) + if err = s.adapter.Config(ctx, tmpBasePath, "filter.lfs.process", ""); err != nil { + return nil, err } - outbuf.Reset() - errbuf.Reset() - if err = gitConfigCommand().AddArguments("filter.lfs.required", "false"). - Run(&git.RunOpts{ - Dir: tmpBasePath, - Stdout: &outbuf, - Stderr: &errbuf, - }); err != nil { - return nil, fmt.Errorf("git config [filter.lfs.required -> ]: %w\n%s\n%s", - err, outbuf.String(), errbuf.String()) + if err = s.adapter.Config(ctx, tmpBasePath, "filter.lfs.required", "false"); err != nil { + return nil, err } - outbuf.Reset() - errbuf.Reset() - if err = gitConfigCommand().AddArguments("filter.lfs.clean", ""). - Run(&git.RunOpts{ - Dir: tmpBasePath, - Stdout: &outbuf, - Stderr: &errbuf, - }); err != nil { - return nil, fmt.Errorf("git config [filter.lfs.clean -> <> ]: %w\n%s\n%s", - err, outbuf.String(), errbuf.String()) + if err = s.adapter.Config(ctx, tmpBasePath, "filter.lfs.clean", ""); err != nil { + return nil, err } - outbuf.Reset() - errbuf.Reset() - if err = gitConfigCommand().AddArguments("filter.lfs.smudge", ""). - Run(&git.RunOpts{ - Dir: tmpBasePath, - Stdout: &outbuf, - Stderr: &errbuf, - }); err != nil { - return nil, fmt.Errorf("git config [filter.lfs.smudge -> <> ]: %w\n%s\n%s", err, outbuf.String(), errbuf.String()) + if err = s.adapter.Config(ctx, tmpBasePath, "filter.lfs.smudge", ""); err != nil { + return nil, err } - outbuf.Reset() - errbuf.Reset() - if err = gitConfigCommand().AddArguments("core.sparseCheckout", "true"). - Run(&git.RunOpts{ - Dir: tmpBasePath, - Stdout: &outbuf, - Stderr: &errbuf, - }); err != nil { - return nil, fmt.Errorf("git config [core.sparsecheckout -> true]: %w\n%s\n%s", err, outbuf.String(), errbuf.String()) + if err = s.adapter.Config(ctx, tmpBasePath, "core.sparseCheckout", "true"); err != nil { + return nil, err } - outbuf.Reset() - errbuf.Reset() // Read base branch index if err = git.NewCommand(ctx, "read-tree", "HEAD"). @@ -178,38 +136,19 @@ func (s MergeService) MergeBranch( return nil, err } - mergeCommitID, err := git.GetFullCommitID(ctx, tmpBasePath, baseBranch) + mergeCommitID, err := s.adapter.GetFullCommitID(ctx, tmpBasePath, baseBranch) if err != nil { return nil, fmt.Errorf("failed to get full commit id for the new merge: %w", err) } - pushCmd := git.NewCommand(ctx, "push", "origin", baseBranch+":"+git.BranchPrefix+pr.BaseBranch) - - if err = pushCmd.Run(&git.RunOpts{ + if err = s.adapter.Push(ctx, tmpBasePath, types.PushOptions{ + Remote: "origin", + Branch: baseBranch + ":" + git.BranchPrefix + pr.BaseBranch, + Force: request.Force, Env: env, - Dir: tmpBasePath, - Stdout: &outbuf, - Stderr: &errbuf, }); err != nil { - if strings.Contains(errbuf.String(), "non-fast-forward") { - return nil, &git.ErrPushOutOfDate{ - StdOut: outbuf.String(), - StdErr: errbuf.String(), - Err: err, - } - } else if strings.Contains(errbuf.String(), "! [remote rejected]") { - err := &git.ErrPushRejected{ - StdOut: outbuf.String(), - StdErr: errbuf.String(), - Err: err, - } - err.GenerateMessage() - return nil, err - } - return nil, fmt.Errorf("git push: %s", errbuf.String()) + return nil, err } - outbuf.Reset() - errbuf.Reset() return &rpc.MergeBranchResponse{ CommitId: mergeCommitID,