image-20260701111054786

你有没有遇到过这种情况——

凌晨三点赶完需求,提交代码,第二天看 commit 记录,时间戳赫然写着 03:47:22……老板路过瞥了一眼,你尴尬地笑了笑。

或者,某个历史提交的时间记录有误,想统一整理项目时间线,却不知道从哪下手。

还有一种更隐蔽的尴尬:跳槽交接项目,前公司仓库的提交记录一团糟,新老板看了你的 GitHub,默默皱了皱眉……

今天这篇文章,教你 3 种方法 修改 Git 提交时间——从改一条到改一百条,最后还附一个 一键交互脚本,开箱即用。


先搞懂:Git 时间戳,没你想的那么「神圣」

很多同学以为 Git 的提交时间是不可篡改的「历史档案」。其实并不是——Git 的时间戳本质上只是提交对象里的一个字段,完全可以修改。

Git 里其实有 两个时间

字段含义谁能看到
AuthorDate(作者时间)代码是什么时候写的git log 默认显示这个
CommitterDate(提交时间)提交动作发生的时间git log --format=fuller 可查看

两个都可以改。下面从易到难,讲三种方案。


方法一:改最近一次提交(10 秒搞定)

刚提交完发现时间不对?一行命令:

# 改为当前时间
git commit --amend --date=now --no-edit

# 改为指定时间(推荐带时区的 ISO 格式,当然了 yyyy-MM-dd HH:mm:ss 格式的时间也支持,如 2026-06-30 21:00:00)
GIT_COMMITTER_DATE="2026-06-30T21:00:00+0800" \
git commit --amend --date="2026-06-30T21:00:00+0800" --no-edit

💡 注意--amend 只能改最近一次提交。如果 --dateGIT_COMMITTER_DATE 只设一个,两个时间会不一致,建议两个一起设。


方法二:改历史提交(filter-branch 方案)

如果要改的不是最近一次,而是更早的提交,需要借助 filter-branch

原理

git filter-branch --env-filter 会遍历整个提交历史,对每一个提交执行你指定的 shell 脚本。通过 $GIT_COMMIT 判断当前是不是目标提交,然后覆盖 GIT_AUTHOR_DATEGIT_COMMITTER_DATE 两个环境变量。

# 第一步:找到目标提交的完整 hash
git log --oneline

# 第二步:执行修改
FILTER_BRANCH_SQUELCH_WARNING=1 \
git filter-branch -f --env-filter '
  if [ "$GIT_COMMIT" = "完整hash值" ]; then
    export GIT_AUTHOR_DATE="2026-06-30T21:00:00+0800"
    export GIT_COMMITTER_DATE="2026-06-30T21:00:00+0800"
  fi
' -- HEAD

批量修改多个提交

要同时改多条,把多个 hash 放进 case 语句,只跑一次 filter-branch

FILTER_BRANCH_SQUELCH_WARNING=1 \
git filter-branch -f --env-filter '
  case "$GIT_COMMIT" in
    aabbcc11*)
      export GIT_AUTHOR_DATE="2026-06-30T02:22:39+0800"
      export GIT_COMMITTER_DATE="2026-06-30T02:22:39+0800" ;;
    ddeeff22*)
      export GIT_AUTHOR_DATE="2026-06-30T01:49:26+0800"
      export GIT_COMMITTER_DATE="2026-06-30T01:49:26+0800" ;;
  esac
' -- HEAD

⚠️ 为什么不能循环调用多次 filter-branch?
每次执行后,所有提交的 hash 都会被重写。第二次拿着旧 hash 去匹配,永远匹配不上。所以多条一定要合并成一次调用。


方法三:改历史提交(rebase 方案,更推荐)

filter-branch 虽然强大,但 Git 官方已经不太推荐了。对于少量提交的修改,git rebase 交互模式更安全、更直观:

# 1. 启动交互式 rebase,回退 N 条提交
git rebase -i HEAD~5

# 2. 在编辑器中,把要改的提交前面的 pick 改成 edit
#    pick aabbcc1  feat: xxx
#    edit ddeeff2  fix: yyy    ← 改成 edit
#    pick 1122334  docs: zzz

# 3. Git 会暂停在你要改的提交上,此时执行:
GIT_COMMITTER_DATE="2026-06-30T21:00:00+0800" \
git commit --amend --date="2026-06-30T21:00:00+0800" --no-edit

# 4. 继续到下一个
git rebase --continue

# 5. 重复步骤 3-4,直到全部改完

💡 rebase vs filter-branch 怎么选?

  • 改 1~3 条 → 用 rebase,更安全直观
  • 改 5 条以上 → 用 filter-branch,批量效率高
  • 改 20 条以上 → 直接用下面的一键脚本

