One of the powerful features of git rebase -i (interactive mode) is the ability to reorder commits. However, it’s crucial to remember: never rebase commits that have been pushed to a public repository. Doing so can create non-fast-forward merges and cause significant issues for anyone else working on the same project. Rewriting history should only be done with local commits that haven’t been shared with others.
With that warning out of the way, let’s dive into how to reorder commits. Suppose you want to rearrange the order of your commits. Perhaps you need to push certain changes further back in history, or it makes more sense to bring a later commit to the front. Here’s how you can do it.
Scenario
Imagine your commit history looks like this:
css
$ git log –oneline
eb32194 Regenerated gemspec for version 0.4.1
85409cf Version bump to 0.4.1
4c39bca gemspec tweak
Steps to Reorder Commits
Initiate Interactive Rebase
Start by using git rebase -i HEAD~3 to open the interactive rebase editor for the last three commits.
bash
$ git rebase -i HEAD~3
Your editor will open with the following text:
graphql
pick 4c39bca gemspec tweak
pick 85409cf Version bump to 0.4.1
pick eb32194 Regenerated gemspec for version 0.4.1
Rebase 60709da..eb32194 onto 60709da
#
Commands:
p, pick = use commit
e, edit = use commit, but stop for amending
s, squash = use commit, but meld into previous commit
#
If you remove a line here THAT COMMIT WILL BE LOST.
However, if you remove everything, the rebase will be aborted.
Reorder the Commits
To change the order, simply move the pick commands around. If you want to make the third commit the first, it would look like this:
css
pick eb32194 Regenerated gemspec for version 0.4.1
pick 85409cf Version bump to 0.4.1
pick 4c39bca gemspec tweak
Save and Complete the Rebase
Save the file and close the editor. Git will proceed with the rebase:
bash
$ git rebase -i HEAD~3
Successfully rebased and updated refs/heads/test.
If everything goes smoothly, your commits will be reordered. If you encounter conflicts, you will need to resolve them, add the resolved files, and continue the rebase with git rebase --continue.
Handling Issues
Aborting the Rebase
If the rebase process becomes too complicated or problematic, you can abort it at any time:
bash
$ git rebase –abort
This command will return your repository to its previous state before the rebase started.
Recovering Lost Commits
Don’t worry about losing any data. If you accidentally lose some changes, you can always use the reflog to recover them:
bash
$ git reflog
Final Thoughts
Reordering commits can be particularly useful when combined with other interactive rebase options, such as squashing commits or editing commit messages. Keep in mind that while the commit dates remain the same, the logical order of commits might appear odd to others reviewing your repository. If you’ve found reordering commits helpful (or if it’s caused you trouble), feel free to share your experiences in the comments!