@@ -71,34 +71,23 @@ type loadStackResult struct {
7171 StackFile * stack.StackFile
7272 Stack * stack.Stack
7373 CurrentBranch string
74- Lock * stack.FileLock // caller must defer Lock.Unlock() if non-nil
7574}
7675
7776// loadStack is the standard way to obtain a Stack for the current (or given)
7877// branch. It resolves the git directory, loads the stack file, determines the
7978// branch, calls resolveStack (which may prompt for disambiguation), checks for
8079// a nil stack, and re-reads the current branch (in case disambiguation caused
8180// a checkout). Errors are printed via cfg and returned.
81+ //
82+ // loadStack does NOT acquire the stack file lock. The lock is acquired
83+ // automatically by stack.Save() when writing.
8284func loadStack (cfg * config.Config , branch string ) (* loadStackResult , error ) {
8385 gitDir , err := git .GitDir ()
8486 if err != nil {
8587 cfg .Errorf ("not a git repository" )
8688 return nil , fmt .Errorf ("not a git repository" )
8789 }
8890
89- lock , err := stack .Lock (gitDir )
90- if err != nil {
91- cfg .Errorf ("another process is currently editing the stack — try again later" )
92- return nil , ErrLockFailed
93- }
94- // Release the lock if we fail before returning it to the caller.
95- success := false
96- defer func () {
97- if ! success {
98- lock .Unlock ()
99- }
100- }()
101-
10291 sf , err := stack .Load (gitDir )
10392 if err != nil {
10493 cfg .Errorf ("failed to load stack state: %s" , err )
@@ -140,71 +129,25 @@ func loadStack(cfg *config.Config, branch string) (*loadStackResult, error) {
140129 return nil , fmt .Errorf ("failed to get current branch: %w" , err )
141130 }
142131
143- success = true
144132 return & loadStackResult {
145133 GitDir : gitDir ,
146134 StackFile : sf ,
147135 Stack : s ,
148136 CurrentBranch : currentBranch ,
149- Lock : lock ,
150137 }, nil
151138}
152139
153- // loadStackReadOnly loads the stack without acquiring an exclusive lock.
154- // Use this for commands that only read the stack and never call Save().
155- func loadStackReadOnly (cfg * config.Config , branch string ) (* loadStackResult , error ) {
156- gitDir , err := git .GitDir ()
157- if err != nil {
158- cfg .Errorf ("not a git repository" )
159- return nil , fmt .Errorf ("not a git repository" )
160- }
161-
162- sf , err := stack .Load (gitDir )
163- if err != nil {
164- cfg .Errorf ("failed to load stack state: %s" , err )
165- return nil , fmt .Errorf ("failed to load stack state: %w" , err )
166- }
167-
168- branchFromArg := branch != ""
169- if branch == "" {
170- branch , err = git .CurrentBranch ()
171- if err != nil {
172- cfg .Errorf ("failed to get current branch: %s" , err )
173- return nil , fmt .Errorf ("failed to get current branch: %w" , err )
174- }
175- }
176-
177- s , err := resolveStack (sf , branch , cfg )
178- if err != nil {
179- if errors .Is (err , errInterrupt ) {
180- return nil , errInterrupt
181- }
182- cfg .Errorf ("%s" , err )
183- return nil , err
184- }
185- if s == nil {
186- if branchFromArg {
187- cfg .Errorf ("branch %q is not part of a stack" , branch )
188- } else {
189- cfg .Errorf ("current branch %q is not part of a stack" , branch )
190- }
191- cfg .Printf ("Checkout an existing stack using `%s` or create a new stack using `%s`" ,
192- cfg .ColorCyan ("gh stack checkout" ), cfg .ColorCyan ("gh stack init" ))
193- return nil , fmt .Errorf ("branch %q is not part of a stack" , branch )
194- }
195-
196- currentBranch , err := git .CurrentBranch ()
197- if err != nil {
198- cfg .Errorf ("failed to get current branch: %s" , err )
199- return nil , fmt .Errorf ("failed to get current branch: %w" , err )
140+ // handleSaveError translates a stack.Save error into the appropriate user
141+ // message and exit error. Lock failures return ErrLockFailed (exit 8);
142+ // other write failures return ErrSilent (exit 1).
143+ func handleSaveError (cfg * config.Config , err error ) error {
144+ var lockErr * stack.LockError
145+ if errors .As (err , & lockErr ) {
146+ cfg .Errorf ("another process is currently editing the stack — try again later" )
147+ return ErrLockFailed
200148 }
201-
202- return & loadStackResult {
203- GitDir : gitDir ,
204- StackFile : sf ,
205- Stack : s ,
206- CurrentBranch : currentBranch ,
207- }, nil
149+ cfg .Errorf ("failed to save stack state: %s" , err )
150+ return ErrSilent
208151}
209152
210153// resolveStack finds the stack for the given branch, handling ambiguity when
0 commit comments