To undo a bad commit in Git while preserving the commit history, you can use the `git revert` command followed by the commit hash of the revision you want to revert.
git revert <commit-hash>
Understanding Git Revert
What is Git Revert?
Git revert is a command used in Git to undo changes made by a specific commit. Unlike other commands such as git reset, which can alter the commit history and potentially lose data, git revert creates a new commit that negates the changes introduced by the bad revision. This makes it a safe option for making corrections without impacting the integrity of the project’s history.
Using git revert is particularly beneficial in collaborative environments where preserving the commit history is essential. When you encounter an issue introduced by a previous commit, rather than removing it from the history, git revert allows you to address the problem while keeping a complete record of all changes.
How Git Revert Works
When you execute git revert, Git identifies the specific commit you want to negate and applies the opposite changes from that commit to the current branch. This process results in a new commit, which is referred to as a revert commit. The history remains intact, providing a clear picture of the changes made over time.
Imagine a commit that adds a file that turns out to be unnecessary. After reverting that commit, the file will be removed, thus undoing the changes from that specific revision. The original commit will still remain in your history, but its effects are countered by the new revert commit.

Steps to Revert a Bad Revision
Step 1: Identify the Bad Revision
Before you can revert a commit, you need to find out which one caused the issue. You can easily view the commit history with:
git log --oneline
This command provides a concise view of your commit history, showing each commit’s hash and summary message. Look for the commit that introduced the undesired changes—this will be the bad revision you're targeting for a revert.
Step 2: Executing Git Revert
The Basic Command
Once you have identified the bad revision, you can execute the revert command with the following syntax:
git revert <commit_hash>
Here, `<commit_hash>` should be replaced with the unique hash of the commit you want to revert. This command will create a new commit that undoes the changes made by the specified commit.
Real-world Example
Let’s say you find that a commit with hash `abc1234` introduced a bug. You can revert this bad commit by running:
git revert abc1234
After executing this command, Git will generate a new commit that negates `abc1234`. You'll also be prompted to edit the default commit message, which includes information about the commit being reverted. This promotes clarity as you keep your project documentation intact.
Step 3: Handling Merge Commits
Why Merging Can Complicate Reverts
Reverting merge commits is slightly more complex than reverting regular commits. A merge commit incorporates changes from multiple branches, making it harder to identify which specific changes you want to negate.
Reverting a Merge Commit
To revert a merge commit, you must specify a parent. The command syntax looks like this:
git revert -m 1 <merge_commit_hash>
In this command, `-m 1` indicates that we want to keep changes from the first parent of the merge while negating the effects of the merge itself. If your merge commit has hash `5678def`, you would run:
git revert -m 1 5678def
This approach helps in selectively reverting changes caused by a merge while maintaining the branch's stability.

Advanced Reverting Techniques
Reverting Multiple Commits
Sometimes, you might need to undo changes across multiple commits. Git allows you to revert a range of commits using the following syntax:
git revert A..B
Here, `A` is the hash of the first commit you want to revert, and `B` is the hash of the last one. Be cautious with this command; it creates a new commit for each commit being reverted. Therefore, if there are many commits in your specified range, it could clutter history significantly.
Cherry-Picking a Commit
In case you want to apply a particular commit while negating others, you can use the concept of cherry-picking. Cherry-picking allows you to select a specific commit from your project history and apply it to your current branch. Use the following command:
git cherry-pick <commit_hash>
This can be handy if you want to bring in changes from a previous commit while discarding the negative impacts of other changes made afterward.

After the Revert: What’s Next?
Verifying Changes
Once you have reverted the desired commit, it’s essential to verify that the changes took effect as intended. You can check the differences using:
git diff HEAD
This command provides an overview of what changes have been made in the most recent commit. Always ensure that the revert has resolved the issue without introducing new ones.
Committing the Revert
Using git revert automatically creates a new commit. You'll have an opportunity to customize the commit message to reflect the reason for the revert. Consider making the message informative, as this aids in understanding the history of changes when reviewing later.

Best Practices for Using Git Revert
To maintain a clean commit history, here are some best practices to follow when using git revert:
- Commit Often: Regular commits allow you to revert smaller changes and maintain better control over the codebase.
- Document Changes: Clearly explain why a commit was reverted in the commit message. This will help future developers understand the context of changes.
- Testing: Always test your code after performing a revert to ensure everything functions correctly. This prevents introducing bugs inadvertently.

Conclusion
In summary, using git revert to address a bad revision is an effective strategy for managing your code base. It provides a reliable way to navigate mistakes while preserving the full history of your project. By understanding how to identify issues, apply the revert command, and handle complexities like merge commits, you can maintain a robust and professional workflow.

Call to Action
If you want to deepen your understanding of Git and learn more advanced commands, consider exploring the resources we provide. Understanding and mastering Git ultimately enhances your software development skills, empowering you to write cleaner code and maintain reliable project histories.

Additional Resources
For deeper insights and further learning, check out the official Git documentation on git revert. It's an excellent resource for mastering the nuances of version control.