Git, CI/CD & GitOpsXIV · RevertFoundations
Revert without committing — staging the inverse with `git revert -n`
What you'll learn
- Explain what `git revert -n <commit>` (also `--no-commit`) does to the index and the branch tip
- Identify the production use cases for staging a revert without committing: combining multiple inverses, splitting a revert across commits, and combining a revert with related fixes
- Use `git revert -n` followed by `git commit` to record a single commit that combines the inverses of several commits
- Recognise that `--no-commit` leaves you in a normal working state, not a revert-in-progress state, so `--continue` is not available
- Distinguish `git revert -n` (stage the inverse, no commit) from `git revert --continue` (resume a multi-commit revert after conflict resolution)
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
git revert -n <commit> (also --no-commit) does everything
git revert <commit> does except create the revert commit. It
applies the inverse of <commit> to the working tree, stages the
inverse in the index, and stops. The branch tip does not move. No
commit is created. The engineer is now in a normal working state
with the inverse staged, free to combine it with other changes,
split it into multiple commits, or amend it before recording.
The default git revert workflow assumes one revert equals one
commit. The -n workflow assumes the engineer may want to do
something more interesting: collapse several reverts into one
reviewable commit, combine a revert with a forward fix, or split
a revert into separate logical commits. None of those is possible
without staging without committing first.
The shape of a no-commit revert
git revert -n <commit> runs the three-way merge, applies the
inverse to the working tree, and stages the result. The branch
tip is unchanged. The index contains the inverse; git status
shows the inverse as “Changes to be committed”:
COMMIT=abc1234
git revert -n $COMMIT
git status
# On branch main
# Your branch is up to date with 'origin/main'.
#
# Changes to be committed:
# modified: service.yaml
# modified: iam.tf
# deleted: policies/feature.rego
#
# no changes added to use git commit (use "git add" and/or "git commit -a")
The next command is git commit (or git commit -m "..."),
which records the staged inverse as an ordinary commit. The
commit’s parent is the current branch tip — the same parent it
would have had if git revert <commit> had run without -n. The
only difference is that the engineer has full control over the
commit message and the staging area between the revert and the
commit:
COMMIT=abc1234
git revert -n $COMMIT
git commit -m "Revert \"$ORIGINAL\" due to CVE-2024-XXXX
This reverts commit $COMMIT.
Refs: INC-1234"
The resulting commit is functionally identical to one produced
by git revert <commit> without -n — it has the same parent,
the same tree diff, and the same effect on the tree at HEAD.
The difference is in the workflow that produced it: the engineer
had a chance to inspect, modify, and stage the inverse before
committing.
When to use -n
There are four production workflows where -n is the right
choice:
flowchart LR
A["git revert -n"] --> B["Stage the inverse"]
B --> C{"What next?"}
C -- "single commit" --> D["git commit"]
C -- "combine with fix" --> E["edit, git add, git commit"]
C -- "split into pieces" --> F["git reset, partial git add, multiple commits"]
C -- "combine multiple reverts" --> G["revert -n each, git commit once"]
- Combining multiple reverts into one commit. When several
commits need to be undone as a single logical rollback,
git revert -neach in sequence and thengit commitonce. The result is one revert commit that names multiple original commits in its message, which is easier to review and easier to revert later. - Combining a revert with a forward fix. When the revert is
part of a larger change (for example, reverting a feature and
replacing it with a fixed version),
-nlets you stage the inverse, then stage the fix on top, then commit both as one logical change. The audit trail is one commit, not two. - Splitting a revert into separate commits. When the inverse
touches multiple files that should be reviewed separately,
git revert -nthengit reset(to unstage) thengit add -pto stage hunks selectively. The result is several commits that each revert a logical slice of the original. - Inspecting the inverse before committing. When the original
commit is large or unfamiliar,
-nlets you read the staged diff withgit diff --cachedbefore deciding whether to commit, amend, or discard.
Multi-commit reverts without -n
For contrast: git revert <commit-A> <commit-B> <commit-C>
(default, no -n) creates three separate revert commits in
sequence, stopping for conflict resolution if needed. The first
commit inverts <commit-A>; the second inverts <commit-B>
(applied on top of the first); the third inverts <commit-C>.
Each commit has the default “Revert …” message. The result is
three reviewable, individually revertible commits — but three
separate audit-trail entries, three CI runs, three deployments.
git revert abc1234 def5678 9abcdef
# produces three revert commits, one per original
git revert -n collapses this into one commit:
git revert -n abc1234
git revert -n def5678
git revert -n 9abcdef
git commit -m "Revert feature X (commits abc1234, def5678, 9abcdef)"
# produces one revert commit whose message names all three
The choice between “many small revert commits” and “one combined
revert commit” is a team-policy decision. Small reverts are
easier to revert-of-revert individually; combined reverts are
easier to review and reason about. -n is the tool for the
combined case.
UnderTheHood: what -n actually skips
The default git revert <commit> flow runs the three-way merge,
applies the inverse to the index, creates a commit object with
the staged tree, updates the branch tip to point at the new
commit, and reports the new OID. git revert -n <commit> does
everything except the last two steps. The commit object is never
created; the branch tip is never updated. The internal state
after -n is identical to the internal state after a successful
three-way merge in a git merge workflow: working tree and
index updated, branch tip unchanged, ready for the next commit.
Production discipline
The production discipline for git revert -n has three rules:
- Use
-nwhen the revert must be combined with other changes. A revert that is the only change in a commit should use the default flow; a revert that is part of a larger change (forward fix, multi-commit rollback, split-by-file revert) should use-n. - Write the commit message after staging, not before. The
-nworkflow gives you a chance to inspect the inverse; the commit message should describe what is actually in the index, not what you expected the inverse to be. Usegit diff --cachedto verify before committing. - Do not use
-nto defer the commit indefinitely. A long-lived-nrevert in the index is a revert that has not been audited, reviewed, or deployed. Commit it or discard it; do not leave it staged across multiple sessions.
Cross-course references
- Git, CI/CD & GitOps — Part IX (Three-way merges) — the
three-way merge that produces the inverse is the same merge
that powers
git mergeandgit cherry-pick;-nis a post-merge, pre-commit hook for the result. - Git, CI/CD & GitOps — Part VI (Index) —
-nleaves the inverse in the index; the staging area is the engineer’s workspace for combining the inverse with other changes. - Git, CI/CD & GitOps — Part XIII (Cherry-pick) —
git cherry-pick -n <commit>is the same workflow asgit revert -n <commit>; both stage a patch without committing. - Terraform for Production Sysadmins — Part IX-XII (State) —
when reverting a Terraform-bearing commit,
-nlets you stage the inverse and then add manualterraform stateadjustments to the same commit, producing one rollback commit that addresses both the code and the state.
Quiz
Knowledge check · 4 questions
Q1. An engineer needs to revert three commits (`abc1234`, `def5678`, `9abcdef`) and combine the inverses into a single reviewable commit. What is the cleanest workflow?
Q2. After `git revert -n <commit>`, you are in a revert-in-progress state and must run `git revert --continue` to finish.
Q3. Name the flag that stages the inverse of a commit without creating a commit, and state where the inverse is staged.
Q4. Plan the rollback of a feature that introduced a broken IAM policy, where the rollback must also include a one-line forward fix to an unrelated file that was edited in the same release.
Release `v3.2.0` introduced a broken IAM policy via commit `i4m0a11` and an unrelated typo fix via commit `t1y0o11`. The team needs to roll back the IAM policy but keep the typo fix. The rollback must be a single reviewable commit because the team requires one CI run per rollback.
Passing score: 75%. Answers are checked in this browser.