When using Git Rebase, you’ll be greeted with a list of commits to pick when rebasing changes onto your feature branch. The pick command can seem rudimentary, even boring, but did you know it has superpowers? Well, you can use pick to reorder your commits which allows you to tell a compelling story of how you implemented your work.
Let’s say you are working on the release feature branch and want to rebase as follows:
git rebase --interactive
Let’s also assume the following commits appear in your Git Rebase Editor as shown in the screenshot above but listed here for convenience:
p 85b2df679865 Added project skeleton p b7a0c4538558 Added method scopes constant p 34f8e08aaad6 Added builder p adcde793040e Added Marameters gem p 494a5f2d9e86 Added primary object API p 98492982468e Added documentation p 28882af8641a Added version release notes
💡 I have the p abbreviation enabled which is short for pick as set via my Git Rebase Abbreviations configuration.
Normally, you’d change p to one of the other commands like reword, fixup, etc but, in this case, it’d be nice to re-arrange the following commit so it appears earlier in history:
p adcde793040e Added Marameters gem
We can do this by moving this commit so it appears after the Added project skeleton commit which results in the following:
p 85b2df679865 Added project skeleton p adcde793040e Added Marameters gem p b7a0c4538558 Added method scopes constant p 34f8e08aaad6 Added builder p 494a5f2d9e86 Added primary object API p 98492982468e Added documentation p 28882af8641a Added version release notes
Notice all I did was move the Added Marameters gem commit after the Added project skeleton commit. Now when I save these changes and close my Git Rebase Editor, Git will happily rebase and apply these changes in the order defined. This is possible because each commit is an atomic commit (see my Git Commit Anatomy for details) which means I can re-arrange my commits as I please since they don’t cause merge conflicts. This makes the pick command extremely powerful when organizing code, ideas, and showing how I implemented a solution.
Why did I do this? Well, I meant to add the Marameters gem earlier during development because the gem is necessary to implement the commits that come after. I had already added the gem dependency to my *.gemspec but failed to add the commit (oops). With the power of the pick command, I’ve corrected my mistake. 🎉
Oh, but there’s more! The pick command can pull in commits from different branches you might be working on. Let’s say you have a legal feature branch which has the following commits:
527a1ff4c7b4 Added license 8aa64afd153d Added branding
Let’s also say you are currently working on a release branch (which includes the commits discussed earlier) but you want to pull in the Added license commit from the legal branch because you realize you need to address legal concerns sooner rather than later. To accomplish this, we can initiate an interactive rebase on our release branch (git rebase --interactive) which, again, yields the following in our Git Rebase Editor
p 85b2df679865 Added project skeleton p adcde793040e Added Marameters gem p b7a0c4538558 Added method scopes constant p 34f8e08aaad6 Added builder p 494a5f2d9e86 Added primary object API p 98492982468e Added documentation p 28882af8641a Added version release notes
To pull in the Added license commit from our license branch, we copy and paste (or manually write the line) before the Added documentation commit, like this:
p 85b2df679865 Added project skeleton p adcde793040e Added Marameters gem p b7a0c4538558 Added method scopes constant p 34f8e08aaad6 Added builder p 494a5f2d9e86 Added primary object API p 527a1ff4c7b4 Added license p 98492982468e Added documentation p 28882af8641a Added version release notes
Notice I added this line:
p 527a1ff4c7b4 Added license
In truth, all I did was add p 527a1ff4c7b4 — because Git only cares about the SHA — but I added the commit subject for clarity in case this helps you follow along.
You might also be thinking "Hey, isn’t this like cherry picking". Yep, exactly! Only I opted to combine rebasing with cherry picking in one fell swoop.
Using pick to re-arrange, or cherry pick, commits allows you to make Code Reviews a joy and helps automate the creation of Milestones for great effect. You get all of this because you took the time to use pick to organize your code and thoughts for upstream benefit. Congrats and enjoy!