|
26 | 26 | ErrInvalidArgs = &ExitError{Code: 5} // invalid arguments or flags |
27 | 27 | ErrDisambiguate = &ExitError{Code: 6} // multiple stacks/remotes, can't auto-select |
28 | 28 | ErrRebaseActive = &ExitError{Code: 7} // rebase already in progress |
| 29 | + ErrLockFailed = &ExitError{Code: 8} // could not acquire stack file lock |
29 | 30 | ) |
30 | 31 |
|
31 | 32 | // ExitError is returned by commands to indicate a specific exit code. |
@@ -77,6 +78,9 @@ type loadStackResult struct { |
77 | 78 | // branch, calls resolveStack (which may prompt for disambiguation), checks for |
78 | 79 | // a nil stack, and re-reads the current branch (in case disambiguation caused |
79 | 80 | // 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. |
80 | 84 | func loadStack(cfg *config.Config, branch string) (*loadStackResult, error) { |
81 | 85 | gitDir, err := git.GitDir() |
82 | 86 | if err != nil { |
@@ -133,6 +137,24 @@ func loadStack(cfg *config.Config, branch string) (*loadStackResult, error) { |
133 | 137 | }, nil |
134 | 138 | } |
135 | 139 |
|
| 140 | +// handleSaveError translates a stack.Save error into the appropriate user |
| 141 | +// message and exit error. Lock contention and stale-file detection both |
| 142 | +// return ErrLockFailed (exit 8); 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 |
| 148 | + } |
| 149 | + var staleErr *stack.StaleError |
| 150 | + if errors.As(err, &staleErr) { |
| 151 | + cfg.Errorf("stack file was modified by another process — please re-run the command") |
| 152 | + return ErrLockFailed |
| 153 | + } |
| 154 | + cfg.Errorf("failed to save stack state: %s", err) |
| 155 | + return ErrSilent |
| 156 | +} |
| 157 | + |
136 | 158 | // resolveStack finds the stack for the given branch, handling ambiguity when |
137 | 159 | // a branch (typically a trunk) belongs to multiple stacks. If exactly one |
138 | 160 | // stack matches, it is returned directly. If multiple stacks match, the user |
|
0 commit comments