|$ curl https://forge-ai.dev/api/markdown?path=docs/git/revert
$cat docs/git-revert.md
updated Today·20-28 min read·published

Git Revert

GitRevertHistoryIntermediate🎯Free Tools
Introduction

Revert creates a new commit that applies the inverse of a previous commit. It is the safe way to undo changes that already exist on shared branches — no history rewrite.

best practice

Prefer revert over reset for anything already pushed to main. See Reset & Restore for local-only undos.
Basic Revert
basic.sh
Bash
1git log --oneline -5
2git revert abc1234 --no-edit
3git push
4
5# Revert without committing immediately
6git revert -n abc1234
7git diff --staged
8git commit -m "revert: undo abc1234 pricing bug"
Reverting Multiple Commits
range.sh
Bash
1# Revert newest first to reduce conflicts
2git revert --no-edit def5678
3git revert --no-edit abc1234
4
5# Or a range (parent of oldest..newest)
6git revert --no-edit abc1234^..def5678
7
8# Abort
9git revert --abort
Reverting Merge Commits (-m)

A merge commit has multiple parents. -m tells Git which parent line is 'mainline' to revert relative to. Usually -m 1 (the branch you merged into).

revert-merge.sh
Bash
1# Find merge commit
2git log --oneline --merges -5
3git show --format=fuller MERGE_SHA
4
5# Revert the merge, keeping first parent as mainline
6git revert -m 1 MERGE_SHA --no-edit
7
8# IMPORTANT: re-merging the same branch later needs care
9# (Git thinks changes are already present). Options:
10# 1) revert the revert
11# 2) rebase feature onto new main and merge fresh

danger

After reverting a merge, you cannot simply merge the same branch again and expect Git to re-apply those changes. Revert the revert or recreate commits.
Conflicts During Revert
conflicts.sh
Bash
1git revert abc1234
2# conflict — resolve files
3git add -A
4git revert --continue
5# or
6git revert --abort
Revert vs Reset vs Checkout
ToolRewrites history?Use on main?
revertNo — adds commitYes
resetYes — moves tipOnly if unpublished
restoreNo — file levelYes for uncommitted
Hands-on Lab
lab-revert.sh
Bash
1rm -rf /tmp/revert-lab && mkdir /tmp/revert-lab && cd /tmp/revert-lab
2git init -b main
3echo v1 > app.txt && git add app.txt && git commit -m "v1"
4echo v2 > app.txt && git commit -am "v2 bad"
5echo v3 > app.txt && git commit -am "v3"
6git revert --no-edit HEAD~1
7cat app.txt # should be v1 content after reverting v2? careful with later commits
8git log --oneline
FAQ

Common questions.

Will revert delete the old commit?

No — history still contains it; a new inverse commit is added.

Can I revert a revert?

Yes — that restores the original changes.

Squash merge then revert?

Revert the squash commit on main as a normal single-parent commit.

Notes for AI Agents
  • Default to revert for published undos
  • For merges always specify -m 1 unless user says otherwise
  • Explain re-merge caveats after merge reverts
  • Never reset --hard origin/main to 'undo' a bad deploy on shared history
🔥

pro tip

Curriculum: How to Master Git.
Worked Examples

These end-to-end examples reinforce the revert concepts above. Run them in a disposable lab under /tmp so mistakes are cheap.

Example A — happy path

example-a.sh
Bash
1# Lab for revert
2rm -rf /tmp/git-lab-revert && mkdir -p /tmp/git-lab-revert
3cd /tmp/git-lab-revert
4git init -b main
5git config user.email "lab@example.com"
6git config user.name "Lab User"
7echo "# lab" > README.md
8git add README.md
9git commit -m "chore: init lab for revert"
10git status -sb
11git log --oneline --decorate

Example B — recover from a mistake

example-b.sh
Bash
1# Make a bad commit, then recover safely
2echo bad > oops.txt
3git add oops.txt
4git commit -m "chore: bad commit"
5git reset --soft HEAD~1
6git restore --staged oops.txt
7rm oops.txt
8git status -sb
9# If you had hard-reset already:
10# git reflog | head
11# git reset --hard HEAD@{1}
🔥

pro tip

Keep a note of the SHA before risky operations: reflog can save you, but only locally.
Troubleshooting

Symptoms you will hit in real repos, and the first commands to run.

Unexpected dirty tree

