Skip to content
LatchkeyLatchkey home

git revert -n and -m: Safe Undo in Shared History

git revert <commit> records a new commit that reverses the changes of <commit>, the safe undo for shared branches; -n stages without committing and -m reverts a merge.

Unlike reset, revert does not rewrite history, so it is the right tool on branches others have pulled. The flags worth knowing are -n to batch several reverts into one commit and -m to revert a merge at all.

What it does

git revert computes the inverse of a commit and applies it as a new commit, leaving the original in history. -n (--no-commit) applies the inverse to the index/working tree without committing, so you can revert several commits and commit once. -m N reverts a merge relative to parent N.

Common usage

Terminal
git revert abc1234
# revert several commits into one new commit
git revert -n abc1234 def5678
git commit -m "Revert bad batch"
# revert a merge commit (keep the first-parent line)
git revert -m 1 9f8e7d6

Options

FlagWhat it does
-n / --no-commitApply the inverse without creating a commit
-m <parent-number>Revert a merge relative to that parent
--continueResume after resolving conflicts
--abortCancel the in-progress revert
-e / --editEdit the generated commit message
--no-editAccept the default message (good for CI)

In CI

revert needs a committer identity; set git config user.email/user.name in the job. Use --no-edit so it does not block on an editor. Reverting a merge with -m is one-directional: re-merging the same branch later will not re-introduce the changes unless you revert the revert, a common surprise in release pipelines.

Common errors in CI

"error: commit <sha> is a merge but no -m option was given" means add -m 1. "error: could not revert <sha>... after resolving the conflicts" is a conflict; resolve and --continue or --abort. "fatal: empty commit set passed" means the revert produced no change (already reverted).

Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached

Frequently asked questions

git revert -n and -m: Safe Undo in Shared History?
Unlike reset, revert does not rewrite history, so it is the right tool on branches others have pulled. The flags worth knowing are -n to batch several reverts into one commit and -m to revert a merge at all.
What it does?
git revert computes the inverse of a commit and applies it as a new commit, leaving the original in history. -n (--no-commit) applies the inverse to the index/working tree without committing, so you can revert several commits and commit once. -m N reverts a merge relative to parent N.
In CI?
revert needs a committer identity; set git config user.email/user.name in the job. Use --no-edit so it does not block on an editor. Reverting a merge with -m is one-directional: re-merging the same branch later will not re-introduce the changes unless you revert the revert, a common surprise in release pipelines.
Common errors in CI?
"error: commit <sha> is a merge but no -m option was given" means add -m 1. "error: could not revert <sha>... after resolving the conflicts" is a conflict; resolve and --continue or --abort. "fatal: empty commit set passed" means the revert produced no change (already reverted).

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card