时间格式备忘

Git 支持多种时间格式,推荐用带时区的 ISO 格式,避免歧义:

# ✅ 推荐:ISO 8601 含时区
2026-06-30T21:00:00+0800

# ✅ 也支持
"2026-06-30 21:00:00"
"Mon Jun 30 21:00:00 2026 +0800"
now        # 当前时间
yesterday  # 昨天

# ❌ 不推荐:不带时区,容易和服务器时区冲突
2026-06-30T21:00:00

一键脚本:懒人福音

每次手动查 hash、拼命令太麻烦?我写了一个交互式脚本,开箱即用

🔗 GitHub 地址git-change-commit-time.sh

这个脚本比你想象的要靠谱得多,来看几个亮点:

支持两种使用方式

# 方式一:全交互模式(跟着提示走就行)
bash git-change-commit-time.sh

# 方式二:命令行直传参数(适合写进 CI 或自动化脚本)
bash git-change-commit-time.sh -c 1,3-5 -d "2026-06-30"
bash git-change-commit-time.sh -c 3 -d "2026-06-30 10:30:00"

支持:

  • 列出最近 20 条提交,输入序号选择
  • 支持多选31,3,52-51,3-5 随意组合
  • 两种修改模式
    • 只输入 YYYY-MM-DD:仅替换日期,时分秒保留原值
    • 输入 YYYY-MM-DD HH:MM:SS:完整替换
  • 执行前展示变更摘要,二次确认

交互模式效果演示

╔══════════════════════════════════════╗
║    Git 提交时间修改工具               ║
╚══════════════════════════════════════╝

最近 20 条提交:
──────────────────────────────────────────────────────────
   1. 7ce9d05  2026-07-01 10:41:07  feat: xxx
   2. bb4aeb3  2026-07-01 10:15:05  style: 更新图标
   3. bbe61de  2025-06-30 21:39:45  rename: 重命名插件
   ...
──────────────────────────────────────────────────────────
请输入序号: 6-11

请输入新时间: 2026-06-30
[INFO]  模式:仅替换日期 → 2026-06-30(时分秒保留原值)

即将修改以下提交:
──────────────────────────────────────────────────────────
  b5b96ba  2025-06-30 02:22:39 → 2026-06-30T02:22:39+0800
  e9970d9  2025-06-30 02:01:39 → 2026-06-30T02:01:39+0800
  ...
──────────────────────────────────────────────────────────
确认修改?(y/N): y
[OK]    共修改 6 条提交完成!

⚠️  如已推送到远程,需要强制推送:
  git push --force-with-lease

💡 为什么不直接贴代码? 脚本有 200+ 行,在手机上阅读体验极差。点上方 GitHub 链接直接拿最新版,也方便后续更新维护。


推送到远程

修改历史提交后,本地和远程的提交 hash 已经不同,需要强制推送:

# ✅ 推荐:比 --force 更安全,防止覆盖别人的推送
git push --force-with-lease

# ⚠️ 不推荐:可能覆盖别人的推送
git push --force

🚨 多人协作必看
强制推送会导致他人本地分支与远程分叉,同事需要 git fetch && git reset --hard origin/branch 重新同步。改之前务必在群里通知一声!


避坑指南:这些错误别犯

后果正确做法
只改 --date 没改 GIT_COMMITTER_DATE两个时间不一致,git log --format=fuller 露馅两个一起设
循环调用多次 filter-branch第二次拿旧 hash 匹配,永远改不到合并成一次 case 调用
不带时区的时间格式服务器时区不同导致时间偏移+0800+0900 明确时区
改完直接 git push --force覆盖同事的提交,引发事故--force-with-lease
改了已推送的提交不通知团队同事拉取冲突,浪费时间提前在群里说明

总结速查表

场景方案难度
改最近一次提交git commit --amend --date=...
改 1~3 条历史提交git rebase -i + --amend⭐⭐
改 5+ 条历史提交filter-branch + case 语句⭐⭐⭐
改 20+ 条 / 懒得手敲一键脚本 GitHub
改完推送远程git push --force-with-lease

Git 的时间戳从来不是枷锁,合理使用,让提交历史更整洁、更专业。


📌 觉得有用?三个动作帮到你身边的同学:

  1. 转发 给还在为提交时间烦恼的同事
  2. 收藏 这篇,下次改时间直接翻出来用
  3. 留言 告诉我:你还想了解哪些 Git 骗操作?

下一期我们聊聊:如何用 Git Hooks 自动化你的工作流,关注不迷路 👆

Q.E.D.


寻门而入,破门而出