Skip to content

Commit c33ac14

Browse files
committed
Move GetDiverging functions to gitrepo
1 parent 198f37e commit c33ac14

File tree

11 files changed

+175
-110
lines changed

11 files changed

+175
-110
lines changed

models/migrations/v1_12/v136.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ package v1_12
66
import (
77
"fmt"
88
"math"
9-
"path/filepath"
10-
"strings"
119
"time"
1210

13-
"code.gitea.io/gitea/modules/git"
11+
repo_model "code.gitea.io/gitea/models/repo"
12+
"code.gitea.io/gitea/modules/gitrepo"
1413
"code.gitea.io/gitea/modules/graceful"
1514
"code.gitea.io/gitea/modules/log"
1615
"code.gitea.io/gitea/modules/setting"
@@ -85,12 +84,12 @@ func AddCommitDivergenceToPulls(x *xorm.Engine) error {
8584
log.Error("Missing base repo with id %d for PR ID %d", pr.BaseRepoID, pr.ID)
8685
continue
8786
}
88-
userPath := filepath.Join(setting.RepoRootPath, strings.ToLower(baseRepo.OwnerName))
89-
repoPath := filepath.Join(userPath, strings.ToLower(baseRepo.Name)+".git")
9087

9188
gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index)
9289

93-
divergence, err := git.GetDivergingCommits(graceful.GetManager().HammerContext(), repoPath, pr.BaseBranch, gitRefName)
90+
divergence, err := gitrepo.GetDivergingCommits(graceful.GetManager().HammerContext(),
91+
repo_model.StorageRepo(repo_model.RelativePath(baseRepo.OwnerName, baseRepo.Name)),
92+
pr.BaseBranch, gitRefName)
9493
if err != nil {
9594
log.Warn("Could not recalculate Divergence for pull: %d", pr.ID)
9695
pr.CommitsAhead = 0

modules/git/repo.go

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -243,36 +243,6 @@ func GetLatestCommitTime(ctx context.Context, repoPath string) (time.Time, error
243243
return time.Parse("Mon Jan _2 15:04:05 2006 -0700", commitTime)
244244
}
245245

246-
// DivergeObject represents commit count diverging commits
247-
type DivergeObject struct {
248-
Ahead int
249-
Behind int
250-
}
251-
252-
// GetDivergingCommits returns the number of commits a targetBranch is ahead or behind a baseBranch
253-
func GetDivergingCommits(ctx context.Context, repoPath, baseBranch, targetBranch string) (do DivergeObject, err error) {
254-
cmd := gitcmd.NewCommand("rev-list", "--count", "--left-right").
255-
AddDynamicArguments(baseBranch + "..." + targetBranch).AddArguments("--")
256-
stdout, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
257-
if err != nil {
258-
return do, err
259-
}
260-
left, right, found := strings.Cut(strings.Trim(stdout, "\n"), "\t")
261-
if !found {
262-
return do, fmt.Errorf("git rev-list output is missing a tab: %q", stdout)
263-
}
264-
265-
do.Behind, err = strconv.Atoi(left)
266-
if err != nil {
267-
return do, err
268-
}
269-
do.Ahead, err = strconv.Atoi(right)
270-
if err != nil {
271-
return do, err
272-
}
273-
return do, nil
274-
}
275-
276246
// CreateBundle create bundle content to the target path
277247
func (repo *Repository) CreateBundle(ctx context.Context, commit string, out io.Writer) error {
278248
tmp, cleanup, err := setting.AppDataTempDir("git-repo-content").MkdirTempRandom("gitea-bundle")

modules/git/repo_test.go

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,3 @@ func TestRepoIsEmpty(t *testing.T) {
2929
assert.NoError(t, err)
3030
assert.True(t, isEmpty)
3131
}
32-
33-
func TestRepoGetDivergingCommits(t *testing.T) {
34-
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
35-
do, err := GetDivergingCommits(t.Context(), bareRepo1Path, "master", "branch2")
36-
assert.NoError(t, err)
37-
assert.Equal(t, DivergeObject{
38-
Ahead: 1,
39-
Behind: 5,
40-
}, do)
41-
42-
do, err = GetDivergingCommits(t.Context(), bareRepo1Path, "master", "master")
43-
assert.NoError(t, err)
44-
assert.Equal(t, DivergeObject{
45-
Ahead: 0,
46-
Behind: 0,
47-
}, do)
48-
49-
do, err = GetDivergingCommits(t.Context(), bareRepo1Path, "master", "test")
50-
assert.NoError(t, err)
51-
assert.Equal(t, DivergeObject{
52-
Ahead: 0,
53-
Behind: 2,
54-
}, do)
55-
}

modules/gitrepo/compare.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package gitrepo
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"strconv"
10+
"strings"
11+
12+
"code.gitea.io/gitea/modules/git/gitcmd"
13+
)
14+
15+
// DivergeObject represents commit count diverging commits
16+
type DivergeObject struct {
17+
Ahead int
18+
Behind int
19+
}
20+
21+
// GetDivergingCommits returns the number of commits a targetBranch is ahead or behind a baseBranch
22+
func GetDivergingCommits(ctx context.Context, repo Repository, baseBranch, targetBranch string) (*DivergeObject, error) {
23+
cmd := gitcmd.NewCommand("rev-list", "--count", "--left-right").
24+
AddDynamicArguments(baseBranch + "..." + targetBranch).AddArguments("--")
25+
stdout, _, err1 := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath(repo)})
26+
if err1 != nil {
27+
return nil, err1
28+
}
29+
30+
left, right, found := strings.Cut(strings.Trim(stdout, "\n"), "\t")
31+
if !found {
32+
return nil, fmt.Errorf("git rev-list output is missing a tab: %q", stdout)
33+
}
34+
35+
behind, err := strconv.Atoi(left)
36+
if err != nil {
37+
return nil, err
38+
}
39+
ahead, err := strconv.Atoi(right)
40+
if err != nil {
41+
return nil, err
42+
}
43+
return &DivergeObject{Ahead: ahead, Behind: behind}, nil
44+
}

