Revert or reset?

Two ways back: a new commit that undoes an old one, or moving the branch to where it was.

Git has two ways to take a commit back, and they differ in what they do to the history. Revert makes a new commit that applies the opposite of an old one: the history keeps both, what happened and its undoing, and nothing that already exists changes. Reset moves the branch back to an earlier commit, as if the ones after it had not been made. They still exist, but no name reaches them.

The choice follows from that. A revert is safe on a branch other people have, because it only adds. A reset rewrites what the branch is, and is for commits nobody else has yet.

  1. Three commits on main. Suppose C was a mistake.

  2. Revert C. D applies the opposite of C's changes and main moves to it. The history still shows C, and shows that it was undone.

  3. A reset to B. main moves back, and C and D are left with no branch reaching them. A hard reset makes the working copy B's files too.

  4. Nothing is gone yet. The reflog remembers every place main has been, and pointing main at D again brings both commits back.

Three kinds of reset

A reset always moves the branch. What it does with the changes from the commits it moved past is the option. --soft leaves them staged, ready to commit again; --mixed, the default, leaves them in the working copy, unstaged; --hard throws them away and makes the files on disk match the commit you reset to. The third is the one that can lose work you never committed, which is why it is the one to be careful with.

Amending is a small reset and a new commit in one: the last commit is replaced by a new one with the corrected message or contents, and the old one is left unreachable. The same rule applies: not after pushing, unless you are prepared to force push.

On the command line

git revert C            # a new commit that undoes C
git reset --hard B      # main back to B; the working copy too
git commit --amend      # replace the last commit
git reflog              # where HEAD has been, newest first

Git’s own reference: git-revert, git-reset and git-reflog. The Pro Git book takes reset apart at length.

In Innesta

Reverting a commit is the safe way back. A hard reset in Innesta takes a backup first, and undoing a discard or a reset is where that backup is; the safety net lists everything else it keeps. Amending has its own page, and undoing your last commit is the short answer to the commonest case. The reflog is read by finding a commit that has disappeared.

The Playground is a repository made for trying this on.