So, I have a very simple use case; I want to squash all the commits that need to go back into master from my 'todays working' branch.
Until now I've been using git rebase -i
for this, but it doesn't work quite right; the timestamp on the final commit isn't right.
Here's an example of doing this:
[work1] git checkout master
Switched to branch 'master'
[work1] git rebase today
First, rewinding head to replay your work on top of it...
Fast-forwarded master to today.
[work1] git log --pretty=format:"%h%x09%an%x09%ad%x09%s"
5ad95ff Doug Wed Nov 7 10:12:42 2012 +0800 Updated TODO again
abb891c Doug Wed Nov 7 10:12:24 2012 +0800 Added more work
c5fd35c Doug Wed Nov 7 10:11:50 2012 +0800 Added more work
a98facd Doug Wed Nov 7 10:11:22 2012 +0800 Add work
b4465be Doug Tue Nov 6 21:38:53 2012 -0800 Updated TODO
403cea9 Doug Fri Jan 2 21:38:53 2009 -0800 Added todo
Right, now I want to squash these last four commits into one commit.
[work2] date
Wed 7 Nov 2012 10:39:39 WST
[work2] git rebase -i b4465be
pick a98facd Add work
squash c5fd35c Added more work
squash abb891c Added more work
squash 5ad95ff Updated TODO to reflect todays work
And the result:
[work2] git log
commit 3f7f1d2eb4ef23c73dce95f718152c7d5683a926
Author: Doug <[email protected]>
Date: Wed Nov 7 10:11:22 2012 +0800
Add work
Added more work
Added more work
Updated TODO to reflect todays work
commit b4465bee5b278214704edcfef3f6e222b5b52964
Author: Doug <[email protected]>
Date: Tue Nov 6 21:38:53 2012 -0800
Updated TODO
No! That's not what I wanted. The timestamp of the resulting commit is the timestamp of the commit we squashed into; what I wanted was the new commit date to be the current time.
Just to show exactly what I'm talking about:
[work2] date
Wed 7 Nov 2012 10:39:39 WST
Author: Doug <[email protected]>
Date: Wed Nov 7 10:11:22 2012 +0800
I want the resulting commit to be date by the merge time, ie. now, not the time of the commit.
As far as I'm aware you can only squash down into a previous commit, not upwards into a new commit, but is there some way of doing this?
The correct solution seems to be
How do I do that?
If the commits to be squahed are not the last few commits, an interactive rebase is needed. Similar to how we reword commits in middle, we start an interactive rebase, but this time instead of reword , we change the pick to s or squash for the second commit meaning squash the second up into the first commit.
In GitHub Desktop, click Current Branch. In the list of branches, select the branch that has the commits that you want to squash. Click History. Select the commits to squash and drop them on the commit you want to combine them with.
In case you are using the Tower Git client, using Interactive Rebase to squash some commits is very simple: just select the commits you want to combine, right-click any of them, and select the "Squash Revisions..." option from the contextual menu.
error: cannot 'squash' without a previous commit You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'. Or you can abort the rebase with 'git rebase --abort'.
Hack: You can use
git commit --amend --reset-author
The git commit man page says that this "also renews the author timestamp". You don't have to make any changes to the commit (I tried it locally), and it will update the timestamp to the current time. Definitely kind of an abuse, but it seems to work.
git commit --amend --date="now"
Or, if you do not want to edit the commit message:
git commit --amend --date="now" --no-edit
By default, amend
will update the Committer date to the current time, but leave the Author commit date untouched.--date="now"
will also set the Author commit date to the current time.
Why does it matter if Author and Committer date are different?
When doing a git log
, by default the Author date is shown (git log --format=fuller
shows the Committer date).
What may be unexpected, however, is if you use since
/until
it uses the Committer date, not the Author date.
This discrepancy can be a bit confusing, or lead to unexpected results.
eg: git log --since="yesterday"
--date
You can commit or amend, setting the Author date to any date:
git commit --date="Wed Apr 15 13:00 2037 -0700"
git commit --amend --date="Wed Apr 15 13:00 2037 -0700"
But, you have to use fixed dates, in a format such as ISO 8601, or Internet Message RFC 2822 Format. YYYY.MM.DD, MM/DD/YYYY, DD.MM.YYYY will all work, but I believe a time must also be included.
source has additional options: https://alexpeattie.com/blog/working-with-dates-in-git
This SO post shows a method to set Commit and Author dates, independently, to specific dates, and on multiple commits. Though it is recommended to not change Commit dates on anything that other people use.
Instead of git rebase -i b4465be
, copy the recent log into the clipboard and do:
git reset --soft b4465be
git commit
paste and edit the change logs, save & exit from the commit message editor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With