Git Revert and Reset

Understand how to revert (undo) changes made in commits using 'git revert'. Learn the different types of reset (soft, mixed, hard) and their effects using 'git reset'.


Learn Git and GitHub: Git Reset

Introduction to Git Reset

git reset is a powerful command in Git that allows you to move the current branch's pointer to a previous commit. This effectively "rewinds" your commit history. It's a key tool for undoing changes, but it's crucial to understand its different modes and potential consequences, especially when working with shared repositories. While git reset can be helpful for cleaning up your local branch, it can create issues if used improperly on branches shared with others.

Essentially, git reset affects three key areas:

  • The HEAD: The pointer to the current branch.
  • The Staging Area (Index): Where you prepare files for your next commit.
  • The Working Directory: The files on your computer's file system.

Understanding 'git reset' and its Modes

The basic syntax for git reset is: git reset [mode] [commit] Where:

  • mode: Specifies how the reset operation will affect the staging area and working directory. If omitted, the default mode is --mixed.
  • commit: The commit to which you want to reset the branch. You can use a commit hash, branch name, tag, or relative references like HEAD^ (previous commit) or HEAD~2 (two commits ago). If omitted, it resets to HEAD in the mode specified.

Git Reset --soft

The --soft mode is the least destructive. It moves the HEAD to the specified commit, but it leaves both the staging area and the working directory untouched. All changes from the commits after the specified commit are staged and ready to be committed again. Think of it as undoing the last commit, but keeping your changes ready for the next commit.

Example: git reset --soft HEAD^ (Undoes the last commit, but stages the changes)

Impact:

  • HEAD: Moves to the specified commit.
  • Staging Area: Unchanged (contains all the changes from the undone commits).
  • Working Directory: Unchanged (contains all the changes from the undone commits).

Git Reset --mixed

The --mixed mode is the default mode if no mode is specified. It moves the HEAD to the specified commit and resets the staging area to match that commit. However, the working directory is left untouched. This means the changes from the commits after the specified commit are now unstaged, but still present in your working directory. You'll need to use git add to stage them again before committing.

Example: git reset --mixed HEAD~2 (Resets to two commits ago, unstaging the changes)
git reset HEAD~2 (Equivalent to the above, as --mixed is the default)

Impact:

  • HEAD: Moves to the specified commit.
  • Staging Area: Resets to match the specified commit (changes are unstaged).
  • Working Directory: Unchanged (contains all the changes from the undone commits, but they are unstaged).

Git Reset --hard

The --hard mode is the most destructive. It moves the HEAD to the specified commit and resets both the staging area and the working directory to match that commit. Any changes in the staging area and working directory that were introduced by commits after the specified commit are permanently lost. Use this mode with extreme caution, especially when working on a shared branch, as it can lead to data loss if not used carefully.

Example: git reset --hard <commit-hash> (Resets to the specified commit, discarding any changes made since then)

Impact:

  • HEAD: Moves to the specified commit.
  • Staging Area: Resets to match the specified commit.
  • Working Directory: Resets to match the specified commit (changes are discarded).

Important Note: Before using git reset --hard, especially when you're unsure, it's highly recommended to use git stash or create a branch to save your current work. This allows you to recover the changes if you accidentally reset to the wrong commit.