mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-06 14:36:43 +02:00
Merge remote-tracking branch 'upstream/main' into limit-repo-size
This commit is contained in:
+24
-12
@@ -160,15 +160,29 @@ func AllCommitsCount(ctx context.Context, repoPath string, hidePRRefs bool, file
|
||||
return strconv.ParseInt(strings.TrimSpace(stdout), 10, 64)
|
||||
}
|
||||
|
||||
// CommitsCountFiles returns number of total commits of until given revision.
|
||||
func CommitsCountFiles(ctx context.Context, repoPath string, revision, relpath []string) (int64, error) {
|
||||
// CommitsCountOptions the options when counting commits
|
||||
type CommitsCountOptions struct {
|
||||
RepoPath string
|
||||
Not string
|
||||
Revision []string
|
||||
RelPath []string
|
||||
}
|
||||
|
||||
// CommitsCount returns number of total commits of until given revision.
|
||||
func CommitsCount(ctx context.Context, opts CommitsCountOptions) (int64, error) {
|
||||
cmd := NewCommand(ctx, "rev-list", "--count")
|
||||
cmd.AddDynamicArguments(revision...)
|
||||
if len(relpath) > 0 {
|
||||
cmd.AddDashesAndList(relpath...)
|
||||
|
||||
cmd.AddDynamicArguments(opts.Revision...)
|
||||
|
||||
if opts.Not != "" {
|
||||
cmd.AddOptionValues("--not", opts.Not)
|
||||
}
|
||||
|
||||
stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath})
|
||||
if len(opts.RelPath) > 0 {
|
||||
cmd.AddDashesAndList(opts.RelPath...)
|
||||
}
|
||||
|
||||
stdout, _, err := cmd.RunStdString(&RunOpts{Dir: opts.RepoPath})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -176,14 +190,12 @@ func CommitsCountFiles(ctx context.Context, repoPath string, revision, relpath [
|
||||
return strconv.ParseInt(strings.TrimSpace(stdout), 10, 64)
|
||||
}
|
||||
|
||||
// CommitsCount returns number of total commits of until given revision.
|
||||
func CommitsCount(ctx context.Context, repoPath string, revision ...string) (int64, error) {
|
||||
return CommitsCountFiles(ctx, repoPath, revision, []string{})
|
||||
}
|
||||
|
||||
// CommitsCount returns number of total commits of until current revision.
|
||||
func (c *Commit) CommitsCount() (int64, error) {
|
||||
return CommitsCount(c.repo.Ctx, c.repo.Path, c.ID.String())
|
||||
return CommitsCount(c.repo.Ctx, CommitsCountOptions{
|
||||
RepoPath: c.repo.Path,
|
||||
Revision: []string{c.ID.String()},
|
||||
})
|
||||
}
|
||||
|
||||
// CommitsByRange returns the specific page commits before current revision, every page's number default by CommitsRangeSize
|
||||
|
||||
@@ -14,11 +14,30 @@ import (
|
||||
func TestCommitsCount(t *testing.T) {
|
||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||
|
||||
commitsCount, err := CommitsCount(DefaultContext, bareRepo1Path, "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0")
|
||||
commitsCount, err := CommitsCount(DefaultContext,
|
||||
CommitsCountOptions{
|
||||
RepoPath: bareRepo1Path,
|
||||
Revision: []string{"8006ff9adbf0cb94da7dad9e537e53817f9fa5c0"},
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(3), commitsCount)
|
||||
}
|
||||
|
||||
func TestCommitsCountWithoutBase(t *testing.T) {
|
||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||
|
||||
commitsCount, err := CommitsCount(DefaultContext,
|
||||
CommitsCountOptions{
|
||||
RepoPath: bareRepo1Path,
|
||||
Not: "master",
|
||||
Revision: []string{"branch1"},
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(2), commitsCount)
|
||||
}
|
||||
|
||||
func TestGetFullCommitID(t *testing.T) {
|
||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||
|
||||
|
||||
+16
-23
@@ -312,35 +312,28 @@ type DivergeObject struct {
|
||||
Behind int
|
||||
}
|
||||
|
||||
func checkDivergence(ctx context.Context, repoPath, baseBranch, targetBranch string) (int, error) {
|
||||
branches := fmt.Sprintf("%s..%s", baseBranch, targetBranch)
|
||||
cmd := NewCommand(ctx, "rev-list", "--count").AddDynamicArguments(branches)
|
||||
// GetDivergingCommits returns the number of commits a targetBranch is ahead or behind a baseBranch
|
||||
func GetDivergingCommits(ctx context.Context, repoPath, baseBranch, targetBranch string) (do DivergeObject, err error) {
|
||||
cmd := NewCommand(ctx, "rev-list", "--count", "--left-right").
|
||||
AddDynamicArguments(baseBranch + "..." + targetBranch)
|
||||
stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath})
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return do, err
|
||||
}
|
||||
outInteger, errInteger := strconv.Atoi(strings.Trim(stdout, "\n"))
|
||||
if errInteger != nil {
|
||||
return -1, errInteger
|
||||
}
|
||||
return outInteger, nil
|
||||
}
|
||||
|
||||
// GetDivergingCommits returns the number of commits a targetBranch is ahead or behind a baseBranch
|
||||
func GetDivergingCommits(ctx context.Context, repoPath, baseBranch, targetBranch string) (DivergeObject, error) {
|
||||
// $(git rev-list --count master..feature) commits ahead of master
|
||||
ahead, errorAhead := checkDivergence(ctx, repoPath, baseBranch, targetBranch)
|
||||
if errorAhead != nil {
|
||||
return DivergeObject{}, errorAhead
|
||||
left, right, found := strings.Cut(strings.Trim(stdout, "\n"), "\t")
|
||||
if !found {
|
||||
return do, fmt.Errorf("git rev-list output is missing a tab: %q", stdout)
|
||||
}
|
||||
|
||||
// $(git rev-list --count feature..master) commits behind master
|
||||
behind, errorBehind := checkDivergence(ctx, repoPath, targetBranch, baseBranch)
|
||||
if errorBehind != nil {
|
||||
return DivergeObject{}, errorBehind
|
||||
do.Behind, err = strconv.Atoi(left)
|
||||
if err != nil {
|
||||
return do, err
|
||||
}
|
||||
|
||||
return DivergeObject{ahead, behind}, nil
|
||||
do.Ahead, err = strconv.Atoi(right)
|
||||
if err != nil {
|
||||
return do, err
|
||||
}
|
||||
return do, nil
|
||||
}
|
||||
|
||||
// CreateBundle create bundle content to the target path
|
||||
|
||||
@@ -205,12 +205,24 @@ func (repo *Repository) FileChangedBetweenCommits(filename, id1, id2 string) (bo
|
||||
|
||||
// FileCommitsCount return the number of files at a revision
|
||||
func (repo *Repository) FileCommitsCount(revision, file string) (int64, error) {
|
||||
return CommitsCountFiles(repo.Ctx, repo.Path, []string{revision}, []string{file})
|
||||
return CommitsCount(repo.Ctx,
|
||||
CommitsCountOptions{
|
||||
RepoPath: repo.Path,
|
||||
Revision: []string{revision},
|
||||
RelPath: []string{file},
|
||||
})
|
||||
}
|
||||
|
||||
type CommitsByFileAndRangeOptions struct {
|
||||
Revision string
|
||||
File string
|
||||
Not string
|
||||
Page int
|
||||
}
|
||||
|
||||
// CommitsByFileAndRange return the commits according revision file and the page
|
||||
func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) ([]*Commit, error) {
|
||||
skip := (page - 1) * setting.Git.CommitsRangeSize
|
||||
func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions) ([]*Commit, error) {
|
||||
skip := (opts.Page - 1) * setting.Git.CommitsRangeSize
|
||||
|
||||
stdoutReader, stdoutWriter := io.Pipe()
|
||||
defer func() {
|
||||
@@ -220,10 +232,15 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (
|
||||
go func() {
|
||||
stderr := strings.Builder{}
|
||||
gitCmd := NewCommand(repo.Ctx, "rev-list").
|
||||
AddOptionFormat("--max-count=%d", setting.Git.CommitsRangeSize*page).
|
||||
AddOptionFormat("--max-count=%d", setting.Git.CommitsRangeSize*opts.Page).
|
||||
AddOptionFormat("--skip=%d", skip)
|
||||
gitCmd.AddDynamicArguments(revision)
|
||||
gitCmd.AddDashesAndList(file)
|
||||
gitCmd.AddDynamicArguments(opts.Revision)
|
||||
|
||||
if opts.Not != "" {
|
||||
gitCmd.AddOptionValues("--not", opts.Not)
|
||||
}
|
||||
|
||||
gitCmd.AddDashesAndList(opts.File)
|
||||
err := gitCmd.Run(&RunOpts{
|
||||
Dir: repo.Path,
|
||||
Stdout: stdoutWriter,
|
||||
@@ -365,11 +382,18 @@ func (repo *Repository) CommitsBetweenIDs(last, before string) ([]*Commit, error
|
||||
|
||||
// CommitsCountBetween return numbers of commits between two commits
|
||||
func (repo *Repository) CommitsCountBetween(start, end string) (int64, error) {
|
||||
count, err := CommitsCountFiles(repo.Ctx, repo.Path, []string{start + ".." + end}, []string{})
|
||||
count, err := CommitsCount(repo.Ctx, CommitsCountOptions{
|
||||
RepoPath: repo.Path,
|
||||
Revision: []string{start + ".." + end},
|
||||
})
|
||||
|
||||
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
||||
// previously it would return the results of git rev-list before last so let's try that...
|
||||
return CommitsCountFiles(repo.Ctx, repo.Path, []string{start, end}, []string{})
|
||||
return CommitsCount(repo.Ctx, CommitsCountOptions{
|
||||
RepoPath: repo.Path,
|
||||
Revision: []string{start, end},
|
||||
})
|
||||
}
|
||||
|
||||
return count, err
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
@@ -29,3 +30,27 @@ func TestRepoIsEmpty(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, isEmpty)
|
||||
}
|
||||
|
||||
func TestRepoGetDivergingCommits(t *testing.T) {
|
||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||
do, err := GetDivergingCommits(context.Background(), bareRepo1Path, "master", "branch2")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, DivergeObject{
|
||||
Ahead: 1,
|
||||
Behind: 5,
|
||||
}, do)
|
||||
|
||||
do, err = GetDivergingCommits(context.Background(), bareRepo1Path, "master", "master")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, DivergeObject{
|
||||
Ahead: 0,
|
||||
Behind: 0,
|
||||
}, do)
|
||||
|
||||
do, err = GetDivergingCommits(context.Background(), bareRepo1Path, "master", "test")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, DivergeObject{
|
||||
Ahead: 0,
|
||||
Behind: 2,
|
||||
}, do)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user