Skip to content

Report a signing failure from restack's rebase and get past it - #30

Merged
DomBlack merged 1 commit into
undo-create-when-commit-failsfrom
signing-failures-in-restack
Oct 9, 2026
Merged

DomBlack merged 1 commit into
undo-create-when-commit-failsfrom
signing-failures-in-restack

Conversation

@DomBlack

@DomBlack DomBlack commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

The conflict path of a restack is a real git rebase, and a rebase signs every commit it replays, so a key git can't use stops it on the first pick. We read any rebase still in progress after a non-zero exit as a conflict stop, so the user was told to resolve files from merge-tree that weren't conflicted at all, and never that the key needed unlocking. Worse, git won't continue over the failed pick: it leaves the changes staged and says to commit them yourself, so continue was stuck even once the key was loaded.

The rebase outcome now spots git's signing marker and returns the same SigningError commit does. Restack and continue map it to signing_failed with the ssh-add line, and continue and abort as the next steps; the rebase is left where it is so abort still puts the moved branches back. Continue does what git's hint says: when rebase --continue refuses because the failed pick is still staged, it commits it (git keeps the pick's author and message in its own state and then drops the rescheduled pick as already applied) and continues again. Modify's amend already came through the commit path.

While testing this I found commit-tree doesn't honour commit.gpgsign at all, whatever its docs say, so the native replay never needs the key. Its comment claimed the opposite and now says what it actually does.

@DomBlack
DomBlack added this pull request to stack #31 October 9, 2026 16:30
@DomBlack
DomBlack requested a balanced review from Copilot October 9, 2026 16:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The fallback commit can unexpectedly execute hooks that ordinary rebase picks bypass.

1 open finding
What changed in this PR

Adds signing-failure handling and recovery for restack rebases.

Changes:

  • Detects rebase signing failures and returns actionable signing_failed errors.
  • Commits staged failed picks before continuing the rebase.
  • Adds coverage and updates MCP guidance.
File Description
pkg/​git/​rebase.go Detects and recovers rebase signing failures.
pkg/​git/​objects.go Clarifies commit-tree signing behavior.
pkg/​git/​commit_test.go Tests rebase signing recovery.
pkg/​app/​staging.go Maps signing errors to recovery steps.
pkg/​app/​restack.go Applies signing-error mapping during restacks.
pkg/​app/​restack_test.go Tests restack failure, continuation, and abort.
pkg/​app/​mutate_test.go Tests modify signing failures.
pkg/​mcp/​instructions.go Adds MCP recovery guidance.
docs/​mcp.md Documents rebase signing failures.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/git/rebase.go Outdated
Copilot AI balanced review requested due to automatic review settings October 9, 2026 17:00
@DomBlack
DomBlack force-pushed the signing-failures-in-restack branch from fa2577a to c1528fb Compare October 9, 2026 17:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

A non-signing commit-object failure can currently be returned as successful while the rebase remains active.

1 open finding
1 resolved since last review

🧠 Review effort: Balanced

Comment thread pkg/git/rebase.go
Copilot AI balanced review requested due to automatic review settings October 9, 2026 17:17
@DomBlack
DomBlack force-pushed the signing-failures-in-restack branch from c1528fb to 3340de4 Compare October 9, 2026 17:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Signed empty commits can still leave continue stuck as a conflict with no files.

3 open findings
1 resolved since last review

🧠 Review effort: Balanced

Comment thread pkg/git/rebase.go
Comment thread pkg/git/rebase.go Outdated
Comment thread pkg/git/rebase.go
Comment on lines +179 to +180
if se := c.signingError(ctx, repo, stderr); se != nil {
return false, se

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, the type's doc now says what state each path leaves: untouched index from Commit, rebase in progress with the pick staged from a rebase.

The conflict path of a restack is a real git rebase, and a rebase signs every commit it replays, so a key git can't use stops it on the first pick. We read any rebase still in progress after a non-zero exit as a conflict stop, so the user was told to resolve files from merge-tree that weren't conflicted at all, and never that the key needed unlocking. Worse, git won't continue over the failed pick: it leaves the changes staged and says to commit them yourself, so continue was stuck even once the key was loaded.

The rebase outcome now spots git's signing marker and returns the same SigningError commit does. Restack and continue map it to signing_failed with the ssh-add line, and continue and abort as the next steps; the rebase is left where it is so abort still puts the moved branches back. Continue does what git's hint says: when rebase --continue refuses because the failed pick is still staged, it commits it (git keeps the pick's author and message in its own state and then drops the rescheduled pick as already applied) and continues again. Modify's amend already came through the commit path; it now has a test proving it.

While testing this I found commit-tree doesn't honour commit.gpgsign at all, whatever its docs say, so the native replay never needs the key. Its comment claimed the opposite and now says what it actually does.
@DomBlack
DomBlack force-pushed the signing-failures-in-restack branch from 3340de4 to 7de1735 Compare October 9, 2026 17:37
Copilot AI balanced review requested due to automatic review settings October 9, 2026 17:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approved

The implementation correctly distinguishes signing failures, preserves recovery state, and includes focused end-to-end coverage.

1 open finding
2 resolved since last review

🧠 Review effort: Balanced

@DomBlack
DomBlack merged commit b794117 into main Oct 9, 2026
6 checks passed
@DomBlack
DomBlack deleted the signing-failures-in-restack branch October 9, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants