Skip to content

fix(stack): keep squash --message temp file alive across rebase conflicts#1386

Draft
jd wants to merge 1 commit intomainfrom
devs/jd/fix/squash-msg-file-conflict/keep-squash-msg-temp-file-alive-across-rebase--a026b5b6
Draft

fix(stack): keep squash --message temp file alive across rebase conflicts#1386
jd wants to merge 1 commit intomainfrom
devs/jd/fix/squash-msg-file-conflict/keep-squash-msg-temp-file-alive-across-rebase--a026b5b6

Conversation

@jd
Copy link
Copy Markdown
Member

@jd jd commented May 7, 2026

stack_squash with -m writes the new commit message to a temp file
and inserts an exec git commit --amend -F <tmpfile> line in the
rebase todo. The previous code wrapped the rebase in try/finally so
the temp file was unlinked even when the rebase failed mid-way (e.g.
conflicts on a fixup line that runs before the exec). After the user
resolved conflicts and ran git rebase --continue, git would replay
the exec line and fail because the message file no longer existed.

Drop the finally; only unlink on the success path. If the rebase
raises SystemExit, the file persists so --continue can still execute
the amend. The temp file lives in /tmp and gets cleaned by the OS.

Same pattern (and same fix) as stack_reword — flagged by Copilot on

#1384 review.

…icts

`stack_squash` with `-m` writes the new commit message to a temp file
and inserts an `exec git commit --amend -F <tmpfile>` line in the
rebase todo. The previous code wrapped the rebase in `try/finally` so
the temp file was unlinked even when the rebase failed mid-way (e.g.
conflicts on a fixup line that runs before the exec). After the user
resolved conflicts and ran `git rebase --continue`, git would replay
the exec line and fail because the message file no longer existed.

Drop the `finally`; only unlink on the success path. If the rebase
raises SystemExit, the file persists so `--continue` can still execute
the amend. The temp file lives in `/tmp` and gets cleaned by the OS.

Same pattern (and same fix) as `stack_reword` — flagged by Copilot on

Change-Id: Ia026b5b631ed043a03983beec5ca81fd29f77633
#1384 review.
Copilot AI review requested due to automatic review settings May 7, 2026 18:33
@mergify mergify Bot had a problem deploying to Mergify Merge Protections May 7, 2026 18:33 Failure
@jd jd deployed to func-tests-live May 7, 2026 18:33 — with GitHub Actions Active
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 7, 2026

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🔴 👀 Review Requirements

Waiting for

  • #approved-reviews-by>=2
This rule is failing.
  • any of:
    • #approved-reviews-by>=2
    • author = dependabot[bot]
    • author = mergify-ci-bot
    • author = renovate[bot]

🔴 🔎 Reviews

Waiting for

  • #review-requested = 0
  • #review-threads-unresolved = 0
This rule is failing.
  • #review-requested = 0
  • #review-threads-unresolved = 0
  • #changes-requested-reviews-by = 0

🟢 🤖 Continuous Integration

Wonderful, this rule succeeded.
  • all of:
    • check-success=ci-gate

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?:

🟢 📕 PR description

Wonderful, this rule succeeded.
  • body ~= (?ms:.{48,})

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adjusts stack_squash -m/--message to avoid deleting the temporary commit-message file when an interactive rebase stops mid-way (e.g., due to conflicts), so git rebase --continue can still replay the inserted exec git commit --amend -F <tmpfile> line successfully.

Changes:

  • Removes the try/finally cleanup around the temp message file in stack_squash.
  • Unlinks the temp message file only after a successful run_action_rebase completion.
  • Adds inline rationale explaining why the file must persist across conflict-driven rebase interruptions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# SystemExit (conflicts), the rebase-todo still references this
# file, so `git rebase --continue` will need it to complete the
# `exec git commit --amend -F …` line. Leak the file rather than
# break --continue; /tmp gets cleaned by the OS.
Comment on lines 152 to +167
msg_fd, msg_path = tempfile.mkstemp(suffix=".txt", prefix="mergify_squash_msg_")
try:
with os.fdopen(msg_fd, "w") as f:
f.write(message)
run_action_rebase(
base,
new_shas,
actions,
exec_after_sha=src_shas[-1],
exec_command=f"git commit --amend -F {shlex.quote(msg_path)}",
)
finally:
pathlib.Path(msg_path).unlink(missing_ok=True)
with os.fdopen(msg_fd, "w") as f:
f.write(message)
# Intentionally NOT in a `finally`: if `run_action_rebase` raises
# SystemExit (conflicts), the rebase-todo still references this
# file, so `git rebase --continue` will need it to complete the
# `exec git commit --amend -F …` line. Leak the file rather than
# break --continue; /tmp gets cleaned by the OS.
run_action_rebase(
base,
new_shas,
actions,
exec_after_sha=src_shas[-1],
exec_command=f"git commit --amend -F {shlex.quote(msg_path)}",
)
pathlib.Path(msg_path).unlink(missing_ok=True)
@mergify mergify Bot requested a review from a team May 7, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants