git rebase没有改变提交时间戳

在保留提交时间戳的同时执行git rebase是否有意义?

我相信一个后果就是新的分支不一定会按时间顺序提交date。 这在理论上是可能的吗? (例如使用pipe道命令;只是在这里好奇)

如果这在理论上是可行的,那么在实践中是否可以使用rebase,而不是改变时间戳?

例如,假设我有以下树:

 master <jun 2010> | : : : oldbranch <feb 1984> : / oldcommit <jan 1984> 

现在,如果我在master oldbranch ,提交的date从1984年2月更改为2010年6月。是否可以更改该行为,以便提交时间戳不被更改? 最后我会得到:

  oldbranch <feb 1984> / master <jun 2010> | : 

那有意义吗? 它甚至允许在git中有一个旧的提交具有更近的提交作为父母的历史?

如果你已经搞砸了提交date(可能是用rebase)并且想把它们重置为相应的作者date,你可以运行:

git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE'

2014年6月更新: David Fraser 在评论中提到了一个解决scheme,该解决scheme在“更新时间戳,同时重新设定git分支 ”中也有详细说明,使用选项--committer-date-is-author-date (最初于2009年1月在commit 3f01ad6

注意--committer-date-is-author-date选项似乎留下了作者时间戳,并将提交者时间戳设置为与原作者时间戳相同,这是OP Olivier Verdier所需要的。

我发现最后一次提交的date是正确的:

 git rebase --committer-date-is-author-date SHA 

请参阅git am

 --committer-date-is-author-date 

默认情况下,命令将来自电子邮件的datelogging为落实作者date,并使用提交创build时间作为提交者date。
这允许用户通过使用与作者date相同的值来说谎提交者date


(原文,2012年6月)

你可以尝试,为一个非交互式的 rebase

 git rebase --ignore-date 

(从这个答案 )

这是传给git am ,里面提到:

  --ignore-date 

默认情况下,命令将来自电子邮件的datelogging为落实作者date,并使用提交创build时间作为提交者date。
这允许用户通过使用与提交者date相同的值来说谎作者date。

对于git rebase ,这个选项是“与-interactive选项不兼容”。

既然你可以随意更改旧提交date (使用git filter-branch ) 的时间戳 ,我想你可以用你想要/需要的任何提交date顺序来组织你的Git历史logging,甚至将它设置为未来! 。


正如奥利维尔在他的提问中提到的那样, 作者的date永远不会被改变;
从Pro Git Book :

  • 作者是原本写作的人,
  • 而提交者是最后一个应用工作的人。

所以,如果你给一个项目打补丁,而其中一个核心成员应用这个补丁,那么你们都得到了信任。

在这种情况下,如奥利维尔所言:

--ignore-date与我试图达到的目的相反
也就是说,它会删除作者的时间戳,并用提交时间戳replace它们!
所以我的问题的正确答案是:
不要做任何事情,因为默认情况下, git rebase确实不会改变作者的时间戳。


冯·C的一个关键问题帮助我理解了发生了什么事情:当你的基金会, 提交者的时间戳发生变化,而不是作者的时间戳,这一切都是有道理的。 所以我的问题其实不够精确。

答案是rebase实际上不会改变作者的时间戳(你不需要做任何事情),这完全适合我。

默认情况下,git rebase会将提交者的时间戳设置为创build新提交的时间,但保持作者的时间戳完好无损。 大多数情况下,这是期望的行为,但在某些情况下,我们不希望更改提交者的时间戳。 我们怎样才能做到这一点? 那么,这是我通常所做的诀窍。

首先,确保你要提交的每个提交都有一个唯一的提交信息(这就是技巧需要改进的地方,目前它虽然适合我的需求)。

在rebase之前,logging提交者的时间戳和提交所有提交的提交信息,这些提交将被重新发布到一个文件中。

 #NOTE: BASE is the commit where your rebase begins git log --pretty='%ct %s' BASE..HEAD > hashlog 

然后,让实际rebase发生。

最后,如果通过使用git filter-branch提交消息是相同的,我们用当前提交者的时间戳replace文件中logging的时间戳。

  git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_COMMITTER_DATE=$__date || cat' 

如果出现问题,只需签出git reflog或所有的refs/original/ refs。

还有,你可以做类似的事情作者的时间戳。

例如,如果作者的某些提交的时间戳不符合要求,并且不重新排列这些提交,我们只是希望作者的时间戳按顺序显示,那么以下命令将有所帮助。

 git log --pretty='%at %s' COMMIT1..COMMIT2 > hashlog join -1 1 -2 1 <(cat hashlog | cut -f 1 | sort -nr | awk '{ print NR" "$1 }') <(cat hashlog | awk '{ print NR" "$0 }') | cut -d" " -f2,4- > hashlog_ mv hashlog_ hashlog git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_AUTHOR_DATE=$__date || cat'