Reverting local mistakes in code using Git revert, rebase, restore and reset

published on Sat Jan 23 2021

We all make mistakes while programming and we tend to only realize it after we’ve made some more mistakes. 🙄 However, our friend Git is there for us and we can use Git to revert or modify our repository history to get to a desirable state.

The gotcha to remember is that most of these should be applied to our local branch that has not yet been committed. If we make changes to a branch that has been committed and force push our modified history to it, it will break repositories for other people who are tracking the same repository. And they’ll not like us anymore. 😭

Remove all local changes in a file or undelete a file

git restore <filename>

Restore patches/chunks in a changed file

git restore -p <filename>

Remove all local changes in the branch

git restore .

Fixing the last commit

git commit --amend -m "correct commit"

Here, we include whatever changes we missed to make git include those changes in the last commit. The -m flag lets us change the commit message

Removing changes from a commit in the middle

git revert <commit_hash>

This creates a new commit that has the exact opposite changes from the commit we are reverting and applying it leaves us with a repository where the changes from the old commit have been negated by the new commit

Reset branch to an old commit state

git reset --hard <commit_hash>
git reset --mixed <commit_hash>

Reset a particular file to an old commit state

git restore --source <commit_hash> <filename>

Undelete deleted/reset commits by using reflog

git reflog
git branch <new_branch_name> <deleted_commit_hash_to_branch_from>

git reflog shows us a journal of the git commands run on a repository including deletions and we can use it to find the commit hash of deleted commits that we might want to restore

Get the deleted changes from a deleted branch

git reflog
git branch <new_branch_name> <commit_hash_at_which_branch_was_deleted>

Moving a commit to a new branch and removing the changes from the old branch

git branch <new_branch_name>
git reset HEAD~1 --hard

This creates the new branch with the changes included and resets the original branch to the penultimate commit state. We can define how many commits we want to move back by relative to the HEAD by specifying a number with the ~ sign. Ideally, this kind of scenario is encountered when you want to revert committed changes from the long running branch like master or development and move those changes to a feature branch

Moving a commit to an existing branch and removing the change from the old branch

git checkout <destination_branch_name>
git cherry-pick <commit_hash_to_be_moved>
git checkout <source_branch_name>
git reset HEAD~1 --HARD

Rewriting commit history using interactive rebase

git rebase -i HEAD~<number_of_commits_to_move_back_by>
git rebase -i <commit_hash_to_move_back_to>

This determines which actions we want to perform. Once confirmed we’ll get subsequent prompts with options to change the history. Some of the possible options are: