代码之家  ›  专栏  ›  技术社区  ›  Olivier Verdier

不更改提交时间戳的Git Rebase

  •  130
  • Olivier Verdier  · 技术社区  · 14 年前

    表演有意义吗 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 回复  |  直到 6 年前
        1
  •  123
  •   Community noseratio    7 年前

    2014年6月更新: David Fraser 提到 in the comments 一个解决方案也在 Change timestamps while rebasing git branch “,使用选项 --committer-date-is-author-date (最初于2009年1月引入 commit 3f01ad6

    请注意 --提交日期是作者日期 选项似乎离开了作者时间戳,并将提交者时间戳设置为与原始作者时间戳相同,这就是 OP Olivier Verdier 通缉犯。

    我发现最后一次提交的日期是正确的,并做到了:

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

    git am :

    --committer-date-is-author-date
    

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


    (原始答案,2012年6月)

    你可以尝试一下 非交互式 重碱

    git rebase --ignore-date
    

    (从这个 SO answer )

    这个传给 吉特AM 其中提到:

     --ignore-date
    

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

    为了 git rebase ,此选项“与--interactive选项不兼容”。

    自从 you can change at will the timestamp of old commit date git filter-branch ,我想您可以用您想要/需要的任何提交日期顺序来组织您的Git历史,甚至 set it to the future! .


    AS Olivier 在他的问题中提到, 作者日期 不会被钢筋改变;
    Pro Git Book :

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

    所以,如果您向一个项目发送一个补丁,并且其中一个核心成员应用了这个补丁,那么你们两个都会得到奖励。

    更清楚的是,在这种情况下,正如奥利维尔所说:

    这个 --ignore-date 与我试图达到的目标相反吗? !
    也就是说,它删除作者的时间戳,并用提交时间戳替换它们!
    所以我的问题的正确答案是:
    不要做任何事,因为 GIT重碱 默认情况下不会更改作者的时间戳。


        2
  •  112
  •   Andy    11 年前

    如果您已经将提交日期弄错了(可能使用了一个钢筋网),并希望将其重置为相应的作者日期,则可以运行:

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

        3
  •  30
  •   Olivier Verdier    13 年前

    冯C的一个关键问题帮助我理解了正在发生的事情:当你的钢筋 提交人 时间戳更改,但不是 作者的 时间戳,突然间一切都变得有意义了。所以我的问题实际上不够精确。

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

        4
  •  11
  •   audun torek    7 年前

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

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

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

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

    然后,让实际的重新平衡发生。

    最后,如果提交消息相同,我们使用 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'