如何改变Git中一个旧提交的时间戳?

如何修改现有的,提交的提交的答案? 描述一种方法来修改先前未被推送的提交消息。 新消息inheritance原始提交的时间戳。 这似乎是合乎逻辑的,但有没有办法重新设定时代呢?

git filter-branch与envfilter一起使用,该filter将GIT_AUTHOR_DATE和GIT_COMMITTER_DATE设置为您正在修复的提交的特定散列。

这将会使这个和所有将来的哈希无效。

例:

如果你想改变提交119f9ecf58069b265ab22f1f97d2b648faf932e0的date ,你可以这样做:

 git filter-branch --env-filter \ 'if [ $GIT_COMMIT = 119f9ecf58069b265ab22f1f97d2b648faf932e0 ] then export GIT_AUTHOR_DATE="Fri Jan 2 21:38:53 2009 -0800" export GIT_COMMITTER_DATE="Sat May 19 01:01:01 2007 -0700" fi' 

你可以做一个交互式的重新分配,并select编辑提交你想改变的date。 例如,当rebase进程停止修改您input的提交时:

 git commit --amend --date="Wed Feb 16 14:00 2011 +0100" 

之后,你继续你的互动rebase。

更新 (响应studgeek的评论):改变提交date而不是作者date:

 GIT_COMMITTER_DATE="Wed Feb 16 14:00 2011 +0100" git commit --amend 

上面的行设置了一个环境variablesGIT_COMMITTER_DATE,它用于修改提交。

一切都在Git Bash中进行testing。

在一个命令中处理所有这些build议的更好方法是

 GIT_COMMITTER_DATE="`date`" git commit --amend --date "`date`" 

这会将上次提交的提交和作者date设置为“现在”。

只要做git commit --amend --reset-author --no-edit 。 对于较早的提交,您可以执行交互式重新分页,然后为要修改date的提交selectedit

 git rebase -i <ref> 

然后使用--reset-author--no-edit修改提交,将作者date更改为当前date:

 git commit --amend --reset-author --no-edit 

最后继续你的交互式rebase:

 git rebase --continue 

基于theosp的回答 ,我写了一个名为git-cdc (用于更改date提交)的脚本,放在我的PATH

这个名字很重要:你的PATH任何地方的git-xxx都允许你键入:

 git xxx # here git cdc ... 

该脚本是在bash中,即使在Windows上(因为Git将从它的msys环境中调用它)

 #!/bin/bash # commit # date YYYY-mm-dd HH:MM:SS commit="$1" datecal="$2" temp_branch="temp-rebasing-branch" current_branch="$(git rev-parse --abbrev-ref HEAD)" date_timestamp=$(date -d "$datecal" +%s) date_r=$(date -R -d "$datecal") if [[ -z "$commit" ]]; then exit 0 fi git checkout -b "$temp_branch" "$commit" GIT_COMMITTER_DATE="$date_timestamp" GIT_AUTHOR_DATE="$date_timestamp" git commit --amend --no-edit --date "$date_r" git checkout "$current_branch" git rebase --autostash --committer-date-is-author-date "$commit" --onto "$temp_branch" git branch -d "$temp_branch" 

用这个,你可以input:

 git cdc @~ "2014-07-04 20:32:45" 

这会将HEAD( @~ )之前提交的作者/提交date重置为指定的date。

 git cdc @~ "2 days ago" 

这会将HEAD( @~ )之前提交的作者/提交date重置为同一小时,但是2天前。


伊利亚·谢苗诺夫 在评论中提到:

对于OS X,您也可以安装GNU coreutilsbrew install coreutils ),将其添加到PATHPATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" ),然后使用“ 2 days ago ”语法。

git redate -c 3

我为此写了一个脚本/自制软件包。 超级简单的安装,你可以在这里find它: https : //github.com/PotatoLabs/git-redate 。

你只需要运行git redate ,你就可以编辑最近5次提交的vim中的所有date(还有一个-c选项,你可以返回多less次提交,默认是5)。 让我知道如果您有任何问题,意见或build议!

在这里输入图像描述

如果你想改变最近6次提交的date,你可以简单地使用一个交互式rebase:

 git rebase -i HEAD~6 

 pick c95a4b7 Modification 1 pick 1bc0b44 Modification 2 pick de19ad3 Modification 3 pick c110e7e Modification 4 pick 342256c Modification 5 pick 5108205 Modification 6 # Rebase eadedca..5108205 onto eadedca (6 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit 

对于所有需要更改date的提交,请pick edit (或者只是e ),然后保存并退出编辑器。

您现在可以修改每个提交,将当前date设置为:

 git commit --amend --date=now 

或者如果你想要一个ISO-8601格式的指定date:

 git commit --amend --date=2017-10-08T09:51:07 

然后转到下一个提交:

 git rebase --continue 

重复这个过程直到你修改所有的提交。 用git status检查你的进度。

这会更改上次提交的date(时间戳)

git commit --amend --date "Thu May 28 18:21:46 2015 +0530"

