Skip to content

Commit d5f6460

Browse files
Merge pull request #283 from kristijanhusak/feature/commit-amend
Add action for amending a commit
2 parents b8b59ba + 4287f8a commit d5f6460

File tree

8 files changed

+141
-13
lines changed

8 files changed

+141
-13
lines changed

pkg/commands/git.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,11 @@ func (c *GitCommand) ResetHard() error {
221221
// UpstreamDifferenceCount checks how many pushables/pullables there are for the
222222
// current branch
223223
func (c *GitCommand) UpstreamDifferenceCount() (string, string) {
224-
pushableCount, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..head --count")
224+
pushableCount, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..HEAD --count")
225225
if err != nil {
226226
return "?", "?"
227227
}
228-
pullableCount, err := c.OSCommand.RunCommandWithOutput("git rev-list head..@{u} --count")
228+
pullableCount, err := c.OSCommand.RunCommandWithOutput("git rev-list HEAD..@{u} --count")
229229
if err != nil {
230230
return "?", "?"
231231
}
@@ -236,7 +236,7 @@ func (c *GitCommand) UpstreamDifferenceCount() (string, string) {
236236
// to the remote branch of the current branch, a map is returned to ease look up
237237
func (c *GitCommand) GetCommitsToPush() map[string]bool {
238238
pushables := map[string]bool{}
239-
o, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..head --abbrev-commit")
239+
o, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..HEAD --abbrev-commit")
240240
if err != nil {
241241
return pushables
242242
}
@@ -314,8 +314,12 @@ func (c *GitCommand) usingGpg() bool {
314314
}
315315

316316
// Commit commits to git
317-
func (c *GitCommand) Commit(message string) (*exec.Cmd, error) {
318-
command := fmt.Sprintf("git commit -m %s", c.OSCommand.Quote(message))
317+
func (c *GitCommand) Commit(message string, amend bool) (*exec.Cmd, error) {
318+
amendParam := ""
319+
if amend {
320+
amendParam = " --amend"
321+
}
322+
command := fmt.Sprintf("git commit%s -m %s", amendParam, c.OSCommand.Quote(message))
319323
if c.usingGpg() {
320324
return c.OSCommand.PrepareSubProcess(c.OSCommand.Platform.shell, c.OSCommand.Platform.shellArg, command), nil
321325
}

pkg/commands/git_test.go

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ func TestGitCommandUpstreamDifferentCount(t *testing.T) {
561561
{
562562
"Can't retrieve pullable count",
563563
func(cmd string, args ...string) *exec.Cmd {
564-
if args[1] == "head..@{u}" {
564+
if args[1] == "HEAD..@{u}" {
565565
return exec.Command("test")
566566
}
567567

@@ -575,7 +575,7 @@ func TestGitCommandUpstreamDifferentCount(t *testing.T) {
575575
{
576576
"Retrieve pullable and pushable count",
577577
func(cmd string, args ...string) *exec.Cmd {
578-
if args[1] == "head..@{u}" {
578+
if args[1] == "HEAD..@{u}" {
579579
return exec.Command("echo", "10")
580580
}
581581

@@ -889,7 +889,76 @@ func TestGitCommandCommit(t *testing.T) {
889889
gitCmd := newDummyGitCommand()
890890
gitCmd.getGlobalGitConfig = s.getGlobalGitConfig
891891
gitCmd.OSCommand.command = s.command
892-
s.test(gitCmd.Commit("test"))
892+
s.test(gitCmd.Commit("test", false))
893+
})
894+
}
895+
}
896+
897+
func TestGitCommandCommitAmendFromFiles(t *testing.T) {
898+
type scenario struct {
899+
testName string
900+
command func(string, ...string) *exec.Cmd
901+
getGlobalGitConfig func(string) (string, error)
902+
test func(*exec.Cmd, error)
903+
}
904+
905+
scenarios := []scenario{
906+
{
907+
"Amend commit using gpg",
908+
func(cmd string, args ...string) *exec.Cmd {
909+
assert.EqualValues(t, "bash", cmd)
910+
assert.EqualValues(t, []string{"-c", `git commit --amend -m 'test'`}, args)
911+
912+
return exec.Command("echo")
913+
},
914+
func(string) (string, error) {
915+
return "true", nil
916+
},
917+
func(cmd *exec.Cmd, err error) {
918+
assert.NotNil(t, cmd)
919+
assert.Nil(t, err)
920+
},
921+
},
922+
{
923+
"Amend commit without using gpg",
924+
func(cmd string, args ...string) *exec.Cmd {
925+
assert.EqualValues(t, "git", cmd)
926+
assert.EqualValues(t, []string{"commit", "--amend", "-m", "test"}, args)
927+
928+
return exec.Command("echo")
929+
},
930+
func(string) (string, error) {
931+
return "false", nil
932+
},
933+
func(cmd *exec.Cmd, err error) {
934+
assert.Nil(t, cmd)
935+
assert.Nil(t, err)
936+
},
937+
},
938+
{
939+
"Amend commit without using gpg with an error",
940+
func(cmd string, args ...string) *exec.Cmd {
941+
assert.EqualValues(t, "git", cmd)
942+
assert.EqualValues(t, []string{"commit", "--amend", "-m", "test"}, args)
943+
944+
return exec.Command("test")
945+
},
946+
func(string) (string, error) {
947+
return "false", nil
948+
},
949+
func(cmd *exec.Cmd, err error) {
950+
assert.Nil(t, cmd)
951+
assert.Error(t, err)
952+
},
953+
},
954+
}
955+
956+
for _, s := range scenarios {
957+
t.Run(s.testName, func(t *testing.T) {
958+
gitCmd := newDummyGitCommand()
959+
gitCmd.getGlobalGitConfig = s.getGlobalGitConfig
960+
gitCmd.OSCommand.command = s.command
961+
s.test(gitCmd.Commit("test", true))
893962
})
894963
}
895964
}
@@ -1507,7 +1576,7 @@ func TestGitCommandGetCommits(t *testing.T) {
15071576

15081577
switch args[0] {
15091578
case "rev-list":
1510-
assert.EqualValues(t, []string{"rev-list", "@{u}..head", "--abbrev-commit"}, args)
1579+
assert.EqualValues(t, []string{"rev-list", "@{u}..HEAD", "--abbrev-commit"}, args)
15111580
return exec.Command("echo")
15121581
case "log":
15131582
assert.EqualValues(t, []string{"log", "--oneline", "-30"}, args)
@@ -1534,7 +1603,7 @@ func TestGitCommandGetCommits(t *testing.T) {
15341603

15351604
switch args[0] {
15361605
case "rev-list":
1537-
assert.EqualValues(t, []string{"rev-list", "@{u}..head", "--abbrev-commit"}, args)
1606+
assert.EqualValues(t, []string{"rev-list", "@{u}..HEAD", "--abbrev-commit"}, args)
15381607
return exec.Command("echo", "8a2bb0e")
15391608
case "log":
15401609
assert.EqualValues(t, []string{"log", "--oneline", "-30"}, args)
@@ -1577,7 +1646,7 @@ func TestGitCommandGetCommits(t *testing.T) {
15771646

15781647
switch args[0] {
15791648
case "rev-list":
1580-
assert.EqualValues(t, []string{"rev-list", "@{u}..head", "--abbrev-commit"}, args)
1649+
assert.EqualValues(t, []string{"rev-list", "@{u}..HEAD", "--abbrev-commit"}, args)
15811650
return exec.Command("echo", "8a2bb0e")
15821651
case "log":
15831652
assert.EqualValues(t, []string{"log", "--oneline", "-30"}, args)

pkg/gui/commit_message_panel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func (gui *Gui) handleCommitConfirm(g *gocui.Gui, v *gocui.View) error {
1212
if message == "" {
1313
return gui.createErrorPanel(g, gui.Tr.SLocalize("CommitWithoutMessageErr"))
1414
}
15-
sub, err := gui.GitCommand.Commit(message)
15+
sub, err := gui.GitCommand.Commit(message, false)
1616
if err != nil {
1717
// TODO need to find a way to send through this error
1818
if err != gui.Errors.ErrSubProcess {

pkg/gui/files_panel.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,28 @@ func (gui *Gui) handleCommitPress(g *gocui.Gui, filesView *gocui.View) error {
211211
return nil
212212
}
213213

214+
func (gui *Gui) handleAmendCommitPress(g *gocui.Gui, filesView *gocui.View) error {
215+
if len(gui.stagedFiles()) == 0 && !gui.State.HasMergeConflicts {
216+
return gui.createErrorPanel(g, gui.Tr.SLocalize("NoStagedFilesToCommit"))
217+
}
218+
title := strings.Title(gui.Tr.SLocalize("AmendLastCommit"))
219+
question := gui.Tr.SLocalize("SureToAmend")
220+
221+
if len(gui.State.Commits) == 0 {
222+
return gui.createErrorPanel(g, gui.Tr.SLocalize("NoCommitToAmend"))
223+
}
224+
225+
return gui.createConfirmationPanel(g, filesView, title, question, func(g *gocui.Gui, v *gocui.View) error {
226+
lastCommitMsg := gui.State.Commits[0].Name
227+
_, err := gui.GitCommand.Commit(lastCommitMsg, true)
228+
if err != nil {
229+
return gui.createErrorPanel(g, err.Error())
230+
}
231+
232+
return gui.refreshSidePanels(g)
233+
}, nil)
234+
}
235+
214236
// handleCommitEditorPress - handle when the user wants to commit changes via
215237
// their editor rather than via the popup panel
216238
func (gui *Gui) handleCommitEditorPress(g *gocui.Gui, filesView *gocui.View) error {

pkg/gui/keybindings.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ func (gui *Gui) GetKeybindings() []*Binding {
125125
Modifier: gocui.ModNone,
126126
Handler: gui.handleCommitPress,
127127
Description: gui.Tr.SLocalize("CommitChanges"),
128+
}, {
129+
ViewName: "files",
130+
Key: 'A',
131+
Modifier: gocui.ModNone,
132+
Handler: gui.handleAmendCommitPress,
133+
Description: gui.Tr.SLocalize("AmendLastCommit"),
128134
}, {
129135
ViewName: "files",
130136
Key: 'C',
@@ -182,7 +188,7 @@ func (gui *Gui) GetKeybindings() []*Binding {
182188
Description: gui.Tr.SLocalize("stashFiles"),
183189
}, {
184190
ViewName: "files",
185-
Key: 'A',
191+
Key: 'M',
186192
Modifier: gocui.ModNone,
187193
Handler: gui.handleAbortMerge,
188194
Description: gui.Tr.SLocalize("abortMerge"),

pkg/i18n/dutch.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ func addDutch(i18nObject *i18n.Bundle) error {
3434
}, &i18n.Message{
3535
ID: "CommitChanges",
3636
Other: "Commit Veranderingen",
37+
}, &i18n.Message{
38+
ID: "AmendLastCommit",
39+
Other: "wijzig laatste commit",
40+
}, &i18n.Message{
41+
ID: "SureToAmend",
42+
Other: "Weet je zeker dat je de laatste commit wilt wijzigen? U kunt het commit-bericht wijzigen vanuit het commits-paneel.",
43+
}, &i18n.Message{
44+
ID: "NoCommitToAmend",
45+
Other: "Er is geen verplichting om te wijzigen.",
3746
}, &i18n.Message{
3847
ID: "CommitChangesWithEditor",
3948
Other: "commit Veranderingen met de git editor",

pkg/i18n/english.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ func addEnglish(i18nObject *i18n.Bundle) error {
4242
}, &i18n.Message{
4343
ID: "CommitChanges",
4444
Other: "commit changes",
45+
}, &i18n.Message{
46+
ID: "AmendLastCommit",
47+
Other: "amend last commit",
48+
}, &i18n.Message{
49+
ID: "SureToAmend",
50+
Other: "Are you sure you want to amend last commit? You can change commit message from commits panel.",
51+
}, &i18n.Message{
52+
ID: "NoCommitToAmend",
53+
Other: "There's no commit to amend.",
4554
}, &i18n.Message{
4655
ID: "CommitChangesWithEditor",
4756
Other: "commit changes using git editor",

pkg/i18n/polish.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ func addPolish(i18nObject *i18n.Bundle) error {
3232
}, &i18n.Message{
3333
ID: "CommitChanges",
3434
Other: "commituj zmiany",
35+
}, &i18n.Message{
36+
ID: "AmendLastCommit",
37+
Other: "zmień ostatnie zatwierdzenie",
38+
}, &i18n.Message{
39+
ID: "SureToAmend",
40+
Other: "Czy na pewno chcesz zmienić ostatnie zatwierdzenie? Możesz zmienić komunikat zatwierdzenia z panelu zatwierdzeń.",
41+
}, &i18n.Message{
42+
ID: "NoCommitToAmend",
43+
Other: "Nie ma zobowiązania do zmiany.",
3544
}, &i18n.Message{
3645
ID: "CommitChangesWithEditor",
3746
Other: "commituj zmiany używając edytora z gita",

0 commit comments

Comments
 (0)