gitea_hat/modules/git/repo_commit.go

116 lines
2.9 KiB
Go

package git
import (
"bytes"
"encoding/hex"
"fmt"
"io"
"strconv"
"strings"
gitea_git "code.gitea.io/gitea/modules/git"
)
const prettyLogFormat = `--pretty=format:%H`
func GetFirstAndLastCommitByPath(repo *gitea_git.Repository, revision, relpath string) (*gitea_git.Commit, *gitea_git.Commit, error) {
stdout, _, runErr := gitea_git.NewCommand(repo.Ctx, "log").AddDynamicArguments(revision, prettyLogFormat, "--"+relpath).RunStdBytes(&gitea_git.RunOpts{Dir: repo.Path})
if runErr != nil {
return nil, nil, runErr
}
var commits []*gitea_git.Commit
if len(stdout) == 0 {
return nil, nil, nil
}
parts := bytes.Split(stdout, []byte{'\n'})
for _, commitID := range parts {
commit, err := repo.GetCommit(string(commitID))
if err != nil {
return nil, nil, err
}
commits = append(commits, commit)
}
return commits[0], commits[len(commits)-1], nil
}
// CommitsByFileAndRange return the commits according revision file and the page
func AllCommitsByFileAndRange(repo *gitea_git.Repository, opts gitea_git.CommitsByFileAndRangeOptions, keyword string, pageSize int) ([]*gitea_git.Commit, error) {
skip := (opts.Page - 1) * pageSize
stdoutReader, stdoutWriter := io.Pipe()
defer func() {
_ = stdoutReader.Close()
_ = stdoutWriter.Close()
}()
go func() {
stderr := strings.Builder{}
gitCmd := gitea_git.NewCommand(repo.Ctx, "rev-list").
AddOptionFormat("--max-count=%d", pageSize*opts.Page).
AddOptionFormat("--skip=%d", skip).
AddOptionFormat("--grep=%s", keyword)
gitCmd.AddDynamicArguments(opts.Revision)
if opts.Not != "" {
gitCmd.AddOptionValues("--not", opts.Not)
}
gitCmd.AddArguments("--all")
// gitCmd.AddDashesAndList(opts.File)
err := gitCmd.Run(&gitea_git.RunOpts{
Dir: repo.Path,
Stdout: stdoutWriter,
Stderr: &stderr,
})
if err != nil {
_ = stdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
} else {
_ = stdoutWriter.Close()
}
}()
commits := []*gitea_git.Commit{}
shaline := [41]byte{}
var sha1 gitea_git.SHA1
for {
n, err := io.ReadFull(stdoutReader, shaline[:])
if err != nil || n < 40 {
if err == io.EOF {
err = nil
}
return commits, err
}
n, err = hex.Decode(sha1[:], shaline[0:40])
if n != 20 {
err = fmt.Errorf("invalid sha %q", string(shaline[:40]))
}
if err != nil {
return nil, err
}
commit, err := repo.GetCommit(sha1.String())
if err != nil {
return nil, err
}
commits = append(commits, commit)
}
}
func GetAllCommitsCount(repo *gitea_git.Repository, keyword string) (int64, error) {
cmd := gitea_git.NewCommand(repo.Ctx, "rev-list").
AddOptionFormat("--grep=%s", keyword)
cmd.AddArguments("--exclude=" + "refs/pull/" + "*")
cmd.AddArguments("--all", "--count")
stdout, _, err := cmd.RunStdString(&gitea_git.RunOpts{Dir: repo.Path})
if err != nil {
return 0, err
}
return strconv.ParseInt(strings.TrimSpace(stdout), 10, 64)
}