1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-04 03:48:07 +02:00
lazygit/pkg/commands/git_commands/reflog_commit_loader.go

92 lines
2.7 KiB
Go
Raw Normal View History

package git_commands
2020-09-29 11:22:26 +02:00
import (
"strconv"
2021-10-18 15:44:01 +02:00
"strings"
2020-09-29 11:22:26 +02:00
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/common"
2020-09-29 11:22:26 +02:00
)
type ReflogCommitLoader struct {
*common.Common
cmd oscommands.ICmdObjBuilder
}
func NewReflogCommitLoader(common *common.Common, cmd oscommands.ICmdObjBuilder) *ReflogCommitLoader {
return &ReflogCommitLoader{
Common: common,
cmd: cmd,
}
}
2020-09-29 11:22:26 +02:00
// GetReflogCommits only returns the new reflog commits since the given lastReflogCommit
// if none is passed (i.e. it's value is nil) then we get all the reflog commits
func (self *ReflogCommitLoader) GetReflogCommits(lastReflogCommit *models.Commit, filterPath string) ([]*models.Commit, bool, error) {
2020-09-29 11:22:26 +02:00
commits := make([]*models.Commit, 0)
cmdArgs := NewGitCmd("log").
Config("log.showSignature=false").
Arg("-g").
Arg("--abbrev=40").
Arg("--format=%h%x00%ct%x00%gs%x00%p").
ArgIf(filterPath != "", "--follow", "--", filterPath).
ToArgv()
2020-09-29 11:22:26 +02:00
cmdObj := self.cmd.New(cmdArgs).DontLog()
2020-09-29 11:22:26 +02:00
onlyObtainedNewReflogCommits := false
2021-12-30 02:22:29 +02:00
err := cmdObj.RunAndProcessLines(func(line string) (bool, error) {
commit, ok := self.parseLine(line)
if !ok {
2020-09-29 11:22:26 +02:00
return false, nil
}
2022-01-26 01:34:56 +02:00
// note that the unix timestamp here is the timestamp of the COMMIT, not the reflog entry itself,
2022-04-03 22:19:15 +02:00
// so two consecutive reflog entries may have both the same SHA and therefore same timestamp.
2022-01-26 01:34:56 +02:00
// We use the reflog message to disambiguate, and fingers crossed that we never see the same of those
// twice in a row. Reason being that it would mean we'd be erroneously exiting early.
if lastReflogCommit != nil && self.sameReflogCommit(commit, lastReflogCommit) {
2020-09-29 11:22:26 +02:00
onlyObtainedNewReflogCommits = true
// after this point we already have these reflogs loaded so we'll simply return the new ones
return true, nil
}
commits = append(commits, commit)
return false, nil
})
if err != nil {
return nil, false, err
}
return commits, onlyObtainedNewReflogCommits, nil
}
func (self *ReflogCommitLoader) sameReflogCommit(a *models.Commit, b *models.Commit) bool {
return a.Sha == b.Sha && a.UnixTimestamp == b.UnixTimestamp && a.Name == b.Name
}
func (self *ReflogCommitLoader) parseLine(line string) (*models.Commit, bool) {
fields := strings.SplitN(line, "\x00", 4)
if len(fields) <= 3 {
return nil, false
}
unixTimestamp, _ := strconv.Atoi(fields[1])
parentHashes := fields[3]
parents := []string{}
if len(parentHashes) > 0 {
parents = strings.Split(parentHashes, " ")
}
return &models.Commit{
Sha: fields[0],
Name: fields[2],
UnixTimestamp: int64(unixTimestamp),
Status: models.StatusReflog,
Parents: parents,
}, true
}