mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-11 20:36:03 +02:00
Show original todo action instead of "conflict", and show <-- CONFLICT
instead
It is useful to see if the conflicted commit was a "pick" or an "edit". What's more, we're about to add support for showing cherry-picks and reverts, and seeing that a conflicted commit was a revert is important because its diff is backwards compared to the diff of the conflicting files in the Files panel.
This commit is contained in:
parent
9c8f987934
commit
ff465e2581
19 changed files with 81 additions and 63 deletions
|
@ -322,13 +322,8 @@ func (self *CommitLoader) getRebasingCommits() []*models.Commit {
|
|||
|
||||
// See if the current commit couldn't be applied because it conflicted; if
|
||||
// so, add a fake entry for it
|
||||
if conflictedCommitHash := self.getConflictedCommit(todos); conflictedCommitHash != "" {
|
||||
commits = append(commits, &models.Commit{
|
||||
Hash: conflictedCommitHash,
|
||||
Name: "",
|
||||
Status: models.StatusRebasing,
|
||||
Action: models.ActionConflict,
|
||||
})
|
||||
if conflictedCommit := self.getConflictedCommit(todos); conflictedCommit != nil {
|
||||
commits = append(commits, conflictedCommit)
|
||||
}
|
||||
|
||||
for _, t := range todos {
|
||||
|
@ -351,17 +346,17 @@ func (self *CommitLoader) getRebasingCommits() []*models.Commit {
|
|||
return commits
|
||||
}
|
||||
|
||||
func (self *CommitLoader) getConflictedCommit(todos []todo.Todo) string {
|
||||
func (self *CommitLoader) getConflictedCommit(todos []todo.Todo) *models.Commit {
|
||||
bytesContent, err := self.readFile(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/done"))
|
||||
if err != nil {
|
||||
self.Log.Error(fmt.Sprintf("error occurred reading rebase-merge/done: %s", err.Error()))
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
doneTodos, err := todo.Parse(bytes.NewBuffer(bytesContent), self.config.GetCoreCommentChar())
|
||||
if err != nil {
|
||||
self.Log.Error(fmt.Sprintf("error occurred while parsing rebase-merge/done file: %s", err.Error()))
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
amendFileExists := false
|
||||
|
@ -372,15 +367,15 @@ func (self *CommitLoader) getConflictedCommit(todos []todo.Todo) string {
|
|||
return self.getConflictedCommitImpl(todos, doneTodos, amendFileExists)
|
||||
}
|
||||
|
||||
func (self *CommitLoader) getConflictedCommitImpl(todos []todo.Todo, doneTodos []todo.Todo, amendFileExists bool) string {
|
||||
func (self *CommitLoader) getConflictedCommitImpl(todos []todo.Todo, doneTodos []todo.Todo, amendFileExists bool) *models.Commit {
|
||||
// Should never be possible, but just to be safe:
|
||||
if len(doneTodos) == 0 {
|
||||
self.Log.Error("no done entries in rebase-merge/done file")
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
lastTodo := doneTodos[len(doneTodos)-1]
|
||||
if lastTodo.Command == todo.Break || lastTodo.Command == todo.Exec || lastTodo.Command == todo.Reword {
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
// In certain cases, git reschedules commands that failed. One example is if
|
||||
|
@ -391,7 +386,7 @@ func (self *CommitLoader) getConflictedCommitImpl(todos []todo.Todo, doneTodos [
|
|||
// same, the command was rescheduled.
|
||||
if len(doneTodos) > 0 && len(todos) > 0 && doneTodos[len(doneTodos)-1] == todos[0] {
|
||||
// Command was rescheduled, no need to display it
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
// Older versions of git have a bug whereby, if a command is rescheduled,
|
||||
|
@ -416,26 +411,30 @@ func (self *CommitLoader) getConflictedCommitImpl(todos []todo.Todo, doneTodos [
|
|||
if len(doneTodos) >= 3 && len(todos) > 0 && doneTodos[len(doneTodos)-2] == todos[0] &&
|
||||
doneTodos[len(doneTodos)-1] == doneTodos[len(doneTodos)-3] {
|
||||
// Command was rescheduled, no need to display it
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
if lastTodo.Command == todo.Edit {
|
||||
if amendFileExists {
|
||||
// Special case for "edit": if the "amend" file exists, the "edit"
|
||||
// command was successful, otherwise it wasn't
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// I don't think this is ever possible, but again, just to be safe:
|
||||
if lastTodo.Commit == "" {
|
||||
self.Log.Error("last command in rebase-merge/done file doesn't have a commit")
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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 lastTodo.Commit
|
||||
return &models.Commit{
|
||||
Hash: lastTodo.Commit,
|
||||
Action: lastTodo.Command,
|
||||
Status: models.StatusConflicted,
|
||||
}
|
||||
}
|
||||
|
||||
func setCommitMergedStatuses(ancestor string, commits []*models.Commit) {
|
||||
|
|
|
@ -332,14 +332,14 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
todos []todo.Todo
|
||||
doneTodos []todo.Todo
|
||||
amendFileExists bool
|
||||
expectedHash string
|
||||
expectedResult *models.Commit
|
||||
}{
|
||||
{
|
||||
testName: "no done todos",
|
||||
todos: []todo.Todo{},
|
||||
doneTodos: []todo.Todo{},
|
||||
amendFileExists: false,
|
||||
expectedHash: "",
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
testName: "common case (conflict)",
|
||||
|
@ -355,7 +355,11 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
},
|
||||
},
|
||||
amendFileExists: false,
|
||||
expectedHash: "fa1afe1",
|
||||
expectedResult: &models.Commit{
|
||||
Hash: "fa1afe1",
|
||||
Action: todo.Pick,
|
||||
Status: models.StatusConflicted,
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "last command was 'break'",
|
||||
|
@ -364,7 +368,7 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
{Command: todo.Break},
|
||||
},
|
||||
amendFileExists: false,
|
||||
expectedHash: "",
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
testName: "last command was 'exec'",
|
||||
|
@ -376,7 +380,7 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
},
|
||||
},
|
||||
amendFileExists: false,
|
||||
expectedHash: "",
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
testName: "last command was 'reword'",
|
||||
|
@ -385,7 +389,7 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
{Command: todo.Reword},
|
||||
},
|
||||
amendFileExists: false,
|
||||
expectedHash: "",
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
testName: "'pick' was rescheduled",
|
||||
|
@ -402,7 +406,7 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
},
|
||||
},
|
||||
amendFileExists: false,
|
||||
expectedHash: "",
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
testName: "'pick' was rescheduled, buggy git version",
|
||||
|
@ -427,7 +431,7 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
},
|
||||
},
|
||||
amendFileExists: false,
|
||||
expectedHash: "",
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
testName: "conflicting 'pick' after 'exec'",
|
||||
|
@ -452,7 +456,11 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
},
|
||||
},
|
||||
amendFileExists: false,
|
||||
expectedHash: "fa1afe1",
|
||||
expectedResult: &models.Commit{
|
||||
Hash: "fa1afe1",
|
||||
Action: todo.Pick,
|
||||
Status: models.StatusConflicted,
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "'edit' with amend file",
|
||||
|
@ -464,7 +472,7 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
},
|
||||
},
|
||||
amendFileExists: true,
|
||||
expectedHash: "",
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
testName: "'edit' without amend file",
|
||||
|
@ -476,7 +484,11 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
},
|
||||
},
|
||||
amendFileExists: false,
|
||||
expectedHash: "fa1afe1",
|
||||
expectedResult: &models.Commit{
|
||||
Hash: "fa1afe1",
|
||||
Action: todo.Edit,
|
||||
Status: models.StatusConflicted,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, scenario := range scenarios {
|
||||
|
@ -497,7 +509,7 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
|
|||
}
|
||||
|
||||
hash := builder.getConflictedCommitImpl(scenario.todos, scenario.doneTodos, scenario.amendFileExists)
|
||||
assert.Equal(t, scenario.expectedHash, hash)
|
||||
assert.Equal(t, scenario.expectedResult, hash)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ const (
|
|||
StatusPushed
|
||||
StatusMerged
|
||||
StatusRebasing
|
||||
StatusConflicted
|
||||
StatusReflog
|
||||
)
|
||||
|
||||
|
@ -25,8 +26,6 @@ const (
|
|||
// Conveniently for us, the todo package starts the enum at 1, and given
|
||||
// that it doesn't have a "none" value, we're setting ours to 0
|
||||
ActionNone todo.TodoCommand = 0
|
||||
// "Comment" is the last one of the todo package's enum entries
|
||||
ActionConflict = todo.Comment + 1
|
||||
)
|
||||
|
||||
type Divergence int
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue