Oftentimes, we’ve run into trouble while coding. Some of the problems include creating a build error, pushing code that doesn’t pass CI, or, even worse, deleting someone else’s code that we thought are not used. Though, there are ways to mitigate those events using git that you might not know.
Usually, git checkout is a tool to move into another branch. But, it also can move to a specific git commit hash. This can resolve the problem when some of the files in previous commits are faulty and you want to return some commits back to fix it. For example, consider there’s an error that’s caused by commit #ba45daf below and we want to go back to the commit before it. Then, we can check out to commit #e76c604 and then create a new branch from there.
git checkout e76c604
git switch -c fix/new-branch
# or just:
git checkout -b fix/new-branch e76c604
Then, you can fix your problem in that new branch and merge it back to the original branch when finished.
- You want to redo the work previously done in a new branch
- You’re fine with a merge commit to fixing the branch
Not useful when
- You only want to delete the changes in previous commits
- Your commits are still local(not pushed yet) since for local commits, there are better options below
This is probably the first thing that comes to mind when talking about reverting changes in git. You use this command to remove the changes caused by previous commits but keep the commit history since this command will create a new revert commit.
# Remove 2 commits from top (head to head~1)
git revert HEAD~1..HEAD
# Remove commits by id
git revert e76e604 ffc035f
- Your commits are atomic (meaning, one commit removed probably wouldn’t affect the other)
- Your commits are pushed, since this won’t rewrite history and create a new revert commit, your branch history is safe
- You specifically know what commit is causing trouble
Not Useful When
- Your commits are not atomic, meaning reverting change in one commit will cause a conflict within the branch (this might seem confusing but it’s not when you try it out yourself)
- Commits are not pushed (since there’s a better option)
Git reset basically means that you want to erase commits. Use this command only when your commits are local, since using this with pushed commits will cause conflict, and, probably you need to force push the changes (which is not preferable). Git reset has 2 modes, hard and soft. Soft will reset the commits but not the changes, while hard will reset the commits and the changes.
# resets to commit at HEAD~1 (removing HEAD which is latest commit)
# will not remove changes so you can commit them again
git reset --soft HEAD~1
# resets to commit at HEAD~1 while removing all of its changes
git reset --hard HEAD~1
Nowadays, I rarely use reset because either my changes are already in a remote server so I need to create a fixed commit, or I can use a simpler command if I only want to change my commit name (git commit — amend). Nonetheless, git reset remains a solid option if there are some problems in your local that need a lot of edits if you use other approaches.
- Your problems are still in local (no need to worry about branch conflict when pushing)
- The depth of the reset is not that deep (around 1–2 commits)
Not Useful When
- The depth of the reset is deep (3+ commits), which calls for
git revertto being used
- You only want to change the commit message of the latest commit (use
git commit --amendinstead)
- The changes are already in a remote server
There’s more to it. As I mentioned, there are a LOT of ways you can mitigate disasters using git. That’s why it’s such a great tool to use when you’re programming. Some of the other ones that can mitigate disasters are
git commit --amend, and
git rebase but I don’t use them quite often (except commit amend which basically overrides previous commit changes & messages with a new one).
That’s all about this article. See ya