如果是以前的最后一次提交。

 git rebase -i HEAD~2 git commit --amend --date=now 

如果你已经推到orgin,可以强制使用:

 git push --force 

如果你不能强制推送,而且推送的话,你不能改变提交! 。

这是一个方便的别名,它将上次提交的提交时间和作者时间更改为date --date接受的date --date

 [alias] cd = "!d=\"$(date -d \"$1\")\" && shift && GIT_COMMITTER_DATE=\"$d\" \ git commit --amend --date \"$d\"" 

用法: git cd <date_arg>

例子:

 git cd now # update the last commit time to current time git cd '1 hour ago' # set time to 1 hour ago 

编辑:这是一个更自动化的版本,它检查索引是否干净(没有未提交的更改),并重复使用上次提交的消息,否则失败(防呆):

 [alias] cd = "!d=\"$(date -d \"$1\")\" && shift && \ git diff-index --cached --quiet HEAD --ignore-submodules -- && \ GIT_COMMITTER_DATE=\"$d\" git commit --amend -C HEAD --date \"$d\"" \ || echo >&2 "error: date change failed: index not clean!" 

下面的bash函数将改变当前分支上任何提交的时间。

如果您已经推送提交或者如果您在另一个分支中使用提交,请小心不要使用。

 # rewrite_commit_date(commit, date_timestamp) # # !! Commit has to be on the current branch, and only on the current branch !! # # Usage example: # # 1. Set commit 0c935403 date to now: # # rewrite_commit_date 0c935403 # # 2. Set commit 0c935403 date to 1402221655: # # rewrite_commit_date 0c935403 1402221655 # rewrite_commit_date () { local commit="$1" date_timestamp="$2" local date temp_branch="temp-rebasing-branch" local current_branch="$(git rev-parse --abbrev-ref HEAD)" if [[ -z "$commit" ]]; then date="$(date -R)" else date="$(date -R --date "@$date_timestamp")" fi git checkout -b "$temp_branch" "$commit" GIT_COMMITTER_DATE="$date" git commit --amend --date "$date" git checkout "$current_branch" git rebase "$commit" --onto "$temp_branch" git branch -d "$temp_branch" } 

如果你想得到另一个提交的确切date(比如说你重新编辑了一个提交,并希望它具有原始预先版本的date):

 git commit --amend --date="$(git show -s --format=%ai a383243)" 

这会将HEAD提交的date更正为提交datea383243(如果有歧义,请包含更多数字)。 它也会popup一个编辑器窗口,以便编辑提交消息。

这是作者的date,这是你通常关心的东西 – 见提交date的其他答案。

要更改作者date和提交date:

 GIT_COMMITTER_DATE="Wed Sep 23 9:40 2015 +0200" git commit --amend --date "Wed Sep 23 9:40 2015 +0200" 

如果要在标准的Windows命令行中执行接受的答案( https://stackoverflow.com/a/454750/72809 ),则需要以下命令:

 git filter-branch -f --env-filter "if [ $GIT_COMMIT = 578e6a450ff5318981367fe1f6f2390ce60ee045 ]; then export GIT_AUTHOR_DATE='2009-10-16T16:00+03:00'; export GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; fi" 

笔记:

  • 也许可以将命令分成多行(Windows支持用分号^分行),但是我没有成功。
  • 您可以编写ISOdate,节省大量的时间来查找正确的星期几和对元素顺序的普遍沮丧。
  • 如果您希望“作者”和“提交者”date相同,则可以引用先前设置的variables。

非常感谢Colin Svingen的博客文章 。 即使他的代码不适合我,它帮助我find正确的解决scheme。

已经有很多很好的答案,但是当我想在一天或一个月内更改多个提交的date时,我找不到合适的答案。 所以我用解释为这个创build一个新的脚本,希望它能帮助某人:

 #!/bin/bash # change GIT_AUTHOR_DATE for commit at Thu Sep 14 13:39:41 2017 +0800 # you can change the data_match to change all commits at any date, one day or one month # you can also do the same for GIT_COMMITTER_DATE git filter-branch --force --env-filter ' date_match="^Thu, 14 Sep 2017 13+" # GIT_AUTHOR_DATE will be @1505367581 +0800, Git internal format author_data=$GIT_AUTHOR_DATE; author_data=${author_data#@} author_data=${author_data% +0800} # author_data is 1505367581 oneday=$((24*60*60)) # author_data_str will be "Thu, 14 Sep 2017 13:39:41 +0800", RFC2822 format author_data_str=`date -R -d @$author_data` if [[ $author_data_str =~ $date_match ]]; then # remove one day from author_data new_data_sec=$(($author_data-$oneday)) # change to git internal format based on new_data_sec new_data="@$new_data_sec +0800" export GIT_AUTHOR_DATE="$new_data" fi ' --tag-name-filter cat -- --branches --tags 

date将被改变:

 AuthorDate: Wed Sep 13 13:39:41 2017 +0800