Skip to content

pr-git-2389/newren/refuse-amend-during-conflicts-v1

tagged this 26 Aug 05:21
From: Elijah Newren <newren@gmail.com>

Running `git commit --amend` during conflict resolution is an ugly
foot-gun.  For many years, we have rejected amending during conflict
resolution in the middle of
  - a merge
  - a cherry-pick
However, this was never extended to other operations that can also
produce conflicts:
  - an `am` operation
  - a revert
  - a rebase

Extend it to handle these other cases now.

Extending to `am`, revert, and the apply backend of rebase are fairly
straightforward.  However, with the merge backend of rebase we have to
be more careful, since it powers interactive rebases and
  - the interactive machinery internally uses `git commit --amend` for
    `squash` and `reword` directives
  - users are expected to `git commit --amend` after hitting an `edit`
    or `break` directive
So, we need to be careful with rebase to only reject amending when doing
conflict resolution.

A few files under the rebase-merge/ directory provide us the necessary
information:

  - stopped-sha is written only when the rebase stops and hands control
    back to the user, so its presence marks a genuine stop -- as opposed
    to the sequencer's own internal `git commit --amend` while applying
    a squash, fixup, or reword, during which no stopped-sha exists.

  - amend is written only when the rebase stops with HEAD already
    pointing at the commit the user is meant to amend: a clean `edit`,
    or a fast-forward `reword`.  Its absence at a stop therefore means
    the commit did not apply, so HEAD is the previously-applied commit
    rather than the one being rebased -- exactly the case we refuse.

So for the merge backend we die when stopped-sha exists and amend does
not.  This covers a plain conflicted pick as well as a conflicted `edit`
(both leave HEAD on the previously-applied commit), while still allowing
a clean `edit` or `reword` stop and a `break` stop (no stopped-sha).
stopped-sha is unlinked at the start of the resume loop, so a resumed
squash's internal amend is unaffected.

Signed-off-by: Elijah Newren <newren@gmail.com>

Submitted-As: https://lore.kernel.org/git/pull.2389.git.git.1787721681893.gitgitgadget@gmail.com
Assets 2
Loading