diff options
| author | Taras Madan <tarasmadan@google.com> | 2024-08-28 11:54:59 +0200 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2024-08-29 13:21:19 +0000 |
| commit | e46dcff2767435630f9f28e4e5ea141309798801 (patch) | |
| tree | 1c62decf65a6fdf1829b2f4b33fbb9ea8e3b1cf9 /pkg | |
| parent | af983df1f68f6c49fc740287927618a30ce3e8a8 (diff) | |
pkg/covermerger: optimize checkouts
Every commit checkout takes >3 seconds.
Let's optimize this operation to save on large merges.
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/covermerger/provider_monorepo.go | 9 | ||||
| -rw-r--r-- | pkg/vcs/fuchsia.go | 4 | ||||
| -rw-r--r-- | pkg/vcs/git.go | 16 | ||||
| -rw-r--r-- | pkg/vcs/vcs.go | 3 |
4 files changed, 32 insertions, 0 deletions
diff --git a/pkg/covermerger/provider_monorepo.go b/pkg/covermerger/provider_monorepo.go index 4f908606f..379c8c138 100644 --- a/pkg/covermerger/provider_monorepo.go +++ b/pkg/covermerger/provider_monorepo.go @@ -94,6 +94,15 @@ func (mr *monoRepo) cloneCommits(rbcs []RepoCommit) { if mr.repoCommitPresent(rbc) { continue } + commitExistsInRepo, err := mr.repo.CommitExists(rbc.Commit) + if err != nil { + log.Logf(0, "can't check CommitExists: %s", err.Error()) + } + if commitExistsInRepo { + log.Logf(0, "commit %s exists in local repo, no need to clone", rbc.Commit) + mr.repoCommits[rbc] = struct{}{} + continue + } mr.addRepoCommit(rbc) } } diff --git a/pkg/vcs/fuchsia.go b/pkg/vcs/fuchsia.go index 223c0b860..2ad0e1878 100644 --- a/pkg/vcs/fuchsia.go +++ b/pkg/vcs/fuchsia.go @@ -103,3 +103,7 @@ func (ctx *fuchsia) Object(name, commit string) ([]byte, error) { func (ctx *fuchsia) MergeBases(firstCommit, secondCommit string) ([]*Commit, error) { return ctx.repo.MergeBases(firstCommit, secondCommit) } + +func (ctx *fuchsia) CommitExists(string) (bool, error) { + return false, fmt.Errorf("not implemented for fuchsia") +} diff --git a/pkg/vcs/git.go b/pkg/vcs/git.go index 840a8592e..d1a91404c 100644 --- a/pkg/vcs/git.go +++ b/pkg/vcs/git.go @@ -619,3 +619,19 @@ func (git *git) MergeBases(firstCommit, secondCommit string) ([]*Commit, error) } return ret, nil } + +// CommitExists relies on 'git cat-file -e'. +// If object exists its exit status is 0. +// If object doesn't exist its exit status is 1 (not documented). +// Otherwise, the exit status is 128 (not documented). +func (git *git) CommitExists(commit string) (bool, error) { + _, err := git.git("cat-file", "-e", commit) + var vErr *osutil.VerboseError + if errors.As(err, &vErr) && vErr.ExitCode == 1 { + return false, nil + } + if err != nil { + return false, err + } + return true, nil +} diff --git a/pkg/vcs/vcs.go b/pkg/vcs/vcs.go index faf1cf85d..0730ba721 100644 --- a/pkg/vcs/vcs.go +++ b/pkg/vcs/vcs.go @@ -69,6 +69,9 @@ type Repo interface { // MergeBases returns good common ancestors of the two commits. MergeBases(firstCommit, secondCommit string) ([]*Commit, error) + + // CommitExists check for the commit presence in local checkout. + CommitExists(commit string) (bool, error) } // Bisecter may be optionally implemented by Repo. |
