Make Commit.Hash a getter for an unexported hash field

This is in preparation for turning the hash into pointer to a string.
This commit is contained in:
Stefan Haller 2025-04-24 09:13:40 +02:00
parent 97aa7a04e6
commit 1037371a44
28 changed files with 301 additions and 245 deletions

View file

@ -22,7 +22,7 @@ func (self *TodoLine) ToString() string {
if self.Action == "break" {
return self.Action + "\n"
} else {
return self.Action + " " + self.Commit.Hash + " " + self.Commit.Name + "\n"
return self.Action + " " + self.Commit.Hash() + " " + self.Commit.Name + "\n"
}
}

View file

@ -121,7 +121,7 @@ func (self *CommitLoader) GetCommits(opts GetCommitsOptions) ([]*models.Commit,
}
for _, commit := range commits {
if commit.Hash == firstPushedCommit {
if commit.Hash() == firstPushedCommit {
passedFirstPushedCommit = true
}
if !commit.IsTODO() {
@ -234,7 +234,7 @@ func (self *CommitLoader) extractCommitFromLine(line string, showDivergence bool
parents = strings.Split(parentHashes, " ")
}
return &models.Commit{
return models.NewCommit(models.NewCommitOpts{
Hash: hash,
Name: message,
Tags: tags,
@ -244,7 +244,7 @@ func (self *CommitLoader) extractCommitFromLine(line string, showDivergence bool
AuthorEmail: authorEmail,
Parents: parents,
Divergence: divergence,
}
})
}
func (self *CommitLoader) getHydratedRebasingCommits(addConflictingCommit bool) ([]*models.Commit, error) {
@ -277,7 +277,7 @@ func (self *CommitLoader) getHydratedTodoCommits(todoCommits []*models.Commit, t
}
commitHashes := lo.FilterMap(todoCommits, func(commit *models.Commit, _ int) (string, bool) {
return commit.Hash, commit.Hash != ""
return commit.Hash(), commit.Hash() != ""
})
// note that we're not filtering these as we do non-rebasing commits just because
@ -293,7 +293,7 @@ func (self *CommitLoader) getHydratedTodoCommits(todoCommits []*models.Commit, t
fullCommits := map[string]*models.Commit{}
err := cmdObj.RunAndProcessLines(func(line string) (bool, error) {
commit := self.extractCommitFromLine(line, false)
fullCommits[commit.Hash] = commit
fullCommits[commit.Hash()] = commit
return false, nil
})
if err != nil {
@ -315,9 +315,9 @@ func (self *CommitLoader) getHydratedTodoCommits(todoCommits []*models.Commit, t
hydratedCommits := make([]*models.Commit, 0, len(todoCommits))
for _, rebasingCommit := range todoCommits {
if rebasingCommit.Hash == "" {
if rebasingCommit.Hash() == "" {
hydratedCommits = append(hydratedCommits, rebasingCommit)
} else if commit := findFullCommit(rebasingCommit.Hash); commit != nil {
} else if commit := findFullCommit(rebasingCommit.Hash()); commit != nil {
commit.Action = rebasingCommit.Action
commit.Status = rebasingCommit.Status
hydratedCommits = append(hydratedCommits, commit)
@ -364,12 +364,12 @@ func (self *CommitLoader) getRebasingCommits(addConflictingCommit bool) []*model
// Command does not have a commit associated, skip
continue
}
commits = utils.Prepend(commits, &models.Commit{
commits = utils.Prepend(commits, models.NewCommit(models.NewCommitOpts{
Hash: t.Commit,
Name: t.Msg,
Status: models.StatusRebasing,
Action: t.Command,
})
}))
}
return commits
@ -465,11 +465,11 @@ func (self *CommitLoader) getConflictedCommitImpl(todos []todo.Todo, doneTodos [
// Any other todo that has a commit associated with it must have failed with
// a conflict, otherwise we wouldn't have stopped the rebase:
return &models.Commit{
return models.NewCommit(models.NewCommitOpts{
Hash: lastTodo.Commit,
Action: lastTodo.Command,
Status: models.StatusConflicted,
}
})
}
func (self *CommitLoader) getSequencerCommits() []*models.Commit {
@ -493,12 +493,12 @@ func (self *CommitLoader) getSequencerCommits() []*models.Commit {
// Command does not have a commit associated, skip
continue
}
commits = utils.Prepend(commits, &models.Commit{
commits = utils.Prepend(commits, models.NewCommit(models.NewCommitOpts{
Hash: t.Commit,
Name: t.Msg,
Status: models.StatusCherryPickingOrReverting,
Action: t.Command,
})
}))
}
return commits
@ -526,11 +526,11 @@ func (self *CommitLoader) getConflictedSequencerCommit(workingTreeState models.W
if len(lines) == 0 {
return nil
}
return &models.Commit{
return models.NewCommit(models.NewCommitOpts{
Hash: lines[0],
Status: models.StatusConflicted,
Action: action,
}
})
}
func setCommitMergedStatuses(ancestor string, commits []*models.Commit) {
@ -541,7 +541,7 @@ func setCommitMergedStatuses(ancestor string, commits []*models.Commit) {
passedAncestor := false
for i, commit := range commits {
// some commits aren't really commits and don't have hashes, such as the update-ref todo
if commit.Hash != "" && strings.HasPrefix(ancestor, commit.Hash) {
if commit.Hash() != "" && strings.HasPrefix(ancestor, commit.Hash()) {
passedAncestor = true
}
if commit.Status != models.StatusPushed && commit.Status != models.StatusUnpushed {

View file

@ -10,6 +10,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
"github.com/stefanhaller/git-todo-parser/todo"
"github.com/stretchr/testify/assert"
)
@ -27,13 +28,13 @@ var singleCommitOutput = strings.Replace(`0eea75e8c631fba6b58135697835d58ba4c18d
func TestGetCommits(t *testing.T) {
type scenario struct {
testName string
runner *oscommands.FakeCmdObjRunner
expectedCommits []*models.Commit
expectedError error
logOrder string
opts GetCommitsOptions
mainBranches []string
testName string
runner *oscommands.FakeCmdObjRunner
expectedCommitOpts []models.NewCommitOpts
expectedError error
logOrder string
opts GetCommitsOptions
mainBranches []string
}
scenarios := []scenario{
@ -45,8 +46,8 @@ func TestGetCommits(t *testing.T) {
ExpectGitArgs([]string{"merge-base", "mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
ExpectGitArgs([]string{"log", "HEAD", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%m%x00%s", "--abbrev=40", "--no-show-signature", "--"}, "", nil),
expectedCommits: []*models.Commit{},
expectedError: nil,
expectedCommitOpts: []models.NewCommitOpts{},
expectedError: nil,
},
{
testName: "should use proper upstream name for branch",
@ -56,8 +57,8 @@ func TestGetCommits(t *testing.T) {
ExpectGitArgs([]string{"merge-base", "refs/heads/mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
ExpectGitArgs([]string{"log", "refs/heads/mybranch", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%m%x00%s", "--abbrev=40", "--no-show-signature", "--"}, "", nil),
expectedCommits: []*models.Commit{},
expectedError: nil,
expectedCommitOpts: []models.NewCommitOpts{},
expectedError: nil,
},
{
testName: "should return commits if they are present",
@ -79,7 +80,7 @@ func TestGetCommits(t *testing.T) {
// here it's seeing where our branch diverged from the master branch so that we can mark that commit and parent commits as 'merged'
ExpectGitArgs([]string{"merge-base", "HEAD", "refs/remotes/origin/master", "refs/remotes/origin/main"}, "26c07b1ab33860a1a7591a0638f9925ccf497ffa", nil),
expectedCommits: []*models.Commit{
expectedCommitOpts: []models.NewCommitOpts{
{
Hash: "0eea75e8c631fba6b58135697835d58ba4c18dbc",
Name: "better typing for rebase mode",
@ -213,7 +214,7 @@ func TestGetCommits(t *testing.T) {
ExpectGitArgs([]string{"rev-parse", "--verify", "--quiet", "refs/remotes/origin/main"}, "", errors.New("error")).
ExpectGitArgs([]string{"rev-parse", "--verify", "--quiet", "refs/heads/main"}, "", errors.New("error")),
expectedCommits: []*models.Commit{
expectedCommitOpts: []models.NewCommitOpts{
{
Hash: "0eea75e8c631fba6b58135697835d58ba4c18dbc",
Name: "better typing for rebase mode",
@ -251,7 +252,7 @@ func TestGetCommits(t *testing.T) {
// here it's seeing where our branch diverged from the master branch so that we can mark that commit and parent commits as 'merged'
ExpectGitArgs([]string{"merge-base", "HEAD", "refs/remotes/origin/master", "refs/remotes/origin/develop", "refs/remotes/origin/1.0-hotfixes"}, "26c07b1ab33860a1a7591a0638f9925ccf497ffa", nil),
expectedCommits: []*models.Commit{
expectedCommitOpts: []models.NewCommitOpts{
{
Hash: "0eea75e8c631fba6b58135697835d58ba4c18dbc",
Name: "better typing for rebase mode",
@ -277,8 +278,8 @@ func TestGetCommits(t *testing.T) {
ExpectGitArgs([]string{"merge-base", "mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
ExpectGitArgs([]string{"log", "HEAD", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%m%x00%s", "--abbrev=40", "--no-show-signature", "--"}, "", nil),
expectedCommits: []*models.Commit{},
expectedError: nil,
expectedCommitOpts: []models.NewCommitOpts{},
expectedError: nil,
},
{
testName: "should set filter path",
@ -288,8 +289,8 @@ func TestGetCommits(t *testing.T) {
ExpectGitArgs([]string{"merge-base", "mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
ExpectGitArgs([]string{"log", "HEAD", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%m%x00%s", "--abbrev=40", "--follow", "--no-show-signature", "--", "src"}, "", nil),
expectedCommits: []*models.Commit{},
expectedError: nil,
expectedCommitOpts: []models.NewCommitOpts{},
expectedError: nil,
},
}
@ -318,7 +319,9 @@ func TestGetCommits(t *testing.T) {
opts.MainBranches = NewMainBranches(common, cmd)
commits, err := builder.GetCommits(opts)
assert.Equal(t, scenario.expectedCommits, commits)
expectedCommits := lo.Map(scenario.expectedCommitOpts,
func(opts models.NewCommitOpts, _ int) *models.Commit { return models.NewCommit(opts) })
assert.Equal(t, expectedCommits, commits)
assert.Equal(t, scenario.expectedError, err)
scenario.runner.CheckForMissingCalls()
@ -356,11 +359,11 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
},
},
amendFileExists: false,
expectedResult: &models.Commit{
expectedResult: models.NewCommit(models.NewCommitOpts{
Hash: "fa1afe1",
Action: todo.Pick,
Status: models.StatusConflicted,
},
}),
},
{
testName: "last command was 'break'",
@ -457,11 +460,11 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
},
},
amendFileExists: false,
expectedResult: &models.Commit{
expectedResult: models.NewCommit(models.NewCommitOpts{
Hash: "fa1afe1",
Action: todo.Pick,
Status: models.StatusConflicted,
},
}),
},
{
testName: "'edit' with amend file",
@ -486,11 +489,11 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
},
amendFileExists: false,
messageFileExists: true,
expectedResult: &models.Commit{
expectedResult: models.NewCommit(models.NewCommitOpts{
Hash: "fa1afe1",
Action: todo.Edit,
Status: models.StatusConflicted,
},
}),
},
{
testName: "'edit' without amend and without message file",
@ -531,22 +534,22 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
func TestCommitLoader_setCommitMergedStatuses(t *testing.T) {
type scenario struct {
testName string
commits []*models.Commit
ancestor string
expectedCommits []*models.Commit
testName string
commitOpts []models.NewCommitOpts
ancestor string
expectedCommitOpts []models.NewCommitOpts
}
scenarios := []scenario{
{
testName: "basic",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "12345", Name: "1", Action: models.ActionNone, Status: models.StatusUnpushed},
{Hash: "67890", Name: "2", Action: models.ActionNone, Status: models.StatusPushed},
{Hash: "abcde", Name: "3", Action: models.ActionNone, Status: models.StatusPushed},
},
ancestor: "67890",
expectedCommits: []*models.Commit{
expectedCommitOpts: []models.NewCommitOpts{
{Hash: "12345", Name: "1", Action: models.ActionNone, Status: models.StatusUnpushed},
{Hash: "67890", Name: "2", Action: models.ActionNone, Status: models.StatusMerged},
{Hash: "abcde", Name: "3", Action: models.ActionNone, Status: models.StatusMerged},
@ -554,13 +557,13 @@ func TestCommitLoader_setCommitMergedStatuses(t *testing.T) {
},
{
testName: "with update-ref",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "12345", Name: "1", Action: models.ActionNone, Status: models.StatusUnpushed},
{Hash: "", Name: "", Action: todo.UpdateRef, Status: models.StatusNone},
{Hash: "abcde", Name: "3", Action: models.ActionNone, Status: models.StatusPushed},
},
ancestor: "deadbeef",
expectedCommits: []*models.Commit{
expectedCommitOpts: []models.NewCommitOpts{
{Hash: "12345", Name: "1", Action: models.ActionNone, Status: models.StatusUnpushed},
{Hash: "", Name: "", Action: todo.UpdateRef, Status: models.StatusNone},
{Hash: "abcde", Name: "3", Action: models.ActionNone, Status: models.StatusPushed},
@ -570,9 +573,12 @@ func TestCommitLoader_setCommitMergedStatuses(t *testing.T) {
for _, scenario := range scenarios {
t.Run(scenario.testName, func(t *testing.T) {
commits := scenario.commits
commits := lo.Map(scenario.commitOpts,
func(opts models.NewCommitOpts, _ int) *models.Commit { return models.NewCommit(opts) })
setCommitMergedStatuses(scenario.ancestor, commits)
assert.Equal(t, scenario.expectedCommits, commits)
expectedCommits := lo.Map(scenario.expectedCommitOpts,
func(opts models.NewCommitOpts, _ int) *models.Commit { return models.NewCommit(opts) })
assert.Equal(t, expectedCommits, commits)
})
}
}

View file

@ -156,13 +156,13 @@ func (self *PatchCommands) MovePatchToSelectedCommit(commits []*models.Commit, s
baseIndex := sourceCommitIdx + 1
changes := []daemon.ChangeTodoAction{
{Hash: commits[sourceCommitIdx].Hash, NewAction: todo.Edit},
{Hash: commits[destinationCommitIdx].Hash, NewAction: todo.Edit},
{Hash: commits[sourceCommitIdx].Hash(), NewAction: todo.Edit},
{Hash: commits[destinationCommitIdx].Hash(), NewAction: todo.Edit},
}
self.os.LogCommand(logTodoChanges(changes), false)
err := self.rebase.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
baseHashOrRoot: commits[baseIndex].Hash,
baseHashOrRoot: commits[baseIndex].Hash(),
overrideEditor: true,
instruction: daemon.NewChangeTodoActionsInstruction(changes),
}).Run()
@ -218,7 +218,7 @@ func (self *PatchCommands) MovePatchToSelectedCommit(commits []*models.Commit, s
func (self *PatchCommands) MovePatchIntoIndex(commits []*models.Commit, commitIdx int, stash bool) error {
if stash {
if err := self.stash.Push(self.Tr.StashPrefix + commits[commitIdx].Hash); err != nil {
if err := self.stash.Push(self.Tr.StashPrefix + commits[commitIdx].Hash()); err != nil {
return err
}
}
@ -323,7 +323,7 @@ func (self *PatchCommands) diffHeadAgainstCommit(commit *models.Commit) (string,
cmdArgs := NewGitCmd("diff").
Config("diff.noprefix=false").
Arg("--no-ext-diff").
Arg("HEAD.." + commit.Hash).
Arg("HEAD.." + commit.Hash()).
ToArgv()
return self.cmd.New(cmdArgs).RunWithOutput()

View file

@ -55,7 +55,7 @@ func (self *RebaseCommands) RewordCommit(commits []*models.Commit, index int, su
func (self *RebaseCommands) RewordCommitInEditor(commits []*models.Commit, index int) (oscommands.ICmdObj, error) {
changes := []daemon.ChangeTodoAction{{
Hash: commits[index].Hash,
Hash: commits[index].Hash(),
NewAction: todo.Reword,
}}
self.os.LogCommand(logTodoChanges(changes), false)
@ -80,7 +80,7 @@ func (self *RebaseCommands) SetCommitAuthor(commits []*models.Commit, start, end
func (self *RebaseCommands) AddCommitCoAuthor(commits []*models.Commit, start, end int, value string) error {
return self.GenericAmend(commits, start, end, func(commit *models.Commit) error {
return self.commit.AddCoAuthor(commit.Hash, value)
return self.commit.AddCoAuthor(commit.Hash(), value)
})
}
@ -113,7 +113,7 @@ func (self *RebaseCommands) MoveCommitsDown(commits []*models.Commit, startIdx i
baseHashOrRoot := getBaseHashOrRoot(commits, endIdx+2)
hashes := lo.Map(commits[startIdx:endIdx+1], func(commit *models.Commit, _ int) string {
return commit.Hash
return commit.Hash()
})
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
@ -127,7 +127,7 @@ func (self *RebaseCommands) MoveCommitsUp(commits []*models.Commit, startIdx int
baseHashOrRoot := getBaseHashOrRoot(commits, endIdx+1)
hashes := lo.Map(commits[startIdx:endIdx+1], func(commit *models.Commit, _ int) string {
return commit.Hash
return commit.Hash()
})
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
@ -147,7 +147,7 @@ func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, startIdx
changes := lo.FilterMap(commits[startIdx:endIdx+1], func(commit *models.Commit, _ int) (daemon.ChangeTodoAction, bool) {
return daemon.ChangeTodoAction{
Hash: commit.Hash,
Hash: commit.Hash(),
NewAction: action,
}, !commit.IsMerge()
})
@ -293,7 +293,7 @@ func (self *RebaseCommands) getHashOfLastCommitMade() (string, error) {
func (self *RebaseCommands) AmendTo(commits []*models.Commit, commitIndex int) error {
commit := commits[commitIndex]
if err := self.commit.CreateFixupCommit(commit.Hash); err != nil {
if err := self.commit.CreateFixupCommit(commit.Hash()); err != nil {
return err
}
@ -305,7 +305,7 @@ func (self *RebaseCommands) AmendTo(commits []*models.Commit, commitIndex int) e
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
baseHashOrRoot: getBaseHashOrRoot(commits, commitIndex+1),
overrideEditor: true,
instruction: daemon.NewMoveFixupCommitDownInstruction(commit.Hash, fixupHash, true),
instruction: daemon.NewMoveFixupCommitDownInstruction(commit.Hash(), fixupHash, true),
}).Run()
}
@ -318,7 +318,7 @@ func (self *RebaseCommands) MoveFixupCommitDown(commits []*models.Commit, target
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
baseHashOrRoot: getBaseHashOrRoot(commits, targetCommitIndex+1),
overrideEditor: true,
instruction: daemon.NewMoveFixupCommitDownInstruction(commits[targetCommitIndex].Hash, fixupHash, false),
instruction: daemon.NewMoveFixupCommitDownInstruction(commits[targetCommitIndex].Hash(), fixupHash, false),
}).Run()
}
@ -326,7 +326,7 @@ func todoFromCommit(commit *models.Commit) utils.Todo {
if commit.Action == todo.UpdateRef {
return utils.Todo{Ref: commit.Name}
} else {
return utils.Todo{Hash: commit.Hash}
return utils.Todo{Hash: commit.Hash()}
}
}
@ -334,7 +334,7 @@ func todoFromCommit(commit *models.Commit) utils.Todo {
func (self *RebaseCommands) EditRebaseTodo(commits []*models.Commit, action todo.TodoCommand) error {
commitsWithAction := lo.Map(commits, func(commit *models.Commit, _ int) utils.TodoChange {
return utils.TodoChange{
Hash: commit.Hash,
Hash: commit.Hash(),
NewAction: action,
}
})
@ -383,7 +383,7 @@ func (self *RebaseCommands) MoveTodosUp(commits []*models.Commit) error {
// SquashAllAboveFixupCommits squashes all fixup! commits above the given one
func (self *RebaseCommands) SquashAllAboveFixupCommits(commit *models.Commit) error {
hashOrRoot := commit.Hash + "^"
hashOrRoot := commit.Hash() + "^"
if commit.IsFirstCommit() {
hashOrRoot = "--root"
}
@ -420,7 +420,7 @@ func (self *RebaseCommands) BeginInteractiveRebaseForCommitRange(
changes := make([]daemon.ChangeTodoAction, 0, end-start)
for commitIndex := end; commitIndex >= start; commitIndex-- {
changes = append(changes, daemon.ChangeTodoAction{
Hash: commits[commitIndex].Hash,
Hash: commits[commitIndex].Hash(),
NewAction: todo.Edit,
})
}
@ -538,7 +538,7 @@ func (self *RebaseCommands) CherryPickCommits(commits []*models.Commit) error {
Arg("--allow-empty").
ArgIf(self.version.IsAtLeast(2, 45, 0), "--empty=keep", "--keep-redundant-commits").
ArgIf(hasMergeCommit, "-m1").
Arg(lo.Reverse(lo.Map(commits, func(c *models.Commit, _ int) string { return c.Hash }))...).
Arg(lo.Reverse(lo.Map(commits, func(c *models.Commit, _ int) string { return c.Hash() }))...).
ToArgv()
return self.cmd.New(cmdArgs).Run()
@ -547,7 +547,7 @@ func (self *RebaseCommands) CherryPickCommits(commits []*models.Commit) error {
func (self *RebaseCommands) DropMergeCommit(commits []*models.Commit, commitIndex int) error {
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
baseHashOrRoot: getBaseHashOrRoot(commits, commitIndex+1),
instruction: daemon.NewDropMergeCommitInstruction(commits[commitIndex].Hash),
instruction: daemon.NewDropMergeCommitInstruction(commits[commitIndex].Hash()),
}).Run()
}
@ -559,7 +559,7 @@ func getBaseHashOrRoot(commits []*models.Commit, index int) string {
// be starting a rebase from 300 commits ago (which is the original commit limit
// at time of writing)
if index < len(commits) {
return commits[index].Hash
return commits[index].Hash()
} else {
return "--root"
}

View file

@ -97,7 +97,7 @@ func TestRebaseDiscardOldFileChanges(t *testing.T) {
type scenario struct {
testName string
gitConfigMockResponses map[string]string
commits []*models.Commit
commitOpts []models.NewCommitOpts
commitIndex int
fileName []string
runner *oscommands.FakeCmdObjRunner
@ -108,7 +108,7 @@ func TestRebaseDiscardOldFileChanges(t *testing.T) {
{
testName: "returns error when index outside of range of commits",
gitConfigMockResponses: nil,
commits: []*models.Commit{},
commitOpts: []models.NewCommitOpts{},
commitIndex: 0,
fileName: []string{"test999.txt"},
runner: oscommands.NewFakeRunner(t),
@ -119,7 +119,7 @@ func TestRebaseDiscardOldFileChanges(t *testing.T) {
{
testName: "returns error when using gpg",
gitConfigMockResponses: map[string]string{"commit.gpgSign": "true"},
commits: []*models.Commit{{Name: "commit", Hash: "123456"}},
commitOpts: []models.NewCommitOpts{{Name: "commit", Hash: "123456"}},
commitIndex: 0,
fileName: []string{"test999.txt"},
runner: oscommands.NewFakeRunner(t),
@ -130,7 +130,7 @@ func TestRebaseDiscardOldFileChanges(t *testing.T) {
{
testName: "checks out file if it already existed",
gitConfigMockResponses: nil,
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit", Hash: "123456"},
{Name: "commit2", Hash: "abcdef"},
},
@ -158,7 +158,10 @@ func TestRebaseDiscardOldFileChanges(t *testing.T) {
gitConfig: git_config.NewFakeGitConfig(s.gitConfigMockResponses),
})
s.test(instance.DiscardOldFileChanges(s.commits, s.commitIndex, s.fileName))
commits := lo.Map(s.commitOpts,
func(opts models.NewCommitOpts, _ int) *models.Commit { return models.NewCommit(opts) })
s.test(instance.DiscardOldFileChanges(commits, s.commitIndex, s.fileName))
s.runner.CheckForMissingCalls()
})
}

View file

@ -65,7 +65,7 @@ func (self *ReflogCommitLoader) GetReflogCommits(lastReflogCommit *models.Commit
}
func (self *ReflogCommitLoader) sameReflogCommit(a *models.Commit, b *models.Commit) bool {
return a.Hash == b.Hash && a.UnixTimestamp == b.UnixTimestamp && a.Name == b.Name
return a.Hash() == b.Hash() && a.UnixTimestamp == b.UnixTimestamp && a.Name == b.Name
}
func (self *ReflogCommitLoader) parseLine(line string) (*models.Commit, bool) {
@ -82,11 +82,11 @@ func (self *ReflogCommitLoader) parseLine(line string) (*models.Commit, bool) {
parents = strings.Split(parentHashes, " ")
}
return &models.Commit{
return models.NewCommit(models.NewCommitOpts{
Hash: fields[0],
Name: fields[2],
UnixTimestamp: int64(unixTimestamp),
Status: models.StatusReflog,
Parents: parents,
}, true
}), true
}

View file

@ -8,6 +8,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
"github.com/sanity-io/litter"
"github.com/stretchr/testify/assert"
)
@ -26,7 +27,7 @@ func TestGetReflogCommits(t *testing.T) {
lastReflogCommit *models.Commit
filterPath string
filterAuthor string
expectedCommits []*models.Commit
expectedCommitOpts []models.NewCommitOpts
expectedOnlyObtainedNew bool
expectedError error
}
@ -38,7 +39,7 @@ func TestGetReflogCommits(t *testing.T) {
ExpectGitArgs([]string{"-c", "log.showSignature=false", "log", "-g", "--abbrev=40", "--format=%h%x00%ct%x00%gs%x00%p"}, "", nil),
lastReflogCommit: nil,
expectedCommits: []*models.Commit{},
expectedCommitOpts: []models.NewCommitOpts{},
expectedOnlyObtainedNew: false,
expectedError: nil,
},
@ -48,7 +49,7 @@ func TestGetReflogCommits(t *testing.T) {
ExpectGitArgs([]string{"-c", "log.showSignature=false", "log", "-g", "--abbrev=40", "--format=%h%x00%ct%x00%gs%x00%p"}, reflogOutput, nil),
lastReflogCommit: nil,
expectedCommits: []*models.Commit{
expectedCommitOpts: []models.NewCommitOpts{
{
Hash: "c3c4b66b64c97ffeecde",
Name: "checkout: moving from A to B",
@ -93,14 +94,14 @@ func TestGetReflogCommits(t *testing.T) {
runner: oscommands.NewFakeRunner(t).
ExpectGitArgs([]string{"-c", "log.showSignature=false", "log", "-g", "--abbrev=40", "--format=%h%x00%ct%x00%gs%x00%p"}, reflogOutput, nil),
lastReflogCommit: &models.Commit{
lastReflogCommit: models.NewCommit(models.NewCommitOpts{
Hash: "c3c4b66b64c97ffeecde",
Name: "checkout: moving from B to A",
Status: models.StatusReflog,
UnixTimestamp: 1643150483,
Parents: []string{"51baa8c1"},
},
expectedCommits: []*models.Commit{
}),
expectedCommitOpts: []models.NewCommitOpts{
{
Hash: "c3c4b66b64c97ffeecde",
Name: "checkout: moving from A to B",
@ -117,15 +118,15 @@ func TestGetReflogCommits(t *testing.T) {
runner: oscommands.NewFakeRunner(t).
ExpectGitArgs([]string{"-c", "log.showSignature=false", "log", "-g", "--abbrev=40", "--format=%h%x00%ct%x00%gs%x00%p", "--follow", "--", "path"}, reflogOutput, nil),
lastReflogCommit: &models.Commit{
lastReflogCommit: models.NewCommit(models.NewCommitOpts{
Hash: "c3c4b66b64c97ffeecde",
Name: "checkout: moving from B to A",
Status: models.StatusReflog,
UnixTimestamp: 1643150483,
Parents: []string{"51baa8c1"},
},
}),
filterPath: "path",
expectedCommits: []*models.Commit{
expectedCommitOpts: []models.NewCommitOpts{
{
Hash: "c3c4b66b64c97ffeecde",
Name: "checkout: moving from A to B",
@ -142,15 +143,15 @@ func TestGetReflogCommits(t *testing.T) {
runner: oscommands.NewFakeRunner(t).
ExpectGitArgs([]string{"-c", "log.showSignature=false", "log", "-g", "--abbrev=40", "--format=%h%x00%ct%x00%gs%x00%p", "--author=John Doe <john@doe.com>"}, reflogOutput, nil),
lastReflogCommit: &models.Commit{
lastReflogCommit: models.NewCommit(models.NewCommitOpts{
Hash: "c3c4b66b64c97ffeecde",
Name: "checkout: moving from B to A",
Status: models.StatusReflog,
UnixTimestamp: 1643150483,
Parents: []string{"51baa8c1"},
},
}),
filterAuthor: "John Doe <john@doe.com>",
expectedCommits: []*models.Commit{
expectedCommitOpts: []models.NewCommitOpts{
{
Hash: "c3c4b66b64c97ffeecde",
Name: "checkout: moving from A to B",
@ -169,7 +170,7 @@ func TestGetReflogCommits(t *testing.T) {
lastReflogCommit: nil,
filterPath: "",
expectedCommits: nil,
expectedCommitOpts: nil,
expectedOnlyObtainedNew: false,
expectedError: errors.New("haha"),
},
@ -186,7 +187,12 @@ func TestGetReflogCommits(t *testing.T) {
assert.Equal(t, scenario.expectedOnlyObtainedNew, onlyObtainednew)
assert.Equal(t, scenario.expectedError, err)
t.Logf("actual commits: \n%s", litter.Sdump(commits))
assert.Equal(t, scenario.expectedCommits, commits)
var expectedCommits []*models.Commit
if scenario.expectedCommitOpts != nil {
expectedCommits = lo.Map(scenario.expectedCommitOpts,
func(opts models.NewCommitOpts, _ int) *models.Commit { return models.NewCommit(opts) })
}
assert.Equal(t, expectedCommits, commits)
scenario.runner.CheckForMissingCalls()
})

View file

@ -42,7 +42,7 @@ const (
// Commit : A git commit
type Commit struct {
Hash string
hash string
Name string
Status CommitStatus
Action todo.TodoCommand
@ -57,20 +57,54 @@ type Commit struct {
Parents []string
}
type NewCommitOpts struct {
Hash string
Name string
Status CommitStatus
Action todo.TodoCommand
Tags []string
ExtraInfo string
AuthorName string
AuthorEmail string
UnixTimestamp int64
Divergence Divergence
Parents []string
}
func NewCommit(opts NewCommitOpts) *Commit {
return &Commit{
hash: opts.Hash,
Name: opts.Name,
Status: opts.Status,
Action: opts.Action,
Tags: opts.Tags,
ExtraInfo: opts.ExtraInfo,
AuthorName: opts.AuthorName,
AuthorEmail: opts.AuthorEmail,
UnixTimestamp: opts.UnixTimestamp,
Divergence: opts.Divergence,
Parents: opts.Parents,
}
}
func (c *Commit) Hash() string {
return c.hash
}
func (c *Commit) ShortHash() string {
return utils.ShortHash(c.Hash)
return utils.ShortHash(c.Hash())
}
func (c *Commit) FullRefName() string {
return c.Hash
return c.Hash()
}
func (c *Commit) RefName() string {
return c.Hash
return c.Hash()
}
func (c *Commit) ShortRefName() string {
return c.Hash[:7]
return c.Hash()[:7]
}
func (c *Commit) ParentRefName() string {
@ -89,7 +123,7 @@ func (c *Commit) ID() string {
}
func (c *Commit) Description() string {
return fmt.Sprintf("%s %s", c.Hash[:7], c.Name)
return fmt.Sprintf("%s %s", c.Hash()[:7], c.Name)
}
func (c *Commit) IsMerge() bool {

View file

@ -37,7 +37,7 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext {
if c.Context().Current().GetKey() == LOCAL_COMMITS_CONTEXT_KEY {
selectedCommit := viewModel.GetSelected()
if selectedCommit != nil {
selectedCommitHash = selectedCommit.Hash
selectedCommitHash = selectedCommit.Hash()
}
}
@ -192,7 +192,7 @@ func (self *LocalCommitsContext) GetSelectedCommitHash() string {
if commit == nil {
return ""
}
return commit.Hash
return commit.Hash()
}
func (self *LocalCommitsContext) SelectCommitByHash(hash string) bool {
@ -200,7 +200,7 @@ func (self *LocalCommitsContext) SelectCommitByHash(hash string) bool {
return false
}
if _, idx, found := lo.FindIndexOf(self.GetItems(), func(c *models.Commit) bool { return c.Hash == hash }); found {
if _, idx, found := lo.FindIndexOf(self.GetItems(), func(c *models.Commit) bool { return c.Hash() == hash }); found {
self.SetSelection(idx)
return true
}
@ -219,7 +219,7 @@ func (self *LocalCommitsContext) RefForAdjustingLineNumberInDiff() string {
if commits == nil {
return ""
}
return commits[0].Hash
return commits[0].Hash()
}
func (self *LocalCommitsContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition {
@ -284,7 +284,7 @@ func searchModelCommits(caseSensitive bool, commits []*models.Commit, columnPosi
// that we render. So we just set the XStart and XEnd values to the
// start and end of the commit hash column, which is the second one.
result := gocui.SearchPosition{XStart: columnPositions[1], XEnd: columnPositions[2] - 1, Y: idx}
return result, strings.Contains(normalize(commit.Hash), searchStr) ||
return result, strings.Contains(normalize(commit.Hash()), searchStr) ||
strings.Contains(normalize(commit.Name), searchStr) ||
strings.Contains(normalize(commit.ExtraInfo), searchStr) // allow searching for tags
})

View file

@ -50,7 +50,7 @@ func NewSubCommitsContext(
if c.Context().Current().GetKey() == SUB_COMMITS_CONTEXT_KEY {
selectedCommit := viewModel.GetSelected()
if selectedCommit != nil {
selectedCommitHash = selectedCommit.Hash
selectedCommitHash = selectedCommit.Hash()
}
}
branches := []*models.Branch{}
@ -221,7 +221,7 @@ func (self *SubCommitsContext) RefForAdjustingLineNumberInDiff() string {
if commits == nil {
return ""
}
return commits[0].Hash
return commits[0].Hash()
}
func (self *SubCommitsContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition {

View file

@ -153,7 +153,7 @@ func (self *BasicCommitsController) getCommitMessageBody(hash string) string {
}
func (self *BasicCommitsController) copyCommitAttribute(commit *models.Commit) error {
commitMessageBody := self.getCommitMessageBody(commit.Hash)
commitMessageBody := self.getCommitMessageBody(commit.Hash())
var commitMessageBodyDisabled *types.DisabledReason
if commitMessageBody == "" {
commitMessageBodyDisabled = &types.DisabledReason{
@ -235,16 +235,16 @@ func (self *BasicCommitsController) copyCommitAttribute(commit *models.Commit) e
func (self *BasicCommitsController) copyCommitHashToClipboard(commit *models.Commit) error {
self.c.LogAction(self.c.Tr.Actions.CopyCommitHashToClipboard)
if err := self.c.OS().CopyToClipboard(commit.Hash); err != nil {
if err := self.c.OS().CopyToClipboard(commit.Hash()); err != nil {
return err
}
self.c.Toast(fmt.Sprintf("'%s' %s", commit.Hash, self.c.Tr.CopiedToClipboard))
self.c.Toast(fmt.Sprintf("'%s' %s", commit.Hash(), self.c.Tr.CopiedToClipboard))
return nil
}
func (self *BasicCommitsController) copyCommitURLToClipboard(commit *models.Commit) error {
url, err := self.c.Helpers().Host.GetCommitURL(commit.Hash)
url, err := self.c.Helpers().Host.GetCommitURL(commit.Hash())
if err != nil {
return err
}
@ -259,7 +259,7 @@ func (self *BasicCommitsController) copyCommitURLToClipboard(commit *models.Comm
}
func (self *BasicCommitsController) copyCommitDiffToClipboard(commit *models.Commit) error {
diff, err := self.c.Git().Commit.GetCommitDiff(commit.Hash)
diff, err := self.c.Git().Commit.GetCommitDiff(commit.Hash())
if err != nil {
return err
}
@ -274,7 +274,7 @@ func (self *BasicCommitsController) copyCommitDiffToClipboard(commit *models.Com
}
func (self *BasicCommitsController) copyAuthorToClipboard(commit *models.Commit) error {
author, err := self.c.Git().Commit.GetCommitAuthor(commit.Hash)
author, err := self.c.Git().Commit.GetCommitAuthor(commit.Hash())
if err != nil {
return err
}
@ -291,7 +291,7 @@ func (self *BasicCommitsController) copyAuthorToClipboard(commit *models.Commit)
}
func (self *BasicCommitsController) copyCommitMessageToClipboard(commit *models.Commit) error {
message, err := self.c.Git().Commit.GetCommitMessage(commit.Hash)
message, err := self.c.Git().Commit.GetCommitMessage(commit.Hash())
if err != nil {
return err
}
@ -316,7 +316,7 @@ func (self *BasicCommitsController) copyCommitMessageBodyToClipboard(commitMessa
}
func (self *BasicCommitsController) copyCommitSubjectToClipboard(commit *models.Commit) error {
message, err := self.c.Git().Commit.GetCommitSubject(commit.Hash)
message, err := self.c.Git().Commit.GetCommitSubject(commit.Hash())
if err != nil {
return err
}
@ -343,7 +343,7 @@ func (self *BasicCommitsController) copyCommitTagsToClipboard(commit *models.Com
}
func (self *BasicCommitsController) openInBrowser(commit *models.Commit) error {
url, err := self.c.Helpers().Host.GetCommitURL(commit.Hash)
url, err := self.c.Helpers().Host.GetCommitURL(commit.Hash())
if err != nil {
return err
}
@ -361,7 +361,7 @@ func (self *BasicCommitsController) newBranch(commit *models.Commit) error {
}
func (self *BasicCommitsController) createResetMenu(commit *models.Commit) error {
return self.c.Helpers().Refs.CreateGitResetMenu(commit.Hash)
return self.c.Helpers().Refs.CreateGitResetMenu(commit.Hash())
}
func (self *BasicCommitsController) checkout(commit *models.Commit) error {
@ -374,7 +374,7 @@ func (self *BasicCommitsController) copyRange(*models.Commit) error {
func (self *BasicCommitsController) canCopyCommits(selectedCommits []*models.Commit, startIdx int, endIdx int) *types.DisabledReason {
for _, commit := range selectedCommits {
if commit.Hash == "" {
if commit.Hash() == "" {
return &types.DisabledReason{Text: self.c.Tr.CannotCherryPickNonCommit, ShowErrorInPanel: true}
}
}

View file

@ -69,7 +69,7 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
// Originally we were allowing the user to, from the bisect menu, select whether
// they were talking about the selected commit or the current bisect commit,
// and that was a bit confusing (and required extra keypresses).
selectCurrentAfter := info.GetCurrentHash() == "" || info.GetCurrentHash() == commit.Hash
selectCurrentAfter := info.GetCurrentHash() == "" || info.GetCurrentHash() == commit.Hash()
// we need to wait to reselect if our bisect commits aren't ancestors of our 'start'
// ref, because we'll be reloading our commits in that case.
waitToReselect := selectCurrentAfter && !self.c.Git().Bisect.ReachableFromStart(info)
@ -79,7 +79,7 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
// use the selected commit in that case.
bisecting := info.GetCurrentHash() != ""
hashToMark := lo.Ternary(bisecting, info.GetCurrentHash(), commit.Hash)
hashToMark := lo.Ternary(bisecting, info.GetCurrentHash(), commit.Hash())
shortHashToMark := utils.ShortHash(hashToMark)
// For marking a commit as bad, when we're not already bisecting, we require
@ -131,12 +131,12 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
Key: 's',
},
}
if info.GetCurrentHash() != "" && info.GetCurrentHash() != commit.Hash {
if info.GetCurrentHash() != "" && info.GetCurrentHash() != commit.Hash() {
menuItems = append(menuItems, lo.ToPtr(types.MenuItem{
Label: fmt.Sprintf(self.c.Tr.Bisect.SkipSelected, commit.ShortHash()),
OnPress: func() error {
self.c.LogAction(self.c.Tr.Actions.BisectSkip)
if err := self.c.Git().Bisect.Skip(commit.Hash); err != nil {
if err := self.c.Git().Bisect.Skip(commit.Hash()); err != nil {
return err
}
@ -172,7 +172,7 @@ func (self *BisectController) openStartBisectMenu(info *git_commands.BisectInfo,
return err
}
if err := self.c.Git().Bisect.Mark(commit.Hash, info.NewTerm()); err != nil {
if err := self.c.Git().Bisect.Mark(commit.Hash(), info.NewTerm()); err != nil {
return err
}
@ -189,7 +189,7 @@ func (self *BisectController) openStartBisectMenu(info *git_commands.BisectInfo,
return err
}
if err := self.c.Git().Bisect.Mark(commit.Hash, info.OldTerm()); err != nil {
if err := self.c.Git().Bisect.Mark(commit.Hash(), info.OldTerm()); err != nil {
return err
}
@ -292,7 +292,7 @@ func (self *BisectController) selectCurrentBisectCommit() {
if info.GetCurrentHash() != "" {
// find index of commit with that hash, move cursor to that.
for i, commit := range self.c.Model().Commits {
if commit.Hash == info.GetCurrentHash() {
if commit.Hash() == info.GetCurrentHash() {
self.context().SetSelection(i)
self.context().HandleFocus(types.OnFocusOpts{})
break

View file

@ -67,7 +67,7 @@ func (self *CustomPatchOptionsMenuAction) Call() error {
if self.c.Context().Current().GetKey() == self.c.Contexts().LocalCommits.GetKey() {
selectedCommit := self.c.Contexts().LocalCommits.GetSelected()
if selectedCommit != nil && self.c.Git().Patch.PatchBuilder.To != selectedCommit.Hash {
if selectedCommit != nil && self.c.Git().Patch.PatchBuilder.To != selectedCommit.Hash() {
var disabledReason *types.DisabledReason
if self.c.Contexts().LocalCommits.AreMultipleItemsSelected() {
@ -80,7 +80,7 @@ func (self *CustomPatchOptionsMenuAction) Call() error {
append(
[]*types.MenuItem{
{
Label: fmt.Sprintf(self.c.Tr.MovePatchToSelectedCommit, selectedCommit.Hash),
Label: fmt.Sprintf(self.c.Tr.MovePatchToSelectedCommit, selectedCommit.Hash()),
Tooltip: self.c.Tr.MovePatchToSelectedCommitTooltip,
OnPress: self.handleMovePatchToSelectedCommit,
Key: 'm',
@ -106,7 +106,7 @@ func (self *CustomPatchOptionsMenuAction) Call() error {
func (self *CustomPatchOptionsMenuAction) getPatchCommitIndex() int {
for index, commit := range self.c.Model().Commits {
if commit.Hash == self.c.Git().Patch.PatchBuilder.To {
if commit.Hash() == self.c.Git().Patch.PatchBuilder.To {
return index
}
}

View file

@ -44,7 +44,7 @@ func (self *CherryPickHelper) CopyRange(commitsList []*models.Commit, context ty
commitSet := self.getData().SelectedHashSet()
allCommitsCopied := lo.EveryBy(commitsList[startIdx:endIdx+1], func(commit *models.Commit) bool {
return commitSet.Includes(commit.Hash)
return commitSet.Includes(commit.Hash())
})
// if all selected commits are already copied, we'll uncopy them

View file

@ -66,7 +66,7 @@ func (self *DiffHelper) GetUpdateTaskForRenderingCommitsDiff(commit *models.Comm
return task
}
cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash, self.c.Modes().Filtering.GetPath())
cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash(), self.c.Modes().Filtering.GetPath())
return types.NewRunPtyTask(cmdObj.GetCmd())
}

View file

@ -342,6 +342,6 @@ func (self *FixupHelper) blameAddedLines(commits []*models.Commit, addedLineHunk
func (self *FixupHelper) findCommit(commits []*models.Commit, hash string) (*models.Commit, int, bool) {
return lo.FindIndexOf(commits, func(commit *models.Commit) bool {
return commit.Hash == hash
return commit.Hash() == hash
})
}

View file

@ -268,10 +268,10 @@ func (self *RefsHelper) CreateGitResetMenu(ref string) error {
func (self *RefsHelper) CreateCheckoutMenu(commit *models.Commit) error {
branches := lo.Filter(self.c.Model().Branches, func(branch *models.Branch, _ int) bool {
return commit.Hash == branch.CommitHash && branch.Name != self.c.Model().CheckedOutBranch
return commit.Hash() == branch.CommitHash && branch.Name != self.c.Model().CheckedOutBranch
})
hash := commit.Hash
hash := commit.Hash()
menuItems := []*types.MenuItem{
{

View file

@ -359,7 +359,7 @@ func (self *LocalCommitsController) fixup(selectedCommits []*models.Commit, star
}
func (self *LocalCommitsController) reword(commit *models.Commit) error {
commitMessage, err := self.c.Git().Commit.GetCommitMessage(commit.Hash)
commitMessage, err := self.c.Git().Commit.GetCommitMessage(commit.Hash())
if err != nil {
return err
}
@ -556,7 +556,7 @@ func (self *LocalCommitsController) startInteractiveRebaseWithEdit(
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(gocui.Task) error {
self.c.LogAction(self.c.Tr.Actions.EditCommit)
selectionRangeAndMode := self.getSelectionRangeAndMode()
err := self.c.Git().Rebase.EditRebase(commitsToEdit[len(commitsToEdit)-1].Hash)
err := self.c.Git().Rebase.EditRebase(commitsToEdit[len(commitsToEdit)-1].Hash())
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebaseWithRefreshOptions(
err,
types.RefreshOptions{Mode: types.BLOCK_UI, Then: func() error {
@ -564,7 +564,7 @@ func (self *LocalCommitsController) startInteractiveRebaseWithEdit(
for _, c := range commitsToEdit[:len(commitsToEdit)-1] {
// Merge commits can't be set to "edit", so just skip them
if !c.IsMerge() {
todos = append(todos, &models.Commit{Hash: c.Hash, Action: todo.Pick})
todos = append(todos, models.NewCommit(models.NewCommitOpts{Hash: c.Hash(), Action: todo.Pick}))
}
}
if len(todos) > 0 {
@ -589,8 +589,8 @@ type SelectionRangeAndMode struct {
func (self *LocalCommitsController) getSelectionRangeAndMode() SelectionRangeAndMode {
selectedIdx, rangeStartIdx, rangeSelectMode := self.context().GetSelectionRangeAndMode()
commits := self.c.Model().Commits
selectedHash := commits[selectedIdx].Hash
rangeStartHash := commits[rangeStartIdx].Hash
selectedHash := commits[selectedIdx].Hash()
rangeStartHash := commits[rangeStartIdx].Hash()
return SelectionRangeAndMode{selectedHash, rangeStartHash, rangeSelectMode}
}
@ -599,10 +599,10 @@ func (self *LocalCommitsController) restoreSelectionRangeAndMode(selectionRangeA
// new lines can be added for update-ref commands in the TODO file, due to
// stacked branches. So the selected commits may be in different positions in the list.
_, newSelectedIdx, ok1 := lo.FindIndexOf(self.c.Model().Commits, func(c *models.Commit) bool {
return c.Hash == selectionRangeAndMode.selectedHash
return c.Hash() == selectionRangeAndMode.selectedHash
})
_, newRangeStartIdx, ok2 := lo.FindIndexOf(self.c.Model().Commits, func(c *models.Commit) bool {
return c.Hash == selectionRangeAndMode.rangeStartHash
return c.Hash() == selectionRangeAndMode.rangeStartHash
})
if ok1 && ok2 {
self.context().SetSelectionRangeAndMode(newSelectedIdx, newRangeStartIdx, selectionRangeAndMode.mode)
@ -868,7 +868,7 @@ func (self *LocalCommitsController) revert(commits []*models.Commit, start, end
} else {
promptText = self.c.Tr.ConfirmRevertCommitRange
}
hashes := lo.Map(commits, func(c *models.Commit, _ int) string { return c.Hash })
hashes := lo.Map(commits, func(c *models.Commit, _ int) string { return c.Hash() })
isMerge := lo.SomeBy(commits, func(c *models.Commit) bool { return c.IsMerge() })
self.c.Confirm(types.ConfirmOpts{
@ -911,7 +911,7 @@ func (self *LocalCommitsController) createFixupCommit(commit *models.Commit) err
return self.c.Helpers().WorkingTree.WithEnsureCommittableFiles(func() error {
self.c.LogAction(self.c.Tr.Actions.CreateFixupCommit)
return self.c.WithWaitingStatusSync(self.c.Tr.CreatingFixupCommitStatus, func() error {
if err := self.c.Git().Commit.CreateFixupCommit(commit.Hash); err != nil {
if err := self.c.Git().Commit.CreateFixupCommit(commit.Hash()); err != nil {
return err
}
@ -978,7 +978,7 @@ func (self *LocalCommitsController) moveFixupCommitToOwnerStackedBranch(targetCo
headOfOwnerBranchIdx := -1
for i := self.context().GetSelectedLineIdx(); i > 0; i-- {
if lo.SomeBy(self.c.Model().Branches, func(b *models.Branch) bool {
return b.CommitHash == self.c.Model().Commits[i].Hash
return b.CommitHash == self.c.Model().Commits[i].Hash()
}) {
headOfOwnerBranchIdx = i
break
@ -993,7 +993,7 @@ func (self *LocalCommitsController) moveFixupCommitToOwnerStackedBranch(targetCo
}
func (self *LocalCommitsController) createAmendCommit(commit *models.Commit, includeFileChanges bool) error {
commitMessage, err := self.c.Git().Commit.GetCommitMessage(commit.Hash)
commitMessage, err := self.c.Git().Commit.GetCommitMessage(commit.Hash())
if err != nil {
return err
}
@ -1139,7 +1139,7 @@ func isFixupCommit(subject string) (string, bool) {
}
func (self *LocalCommitsController) createTag(commit *models.Commit) error {
return self.c.Helpers().Tags.OpenCreateTagPrompt(commit.Hash, func() {})
return self.c.Helpers().Tags.OpenCreateTagPrompt(commit.Hash(), func() {})
}
func (self *LocalCommitsController) openSearch() error {
@ -1304,11 +1304,11 @@ func (self *LocalCommitsController) canPaste() *types.DisabledReason {
}
func (self *LocalCommitsController) markAsBaseCommit(commit *models.Commit) error {
if commit.Hash == self.c.Modes().MarkedBaseCommit.GetHash() {
if commit.Hash() == self.c.Modes().MarkedBaseCommit.GetHash() {
// Reset when invoking it again on the marked commit
self.c.Modes().MarkedBaseCommit.SetHash("")
} else {
self.c.Modes().MarkedBaseCommit.SetHash(commit.Hash)
self.c.Modes().MarkedBaseCommit.SetHash(commit.Hash())
}
self.c.PostRefreshUpdate(self.c.Contexts().LocalCommits)
return nil

View file

@ -45,7 +45,7 @@ func (self *ReflogCommitsController) GetOnRenderToMain() func() {
if commit == nil {
task = types.NewRenderStringTask("No reflog history")
} else {
cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash, self.c.Modes().Filtering.GetPath())
cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash(), self.c.Modes().Filtering.GetPath())
task = types.NewRunPtyTask(cmdObj.GetCmd())
}

View file

@ -207,7 +207,7 @@ func (self *UndoController) parseReflogForActions(onUserAction func(counter int,
prevCommitHash := ""
if len(reflogCommits)-1 >= reflogCommitIdx+1 {
prevCommitHash = reflogCommits[reflogCommitIdx+1].Hash
prevCommitHash = reflogCommits[reflogCommitIdx+1].Hash()
}
if rebaseFinishCommitHash == "" {
@ -216,11 +216,11 @@ func (self *UndoController) parseReflogForActions(onUserAction func(counter int,
} else if ok, _ := utils.FindStringSubmatch(reflogCommit.Name, `^\[lazygit redo\]`); ok {
counter--
} else if ok, _ := utils.FindStringSubmatch(reflogCommit.Name, `^rebase (-i )?\(abort\)|^rebase (-i )?\(finish\)`); ok {
rebaseFinishCommitHash = reflogCommit.Hash
rebaseFinishCommitHash = reflogCommit.Hash()
} else if ok, match := utils.FindStringSubmatch(reflogCommit.Name, `^checkout: moving from ([\S]+) to ([\S]+)`); ok {
action = &reflogAction{kind: CHECKOUT, from: match[1], to: match[2]}
} else if ok, _ := utils.FindStringSubmatch(reflogCommit.Name, `^commit|^reset: moving to|^pull`); ok {
action = &reflogAction{kind: COMMIT, from: prevCommitHash, to: reflogCommit.Hash}
action = &reflogAction{kind: COMMIT, from: prevCommitHash, to: reflogCommit.Hash()}
} else if ok, _ := utils.FindStringSubmatch(reflogCommit.Name, `^rebase (-i )?\(start\)`); ok {
// if we're here then we must be currently inside an interactive rebase
action = &reflogAction{kind: CURRENT_REBASE, from: prevCommitHash}

View file

@ -39,27 +39,27 @@ func (self *CherryPicking) SelectedHashSet() *set.Set[string] {
}
hashes := lo.Map(self.CherryPickedCommits, func(commit *models.Commit, _ int) string {
return commit.Hash
return commit.Hash()
})
return set.NewFromSlice(hashes)
}
func (self *CherryPicking) Add(selectedCommit *models.Commit, commitsList []*models.Commit) {
commitSet := self.SelectedHashSet()
commitSet.Add(selectedCommit.Hash)
commitSet.Add(selectedCommit.Hash())
self.update(commitSet, commitsList)
}
func (self *CherryPicking) Remove(selectedCommit *models.Commit, commitsList []*models.Commit) {
commitSet := self.SelectedHashSet()
commitSet.Remove(selectedCommit.Hash)
commitSet.Remove(selectedCommit.Hash())
self.update(commitSet, commitsList)
}
func (self *CherryPicking) update(selectedHashSet *set.Set[string], commitsList []*models.Commit) {
self.CherryPickedCommits = lo.Filter(commitsList, func(commit *models.Commit, _ int) bool {
return selectedHashSet.Includes(commit.Hash)
return selectedHashSet.Includes(commit.Hash())
})
}

View file

@ -175,7 +175,7 @@ func GetCommitListDisplayStrings(
!lo.Contains(common.UserConfig().Git.MainBranches, b.Name) &&
// Don't show a marker for the head commit unless the
// rebase.updateRefs config is on
(hasRebaseUpdateRefsConfig || b.CommitHash != commits[0].Hash)
(hasRebaseUpdateRefsConfig || b.CommitHash != commits[0].Hash())
}))
lines := make([][]string, 0, len(filteredCommits))
@ -183,8 +183,8 @@ func GetCommitListDisplayStrings(
willBeRebased := markedBaseCommit == ""
for i, commit := range filteredCommits {
unfilteredIdx := i + startIdx
bisectStatus = getBisectStatus(unfilteredIdx, commit.Hash, bisectInfo, bisectBounds)
isMarkedBaseCommit := commit.Hash != "" && commit.Hash == markedBaseCommit
bisectStatus = getBisectStatus(unfilteredIdx, commit.Hash(), bisectInfo, bisectBounds)
isMarkedBaseCommit := commit.Hash() != "" && commit.Hash() == markedBaseCommit
if isMarkedBaseCommit {
willBeRebased = true
}
@ -218,11 +218,11 @@ func getbisectBounds(commits []*models.Commit, bisectInfo *git_commands.BisectIn
bisectBounds := &bisectBounds{}
for i, commit := range commits {
if commit.Hash == bisectInfo.GetNewHash() {
if commit.Hash() == bisectInfo.GetNewHash() {
bisectBounds.newIndex = i
}
status, ok := bisectInfo.Status(commit.Hash)
status, ok := bisectInfo.Status(commit.Hash())
if ok && status == git_commands.BisectStatusOld {
bisectBounds.oldIndex = i
return bisectBounds
@ -249,7 +249,7 @@ func loadPipesets(commits []*models.Commit) [][]*graph.Pipe {
// given that our cache key is a commit hash and a commit count, it's very important that we don't actually try to render pipes
// when dealing with things like filtered commits.
cacheKey := pipeSetCacheKey{
commitHash: commits[0].Hash,
commitHash: commits[0].Hash(),
commitCount: len(commits),
divergence: commits[0].Divergence,
}
@ -363,10 +363,10 @@ func displayCommit(
hashString := ""
hashColor := getHashColor(commit, diffName, cherryPickedCommitHashSet, bisectStatus, bisectInfo)
hashLength := common.UserConfig().Gui.CommitHashLength
if hashLength >= len(commit.Hash) {
hashString = hashColor.Sprint(commit.Hash)
if hashLength >= len(commit.Hash()) {
hashString = hashColor.Sprint(commit.Hash())
} else if hashLength > 0 {
hashString = hashColor.Sprint(commit.Hash[:hashLength])
hashString = hashColor.Sprint(commit.Hash()[:hashLength])
} else if !icons.IsIconEnabled() { // hashLength <= 0
hashString = hashColor.Sprint("*")
}
@ -400,7 +400,7 @@ func displayCommit(
tagString = theme.DiffTerminalColor.SetBold().Sprint(strings.Join(commit.Tags, " ")) + " "
}
if branchHeadsToVisualize.Includes(commit.Hash) &&
if branchHeadsToVisualize.Includes(commit.Hash()) &&
// Don't show branch head on commits that are already merged to a main branch
commit.Status != models.StatusMerged &&
// Don't show branch head on a "pick" todo if the rebase.updateRefs config is on
@ -482,7 +482,7 @@ func getHashColor(
return getBisectStatusColor(bisectStatus)
}
diffed := commit.Hash != "" && commit.Hash == diffName
diffed := commit.Hash() != "" && commit.Hash() == diffName
hashColor := theme.DefaultTextColor
switch commit.Status {
case models.StatusUnpushed:
@ -500,7 +500,7 @@ func getHashColor(
if diffed {
hashColor = theme.DiffTerminalColor
} else if cherryPickedCommitHashSet.Includes(commit.Hash) {
} else if cherryPickedCommitHashSet.Includes(commit.Hash()) {
hashColor = theme.CherryPickedCommitTextStyle
} else if commit.Divergence == models.DivergenceRight && commit.Status != models.StatusMerged {
hashColor = style.FgBlue

View file

@ -11,6 +11,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
"github.com/stefanhaller/git-todo-parser/todo"
"github.com/stretchr/testify/assert"
"github.com/xo/terminfo"
@ -23,7 +24,7 @@ func formatExpected(expected string) string {
func TestGetCommitListDisplayStrings(t *testing.T) {
scenarios := []struct {
testName string
commits []*models.Commit
commitOpts []models.NewCommitOpts
branches []*models.Branch
currentBranchName string
hasUpdateRefConfig bool
@ -45,7 +46,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
}{
{
testName: "no commits",
commits: []*models.Commit{},
commitOpts: []models.NewCommitOpts{},
startIdx: 0,
endIdx: 1,
showGraph: false,
@ -56,7 +57,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "some commits",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1"},
{Name: "commit2", Hash: "hash2"},
},
@ -73,7 +74,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "commit with tags",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1", Tags: []string{"tag1", "tag2"}},
{Name: "commit2", Hash: "hash2"},
},
@ -90,7 +91,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "show local branch head, except the current branch, main branches, or merged branches",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1"},
{Name: "commit2", Hash: "hash2"},
{Name: "commit3", Hash: "hash3"},
@ -119,7 +120,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "show local branch head for head commit if updateRefs is on",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1"},
{Name: "commit2", Hash: "hash2"},
},
@ -142,7 +143,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "don't show local branch head for head commit if updateRefs is off",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1"},
{Name: "commit2", Hash: "hash2"},
},
@ -165,7 +166,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "show local branch head and tag if both exist",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1"},
{Name: "commit2", Hash: "hash2", Tags: []string{"some-tag"}},
{Name: "commit3", Hash: "hash3"},
@ -187,7 +188,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "showing graph",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1", Parents: []string{"hash2", "hash3"}},
{Name: "commit2", Hash: "hash2", Parents: []string{"hash3"}},
{Name: "commit3", Hash: "hash3", Parents: []string{"hash4"}},
@ -210,7 +211,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "showing graph, including rebase commits",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1", Parents: []string{"hash2", "hash3"}, Action: todo.Pick},
{Name: "commit2", Hash: "hash2", Parents: []string{"hash3"}, Action: todo.Pick},
{Name: "commit3", Hash: "hash3", Parents: []string{"hash4"}},
@ -233,7 +234,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "showing graph, including rebase commits, with offset",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1", Parents: []string{"hash2", "hash3"}, Action: todo.Pick},
{Name: "commit2", Hash: "hash2", Parents: []string{"hash3"}, Action: todo.Pick},
{Name: "commit3", Hash: "hash3", Parents: []string{"hash4"}},
@ -255,7 +256,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "startIdx is past TODO commits",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1", Parents: []string{"hash2", "hash3"}, Action: todo.Pick},
{Name: "commit2", Hash: "hash2", Parents: []string{"hash3"}, Action: todo.Pick},
{Name: "commit3", Hash: "hash3", Parents: []string{"hash4"}},
@ -275,7 +276,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "only showing TODO commits",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1", Parents: []string{"hash2", "hash3"}, Action: todo.Pick},
{Name: "commit2", Hash: "hash2", Parents: []string{"hash3"}, Action: todo.Pick},
{Name: "commit3", Hash: "hash3", Parents: []string{"hash4"}},
@ -295,7 +296,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "no TODO commits, towards bottom",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1", Parents: []string{"hash2", "hash3"}},
{Name: "commit2", Hash: "hash2", Parents: []string{"hash3"}},
{Name: "commit3", Hash: "hash3", Parents: []string{"hash4"}},
@ -314,7 +315,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "only TODO commits except last",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1", Parents: []string{"hash2", "hash3"}, Action: todo.Pick},
{Name: "commit2", Hash: "hash2", Parents: []string{"hash3"}, Action: todo.Pick},
{Name: "commit3", Hash: "hash3", Parents: []string{"hash4"}, Action: todo.Pick},
@ -334,7 +335,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "graph in divergence view - all commits visible",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
@ -363,7 +364,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "graph in divergence view - not all remote commits visible",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
@ -390,7 +391,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "graph in divergence view - not all local commits",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
@ -416,7 +417,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "graph in divergence view - no remote commits visible",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
@ -441,7 +442,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "graph in divergence view - no local commits visible",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
@ -464,7 +465,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "graph in divergence view - no remote commits present",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1l", Parents: []string{"hash2l"}, Divergence: models.DivergenceLeft},
{Name: "commit2", Hash: "hash2l", Parents: []string{"hash3l", "hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit3", Hash: "hash3l", Parents: []string{"hash4l"}, Divergence: models.DivergenceLeft},
@ -487,7 +488,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "graph in divergence view - no local commits present",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
@ -506,7 +507,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
},
{
testName: "custom time format",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Name: "commit1", Hash: "hash1", UnixTimestamp: 1577844184, AuthorName: "Jesse Duffield"},
{Name: "commit2", Hash: "hash2", UnixTimestamp: 1576844184, AuthorName: "Jesse Duffield"},
},
@ -543,9 +544,12 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
for _, s := range scenarios {
if !focusing || s.focus {
t.Run(s.testName, func(t *testing.T) {
commits := lo.Map(s.commitOpts,
func(opts models.NewCommitOpts, _ int) *models.Commit { return models.NewCommit(opts) })
result := GetCommitListDisplayStrings(
common,
s.commits,
commits,
s.branches,
s.currentBranchName,
s.hasUpdateRefConfig,

View file

@ -57,7 +57,7 @@ func GetPipeSets(commits []*models.Commit, getStyle func(c *models.Commit) style
return nil
}
pipes := []*Pipe{{fromPos: 0, toPos: 0, fromHash: "START", toHash: commits[0].Hash, kind: STARTS, style: style.FgDefault}}
pipes := []*Pipe{{fromPos: 0, toPos: 0, fromHash: "START", toHash: commits[0].Hash(), kind: STARTS, style: style.FgDefault}}
return lo.Map(commits, func(commit *models.Commit, _ int) []*Pipe {
pipes = getNextPipes(pipes, commit, getStyle)
@ -121,7 +121,7 @@ func getNextPipes(prevPipes []*Pipe, commit *models.Commit, getStyle func(c *mod
// (this only happens when we're doing `git log --all`). These will be tacked onto the far end.
pos := maxPos + 1
for _, pipe := range currentPipes {
if equalHashes(pipe.toHash, commit.Hash) {
if equalHashes(pipe.toHash, commit.Hash()) {
// turns out this commit does have a descendant so we'll place it right under the first instance
pos = pipe.toPos
break
@ -142,7 +142,7 @@ func getNextPipes(prevPipes []*Pipe, commit *models.Commit, getStyle func(c *mod
newPipes = append(newPipes, &Pipe{
fromPos: pos,
toPos: pos,
fromHash: commit.Hash,
fromHash: commit.Hash(),
toHash: toHash,
kind: STARTS,
style: getStyle(commit),
@ -150,7 +150,7 @@ func getNextPipes(prevPipes []*Pipe, commit *models.Commit, getStyle func(c *mod
traversedSpotsForContinuingPipes := set.New[int]()
for _, pipe := range currentPipes {
if !equalHashes(pipe.toHash, commit.Hash) {
if !equalHashes(pipe.toHash, commit.Hash()) {
traversedSpotsForContinuingPipes.Add(pipe.toPos)
}
}
@ -189,7 +189,7 @@ func getNextPipes(prevPipes []*Pipe, commit *models.Commit, getStyle func(c *mod
}
for _, pipe := range currentPipes {
if equalHashes(pipe.toHash, commit.Hash) {
if equalHashes(pipe.toHash, commit.Hash()) {
// terminating here
newPipes = append(newPipes, &Pipe{
fromPos: pipe.toPos,
@ -222,7 +222,7 @@ func getNextPipes(prevPipes []*Pipe, commit *models.Commit, getStyle func(c *mod
newPipes = append(newPipes, &Pipe{
fromPos: pos,
toPos: availablePos,
fromHash: commit.Hash,
fromHash: commit.Hash(),
toHash: parent,
kind: STARTS,
style: getStyle(commit),
@ -233,7 +233,7 @@ func getNextPipes(prevPipes []*Pipe, commit *models.Commit, getStyle func(c *mod
}
for _, pipe := range currentPipes {
if !equalHashes(pipe.toHash, commit.Hash) && pipe.toPos > pos {
if !equalHashes(pipe.toHash, commit.Hash()) && pipe.toPos > pos {
// continuing on, potentially moving left to fill in a blank spot
last := pipe.toPos
for i := pipe.toPos; i > pos; i-- {
@ -315,7 +315,7 @@ func renderPipeSet(
// we don't want to highlight two commits if they're contiguous. We only want
// to highlight multiple things if there's an actual visible pipe involved.
highlight := true
if prevCommit != nil && equalHashes(prevCommit.Hash, selectedCommitHash) {
if prevCommit != nil && equalHashes(prevCommit.Hash(), selectedCommitHash) {
highlight = false
for _, pipe := range pipes {
if equalHashes(pipe.fromHash, selectedCommitHash) && (pipe.kind != TERMINATES || pipe.fromPos != pipe.toPos) {

View file

@ -11,6 +11,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/gui/presentation/authors"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/xo/terminfo"
)
@ -18,12 +19,12 @@ import (
func TestRenderCommitGraph(t *testing.T) {
tests := []struct {
name string
commits []*models.Commit
commitOpts []models.NewCommitOpts
expectedOutput string
}{
{
name: "with some merges",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "1", Parents: []string{"2"}},
{Hash: "2", Parents: []string{"3"}},
{Hash: "3", Parents: []string{"4"}},
@ -57,7 +58,7 @@ func TestRenderCommitGraph(t *testing.T) {
},
{
name: "with a path that has room to move to the left",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "1", Parents: []string{"2"}},
{Hash: "2", Parents: []string{"3", "4"}},
{Hash: "4", Parents: []string{"3", "5"}},
@ -75,7 +76,7 @@ func TestRenderCommitGraph(t *testing.T) {
},
{
name: "with a new commit",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "1", Parents: []string{"2"}},
{Hash: "2", Parents: []string{"3", "4"}},
{Hash: "4", Parents: []string{"3", "5"}},
@ -95,7 +96,7 @@ func TestRenderCommitGraph(t *testing.T) {
},
{
name: "with a path that has room to move to the left and continues",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "1", Parents: []string{"2"}},
{Hash: "2", Parents: []string{"3", "4"}},
{Hash: "3", Parents: []string{"5", "4"}},
@ -113,7 +114,7 @@ func TestRenderCommitGraph(t *testing.T) {
},
{
name: "with a path that has room to move to the left and continues",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "1", Parents: []string{"2"}},
{Hash: "2", Parents: []string{"3", "4"}},
{Hash: "3", Parents: []string{"5", "4"}},
@ -133,7 +134,7 @@ func TestRenderCommitGraph(t *testing.T) {
},
{
name: "with a path that has room to move to the left and continues",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "1", Parents: []string{"2", "3"}},
{Hash: "3", Parents: []string{"2"}},
{Hash: "2", Parents: []string{"4", "5"}},
@ -149,7 +150,7 @@ func TestRenderCommitGraph(t *testing.T) {
},
{
name: "new merge path fills gap before continuing path on right",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "1", Parents: []string{"2", "3", "4", "5"}},
{Hash: "4", Parents: []string{"2"}},
{Hash: "2", Parents: []string{"A"}},
@ -165,7 +166,7 @@ func TestRenderCommitGraph(t *testing.T) {
},
{
name: "with a path that has room to move to the left and continues",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "1", Parents: []string{"2"}},
{Hash: "2", Parents: []string{"3", "4"}},
{Hash: "3", Parents: []string{"5", "4"}},
@ -187,7 +188,7 @@ func TestRenderCommitGraph(t *testing.T) {
},
{
name: "with a path that has room to move to the left and continues",
commits: []*models.Commit{
commitOpts: []models.NewCommitOpts{
{Hash: "1", Parents: []string{"2"}},
{Hash: "2", Parents: []string{"3", "4"}},
{Hash: "3", Parents: []string{"5", "4"}},
@ -219,7 +220,9 @@ func TestRenderCommitGraph(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
getStyle := func(c *models.Commit) style.TextStyle { return style.FgDefault }
lines := RenderCommitGraph(test.commits, "blah", getStyle)
commits := lo.Map(test.commitOpts,
func(opts models.NewCommitOpts, _ int) *models.Commit { return models.NewCommit(opts) })
lines := RenderCommitGraph(commits, "blah", getStyle)
trimmedExpectedOutput := ""
for _, line := range strings.Split(strings.TrimPrefix(test.expectedOutput, "\n"), "\n") {
@ -230,7 +233,7 @@ func TestRenderCommitGraph(t *testing.T) {
output := ""
for i, line := range lines {
description := test.commits[i].Hash
description := test.commitOpts[i].Hash
output += strings.TrimSpace(description+" "+utils.Decolorise(line)) + "\n"
}
t.Log("\nactual: \n" + output)
@ -265,7 +268,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 0, toPos: 0, fromHash: "a", toHash: "b", kind: TERMINATES, style: cyan},
{fromPos: 0, toPos: 0, fromHash: "b", toHash: "c", kind: STARTS, style: green},
},
prevCommit: &models.Commit{Hash: "a"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "a"}),
expectedStr: "◯",
expectedStyles: []style.TextStyle{green},
},
@ -275,7 +278,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 0, toPos: 0, fromHash: "a", toHash: "selected", kind: TERMINATES, style: cyan},
{fromPos: 0, toPos: 0, fromHash: "selected", toHash: "c", kind: STARTS, style: green},
},
prevCommit: &models.Commit{Hash: "a"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "a"}),
expectedStr: "◯",
expectedStyles: []style.TextStyle{highlightStyle},
},
@ -287,7 +290,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 0, toPos: 0, fromHash: "selected", toHash: "d", kind: STARTS, style: green},
{fromPos: 0, toPos: 1, fromHash: "selected", toHash: "e", kind: STARTS, style: green},
},
prevCommit: &models.Commit{Hash: "a"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "a"}),
expectedStr: "⏣─╮",
expectedStyles: []style.TextStyle{
highlightStyle, highlightStyle, highlightStyle,
@ -301,7 +304,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 0, toPos: 0, fromHash: "b", toHash: "d", kind: STARTS, style: green},
{fromPos: 0, toPos: 1, fromHash: "b", toHash: "e", kind: STARTS, style: green},
},
prevCommit: &models.Commit{Hash: "a"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "a"}),
expectedStr: "⏣─│",
expectedStyles: []style.TextStyle{
green, green, magenta,
@ -316,7 +319,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 3, toPos: 0, fromHash: "e1", toHash: "a2", kind: TERMINATES, style: green},
{fromPos: 0, toPos: 2, fromHash: "a2", toHash: "c3", kind: STARTS, style: yellow},
},
prevCommit: &models.Commit{Hash: "a1"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "a1"}),
expectedStr: "⏣─│─┬─╯",
expectedStyles: []style.TextStyle{
yellow, yellow, magenta, yellow, yellow, green, green,
@ -331,7 +334,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 3, toPos: 0, fromHash: "e1", toHash: "selected", kind: TERMINATES, style: green},
{fromPos: 0, toPos: 2, fromHash: "selected", toHash: "c3", kind: STARTS, style: yellow},
},
prevCommit: &models.Commit{Hash: "a1"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "a1"}),
expectedStr: "⏣───╮ ╯",
expectedStyles: []style.TextStyle{
highlightStyle, highlightStyle, highlightStyle, highlightStyle, highlightStyle, nothing, green,
@ -345,7 +348,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 1, toPos: 0, fromHash: "b1", toHash: "a2", kind: TERMINATES, style: magenta},
{fromPos: 2, toPos: 0, fromHash: "c1", toHash: "a2", kind: TERMINATES, style: green},
},
prevCommit: &models.Commit{Hash: "a1"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "a1"}),
expectedStr: "◯─┴─╯",
expectedStyles: []style.TextStyle{
yellow, magenta, magenta, green, green,
@ -360,7 +363,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 1, toPos: 1, fromHash: "b1", toHash: "b3", kind: CONTINUES, style: magenta},
{fromPos: 2, toPos: 2, fromHash: "c1", toHash: "c3", kind: CONTINUES, style: green},
},
prevCommit: &models.Commit{Hash: "a1"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "a1"}),
expectedStr: "⏣─│─│─╮",
expectedStyles: []style.TextStyle{
yellow, yellow, magenta, yellow, green, yellow, yellow,
@ -375,7 +378,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 1, toPos: 1, fromHash: "b1", toHash: "a2", kind: CONTINUES, style: green},
{fromPos: 2, toPos: 0, fromHash: "c1", toHash: "a2", kind: TERMINATES, style: magenta},
},
prevCommit: &models.Commit{Hash: "a1"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "a1"}),
expectedStr: "⏣─│─╯",
expectedStyles: []style.TextStyle{
yellow, yellow, green, magenta, magenta,
@ -390,7 +393,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 2, toPos: 2, fromHash: "c1", toHash: "c3", kind: CONTINUES, style: green},
{fromPos: 3, toPos: 0, fromHash: "d1", toHash: "a2", kind: TERMINATES, style: magenta},
},
prevCommit: &models.Commit{Hash: "a1"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "a1"}),
expectedStr: "⏣─┬─│─╯",
expectedStyles: []style.TextStyle{
yellow, yellow, yellow, magenta, green, magenta, magenta,
@ -402,7 +405,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 0, toPos: 0, fromHash: "selected", toHash: "a2", kind: TERMINATES, style: red},
{fromPos: 0, toPos: 0, fromHash: "a2", toHash: "a3", kind: STARTS, style: yellow},
},
prevCommit: &models.Commit{Hash: "selected"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "selected"}),
expectedStr: "◯",
expectedStyles: []style.TextStyle{
yellow,
@ -414,7 +417,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 0, toPos: 0, fromHash: "selected", toHash: "a2", kind: TERMINATES, style: red},
{fromPos: 1, toPos: 1, fromHash: "selected", toHash: "b3", kind: CONTINUES, style: red},
},
prevCommit: &models.Commit{Hash: "selected"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "selected"}),
expectedStr: "◯ │",
expectedStyles: []style.TextStyle{
highlightStyle, nothing, highlightStyle,
@ -427,7 +430,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 1, toPos: 1, fromHash: "z1", toHash: "z3", kind: CONTINUES, style: green},
{fromPos: 2, toPos: 2, fromHash: "selected", toHash: "b3", kind: CONTINUES, style: red},
},
prevCommit: &models.Commit{Hash: "selected"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "selected"}),
expectedStr: "◯ │ │",
expectedStyles: []style.TextStyle{
highlightStyle, nothing, green, nothing, highlightStyle,
@ -441,7 +444,7 @@ func TestRenderPipeSet(t *testing.T) {
{fromPos: 0, toPos: 1, fromHash: "a2", toHash: "b3", kind: STARTS, style: green},
{fromPos: 1, toPos: 0, fromHash: "selected", toHash: "a2", kind: TERMINATES, style: yellow},
},
prevCommit: &models.Commit{Hash: "selected"},
prevCommit: models.NewCommit(models.NewCommitOpts{Hash: "selected"}),
expectedStr: "⏣─╯",
expectedStyles: []style.TextStyle{
highlightStyle, highlightStyle, highlightStyle,
@ -483,10 +486,10 @@ func TestGetNextPipes(t *testing.T) {
prevPipes: []*Pipe{
{fromPos: 0, toPos: 0, fromHash: "a", toHash: "b", kind: STARTS, style: style.FgDefault},
},
commit: &models.Commit{
commit: models.NewCommit(models.NewCommitOpts{
Hash: "b",
Parents: []string{"c"},
},
}),
expected: []*Pipe{
{fromPos: 0, toPos: 0, fromHash: "a", toHash: "b", kind: TERMINATES, style: style.FgDefault},
{fromPos: 0, toPos: 0, fromHash: "b", toHash: "c", kind: STARTS, style: style.FgDefault},
@ -498,10 +501,10 @@ func TestGetNextPipes(t *testing.T) {
{fromPos: 0, toPos: 0, fromHash: "b", toHash: "c", kind: STARTS, style: style.FgDefault},
{fromPos: 0, toPos: 1, fromHash: "b", toHash: "d", kind: STARTS, style: style.FgDefault},
},
commit: &models.Commit{
commit: models.NewCommit(models.NewCommitOpts{
Hash: "d",
Parents: []string{"e"},
},
}),
expected: []*Pipe{
{fromPos: 0, toPos: 0, fromHash: "b", toHash: "c", kind: CONTINUES, style: style.FgDefault},
{fromPos: 1, toPos: 1, fromHash: "b", toHash: "d", kind: TERMINATES, style: style.FgDefault},
@ -512,10 +515,10 @@ func TestGetNextPipes(t *testing.T) {
prevPipes: []*Pipe{
{fromPos: 0, toPos: 0, fromHash: "a", toHash: "root", kind: TERMINATES, style: style.FgDefault},
},
commit: &models.Commit{
commit: models.NewCommit(models.NewCommitOpts{
Hash: "root",
Parents: []string{},
},
}),
expected: []*Pipe{
{fromPos: 1, toPos: 1, fromHash: "root", toHash: models.EmptyTreeCommitHash, kind: STARTS, style: style.FgDefault},
},
@ -555,7 +558,7 @@ func BenchmarkRenderCommitGraph(b *testing.B) {
func generateCommits(count int) []*models.Commit {
rnd := rand.New(rand.NewSource(1234))
pool := []*models.Commit{{Hash: "a", AuthorName: "A"}}
pool := []*models.Commit{models.NewCommit(models.NewCommitOpts{Hash: "a", AuthorName: "A"})}
commits := make([]*models.Commit, 0, count)
authorPool := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
for len(commits) < count {
@ -572,20 +575,20 @@ func generateCommits(count int) []*models.Commit {
if reuseParent {
newParent = pool[j]
} else {
newParent = &models.Commit{
Hash: fmt.Sprintf("%s%d", currentCommit.Hash, j),
newParent = models.NewCommit(models.NewCommitOpts{
Hash: fmt.Sprintf("%s%d", currentCommit.Hash(), j),
AuthorName: authorPool[rnd.Intn(len(authorPool))],
}
})
pool = append(pool, newParent)
}
parentHashes = append(parentHashes, newParent.Hash)
parentHashes = append(parentHashes, newParent.Hash())
}
changedCommit := &models.Commit{
Hash: currentCommit.Hash,
changedCommit := models.NewCommit(models.NewCommitOpts{
Hash: currentCommit.Hash(),
AuthorName: currentCommit.AuthorName,
Parents: parentHashes,
}
})
commits = append(commits, changedCommit)
}

View file

@ -21,8 +21,8 @@ func GetReflogCommitListDisplayStrings(commits []*models.Commit, fullDescription
}
return lo.Map(commits, func(commit *models.Commit, _ int) []string {
diffed := commit.Hash == diffName
cherryPicked := cherryPickedCommitHashSet.Includes(commit.Hash)
diffed := commit.Hash() == diffName
cherryPicked := cherryPickedCommitHashSet.Includes(commit.Hash())
return displayFunc(commit,
reflogCommitDisplayAttributes{
cherryPicked: cherryPicked,

View file

@ -26,8 +26,8 @@ func commitShimFromModelCommit(commit *models.Commit) *Commit {
}
return &Commit{
Hash: commit.Hash,
Sha: commit.Hash,
Hash: commit.Hash(),
Sha: commit.Hash(),
Name: commit.Name,
Status: commit.Status,
Action: commit.Action,
@ -173,8 +173,8 @@ func makeCommitRange(commits []*models.Commit, _ int, _ int) *CommitRange {
}
return &CommitRange{
From: commits[len(commits)-1].Hash,
To: commits[0].Hash,
From: commits[len(commits)-1].Hash(),
To: commits[0].Hash(),
}
}