2021-12-30 08:25:36 +02:00
|
|
|
package loaders
|
2020-09-29 11:22:26 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
2021-10-18 15:44:01 +02:00
|
|
|
"strings"
|
2020-09-29 11:22:26 +02:00
|
|
|
|
2020-09-29 12:28:39 +02:00
|
|
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
2021-12-30 08:25:36 +02:00
|
|
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
|
|
|
"github.com/jesseduffield/lazygit/pkg/common"
|
2020-09-29 11:22:26 +02:00
|
|
|
)
|
|
|
|
|
2021-12-30 08:25:36 +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
|
2021-12-30 08:25:36 +02:00
|
|
|
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)
|
|
|
|
|
|
|
|
filterPathArg := ""
|
|
|
|
if filterPath != "" {
|
2021-12-30 08:25:36 +02:00
|
|
|
filterPathArg = fmt.Sprintf(" --follow -- %s", self.cmd.Quote(filterPath))
|
2020-09-29 11:22:26 +02:00
|
|
|
}
|
|
|
|
|
2022-05-04 12:41:37 +02:00
|
|
|
cmdObj := self.cmd.New(fmt.Sprintf(`git -c log.showSignature=false log -g --abbrev=40 --format="%s"%s`, "%h%x00%ct%x00%gs%x00%p", filterPathArg)).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) {
|
2022-03-26 15:03:32 +02:00
|
|
|
fields := strings.SplitN(line, "\x00", 4)
|
|
|
|
if len(fields) <= 3 {
|
2020-09-29 11:22:26 +02:00
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
2021-10-18 15:44:01 +02:00
|
|
|
unixTimestamp, _ := strconv.Atoi(fields[1])
|
2020-09-29 11:22:26 +02:00
|
|
|
|
2022-03-26 15:03:32 +02:00
|
|
|
parentHashes := fields[3]
|
|
|
|
parents := []string{}
|
|
|
|
if len(parentHashes) > 0 {
|
|
|
|
parents = strings.Split(parentHashes, " ")
|
|
|
|
}
|
|
|
|
|
2020-09-29 11:22:26 +02:00
|
|
|
commit := &models.Commit{
|
2021-10-18 15:44:01 +02:00
|
|
|
Sha: fields[0],
|
|
|
|
Name: fields[2],
|
2020-09-29 11:22:26 +02:00
|
|
|
UnixTimestamp: int64(unixTimestamp),
|
|
|
|
Status: "reflog",
|
2022-03-26 15:03:32 +02:00
|
|
|
Parents: parents,
|
2020-09-29 11:22:26 +02:00
|
|
|
}
|
|
|
|
|
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 && commit.Sha == lastReflogCommit.Sha && commit.UnixTimestamp == lastReflogCommit.UnixTimestamp && commit.Name == lastReflogCommit.Name {
|
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
|
|
|
|
}
|