Skip to content

Pass 'not' to commit count #24473

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
May 8, 2023
Merged
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
14e9c46
Pass not to commit count
mattwalo32 May 1, 2023
266e2fc
Merge branch 'main' into fix-commit-count
mattwalo32 May 1, 2023
c29eb71
Pass empty arg
mattwalo32 May 1, 2023
13a0c28
Merge branch 'main' into fix-commit-count
mattwalo32 May 1, 2023
a64283e
Bind empty string to cache fn
mattwalo32 May 1, 2023
c2fdad2
Update cache.go
mattwalo32 May 1, 2023
faac614
Merge branch 'main' into fix-commit-count
mattwalo32 May 1, 2023
76adc14
Format
mattwalo32 May 1, 2023
80e08bb
Fix param order
mattwalo32 May 1, 2023
b5d3a78
Use struct to pass opts
mattwalo32 May 2, 2023
b19cf49
Call counts with opts struct
mattwalo32 May 2, 2023
b5bd467
use struct for CommitsByFileAndRange
mattwalo32 May 2, 2023
94291cb
Format
mattwalo32 May 2, 2023
e3342a8
Test passing not
mattwalo32 May 2, 2023
7fe2568
Add tests
mattwalo32 May 2, 2023
2f3cfc2
Merge branch 'main' into fix-commit-count
mattwalo32 May 2, 2023
bd39685
Remove not param
mattwalo32 May 3, 2023
b772430
Merge branch 'main' of https://github.com/mattwalo32/gitea into fix-c…
mattwalo32 May 3, 2023
884a70d
Combine CommitsCount and CommitsCountFiles
mattwalo32 May 4, 2023
226600e
Ignore blank param
mattwalo32 May 4, 2023
f3841d1
Merge branch 'main' into fix-commit-count
mattwalo32 May 4, 2023
d0aacef
Merge branch 'main' into fix-commit-count
mattwalo32 May 4, 2023
fc9883d
Remove defaults
mattwalo32 May 5, 2023
1154aec
Merge branch 'fix-commit-count' of https://github.com/mattwalo32/gite…
mattwalo32 May 5, 2023
de452cc
Merge branch 'main' into fix-commit-count
mattwalo32 May 5, 2023
8fb7f78
Reorder args
mattwalo32 May 5, 2023
f07a4e3
Merge branch 'main' into fix-commit-count
mattwalo32 May 5, 2023
7ccbcf4
t push
mattwalo32 May 5, 2023
04bfe05
Merge branch 'main' into fix-commit-count
lunny May 6, 2023
cc65779
Merge branch 'main' into fix-commit-count
mattwalo32 May 6, 2023
54c7a88
Merge branch 'main' into fix-commit-count
mattwalo32 May 7, 2023
399766a
Remove not param from fileCommitsCount
mattwalo32 May 7, 2023
542e785
Merge branch 'main' into fix-commit-count
GiteaBot May 8, 2023
4ca7478
Merge branch 'main' into fix-commit-count
GiteaBot May 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion modules/context/repo.go
Original file line number Diff line number Diff line change
@@ -208,7 +208,12 @@ func (r *Repository) GetCommitGraphsCount(ctx context.Context, hidePRRefs bool,
if len(branches) == 0 {
return git.AllCommitsCount(ctx, r.Repository.RepoPath(), hidePRRefs, files...)
}
return git.CommitsCountFiles(ctx, r.Repository.RepoPath(), branches, files)
return git.CommitsCount(ctx,
git.CommitsCountOptions{
RepoPath: r.Repository.RepoPath(),
Revision: branches,
RelPath: files,
})
})
}

36 changes: 24 additions & 12 deletions modules/git/commit.go
Original file line number Diff line number Diff line change
@@ -160,30 +160,42 @@ 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
}

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
21 changes: 20 additions & 1 deletion modules/git/commit_test.go
Original file line number Diff line number Diff line change
@@ -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")

