@@ -10,9 +10,12 @@ import (
1010 "go.abhg.dev/gs/internal/spice"
1111 "go.abhg.dev/gs/internal/spice/state"
1212 "go.abhg.dev/gs/internal/text"
13+ "go.abhg.dev/gs/internal/ui"
1314)
1415
1516type commitAmendCmd struct {
17+ branchCreateConfig // TODO: find a way to avoid this
18+
1619 All bool `short:"a" help:"Stage all changes before committing."`
1720 AllowEmpty bool `help:"Create a commit even if it contains no changes."`
1821 Message string `short:"m" placeholder:"MSG" help:"Use the given message as the commit message."`
@@ -37,6 +40,8 @@ func (*commitAmendCmd) Help() string {
3740func (cmd * commitAmendCmd ) Run (
3841 ctx context.Context ,
3942 log * silog.Logger ,
43+ view ui.View ,
44+ repo * git.Repository ,
4045 wt * git.Worktree ,
4146 store * state.Store ,
4247 svc * spice.Service ,
@@ -46,6 +51,74 @@ func (cmd *commitAmendCmd) Run(
4651 log .Warn ("flag '-n' is deprecated; use '--no-edit' instead" )
4752 }
4853
54+ var detachedHead bool
55+ currentBranch , err := wt .CurrentBranch (ctx )
56+ if err != nil {
57+ if ! errors .Is (err , git .ErrDetachedHead ) {
58+ return fmt .Errorf ("get current branch: %w" , err )
59+ }
60+ detachedHead = true
61+ currentBranch = ""
62+ }
63+
64+ if currentBranch == store .Trunk () {
65+ if ! ui .Interactive (view ) {
66+ log .Warnf ("You are about to amend a commit on the trunk branch (%v)." , store .Trunk ())
67+ } else {
68+ var (
69+ amendOnTrunk bool
70+ branchName string
71+ )
72+ fields := []ui.Field {
73+ ui .NewList [bool ]().
74+ WithTitle ("Do you want to amend a commit on trunk?" ).
75+ WithDescription (fmt .Sprintf ("You are about to amend a commit on the trunk branch (%v). " +
76+ "This is usually not what you want to do." , store .Trunk ())).
77+ WithItems (
78+ ui.ListItem [bool ]{
79+ Title : "Yes" ,
80+ Description : func (bool ) string {
81+ return "Amend the commit on trunk"
82+ },
83+ Value : true ,
84+ },
85+ ui.ListItem [bool ]{
86+ Title : "No" ,
87+ Description : func (bool ) string {
88+ return "Create a branch and commit there instead"
89+ },
90+ Value : false ,
91+ },
92+ ).
93+ WithValue (& amendOnTrunk ),
94+ ui .Defer (func () ui.Field {
95+ if amendOnTrunk {
96+ return nil
97+ }
98+
99+ return ui .NewInput ().
100+ WithTitle ("Branch name" ).
101+ WithDescription ("What do you want to call the new branch?" ).
102+ WithValue (& branchName )
103+ }),
104+ }
105+ if err := ui .Run (view , fields ... ); err != nil {
106+ return fmt .Errorf ("run prompt: %w" , err )
107+ }
108+ if ! amendOnTrunk {
109+ // TODO: shared commitOptions struct?
110+ return (& branchCreateCmd {
111+ branchCreateConfig : cmd .branchCreateConfig ,
112+ Name : branchName ,
113+ All : cmd .All ,
114+ NoVerify : cmd .NoVerify ,
115+ Message : cmd .Message ,
116+ Commit : true ,
117+ }).Run (ctx , log , repo , wt , store , svc )
118+ }
119+ }
120+ }
121+
49122 if err := wt .Commit (ctx , git.CommitRequest {
50123 Message : cmd .Message ,
51124 AllowEmpty : cmd .AllowEmpty ,
@@ -62,13 +135,9 @@ func (cmd *commitAmendCmd) Run(
62135 return nil
63136 }
64137
65- currentBranch , err := wt .CurrentBranch (ctx )
66- if err != nil {
67- if errors .Is (err , git .ErrDetachedHead ) {
68- log .Debug ("HEAD is detached, skipping restack" )
69- return nil
70- }
71- return fmt .Errorf ("get current branch: %w" , err )
138+ if detachedHead {
139+ log .Debug ("HEAD is detached, skipping restack" )
140+ return nil
72141 }
73142
74143 return (& upstackRestackCmd {
0 commit comments