git rebase而不更改提交时间戳

时间:2010-06-04 12:20:28

标签: git timestamp git-rebase

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

我认为结果是新分支不一定按时间顺序排列日期。那理论上可能吗? (例如使用管道命令;这里很好奇)

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

例如,假设我有以下树:

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

现在,如果我在oldbranch上重新定义master,则提交日期将从1984年2月更改为2010年6月。是否可以更改该行为以便不更改提交时间戳?最后我会得到:

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

这有意义吗?甚至在git中是否允许有一个旧提交最近提交作为父项的历史记录?

4 个答案:

答案 0 :(得分:127)

2014年6月更新:David Fraser使用选项--committer-date-is-author-date(最初于2009年1月在{{3中引入)中提及“in the comments”中详述的解决方案Change timestamps while rebasing git branch }}

  

请注意,--committer-date-is-author-date选项似乎保留了作者的时间戳,并将提交者时间戳设置为与原始作者时间戳相同,这是commit 3f01ad6所需的。

     

我发现最后一次提交的日期正确,并且确实:

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

请参阅OP Olivier Verdier

--committer-date-is-author-date
  

默认情况下,该命令将电子邮件中的日期记录为提交作者日期,并将提交创建时间用作提交者日期。
  这允许用户使用与作者日期相同的值来说谎提交者日期。


(原始答案,2012年6月)

您可以尝试使用非交互式 rebase

git rebase --ignore-date

(来自此git am

这传递给SO answer,提及:

 --ignore-date
  

默认情况下,该命令将电子邮件中的日期记录为提交作者日期,并将提交创建时间用作提交者日期。
  这允许用户使用与提交者日期相同的值来说谎作者日期。

对于git am,此选项为“与--interactive选项不兼容。”

git rebase(带you can change at will the timestamp of old commit date)以来,我认为您可以使用您想要/需要的任何提交日期顺序来组织您的Git历史记录,甚至是git filter-branch


正如set it to the future!在他的问题中提到的那样,作者日期永远不会被rebase改变;
来自Olivier

  
      
  • 作者是最初撰写作品的人,
  •   
  • 而提交者是最后一次申请工作的人。
  •   
     

因此,如果您向项目发送补丁并且其中一个核心成员应用了补丁,那么您都会获得信誉。

要明确,在这种情况下,正如奥利维尔的评论:

  

--ignore-date与我想要实现的目标相反
  也就是说,它会删除作者的时间戳并将其替换为提交时间戳!   所以我的问题的正确答案是:
  不要做任何事情,因为git rebase实际上并没有默认改变作者的时间戳。


答案 1 :(得分:113)

如果您已经搞砸了提交日期(可能带有rebase)并希望将它们重置为相应的作者日期,则可以运行:

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

答案 2 :(得分:30)

关于Von C的一个关键问题帮助我理解了发生了什么:当您的rebase,提交者的时间戳发生变化时,而不是作者的时间戳,这突然之间感。所以我的问题实际上不够精确。

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

答案 3 :(得分:13)

默认情况下,git rebase会将提交者的时间戳设置为时间戳 创建了新提交,但保持作者的时间戳保持不变。大部分时间, 这是期望的行为,但在某些情况下,我们不希望改变 提交者的时间戳也是。我们怎样才能做到这一点?好吧,这是 我经常做的伎俩。

首先,确保您要进行rebase的每个提交都具有唯一性 提交消息和作者时间戳(这是技巧需要改进的地方,但目前它适合我的需要)。

在rebase之前,记录提交者的时间戳,作者的时间戳以及将被重新绑定到文件的所有提交的提交消息。

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

然后,让实际的rebase发生。

最后,如果使用git filter-branch提交消息相同,我们将当前提交者的时间戳替换为文件中记录的时间戳。

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

如果出现问题,只需检查git reflog或所有refs/original/参考号。

更进一步,你可以对作者的时间戳做类似的事情。

例如,如果作者的某些提交的时间戳不正常,那么 如果没有重新排列这些提交,我们只想让作者的时间戳显示出来 顺序,然后以下命令将有所帮助。

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'