2026-01-11 - How to Sign Old Git Commits Without Changing Their Dates

tl;dr: Learn how to sign all your previous Git commits while keeping the original timestamps intact, avoiding the annoying “now” dates that break your commit history.


The Problem

I recently went down a rabbit hole trying to set up commit signing with SSH keys across all my repositories. Everything was working great for new commits, but I had this nagging feeling about all those old commits that weren’t signed yet.

The obvious solution was to rebase and sign them all. But here’s what I discovered: the standard approach resets all your commit timestamps to “now” - meaning your entire commit history suddenly shows as if you wrote all that code today. Not cool.

The Goal: Sign Everything, Keep History Intact

You want to sign all commits from the very beginning (root) of your repository without messing up the timeline.

The basic command people usually suggest is:

git rebase --root --exec "git commit --amend --no-edit -S"

This does sign everything, but it has that timestamp problem I mentioned.

Understanding Git’s Two Dates

Before we fix this, let’s understand what Git tracks:

  1. GIT_AUTHOR_DATE: When you originally wrote the code
  2. GIT_COMMITTER_DATE: When you last modified the commit (like during a rebase)

When you rebase, Git updates the GIT_COMMITTER_DATE to the current time. This makes your history look like all work happened “now”, even though the GIT_AUTHOR_DATE stays correct.

The Solution: Sign and Preserve Original Timestamps

To sign every commit while forcing the GIT_COMMITTER_DATE to match the original GIT_AUTHOR_DATE, use this magic command:

git rebase --root --exec "GIT_COMMITTER_DATE=\$(git show -s --format=%aD) git commit --amend --no-edit -S"

Breaking it down:

  • GIT_COMMITTER_DATE=\$(git show -s --format=%aD): This grabs the current commit’s Author Date (%aD) and sets it as the Committer Date right before amending
  • The backslash \ before the $ is crucial - it ensures the date gets calculated fresh for each commit, not just once when you start

Pushing Your Changes

Since you’re rewriting history, you’ll need to force push:

git push --force-with-lease

Verification: Making Sure It Worked

Check that both dates match and signatures are present with:

git log --pretty=fuller --show-signature

Look for the “G = Good” next to commits (if you have signature verification set up locally).

Why This Matters

Signed commits prove authenticity and integrity. With SSH signing (my preference over GPG), you get cryptographic proof that commits came from you. But if your history shows everything happened today, that authenticity feels a bit fake.

This approach gives you the best of both worlds: proper signing + honest timestamps.

A Word of Warning

This rewrites your entire commit history, so coordinate with collaborators if you’re working on shared repos. For personal projects, it’s usually fine.


Environment:

  • Git 2.34+
  • SSH key configured for signing

References: