git-redate
Rewrite author and committer timestamps for one or more commits using
git rebase -i with an injected GIT_SEQUENCE_EDITOR. No external plugins required.
⚠️ This rewrites commit history. Safe for unpushed commits. For already-pushed commits a
git push --force-with-leasewill be needed afterward.
Script
./scripts/redate.py
Resolve against the skill directory:
~/.pi/agent/skills/git-redate/scripts/redate.py
Modes
Auto mode — move all weekend commits in a range
Scans a commit range, finds Saturday/Sunday commits, moves them to Monday or Friday.
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py [--range RANGE] [--move-to monday|friday] [--dry-run]
| Option | Default | Description |
|---|---|---|
--range RANGE |
@{u}..HEAD |
Range to scan — default is all unpushed commits |
--move-to monday|friday |
monday |
Where to move Saturday/Sunday commits |
--dry-run |
— | Preview without touching history |
Manual mode — set specific commits to specific dates
Explicitly name which commits to rewrite and to what date/time. Repeatable.
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py --set HASH DATE [--set HASH2 DATE2 ...] [--dry-run]
| Argument | Description |
|---|---|
HASH |
Full or short commit hash (e.g. a1b2c3d) |
DATE |
Target date/time — see formats below |
DATE formats:
| Format | Example | Time behaviour |
|---|---|---|
YYYY-MM-DD |
2025-01-20 |
Preserves original time of day |
YYYY-MM-DDTHH:MM |
2025-01-20T14:30 |
Sets exact time |
YYYY-MM-DDTHH:MM:SS |
2025-01-20T14:30:00 |
Sets exact time |
YYYY-MM-DD HH:MM |
2025-01-20 14:30 |
Sets exact time |
Agent workflow
For "move weekend commits" requests
- Run auto dry-run to show what will change:
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py --dry-run - Present the output to the user.
- If the user explicitly requested this rewrite and the dry-run matches the requested scope, apply without asking again. Otherwise ask for authorization before applying:
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py
For "change specific commits" requests
- Show the user recent commits so they can identify which ones to change:
git log --format="%h %ad %s" --date=format:"%a %Y-%m-%d %H:%M" -n 20 - Understand the user's intent — e.g.:
- "change
a1b2c3dto last Wednesday" - "move these two commits to Monday morning"
- "set commit
deadbeefto 2025-01-15 at 10:00"
- "change
- Resolve natural-language dates to concrete
YYYY-MM-DDorYYYY-MM-DDTHH:MMvalues using the current date as reference. - Run dry-run and present the planned changes:
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py \ --set a1b2c3d 2025-01-15 \ --set deadbeef 2025-01-15T10:00 \ --dry-run - If the request already specified the commits and target dates and the dry-run matches it, apply without another confirmation. Otherwise ask the user to authorize the concrete dry-run plan before applying without
--dry-run.
After applying
Always verify the result:
git log --format="%h %ad %s" --date=format:"%a %Y-%m-%d %H:%M" -n 20
Example invocations
# Auto: preview all unpushed weekend commits
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py --dry-run
# Auto: move unpushed weekend commits to Monday
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py
# Auto: move to Friday, custom range
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py --range main..HEAD --move-to friday
# Manual: move one commit to a specific date (preserves original time)
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py --set a1b2c3d 2025-01-20
# Manual: move one commit to a specific date and time
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py --set a1b2c3d 2025-01-20T10:30
# Manual: rewrite multiple commits at once
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py \
--set a1b2c3d 2025-01-20 \
--set b2c3d4e 2025-01-21T09:00 \
--set c3d4e5f 2025-01-22
# Manual: dry-run first
python3 ~/.pi/agent/skills/git-redate/scripts/redate.py \
--set a1b2c3d 2025-01-20 \
--dry-run
How it works
- Auto mode:
git logcollects commits in the range. Weekend commits get their timestamps shifted ±1–2 days (time of day preserved). - Manual mode: each
--set HASH DATEpair is resolved viagit rev-parse. If only a date is given, the commit's original time is preserved. The rebase base is computed automatically from the oldest targeted commit. - A temporary
GIT_SEQUENCE_EDITORscript is generated that injectsexec env GIT_COMMITTER_DATE='...' git commit --amend --no-edit --date='...'after the relevantpicklines in the rebase todo. (--datesets author date;GIT_COMMITTER_DATEsets committer date.) git rebase -i <base>runs with that editor. The script has its own confirmation prompt; answer it affirmatively only when the rewrite is authorized under the global policy.- Temp files are cleaned up automatically.
Troubleshooting
| Problem | Fix |
|---|---|
fatal: no upstream configured |
Pass --range HEAD~N..HEAD explicitly |
| Rebase fails mid-way | Run git rebase --abort to restore |
| Uncommitted changes | Stop and ask the user to commit/discard them or explicitly request a stash; never stash automatically |
| Already-pushed commits | Report that git push --force-with-lease will be required; never force-push unless the user explicitly requests it |
| Commit not in branch history | Make sure you are on the correct branch |