trouble-dirty.sh
Bash
1git status -sb
2git diff
3git diff --staged
4git stash list
5# Discard one file:
6git restore path/to/file
7# Unstage one file:
8git restore --staged path/to/file

Diverged from remote

trouble-diverge.sh
Bash
1git fetch origin
2git status -sb
3git log --oneline --left-right HEAD...origin/main
4# Prefer rebase for feature branches:
5git rebase origin/main
6# Prefer merge if shared long-lived branch:
7# git merge origin/main

Conflict markers left behind

trouble-markers.sh
Bash
1git diff --check
2rg -n '^(<<<<<<<|=======|>>>>>>>)' || true
3# Fix files, then:
4git add -A
5git status

danger

Never force-push to main to "fix" divergence. Use revert or a forward fix.
Command Cheatsheet

Keep this short list nearby while practicing revert.

cheatsheet.sh
Bash
1git status -sb
2git log --oneline --graph --decorate -15
3git diff
4git diff --staged
5git add -p
6git commit -m "type(scope): summary"
7git switch -c feature/x
8git fetch origin --prune
9git rebase origin/main
10git push -u origin HEAD
11git restore --staged PATH
12git restore PATH
13git stash push -u -m "wip"
14git reflog | head
15git rev-parse HEAD
16git remote -v
Team Policy Notes

Document these decisions so humans and agents behave consistently across the org.

  • Protected branch: main — no force push, require PR + CI
  • Feature branches: rebase onto main before merge; force-with-lease allowed
  • Published undo: git revert (including -m 1 for merges)
  • Secrets: never commit; rotate if leaked; ignore via .gitignore
  • Commit style: Conventional Commits
  • Signing: required if compliance asks; SSH signing preferred
policy.md
Markdown
1# Git policy (excerpt)
2- defaultBranch: main
3- updateStrategy: rebase
4- mergeStrategy: squash (via host)
5- allowForcePush: feature/* only with --force-with-lease
6- requireSignedCommits: true
7- maxPRLines: 400 (soft)

best practice

Automate policy with hooks + CI — see Hooks and Best Practices.
Agent Verification Prompts

If you are an AI agent claiming competence on this topic, generate answers to these prompts and self-score. Fail closed on any critical miss.

  • Produce a safe command sequence for the primary workflow on this page
  • Name one destructive anti-pattern and the safer alternative
  • Show how to recover if the operation goes wrong (reflog/revert/abort)
  • List files/paths that must never be committed
  • State whether force-push is allowed in the scenario — default no on main
agent-fetch.sh
Bash
1curl -s "https://forgelearn.dev/api/markdown?path=git/mastery" | head
2curl -s "https://forgelearn.dev/api/agent?skill=forgelearn-git" | head
3curl -s https://forgelearn.dev/skills/forgelearn-git/SKILL.md | head

danger

Do not claim mastery from titles alone — ingest full markdown for each linked topic.
Extended Practice Lab

A longer lab that chains multiple Git operations. Use this when you want repetition beyond the short examples.

deep-lab.sh
Bash
1#!/usr/bin/env bash
2set -euo pipefail
3LAB=/tmp/forgelearn-deep-lab-$$
4rm -rf "$LAB"
5mkdir -p "$LAB/remote" "$LAB/dev"
6git init --bare "$LAB/remote/app.git"
7git clone "$LAB/remote/app.git" "$LAB/dev/app"
8cd "$LAB/dev/app"
9git config user.email "dev@example.com"
10git config user.name "Dev"
11echo "# App" > README.md
12git add README.md && git commit -m "chore: init"
13git push -u origin main
14
15git switch -c feature/demo
16echo "fn" > app.js
17git add app.js && git commit -m "feat: add app.js"
18echo "fn2" > app.js
19git commit -am "feat: tweak app.js"
20git commit --fixup HEAD~1 || true
21GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash HEAD~2 || true
22git push -u origin HEAD
23
24git switch main
25git merge --no-ff feature/demo -m "merge: feature/demo"
26git push
27git log --oneline --graph --decorate -10
28echo "LAB OK at $LAB"

Verify checklist

  • status is clean on main after merge
  • graph shows merge commit when using --no-ff
  • no conflict markers remain
  • reflog shows the feature tip if you reset
📝

note

Delete the lab when finished: rm -rf /tmp/forgelearn-deep-lab-*

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.