When managing Git versions, you often need to undo certain actions.

This article describes a few of the most important cases and gives detailed explanations.

Withdrawal of submission

A common scenario is that after committing the code, you suddenly realize that there is something wrong with the commit and you should undo it, so you can execute the following command.

$ git revert HEAD

The above command works by adding a new commit after the current commit, offsetting all the changes caused by the previous commit. It doesn’t change the past history, so it’s the preferred way to do it without any risk of losing code.

The git revert command only offsets the last commit; if you want to offset multiple commits, you must specify them in order on the command line. For example, to offset the first two commits, write something like this.

$ git revert [First submission from the bottom] [Penultimate submission]

The git revert command has two more arguments.

  • --no-edit: Runs without opening the default editor and uses Git’s automatically generated commits.
  • --no-commit: Only offsets file changes in the staging area and workspace, no new commits are generated.

Discard Submission

If you want previous commits to disappear completely in the history instead of being offset, you can use the git reset command to discard all commits after a certain commit.

$ git reset [last good SHA]

git reset works by returning the latest commit pointer to a previous point in time, and all commits after that point disappear from the history.

By default, git reset does not change the files in the workspace (but it does change the staging area), and the -hard argument returns the files in the workspace to their previous state as well.

$ git reset --hard [last good SHA]

After running the git reset command, if you want to retrieve those dropped commits, you can use the git reflog command, as described here. However, this practice is time-sensitive and may not be retrieved after a long period of time.

Replaces the previous submission

After committing, you can use the -git commit command with the -amend argument to change the last commit.

$ git commit --amend -m "Fixes bug #42"

It works by generating a new commit object that replaces the commit object generated by the previous commit.

If there are any files in the staging area that have changed, they will be committed to the repository together. So, --amend not only modifies the commit information, but also replaces the entire previous commit.

Undoing file changes in the workspace

If a file in the workspace has been messed up but not yet committed, you can use the git checkout command to retrieve the file before this change.

$ git checkout -- [filename]

It works by first looking for the staging area and restoring the version of the file if it has a staged version, otherwise restoring the last committed version.

Note that file changes in the workspace cannot be recovered once they have been undone.

Withdrawal of documents from staging area

If you accidentally add a file to the staging area, you can undo it with the following command.

$ git rm --cached [filename]

The above command does not affect the content already submitted.

Undo changes in the current branch

You’ve made several commits on the current branch and suddenly realize that you’ve put the wrong branch, and that these commits should have gone to another branch.

# Create a new feature branch that points to the current latest commit
# Note that it is still stuck in the current branch
$ git branch feature

# Switching to the state before these commits
$ git reset --hard [当前分支此前的最后一次提交]

# Switching to feature branch
$ git checkout feature

Reference https://www.ruanyifeng.com/blog/2019/12/git-undo.html