Lesson 3
Undoing and Reverting Changes in Git
Introduction

Welcome to the last lesson of the Undoing Changes and Time Traveling course! In our previous lessons, we explored navigating commit histories and managing changes within a Git project. Now, let's focus on understanding how to undo or revert changes using git reset and git revert. These tools are essential for maintaining a clean project history, especially when mistakes occur or adjustments need to be made.

Deep Dive into "git reset"

The git reset command is a powerful tool in Git that allows you to "rewind" your project’s history by moving the HEAD pointer back to a specific commit. When we do this, any commits that came after the specified commit are effectively removed from the history, but the changes made in those commits remain in the working directory. This gives you the flexibility to decide whether to recommit, modify, or discard these changes after adjusting the history.

Imagine you’re working on a book project where each commit represents progress. Here’s your commit history:

Bash
1d1f2e3a Edit Chapter 3 2b2c3d4f Write Chapter 3 3a3b4c5d Edit Chapter 2 4e5f6g7h Write Chapter 2 5h7i8j9k Initial Draft of Chapter 1

Now, let’s say you realize that everything from "Write Chapter 3" onward is based on a flawed direction for the book. You decide to reset the history to just after "Edit Chapter 2," removing the last two commits.

To do this, you can run:

Bash
1git reset a3b4c5d

After this command, your git log will now show only:

Bash
1a3b4c5d - Edit Chapter 2 2e5f6g7h - Write Chapter 2 3h7i8j9k - Initial Draft of Chapter 1

The commits for "Write Chapter 3" and "Edit Chapter 3" are removed from the history. However, the actual changes from these commits remain in your working directory. This means that while the commit history looks as though they never happened, the changes are still there, allowing you to decide how to handle them next.

Types of "git reset": Soft and Hard

In addition to the mixed reset we discussed earlier (the default reset type), there are two other git reset options: soft and hard. Each affects your commit history, staging area, and working directory differently:

  • Soft Reset (git reset --soft <commit-hash>)
    Removes commits from history but keeps all changes staged in the index, ready to be recommitted. Use this if you want to "uncommit" recent changes while keeping them staged for further adjustments.

  • Hard Reset (git reset --hard <commit-hash>)
    Removes commits from history and discards all changes from both the staging area and working directory. This returns your project to a clean state as of the specified commit, with no trace of the removed commits.

Quick Summary of Reset Types
Reset TypeCommits Removed from HistoryChanges StagedKeeps Changes in the Working Directory
Mixed (Default)YesNoYes
SoftYesYesYes
HardYesNoNo

Each reset type serves a different purpose based on whether you want to keep, review, or completely discard recent changes.

Exploring "git revert"

In Git, undoing changes can sometimes involve rewriting history, as we saw with git reset. However, in collaborative projects or shared repositories, rewriting history can lead to conflicts and confusion. That’s where git revert comes in. Unlike git reset, which changes the commit history, git revert offers a safer alternative by creating a new commit that undoes a specific previous commit. This approach preserves the complete history, making it ideal for shared projects where a clear, traceable record of changes is essential.

In our book project, suppose we’ve already established the following commit history:

Bash
1d1f2e3a Edit Chapter 3 2b2c3d4f Write Chapter 3 3a3b4c5d Edit Chapter 2 4e5f6g7h Write Chapter 2 5h7i8j9k Initial Draft of Chapter 1

Now, let’s say that "Edit Chapter 2" (commit a3b4c5d) introduced an error, and you want to undo this change. Since this is a collaborative project, you decide to use git revert to maintain a clear history.

The changes in commits that come after the reverted commit remain unaffected. Only the specific commit you choose to revert is undone.

Here are the steps you need to follow to revert the commit:

  1. Run:

    Bash
    1git revert a3b4c5d
  2. Git will prompt you to confirm the commit message, which will default to something like:

    1Revert "Edit Chapter 2" 2 3This reverts commit a3b4c5d.
  3. After confirming, a new commit will be added to your history, like so:

    1commit g7h8i9j - "Revert 'Edit Chapter 2'" 2commit d1f2e3a - "Edit Chapter 3" 3commit b2c3d4f - "Write Chapter 3" 4commit a3b4c5d - "Edit Chapter 2" 5commit e5f6g7h - "Write Chapter 2" 6commit h7i8j9k - "Initial Draft of Chapter 1"

This new "Revert 'Edit Chapter 2'" commit (g7h8i9j) undoes the changes made in "Edit Chapter 2" without deleting the original commit, keeping your project history intact and clear. This allows others to understand what changes were undone and why.

Revert vs. Reset: Key Differences

While both git revert and git reset can undo changes, they serve different purposes and have distinct impacts on your project history:

  • git revert

    • Purpose: Safely undo a specific commit by creating a new "revert" commit.
    • Effect on History: Does not delete or alter previous commits; instead, it adds a new commit to reverse changes.
    • Best for: Collaborative projects where maintaining a complete, unaltered history is important.
  • git reset

    • Purpose: Move HEAD to a specified commit, effectively "rewinding" the history by removing later commits.
    • Effect on History: Deletes commits from history.
    • Best for: Local changes that need correction or removal before sharing with others.

In short, use git revert when you want to keep the project history intact and traceable, and use git reset for local changes when rewriting history won’t impact collaborators.

Summary

In this lesson, you gained insights into git reset and git revert, learning how to undo and revert changes safely and effectively. Git reset is best used for correcting commit history locally, while git revert is ideal for collaborative environments where maintaining a clear history is essential. Now, I encourage you to apply these concepts in the practice exercises following this lesson, where you'll get hands-on experience managing Git history.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.