commit: allow amend of a HEAD commit that the remote does not have #636

Open
opened 2026-09-24 19:58:36 +00:00 by hexajon · 1 comment
Owner

What

This proposal reverses part of legacy tracker 1580, which has no decision record. It does not change ADR 0029.

madtea commit and madt_commit refuse --amend. The CHANGELOG.md entry for legacy tracker 1580 says: "make a new commit instead of rewriting history." The plugin hooks also steer agents off raw git commit. So an agent cannot amend a commit, even a commit that exists only in the local clone.

This hurts most on a repo that merges fast-forward only, like this one. Every branch commit reaches main unchanged. A fix for a mistake in the previous unpushed commit stays on main as a separate commit. I hit this on the branch for #631: its second commit only corrects its first.

Why amend fits the destruction model

  • An amend does not touch the working tree. The old commit stays in the reflog, so it can be recovered.
  • ADR 0029 covers irreversible loss only. It puts recoverable acts out of scope.
  • The CHANGELOG.md entry lists amend with the "irreversible, working-tree-destroying" modes. Amend is neither.
  • madtea's own signing guard (internal/service/git/signing_guard.go:250) tells users to run git commit --amend --no-edit -S.
  • The amend removal lives only in CHANGELOG.md, docs/COMPARISON.md, and code comments.

Proposal

Add an amend option to madtea commit and madt_commit. It runs only when no remote-tracking ref contains HEAD. In every other case it refuses. So an amend never needs a force push.

Costs

  • The check needs fresh remote-tracking refs. A branch pushed from a different clone looks unpushed until a fetch, so the amend must fetch first. That fetch is one more implicit fetch, and #635 describes how an implicit fetch can weaken the push lease.
  • A worktree or branch cut from the old commit stays on the old commit. That is recoverable, but it can confuse.

Acceptance

  • A new decision record accepts or rejects the proposal.
  • If accepted: amend works on an unpushed HEAD and refuses on a pushed HEAD, with a test for each case.
  • If accepted: docs/COMPARISON.md, the help text, and the removed-flag redirect in internal/cmd/git/commit.go match the new behavior.
## What This proposal reverses part of legacy tracker 1580, which has no decision record. It does not change ADR 0029. `madtea commit` and `madt_commit` refuse `--amend`. The `CHANGELOG.md` entry for legacy tracker 1580 says: "make a new commit instead of rewriting history." The plugin hooks also steer agents off raw `git commit`. So an agent cannot amend a commit, even a commit that exists only in the local clone. This hurts most on a repo that merges fast-forward only, like this one. Every branch commit reaches `main` unchanged. A fix for a mistake in the previous unpushed commit stays on `main` as a separate commit. I hit this on the branch for #631: its second commit only corrects its first. ## Why amend fits the destruction model - An amend does not touch the working tree. The old commit stays in the reflog, so it can be recovered. - ADR 0029 covers irreversible loss only. It puts recoverable acts out of scope. - The `CHANGELOG.md` entry lists amend with the "irreversible, working-tree-destroying" modes. Amend is neither. - madtea's own signing guard (`internal/service/git/signing_guard.go:250`) tells users to run `git commit --amend --no-edit -S`. - The amend removal lives only in `CHANGELOG.md`, `docs/COMPARISON.md`, and code comments. ## Proposal Add an amend option to `madtea commit` and `madt_commit`. It runs only when no remote-tracking ref contains HEAD. In every other case it refuses. So an amend never needs a force push. ## Costs - The check needs fresh remote-tracking refs. A branch pushed from a different clone looks unpushed until a fetch, so the amend must fetch first. That fetch is one more implicit fetch, and #635 describes how an implicit fetch can weaken the push lease. - A worktree or branch cut from the old commit stays on the old commit. That is recoverable, but it can confuse. ## Acceptance - A new decision record accepts or rejects the proposal. - If accepted: amend works on an unpushed HEAD and refuses on a pushed HEAD, with a test for each case. - If accepted: `docs/COMPARISON.md`, the help text, and the removed-flag redirect in `internal/cmd/git/commit.go` match the new behavior.
Author
Owner

The main argument in this proposal does not hold. It says an amend is safe because "the old commit stays in the reflog, so it can be recovered". The decision on #635 sets the bar for any operation that can lose work: the proof must show that the work still exists on the remote. A reflog copy exists only in the local clone, so it does not meet that bar.

This proposal needs an argument that meets the #635 bar, or it closes.

The main argument in this proposal does not hold. It says an amend is safe because "the old commit stays in the reflog, so it can be recovered". The decision on #635 sets the bar for any operation that can lose work: the proof must show that the work still exists on the remote. A reflog copy exists only in the local clone, so it does not meet that bar. This proposal needs an argument that meets the #635 bar, or it closes.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sixfold-space/madtea#636
No description provided.