Ever needed to move a batch of commits from one branch to another — and make them look like they happened right now? Maybe you're cleaning up your Git history before opening a PR, or reorganizing work across branches after the fact.
Whatever the reason, Git makes this surprisingly doable. Here's how.
The Scenario
You're on a branch called feature-branch and the last 6 commits need to move to a brand new branch called clean-branch. You also want every commit's timestamp to reflect the current time instead of when you originally wrote the code.
By the end of this tutorial:
- ✅ A new branch will have your commits with fresh timestamps
- ✅ The original branch will no longer contain those commits
- ✅ All commit messages and file changes stay intact
Step 1: Note Your Commit Hashes
First, grab the hashes of the commits you want to move. We'll list them oldest-first so they replay in the right order:
git log -6 --reverse --pretty=format:"%h %s"
You'll see something like:
a1b2c3d feat: add user settings page
d4e5f6a fix: sidebar alignment on mobile
...
Step 2: Create the New Branch
Create your new branch starting from the point before those 6 commits:
git checkout -b clean-branch HEAD~6
This puts you on clean-branch, which currently has everything your original branch had except the last 6 commits.
What does
HEAD~6mean?
It means "the commit that is 6 steps before the current one." So the new branch starts right where those 6 commits began.
Step 3: Cherry-Pick With New Timestamps
Now replay each commit onto the new branch, but override the timestamp. Replace the hashes below with your actual ones from Step 1:
NOW="2026-06-24T02:50:33+06:00"
for hash in a1b2c3d d4e5f6a g7h8i9j k0l1m2n o3p4q5r s6t7u8v; do
GIT_AUTHOR_DATE="$NOW" GIT_COMMITTER_DATE="$NOW" git cherry-pick --no-edit "$hash"
done
Replace the NOW value with your desired timestamp, or use the current time dynamically:
NOW=$(date -Iseconds)
Wait — Git has two dates?
Yes! Every commit stores two timestamps:
| Date | What it means |
|---|---|
| Author date | When the change was originally written |
| Committer date | When the commit was last applied (rebased, cherry-picked, amended) |
Tools like GitHub show the author date by default. The GIT_AUTHOR_DATE and GIT_COMMITTER_DATE environment variables let you override both.
Step 4: Verify the Timestamps
Confirm that both dates were updated:
git log -6 --pretty=format:"%h | %s | Author: %ad | Committer: %cd" --date=iso
Every commit should now show your chosen timestamp for both fields.
Step 5: Remove the Commits From the Original Branch
The commits still exist on your original branch. To "move" them (not just copy), reset that branch back:
git branch -f feature-branch feature-branch~6
This rewrites the feature-branch pointer to exclude the last 6 commits. Since you've already got them on clean-branch, nothing is lost.
The Quick Version
If you want the whole thing as a copy-paste script:
# Config — edit these
SOURCE_BRANCH="feature-branch"
NEW_BRANCH="clean-branch"
NUM_COMMITS=6
NOW=$(date -Iseconds)
# 1. Get commit hashes (oldest first)
HASHES=$(git log -$NUM_COMMITS --reverse --pretty=format:"%h")
# 2. Create new branch from before those commits
git checkout -b $NEW_BRANCH ${SOURCE_BRANCH}~${NUM_COMMITS}
# 3. Cherry-pick with updated timestamps
for hash in $HASHES; do
GIT_AUTHOR_DATE="$NOW" GIT_COMMITTER_DATE="$NOW" git cherry-pick --no-edit "$hash"
done
# 4. Remove commits from original branch
git branch -f $SOURCE_BRANCH ${SOURCE_BRANCH}~${NUM_COMMITS}
# 5. Verify
git log -$NUM_COMMITS --pretty=format:"%h | %ad | %s" --date=iso
Good to Know
-
This rewrites history. The new commits will have different hashes. If the original branch was already pushed, you'll need to force-push (
git push --force) — coordinate with your team first. - Cherry-pick preserves authorship. The commit author name and email stay the same; only the dates change.
- Conflicts are possible. If the commits depend on each other in tricky ways, cherry-pick will pause and ask you to resolve conflicts, just like a rebase would.
-
Want different timestamps per commit? Instead of a single
$NOW, you can set a unique date inside the loop for each cherry-pick.
That's it — six commits, new branch, clean timestamps. Happy rebasing! 🎉













