From 2ba3c1dc3fc0afbd5a6965bd19093e7ef980ecdb Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Thu, 15 Jan 2026 20:05:33 +0100 Subject: [PATCH] Move isFixupCommit to FixupHelper --- pkg/gui/controllers/helpers/fixup_helper.go | 27 +++++++++++ .../controllers/helpers/fixup_helper_test.go | 46 +++++++++++++++++++ .../controllers/local_commits_controller.go | 29 +----------- .../local_commits_controller_test.go | 46 ------------------- 4 files changed, 74 insertions(+), 74 deletions(-) diff --git a/pkg/gui/controllers/helpers/fixup_helper.go b/pkg/gui/controllers/helpers/fixup_helper.go index 2e3b19e77..201749761 100644 --- a/pkg/gui/controllers/helpers/fixup_helper.go +++ b/pkg/gui/controllers/helpers/fixup_helper.go @@ -350,3 +350,30 @@ func (self *FixupHelper) findCommit(commits []*models.Commit, hash string) (*mod return commit.Hash() == hash }) } + +// Check whether the given subject line is the subject of a fixup commit, and +// returns (trimmedSubject, true) if so (where trimmedSubject is the subject +// with all fixup prefixes removed), or (subject, false) if not. +func IsFixupCommit(subject string) (string, bool) { + prefixes := []string{"fixup! ", "squash! ", "amend! "} + trimPrefix := func(s string) (string, bool) { + for _, prefix := range prefixes { + if trimmedSubject, ok := strings.CutPrefix(s, prefix); ok { + return trimmedSubject, true + } + } + return s, false + } + + if subject, wasTrimmed := trimPrefix(subject); wasTrimmed { + for { + // handle repeated prefixes like "fixup! amend! fixup! Subject" + if subject, wasTrimmed = trimPrefix(subject); !wasTrimmed { + break + } + } + return subject, true + } + + return subject, false +} diff --git a/pkg/gui/controllers/helpers/fixup_helper_test.go b/pkg/gui/controllers/helpers/fixup_helper_test.go index e50a4249f..e281a4c28 100644 --- a/pkg/gui/controllers/helpers/fixup_helper_test.go +++ b/pkg/gui/controllers/helpers/fixup_helper_test.go @@ -155,3 +155,49 @@ index 9ce8efb33..0632e41b0 100644 }) } } + +func TestFixupHelper_IsFixupCommit(t *testing.T) { + scenarios := []struct { + subject string + expectedTrimmedSubject string + expectedIsFixup bool + }{ + { + subject: "Bla", + expectedTrimmedSubject: "Bla", + expectedIsFixup: false, + }, + { + subject: "fixup Bla", + expectedTrimmedSubject: "fixup Bla", + expectedIsFixup: false, + }, + { + subject: "fixup! Bla", + expectedTrimmedSubject: "Bla", + expectedIsFixup: true, + }, + { + subject: "fixup! fixup! Bla", + expectedTrimmedSubject: "Bla", + expectedIsFixup: true, + }, + { + subject: "amend! squash! Bla", + expectedTrimmedSubject: "Bla", + expectedIsFixup: true, + }, + { + subject: "fixup!", + expectedTrimmedSubject: "fixup!", + expectedIsFixup: false, + }, + } + for _, s := range scenarios { + t.Run(s.subject, func(t *testing.T) { + trimmedSubject, isFixupCommit := IsFixupCommit(s.subject) + assert.Equal(t, s.expectedTrimmedSubject, trimmedSubject) + assert.Equal(t, s.expectedIsFixup, isFixupCommit) + }) + } +} diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index 1091b9178..2c8932f33 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -1096,7 +1096,7 @@ func countSquashableCommitsAbove(commits []*models.Commit, selectedIdx int, reba // For each commit _above_ the selection, ... for i, commit := range commits[0:selectedIdx] { // ... see if it is a fixup commit, and get the base subject it applies to - if baseSubject, isFixup := isFixupCommit(commit.Name); isFixup { + if baseSubject, isFixup := helpers.IsFixupCommit(commit.Name); isFixup { // Then, for each commit after the fixup, up to and including the // rebase start commit, see if we find the base commit for _, baseCommit := range commits[i+1 : rebaseStartIdx+1] { @@ -1109,33 +1109,6 @@ func countSquashableCommitsAbove(commits []*models.Commit, selectedIdx int, reba return result } -// Check whether the given subject line is the subject of a fixup commit, and -// returns (trimmedSubject, true) if so (where trimmedSubject is the subject -// with all fixup prefixes removed), or (subject, false) if not. -func isFixupCommit(subject string) (string, bool) { - prefixes := []string{"fixup! ", "squash! ", "amend! "} - trimPrefix := func(s string) (string, bool) { - for _, prefix := range prefixes { - if trimmedSubject, ok := strings.CutPrefix(s, prefix); ok { - return trimmedSubject, true - } - } - return s, false - } - - if subject, wasTrimmed := trimPrefix(subject); wasTrimmed { - for { - // handle repeated prefixes like "fixup! amend! fixup! Subject" - if subject, wasTrimmed = trimPrefix(subject); !wasTrimmed { - break - } - } - return subject, true - } - - return subject, false -} - func (self *LocalCommitsController) createTag(commit *models.Commit) error { return self.c.Helpers().Tags.OpenCreateTagPrompt(commit.Hash(), func() {}) } diff --git a/pkg/gui/controllers/local_commits_controller_test.go b/pkg/gui/controllers/local_commits_controller_test.go index d425821d7..c5c5e7a5d 100644 --- a/pkg/gui/controllers/local_commits_controller_test.go +++ b/pkg/gui/controllers/local_commits_controller_test.go @@ -93,49 +93,3 @@ func Test_countSquashableCommitsAbove(t *testing.T) { }) } } - -func Test_isFixupCommit(t *testing.T) { - scenarios := []struct { - subject string - expectedTrimmedSubject string - expectedIsFixup bool - }{ - { - subject: "Bla", - expectedTrimmedSubject: "Bla", - expectedIsFixup: false, - }, - { - subject: "fixup Bla", - expectedTrimmedSubject: "fixup Bla", - expectedIsFixup: false, - }, - { - subject: "fixup! Bla", - expectedTrimmedSubject: "Bla", - expectedIsFixup: true, - }, - { - subject: "fixup! fixup! Bla", - expectedTrimmedSubject: "Bla", - expectedIsFixup: true, - }, - { - subject: "amend! squash! Bla", - expectedTrimmedSubject: "Bla", - expectedIsFixup: true, - }, - { - subject: "fixup!", - expectedTrimmedSubject: "fixup!", - expectedIsFixup: false, - }, - } - for _, s := range scenarios { - t.Run(s.subject, func(t *testing.T) { - trimmedSubject, isFixupCommit := isFixupCommit(s.subject) - assert.Equal(t, s.expectedTrimmedSubject, trimmedSubject) - assert.Equal(t, s.expectedIsFixup, isFixupCommit) - }) - } -}