Do you ever wonder about rewriting git commit history. Here is how you can do. One great advantage we get with git version control system is that, we can edit or rewrite the history of commits. Some times may be you want to publish the different commit history or for some reason you may want to edit the few chunks for commit history.
There are different ways to edit the history of commits. There is one quick way to edit the very last commit or HEAD. Using following command
If you want to edit selected commits in the history, you can do it using feature called rebasing in git. Rebasing is a great feature in git. Other than process called merging we can use rebasing to merge different branches in different way other than usual git merge. One of the advantage is we can rewrite the history to make sure commit history looks like the way you want.
We have to use interactive rebasing to edit the commit history, using the following command
where we specify the commit which is parent of the commit from which you want to edit the commit history
Lets say I chosen the commit from where I want to edit the history, I would type the following command
git rebase -i 185a4d16eb696e37a061bc9547b219b5d147cdff
If you perform above command, you wold see the following content in the default editor,
pick 28efa32 Added feature request #f12
pick 38ffdf3 Fixed bug #228
pick f7f3f6d Fixed typeos
pick 310154e updated REDEME and INSTALL
pick a5f4a0d added cat-file
# Rebase 710f0f8..a5f4a0d onto 710f0f8
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# These lines can be re-ordered; they are executed from top to bottom.
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
# Note that empty commits are commented out
The above content is self explanatory, if you want to remove commits just remove corresponding commit line. if you want to abort interactive rebase any time use git rebase –abort. You should notice that your last commit is at bottom. These commits from chronological from top to bottom.
If you chose to edit the selected commits, let’s say want to change author, you have to replace the word pick with word edit for that corresponding commits and quit the editor by saving. Then you will stop at the first commit, you can change the author using following command
git commit --amend --author "user name <email@example.com>"
Like wise you can change the commit message as well. Of course you can also change the content of files to commit
and then to continue rewriting history using following command,
You have to repeat these steps for each commit that you change the word pick to edit. Git will stop to let you amend the commit. Once you are finished with specific commit, you can proceed further by using rebase command using command line argument –continue.
Once you finished with rebase, you may see the following message
Successfully rebased and updated refs/heads/unstable.
If you get conflicts, you have to resolve them in the way you resolve for merging process. Once you resolved the conflicts by removing conflict markers(>>>>>> ======= <<<<<<<). Use to git add to mark them resolved. Then continue to rebase using command
Beware of rebase, you may corrupt the commit history of your team members and it may leads to confusion.
If you are learning don’t try to experiment it on real repository. Instead you create the dummy repo and get hands on experience.
You may produce merge conflicts sometimes, you may have to resolve to proceed the rebase
Want to read more?