modules/gitrepo/compare_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package gitrepo
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
type mockRepository struct {
13+
path string
14+
}
15+
16+
func (r *mockRepository) RelativePath() string {
17+
return r.path
18+
}
19+
20+
func TestRepoGetDivergingCommits(t *testing.T) {
21+
repo := &mockRepository{path: "repo1_bare"}
22+
do, err := GetDivergingCommits(t.Context(), repo, "master", "branch2")
23+
assert.NoError(t, err)
24+
assert.Equal(t, &DivergeObject{
25+
Ahead: 1,
26+
Behind: 5,
27+
}, do)
28+
29+
do, err = GetDivergingCommits(t.Context(), repo, "master", "master")
30+
assert.NoError(t, err)
31+
assert.Equal(t, &DivergeObject{
32+
Ahead: 0,
33+
Behind: 0,
34+
}, do)
35+
36+
do, err = GetDivergingCommits(t.Context(), repo, "master", "test")
37+
assert.NoError(t, err)
38+
assert.Equal(t, &DivergeObject{
39+
Ahead: 0,
40+
Behind: 2,
41+
}, do)
42+
}

modules/gitrepo/main_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package gitrepo
5+
6+
import (
7+
"os"
8+
"path/filepath"
9+
"testing"
10+
11+
"code.gitea.io/gitea/modules/git"
12+
"code.gitea.io/gitea/modules/setting"
13+
)
14+
15+
const (
16+
testReposDir = "../git/tests/repos/"
17+
)
18+
19+
func TestMain(m *testing.M) {
20+
originalRepoRootPath := setting.RepoRootPath
21+
defer func() {
22+
setting.RepoRootPath = originalRepoRootPath
23+
}()
24+
setting.RepoRootPath, _ = filepath.Abs(testReposDir)
25+
26+
originalHomePath := setting.Git.HomePath
27+
defer func() {
28+
setting.Git.HomePath = originalHomePath
29+
}()
30+
setting.Git.HomePath = filepath.Join(setting.RepoRootPath, ".home")
31+
32+
originalGitPath := setting.Git.Path
33+
defer func() {
34+
setting.Git.Path = originalGitPath
35+
}()
36+
setting.Git.Path = "git"
37+
38+
if err := git.InitSimple(); err != nil {
39+
panic(err)
40+
}
41+
42+
exitStatus := m.Run()
43+
os.Exit(exitStatus)
44+
}

services/pull/pull.go

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,6 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error {
9999
return err
100100
}
101101

102-
divergence, err := git.GetDivergingCommits(ctx, prCtx.tmpBasePath, baseBranch, trackingBranch)
103-
if err != nil {
104-
return err
105-
}
106-
pr.CommitsAhead = divergence.Ahead
107-
pr.CommitsBehind = divergence.Behind
108-
109102
assigneeCommentMap := make(map[int64]*issues_model.Comment)
110103

111104
var reviewNotifiers []*issue_service.ReviewRequestNotifier
@@ -134,6 +127,19 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error {
134127
return err
135128
}
136129

130+
// Update Commit Divergence
131+
divergence, err := GetDiverging(ctx, pr)
132+
if err != nil {
133+
return err
134+
}
135+
pr.CommitsAhead = divergence.Ahead
136+
pr.CommitsBehind = divergence.Behind
137+
138+
err = pr.UpdateCommitDivergence(ctx, divergence.Ahead, divergence.Behind)
139+
if err != nil {
140+
return err
141+
}
142+
137143
// add first push codes comment
138144
if _, err := CreatePushPullComment(ctx, issue.Poster, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName(), false); err != nil {
139145
return err
@@ -295,13 +301,6 @@ func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer
295301
pr.CommitsAhead = divergence.Ahead
296302
pr.CommitsBehind = divergence.Behind
297303

298-
// add first push codes comment
299-
baseGitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
300-
if err != nil {
301-
return err
302-
}
303-
defer baseGitRepo.Close()
304-
305304
return db.WithTx(ctx, func(ctx context.Context) error {
306305
if err := pr.UpdateColsIfNotMerged(ctx, "merge_base", "status", "conflicted_files", "changed_protected_files", "base_branch", "commits_ahead", "commits_behind"); err != nil {
307306
return err
@@ -464,7 +463,13 @@ func AddTestPullRequestTask(opts TestPullRequestOptions) {
464463
log.Error("Find pull requests [base_repo_id: %d, base_branch: %s]: %v", opts.RepoID, opts.Branch, err)
465464
return
466465
}
466+
baseRepo, err := repo_model.GetRepositoryByID(ctx, opts.RepoID)
467+
if err != nil {
468+
log.Error("GetRepositoryByID: %v", err)
469+
return
470+
}
467471
for _, pr := range prs {
472+
pr.BaseRepo = baseRepo // avoid loading again
468473
divergence, err := GetDiverging(ctx, pr)
469474
if err != nil {
470475
if git_model.IsErrBranchNotExist(err) && !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) {

services/pull/update.go

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
repo_model "code.gitea.io/gitea/models/repo"
1515
"code.gitea.io/gitea/models/unit"
1616
user_model "code.gitea.io/gitea/models/user"
17-
"code.gitea.io/gitea/modules/git"
17+
"code.gitea.io/gitea/modules/gitrepo"
1818
"code.gitea.io/gitea/modules/globallock"
1919
"code.gitea.io/gitea/modules/log"
2020
"code.gitea.io/gitea/modules/repository"
@@ -34,17 +34,18 @@ func Update(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.
3434
}
3535
defer releaser()
3636

37+
if err := pr.LoadBaseRepo(ctx); err != nil {
38+
log.Error("unable to load BaseRepo for %-v during update-by-merge: %v", pr, err)
39+
return fmt.Errorf("unable to load BaseRepo for PR[%d] during update-by-merge: %w", pr.ID, err)
40+
}
41+
3742
diffCount, err := GetDiverging(ctx, pr)
3843
if err != nil {
3944
return err
4045
} else if diffCount.Behind == 0 {
4146
return fmt.Errorf("HeadBranch of PR %d is up to date", pr.Index)
4247
}
4348

44-
if err := pr.LoadBaseRepo(ctx); err != nil {
45-
log.Error("unable to load BaseRepo for %-v during update-by-merge: %v", pr, err)
46-
return fmt.Errorf("unable to load BaseRepo for PR[%d] during update-by-merge: %w", pr.ID, err)
47-
}
4849
if err := pr.LoadHeadRepo(ctx); err != nil {
4950
log.Error("unable to load HeadRepo for PR %-v during update-by-merge: %v", pr, err)
5051
return fmt.Errorf("unable to load HeadRepo for PR[%d] during update-by-merge: %w", pr.ID, err)
@@ -173,17 +174,12 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *issues_model.PullRequest,
173174
}
174175

175176
// GetDiverging determines how many commits a PR is ahead or behind the PR base branch
176-
func GetDiverging(ctx context.Context, pr *issues_model.PullRequest) (*git.DivergeObject, error) {
177+
func GetDiverging(ctx context.Context, pr *issues_model.PullRequest) (*gitrepo.DivergeObject, error) {
177178
log.Trace("GetDiverging[%-v]: compare commits", pr)
178-
prCtx, cancel, err := createTemporaryRepoForPR(ctx, pr)
179-
if err != nil {
180-
if !git_model.IsErrBranchNotExist(err) {
181-
log.Error("CreateTemporaryRepoForPR %-v: %v", pr, err)
182-
}
179+
180+
if err := pr.LoadBaseRepo(ctx); err != nil {
183181
return nil, err
184182
}
185-
defer cancel()
186183

187-
diff, err := git.GetDivergingCommits(ctx, prCtx.tmpBasePath, baseBranch, trackingBranch)
188-
return &diff, err
184+
return gitrepo.GetDivergingCommits(ctx, pr.BaseRepo, baseBranch, pr.GetGitHeadRefName())
189185
}

0 commit comments

Comments
 (0)