gitrebasegit-rebasesquashgit-squash

Can squash commits be done in both directions of the timestamp?


Say there is a squash of 3 commits into a single commit like so:

pick   abc Jan 1 stuff
squash def Jan 2 stuff
squash ghi Jan 3 stuff
pick   jkl Jan 4 stuff
pick   mno Jan 5 stuff

In the above, my understanding is that commits for Jan 1, 2, and 3 are squashed into a single commit. The resulting single commit is dated Jan 1 from the oldest of the 3.

Is there a way to squash in the other direction of the timestamp? Could Jan 1, 2, and 3 commits be squashed into a single commit, which is dated Jan 3?


Solution

  • If reordering the commits works without conflicts, then @phd's answer works right out.

    Otherwise: you can edit the author date after the facts, by setting GIT_AUTHOR_DATE=... or by using git commit --date=....

    For example:

    # in the interactive rebase todo script:
    pick   abc Jan 1 stuff
    squash def Jan 2 stuff
    squash ghi Jan 3 stuff  # <- write down the hash or short hash for 'ghi'
    
    break   # <- the rebase will pause here after squashing together the 3 commits
    
    pick   jkl Jan 4 stuff
    pick   mno Jan 5 stuff
    # save and close
    
    # when stopped after squashing: get the commit date from commit 'ghi'
    $ git log -1 --format="%ad" ghi
    $ git commit --date="<the date above>" --amend
    
    
    # in one go:
    $ git commit --date="$(git log -1 --format="%ad" ghi)" --amend
    
    # if all is to your liking:
    $ git rebase --continue