40 changes: 32 additions & 8 deletions modules/git/repo_commit.go
Original file line number Diff line number Diff line change
@@ -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
27 changes: 23 additions & 4 deletions routers/api/v1/repo/commits.go
Original file line number Diff line number Diff line change
@@ -146,6 +146,7 @@ func GetAllCommits(ctx *context.APIContext) {

sha := ctx.FormString("sha")
path := ctx.FormString("path")
not := ctx.FormString("not")

var (
commitsCountTotal int64
@@ -178,14 +179,18 @@ func GetAllCommits(ctx *context.APIContext) {
}

// Total commit count
commitsCountTotal, err = baseCommit.CommitsCount()
commitsCountTotal, err = git.CommitsCount(ctx.Repo.GitRepo.Ctx, git.CommitsCountOptions{
RepoPath: ctx.Repo.GitRepo.Path,
Not: not,
Revision: []string{baseCommit.ID.String()},
})

if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommitsCount", err)
return
}

// Query commits
not := ctx.FormString("not")
commits, err = baseCommit.CommitsByRange(listOptions.Page, listOptions.PageSize, not)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommitsByRange", err)
@@ -196,7 +201,14 @@ func GetAllCommits(ctx *context.APIContext) {
sha = ctx.Repo.Repository.DefaultBranch
}

commitsCountTotal, err = ctx.Repo.GitRepo.FileCommitsCount(sha, path)
commitsCountTotal, err = git.CommitsCount(ctx,
git.CommitsCountOptions{
RepoPath: ctx.Repo.GitRepo.Path,
Not: not,
Revision: []string{sha},
RelPath: []string{path},
})

if err != nil {
ctx.Error(http.StatusInternalServerError, "FileCommitsCount", err)
return
@@ -205,7 +217,14 @@ func GetAllCommits(ctx *context.APIContext) {
return
}

commits, err = ctx.Repo.GitRepo.CommitsByFileAndRange(sha, path, listOptions.Page)
commits, err = ctx.Repo.GitRepo.CommitsByFileAndRange(
git.CommitsByFileAndRangeOptions{
Revision: sha,
File: path,
Not: not,
Page: listOptions.Page,
})

if err != nil {
ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err)
return
7 changes: 6 additions & 1 deletion routers/api/v1/repo/wiki.go
Original file line number Diff line number Diff line change
@@ -429,7 +429,12 @@ func ListPageRevisions(ctx *context.APIContext) {
}

// get Commit Count
commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page)
commitsHistory, err := wikiRepo.CommitsByFileAndRange(
git.CommitsByFileAndRangeOptions{
Revision: "master",
File: pageFilename,
Page: page,
})
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err)
return
8 changes: 7 additions & 1 deletion routers/web/feed/file.go
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ import (

"code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/util"

"github.com/gorilla/feeds"
@@ -21,7 +22,12 @@ func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string
if len(fileName) == 0 {
return
}
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(ctx.Repo.RefName, fileName, 1)
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(
git.CommitsByFileAndRangeOptions{
Revision: ctx.Repo.RefName,
File: fileName,
Page: 1,
})
if err != nil {
ctx.ServerError("ShowBranchFeed", err)
return
7 changes: 6 additions & 1 deletion routers/web/repo/commit.go
Original file line number Diff line number Diff line change
@@ -230,7 +230,12 @@ func FileHistory(ctx *context.Context) {
page = 1
}

commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(ctx.Repo.RefName, fileName, page)
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(
git.CommitsByFileAndRangeOptions{
Revision: ctx.Repo.RefName,
File: fileName,
Page: page,
})
if err != nil {
ctx.ServerError("CommitsByFileAndRange", err)
return
7 changes: 6 additions & 1 deletion routers/web/repo/wiki.go
Original file line number Diff line number Diff line change
@@ -376,7 +376,12 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
}

// get Commit Count
commitsHistory, err := wikiRepo.CommitsByFileAndRange(wiki_service.DefaultBranch, pageFilename, page)
commitsHistory, err := wikiRepo.CommitsByFileAndRange(
git.CommitsByFileAndRangeOptions{
Revision: wiki_service.DefaultBranch,
File: pageFilename,
Page: page,
})
if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
47 changes: 47 additions & 0 deletions tests/integration/api_repo_git_commits_test.go
Original file line number Diff line number Diff line change
@@ -58,6 +58,29 @@ func TestAPIReposGitCommitList(t *testing.T) {
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)

// Test getting commits (Page 1)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo20/commits?token="+token+"&not=master&sha=remove-files-a", user.Name)
resp := MakeRequest(t, req, http.StatusOK)

var apiData []api.Commit
DecodeJSON(t, resp, &apiData)

assert.Len(t, apiData, 2)
assert.EqualValues(t, "cfe3b3c1fd36fba04f9183287b106497e1afe986", apiData[0].CommitMeta.SHA)
compareCommitFiles(t, []string{"link_hi", "test.csv"}, apiData[0].Files)
assert.EqualValues(t, "c8e31bc7688741a5287fcde4fbb8fc129ca07027", apiData[1].CommitMeta.SHA)
compareCommitFiles(t, []string{"test.csv"}, apiData[1].Files)

assert.EqualValues(t, resp.Header().Get("X-Total"), "2")
}

func TestAPIReposGitCommitListNotMaster(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)

// Test getting commits (Page 1)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?token="+token, user.Name)
resp := MakeRequest(t, req, http.StatusOK)
@@ -72,6 +95,8 @@ func TestAPIReposGitCommitList(t *testing.T) {
compareCommitFiles(t, []string{"readme.md"}, apiData[1].Files)
assert.EqualValues(t, "5099b81332712fe655e34e8dd63574f503f61811", apiData[2].CommitMeta.SHA)
compareCommitFiles(t, []string{"readme.md"}, apiData[2].Files)

assert.EqualValues(t, resp.Header().Get("X-Total"), "3")
}

func TestAPIReposGitCommitListPage2Empty(t *testing.T) {
@@ -148,4 +173,26 @@ func TestGetFileHistory(t *testing.T) {
assert.Len(t, apiData, 1)
assert.Equal(t, "f27c2b2b03dcab38beaf89b0ab4ff61f6de63441", apiData[0].CommitMeta.SHA)
compareCommitFiles(t, []string{"readme.md"}, apiData[0].Files)

assert.EqualValues(t, resp.Header().Get("X-Total"), "1")
}

func TestGetFileHistoryNotOnMaster(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)

req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo20/commits?path=test.csv&token="+token+"&sha=add-csv&not=master", user.Name)
resp := MakeRequest(t, req, http.StatusOK)

var apiData []api.Commit
DecodeJSON(t, resp, &apiData)

assert.Len(t, apiData, 1)
assert.Equal(t, "c8e31bc7688741a5287fcde4fbb8fc129ca07027", apiData[0].CommitMeta.SHA)
compareCommitFiles(t, []string{"test.csv"}, apiData[0].Files)

assert.EqualValues(t, resp.Header().Get("X-Total"), "1")
}