Git Commit Revert: Tutorial and Examples

Git Commit Revert: Tutorial and Examples

Git’s revert command provides a safe way to undo changes introduced by a specific commit without rewriting history. Unlike reset (which effectively “forgets” commits), revert creates a new commit that reverses the effects of the targeted commit. This makes revert the preferred method for undoing changes on branches shared with others, as it preserves the historical record and avoids causing conflicts for collaborators. This tutorial provides a detailed explanation and practical examples of using git revert.

1. Understanding git revert

  • What it does: git revert <commit> creates a new commit. This new commit applies changes that are the inverse of the changes introduced in the specified <commit>. Think of it as automatically generating a “counter-commit.”
  • Why it’s important: Preserves history. It’s crucial for collaborative workflows because you aren’t erasing past work; you are adding a new commit that negates the old one.
  • How it’s different from git reset:
    • git reset: Moves the branch pointer to a different commit, potentially discarding commits. Don’t use reset on pushed commits that others might have based their work on!
    • git revert: Creates a new commit that undoes changes, leaving the original commit in the history.

2. Basic git revert Usage

The fundamental command structure is straightforward:

bash
git revert <commit_hash>

Where <commit_hash> is the SHA-1 hash of the commit you want to revert. You can find this hash using git log.

Example:

Let’s say your git log shows this (simplified):

“`
commit c1e5f8a9… (HEAD -> main)
Author: …
Date: …

Fix a minor typo

commit a8b7c6d5…
Author: …
Date: …

Introduce a bug (we want to revert this!)

commit f4d3e2c1…
Author: …
Date: …

Initial commit

“`

To revert the commit a8b7c6d5..., you would run:

bash
git revert a8b7c6d5

Process after running git revert:

  1. Editor Opens (Usually): Git will typically open your default text editor. This allows you to modify the default commit message for the revert commit. The default message will usually be something like “Revert ‘Introduce a bug (we want to revert this!)'”. You can change this message or leave it as is.
  2. Save and Close: Once you’re happy with the commit message, save the file and close the editor.
  3. Revert Commit Created: Git will create a new commit. You can verify this with git log. You’ll now see a commit like:

    “`
    commit d2e3f4g5… (HEAD -> main)
    Author: …
    Date: …

    Revert "Introduce a bug (we want to revert this!)"
    
    This reverts commit a8b7c6d5...
    

    commit c1e5f8a9…
    Author: …
    Date: …

    Fix a minor typo
    

    commit a8b7c6d5…
    Author: …
    Date: …

    Introduce a bug (we want to revert this!)
    

    commit f4d3e2c1…
    Author: …
    Date: …

    Initial commit
    

    ``
    Notice that the original commit (
    a8b7c6d5…) is still there, but a new commit (d2e3f4g5…`) has been added to undo its changes.

3. Key git revert Options

  • -n or --no-commit: This option stages the revert changes but doesn’t create a commit. This allows you to:

    • Inspect the changes: You can review what the revert would do before actually committing it. Use git status and git diff to examine the changes.
    • Combine with other changes: You can add other changes to the staging area and then create a single commit containing the revert and your additional modifications.
    • Abort if necessary: If you decide the revert isn’t what you want, you can easily unstage the changes (git restore --staged .) without having to undo a commit.

    “`bash
    git revert -n a8b7c6d5 # Stages the revert, but doesn’t commit
    git status # See the staged changes

    … make further changes or unstage …

    git commit -m “Revert bug and add feature X” # Commit if you’re ready
    “`

  • -e or --edit (default): This is the default behavior. It opens your editor to let you edit the commit message.

  • --no-edit: This reverts the commit without opening the editor. Git will use the default revert commit message. Use this with caution, as you won’t have a chance to customize the message.

    bash
    git revert --no-edit a8b7c6d5

  • -m parent-number or --mainline parent-number: This option is used when reverting a merge commit. Merge commits have multiple parents (one for each branch that was merged). You need to specify which parent represents the “mainline” – the branch you were on when you performed the merge. Typically, this is 1 (the first parent).

    bash
    git revert -m 1 <merge_commit_hash> # Revert a merge, keeping changes from parent 1

    Without the -m option, git revert on a merge commit will return an error such as “error: commit is a merge but no -m option was given.”

4. Reverting Multiple Commits

You can revert multiple commits in a single command by providing a range of commits:

bash
git revert <start_commit>..<end_commit>

This will revert all commits from <start_commit> up to and including <end_commit>. Git will create a separate revert commit for each commit in the range. It’s important to get the order right; Git processes the commits in reverse chronological order (newest to oldest).

Example:

Suppose you have commits A, B, C, D, and E (E being the newest). If you run:

bash
git revert C..E

Git will create three revert commits:

  1. A commit reverting E.
  2. A commit reverting D.
  3. A commit reverting C.

Important Note: Reverting multiple commits can lead to a lot of new commits. If you’re only trying to undo a few related changes, it might be cleaner to revert them individually or use -n to combine the changes into a single revert commit.

5. Handling Merge Conflicts During Revert

Just like merging, reverting can sometimes lead to merge conflicts. This happens when the changes you’re trying to revert have been modified by subsequent commits.

Process for Resolving Conflicts:

  1. Git will report the conflict: You’ll see a message indicating which files have conflicts.
  2. Open the conflicted files: The files will contain conflict markers (similar to merge conflicts):

    “`
    <<<<<<< HEAD
    This is the current version.
    =======
    This is the version from the reverted commit.

    parent of ()
    “`

  3. Edit the files: Choose which version to keep (or combine parts of both). Remove the conflict markers (<<<<<<<, =======, >>>>>>>).

  4. Stage the resolved files: Use git add <file> for each resolved file.
  5. Continue the revert: Run git revert --continue. This will create the revert commit (and open your editor for the commit message, unless you used --no-edit).
  6. If needed, git revert --abort: If you get stuck or want to start over, git revert --abort will cancel the entire revert operation.

6. Practical Examples

  • Scenario 1: Reverting a single, recent commit.

    “`bash
    git log # Find the commit hash of the problematic commit
    git revert

    Edit the commit message (optional)

    Save and close the editor

    “`

  • Scenario 2: Reverting a commit without creating a new commit immediately.

    “`bash
    git revert -n
    git status # Check the staged changes
    git diff # Review the changes in detail

    (Optional) Make further changes

    git commit -m “Revert changes and…” # Combine revert with other changes
    “`

  • Scenario 3: Reverting a merge commit.

    “`bash
    git log –graph –oneline # Find the merge commit hash and visualize the parents
    git revert -m 1 # Assuming parent 1 is the mainline

    Resolve conflicts if any

    “`

  • Scenario 4: Reverting multiple commits.
    bash
    git log # Find the commit hashes
    git revert <oldest_commit_hash>..<newest_commit_hash>
    #Resolve any conflicts that may arise in each revert.

7. Best Practices

  • Use git revert on shared branches: Always prefer revert over reset when working on branches that others are using.
  • Check changes with -n: Use --no-commit to inspect the revert changes before committing them.
  • Write clear commit messages: Explain why you’re reverting the commit.
  • Understand the implications of reverting merges: Be very careful when reverting merge commits, as it can significantly alter your history. Consider if reverting individual commits within the merge is a better approach.
  • Test thoroughly: After reverting, always test your code to ensure that the revert had the desired effect and didn’t introduce new issues.

By following this tutorial and the provided examples, you should now have a solid understanding of how to use git revert effectively and safely to undo changes in your Git repositories. Remember to prioritize preserving history and communicating clearly with your collaborators.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top