Cherry-picking and changing date of last commit in Git
Version control (newbies: keeping the history of changes to a file or files) is funny. I have used Git for a while, and my colleagues currently find it funny that I prefer to use the command line (newbies: that black screen with all the text that looks super nerdy) as opposed to using an interface where you just click buttons and type in text fields. My method is deemed to be somewhat bad-ass and dangerous. I personally find it more comfortable and I feel less likely to break something by typing in commands.
One of my favourite commands is
git cherry-pick. You can pretty much grab any committed changes and apply them to whatever you are doing right now. It’s a bit like looking at your life and going, ‘Yeah, those were some rad times!’ as you choose what to put in a movie of your life.
But let’s say for some reason you want all those rad times to happen on the same day.
I needed some changes from another branch so that I could work on top of those. (I don’t know why I didn’t think of branching off that branch, but whatever.) So I cherry-picked them, but realised, as we all hate – the commits appear as the most recent, but the timestamps have the original date.
This just won’t do!
I made a dummy commit, making a redundant change to a file just so I could make a commit message for today. Hopefully I could squash all my commits into the one.
If you run
git log, it will give you a history of what has been committed already.
commit 938e1d Date: Fri Jan 15 Adding styling for blockquote commit 72fd8a Date: Wed Jan 13 Refactoring card component commit 1a8e31 Date: Wed Jan 13 Adding title to markup commit cca242 Date: Tue Jan 12 Fixing browser inconsistency for input element
And if you want to combine all your commits into one bundle:
git rebase -i HEAD~1
HEAD~1 is the first commit that appears in
git log. You want to update that number to the last commit you want to squash (or ‘bundle’). So if you cherry-picked four things, you will want to do
git rebase -i HEAD~4. The example below has my dummy commit included, so is actually
pick cca242 Fixing browser inconsistency for input element pick 1a8e31 Adding title to markup pick 72fd8a Refactoring card component pick 938e1d Adding styling for blockquote pick 666666 Dummy commit by Georgie
Notice how the commits are displayed in reverse order (newest at the bottom). We are now doing an interactive rebase. Don’t be scared – most people hear the word ‘rebase’ and freak out. We’re going to pick the first commit, and squash the rest into it.
pick cca242 Fixing browser inconsistency for input element squash 1a8e31 Adding title to markup squash 72fd8a Refactoring card component squash 938e1d Adding styling for blockquote squash 666666 Dummy commit by Georgie
Of course you cannot squash forwards in time… so I realised there was no way I was going to be able to squash everything forwards and into my dummy commit from today. 😞 So I worried about squashing them into one commit first. If you look above, you can see that I picked the first commit that appeared (which is
HEAD~5 and therefore the earliest commit in time) I squashed them into the earliest commit in history, bundling them into one.
commit cca242 Date: Tue Jan 12 Fixing browser inconsistency for input element
My discovery (really the cherry on top – no pun intended 🍒) was that I was able to run a command to edit the date of the last commit message.
git commit --amend --reset-author
It is known to be a bit of a hack, and I would hope you hadn’t pushed any changes before running it. In my case, I was cherry-picking my own changes, so I was the original author of these commits anyway. When you run this command, the timestamp will change to the time you ran the command. Which is today.
commit cca242 Date: Mon Jan 18 Bring me my Delorean
Which means all my rad times really did happen on one day. 😎