gitea_hat/modules/git/repo_commit.go

82 lines
2.1 KiB
Go

package git
import (
"bytes"
"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", gitea_git.CmdArg(revision), prettyLogFormat, "--", gitea_git.CmdArg(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 CommitsByFileAndRange(repo *gitea_git.Repository, revision, file string, page, pageSize int) ([]*gitea_git.Commit, error) {
skip := (page - 1) * pageSize
stdoutReader, stdoutWriter := io.Pipe()
defer func() {
_ = stdoutReader.Close()
_ = stdoutWriter.Close()
}()
go func() {
stderr := strings.Builder{}
gitCmd := gitea_git.NewCommand(repo.Ctx, "log", prettyLogFormat, "--follow",
gitea_git.CmdArg("--max-count="+strconv.Itoa(pageSize)))
gitCmd.AddDynamicArguments(revision)
gitCmd.AddArguments("--", gitea_git.CmdArg(file))
err := gitCmd.Run(&gitea_git.RunOpts{
Dir: repo.Path,
Stdout: stdoutWriter,
Stderr: &stderr,
})
if err != nil {
_ = stdoutWriter.CloseWithError(gitea_git.ConcatenateError(err, (&stderr).String()))
} else {
_ = stdoutWriter.Close()
}
}()
if skip > 0 {
_, err := io.CopyN(io.Discard, stdoutReader, int64(skip*41))
if err != nil {
if err == io.EOF {
return []*gitea_git.Commit{}, nil
}
_ = stdoutReader.CloseWithError(err)
return nil, err
}
}
stdout, err := io.ReadAll(stdoutReader)
if err != nil {
return nil, err
}
return parsePrettyFormatLogToList(repo, stdout)
}