Skip to content

Commit 0924834

Browse files
committed
Fix the bug described in the previous commit
What happens here is that when stopping on an "edit" todo entry, we rely on the assumption that if the .git/rebase-merge/amend file exists, the command was successful, and if it doesn't, there was a conflict. The problem is that when you stop on an edit command, and then run a multi-commit cherry-pick or rebase, this will delete the amend file. You may or may not consider this a bug in git; to work around it, we also check the existence of the rebase-merge/message file, which will be deleted as well by the cherry-pick or revert.
1 parent f63d9b2 commit 0924834

File tree

4 files changed

+35
-35
lines changed

4 files changed

+35
-35
lines changed

pkg/commands/git_commands/commit_loader.go

+12-6
Original file line numberDiff line numberDiff line change
@@ -389,15 +389,13 @@ func (self *CommitLoader) getConflictedCommit(todos []todo.Todo) *models.Commit
389389
return nil
390390
}
391391

392-
amendFileExists := false
393-
if _, err := os.Stat(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/amend")); err == nil {
394-
amendFileExists = true
395-
}
392+
amendFileExists, _ := self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/amend"))
393+
messageFileExists, _ := self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/message"))
396394

397-
return self.getConflictedCommitImpl(todos, doneTodos, amendFileExists)
395+
return self.getConflictedCommitImpl(todos, doneTodos, amendFileExists, messageFileExists)
398396
}
399397

400-
func (self *CommitLoader) getConflictedCommitImpl(todos []todo.Todo, doneTodos []todo.Todo, amendFileExists bool) *models.Commit {
398+
func (self *CommitLoader) getConflictedCommitImpl(todos []todo.Todo, doneTodos []todo.Todo, amendFileExists bool, messageFileExists bool) *models.Commit {
401399
// Should never be possible, but just to be safe:
402400
if len(doneTodos) == 0 {
403401
self.Log.Error("no done entries in rebase-merge/done file")
@@ -450,6 +448,14 @@ func (self *CommitLoader) getConflictedCommitImpl(todos []todo.Todo, doneTodos [
450448
// command was successful, otherwise it wasn't
451449
return nil
452450
}
451+
452+
if !messageFileExists {
453+
// As an additional check, see if the "message" file exists; if it
454+
// doesn't, it must be because a multi-commit cherry-pick or revert
455+
// was performed in the meantime, which deleted both the amend file
456+
// and the message file.
457+
return nil
458+
}
453459
}
454460

455461
// I don't think this is ever possible, but again, just to be safe:

pkg/commands/git_commands/commit_loader_test.go

+23-8
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,12 @@ func TestGetCommits(t *testing.T) {
329329

330330
func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
331331
scenarios := []struct {
332-
testName string
333-
todos []todo.Todo
334-
doneTodos []todo.Todo
335-
amendFileExists bool
336-
expectedResult *models.Commit
332+
testName string
333+
todos []todo.Todo
334+
doneTodos []todo.Todo
335+
amendFileExists bool
336+
messageFileExists bool
337+
expectedResult *models.Commit
337338
}{
338339
{
339340
testName: "no done todos",
@@ -476,21 +477,35 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
476477
expectedResult: nil,
477478
},
478479
{
479-
testName: "'edit' without amend file",
480+
testName: "'edit' without amend file but message file",
480481
todos: []todo.Todo{},
481482
doneTodos: []todo.Todo{
482483
{
483484
Command: todo.Edit,
484485
Commit: "fa1afe1",
485486
},
486487
},
487-
amendFileExists: false,
488+
amendFileExists: false,
489+
messageFileExists: true,
488490
expectedResult: &models.Commit{
489491
Hash: "fa1afe1",
490492
Action: todo.Edit,
491493
Status: models.StatusConflicted,
492494
},
493495
},
496+
{
497+
testName: "'edit' without amend and without message file",
498+
todos: []todo.Todo{},
499+
doneTodos: []todo.Todo{
500+
{
501+
Command: todo.Edit,
502+
Commit: "fa1afe1",
503+
},
504+
},
505+
amendFileExists: false,
506+
messageFileExists: false,
507+
expectedResult: nil,
508+
},
494509
}
495510
for _, scenario := range scenarios {
496511
t.Run(scenario.testName, func(t *testing.T) {
@@ -509,7 +524,7 @@ func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
509524
},
510525
}
511526

512-
hash := builder.getConflictedCommitImpl(scenario.todos, scenario.doneTodos, scenario.amendFileExists)
527+
hash := builder.getConflictedCommitImpl(scenario.todos, scenario.doneTodos, scenario.amendFileExists, scenario.messageFileExists)
513528
assert.Equal(t, scenario.expectedResult, hash)
514529
})
515530
}

pkg/integration/tests/interactive_rebase/revert_during_rebase_when_stopped_on_edit.go

-10
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,13 @@ var RevertDuringRebaseWhenStoppedOnEdit = NewIntegrationTest(NewIntegrationTestA
4545
).
4646
Press("X").
4747
Lines(
48-
/* EXPECTED:
4948
Contains("pick").Contains("commit 04"),
5049
Contains(`<-- YOU ARE HERE --- Revert "commit 01"`).IsSelected(),
5150
Contains(`Revert "commit 02"`),
5251
Contains("commit 03"),
5352
Contains("commit 02"),
5453
Contains("commit 01"),
5554
Contains("master commit"),
56-
ACTUAL: */
57-
Contains("pick").Contains("commit 04"),
58-
Contains("edit").Contains("<-- CONFLICT --- commit 03").IsSelected(),
59-
Contains(`Revert "commit 01"`),
60-
Contains(`Revert "commit 02"`),
61-
Contains("commit 03"),
62-
Contains("commit 02"),
63-
Contains("commit 01"),
64-
Contains("master commit"),
6555
)
6656
},
6757
})

pkg/integration/tests/interactive_rebase/revert_multiple_commits_in_interactive_rebase.go

-11
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ var RevertMultipleCommitsInInteractiveRebase = NewIntegrationTest(NewIntegration
8484

8585
t.Views().Commits().
8686
Lines(
87-
/* EXPECTED:
8887
Contains("pick").Contains("CI unrelated change 3"),
8988
Contains("pick").Contains("CI unrelated change 2"),
9089
Contains(`CI ◯ <-- YOU ARE HERE --- Revert "unrelated change 1"`),
@@ -93,16 +92,6 @@ var RevertMultipleCommitsInInteractiveRebase = NewIntegrationTest(NewIntegration
9392
Contains("CI ◯ add first line"),
9493
Contains("CI ◯ unrelated change 1"),
9594
Contains("CI ◯ add empty file"),
96-
ACTUAL: */
97-
Contains("pick").Contains("CI unrelated change 3"),
98-
Contains("pick").Contains("CI unrelated change 2"),
99-
Contains("edit CI <-- CONFLICT --- add second line"),
100-
Contains(`CI ◯ Revert "unrelated change 1"`),
101-
Contains(`CI ◯ Revert "add first line"`),
102-
Contains("CI ◯ add second line"),
103-
Contains("CI ◯ add first line"),
104-
Contains("CI ◯ unrelated change 1"),
105-
Contains("CI ◯ add empty file"),
10695
)
10796

10897
t.Views().Options().Content(Contains("View rebase options: m"))

0 commit comments

Comments
 (0)