116 lines
2.9 KiB
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)
|
|
}
|