In Git, why is amending an already-pushed commit riskier than amending a local one?
answer
- who else already holds a copy
- the remote still has the original
- push refuses non-fast-forward updates
- teammates can drag the old commit back
- prefer an append-only correction
basics
~20 sAmending replaces a commit with a new object. If the original was pushed, it still exists on the remote and in every clone that fetched it, so your branch and the remote now diverge, a normal push is rejected, and teammates can reintroduce the old commit.
solid answer
~50 sAmending a local commit is invisible to everyone — you replace an object nobody else has and move your branch. Once the commit is published, three things change. The remote still holds the original, so your branch and `origin/<branch>` have diverged at that point and a plain `git push` is rejected as a non-fast-forward. Every clone that fetched the original still has it, and any teammate who committed on top of it will drag it back in on their next merge, leaving duplicated changes with two SHAs. And anything that referenced the old SHA — a note in a ticket, a build record, another branch — now points at a commit that is no longer on the branch. Republishing needs a force update, whose safety mechanics are a topic of their own. The working rule: freely amend what you have not shared; coordinate before rewriting what you have.
code
console · 4 lines$ git commit --amend --no-edit
$ git push
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'origin'go deeper
Know the rule: amend freely before you push, and stop to think once the commit has been shared, because other clones already have the original.
Explain the mechanism — the amended commit is a sibling rather than a descendant, so the push is refused as non-fast-forward, and the remote keeps the original until forced.
Walk through the collaborator failure mode concretely: duplicated commits after their next pull, conflicts, and a manual rebase to recover. Name the append-only alternatives you would prefer.
Set the policy: which branches are rewritable by convention, how that is communicated, and why an unbounded number of clones makes rewriting a shared mainline an organisational cost rather than a technical one.
## The asymmetry A local amend is a private edit to a private ref. You create a replacement commit, move your branch, and the old object lingers in your reflog. Nobody else can observe any of it, so nothing can go wrong beyond your own recovery, which the reflog covers. A published commit is different in kind, not degree, because copies exist that you cannot reach. Git has no mechanism to recall an object from a clone or to tell a remote "this commit was replaced". The amend only changes what **your** branch points at. ## Consequence 1: your push is rejected Git accepts a push only when the new tip is a descendant of the old one — a fast-forward. After an amend, the remote's tip is the original commit and your tip is a sibling of it: both share the same parent, neither is an ancestor of the other. The push is refused as non-fast-forward. That rejection is a safety feature: it is Git telling you that accepting your update would drop a commit the remote currently has. The only way forward is a force update of the branch, which overwrites the remote ref. That is a deliberate act with its own safety mechanics and flags, covered as its own subject. ## Consequence 2: colleagues reintroduce the old commit Suppose a teammate fetched the original commit `A` and built `B` on top of it. You amend `A` into `A'` and force-update the branch. Their next pull now merges a history containing `A` and `B` with a history containing `A'`. The merge succeeds — Git has no idea `A` and `A'` are meant to be the same change — and the result contains **both**, so the branch carries the same content twice under different SHAs, plus a good chance of conflicts because the two versions touch the same lines. Cleaning that up means someone has to rebase or reset their work onto the new tip, which is a conversation, not a command. ## Consequence 3: stale references SHAs get quoted in places Git does not control: a comment on a ticket, a deployment log, a message in chat, a tag or another branch you created for safety, an annotation in an incident write-up. After the rewrite those SHAs still resolve locally for a while, because the objects are not deleted, but they name a commit no longer on the branch. Anyone following the link sees history that appears to have vanished. ## What makes it acceptable anyway Rewriting published history is not forbidden; it is a coordination cost you should be able to pay. It is routine and low risk when: - The branch is a personal feature branch nobody else builds on. Publishing it is a backup and a review vehicle, not a shared base. - The team has agreed that such branches may be rewritten, so nobody expects their local copy to be a stable base. - You announce it if anyone could plausibly have pulled. It is unacceptable on shared long-lived branches — the mainline, a release branch — because the number of clones that hold the old commit is unbounded and the cleanup cost is paid by everyone. ## How to avoid needing it - Amend before you push, not after. A fixup commit recorded now and collapsed by a rebase just before publishing gives you a clean series without touching anything shared. - When a published commit is wrong, prefer a new commit that corrects it, or a revert. Both are append-only: every clone converges by fast-forward and no coordination is needed. - Reserve rewrites of published history for cases where the content itself must not remain in the history — and even then treat exposed material as compromised regardless, since copies already exist. ## Interview framing A strong answer distinguishes the two situations by *who else holds a copy*, names the non-fast-forward rejection as the mechanism you actually hit, and describes the duplicate-commit failure mode concretely. Saying "just force push" without naming the coordination cost is the weak answer interviewers are listening for.
- What exactly happens to a teammate who already based a commit on the original?Their clone still contains the original commit and their work descends from it. Pulling after your rewrite merges two histories Git sees as unrelated changes, so both versions of the same work end up in the branch, usually with conflicts. Recovery means they rebase or reset their commits onto the new tip — a coordination step, not something Git resolves automatically.
- When is amending a pushed commit genuinely fine?When the branch is a personal one that nobody uses as a base and the team has agreed such branches are rewritable — typically a review branch you own. It is not fine on the mainline or a release branch, where an unbounded number of clones hold the original and every one of them pays the cleanup cost.
- What is the append-only alternative to rewriting a published commit?Commit the correction on top, or use a revert to add a commit that undoes the bad one. Both leave existing objects reachable, so every clone converges by fast-forward with no force update and no coordination. The history records that a mistake was made and fixed, which is usually honest rather than embarrassing.
saying these in an interview costs you the question
- Says a force push makes the problem go away
- Thinks the remote deletes the original commit automatically
- Assumes the local reflog protects teammates
- Believes Git recognises the old and new commit as the same change
- Treats mainline and personal branches as equally rewritable