关于历史重写(Git),提交作者应该如何处理作者日期?

3
我看到很多关于如何在变基和/或压缩时玩弄作者日期和提交者日期的问题,但我还没有理解为什么。
似乎很清楚,无论另一个人是否代表其作者应用提交,提交者信息都将有所区别(实际上,该人并未重写任何内容)。在将本地(自己的)分支历史记录推送到远程存储库之前,重写它的历史记录呢?
作者有几个选择:
- 修改作者日期以匹配提交者日期。 - 修改提交者日期以保持与作者日期相同。 - 什么都不做。
考虑像这样的东西:

显然,默认的变基会使得在变基提交中两个日期分叉(并且先前提交可能有更早的作者日期!)。压缩将创建一个全新的提交。我不关心它的美观,但是,这有意义吗?在这种情况下,这两个日期的语义是什么?
提前感谢您。
更新:
通过“语义”,我主要是指“传达的意图”。我无论如何都希望不同的工具表现不同,但其他Git用户可以从这两个日期中期待什么?
1个回答

2
Git本身对日期没有语义。嗯,几乎没有。所以这取决于您。主要情况下,Git只显示具有作者日期的提交。如果您使用git log --pretty=fuller,它将显示具有两个日期集的提交,并且就是这样。
唯一的例外情况发生在Git的卑鄙的突起中有多个提交。 git log命令一次只能显示一个提交,但某种原因和方式会告诉您要显示两个或多个提交。例如,假设您有以下内容:
       C--D   <-- br1
      /
...--B
      \
       E--F   <-- br2

当你运行git log br1 br2git log --all时,你告诉Git:展示提交DF,然后从这里向后继续展示更早的提交。那么Git现在应该展示D还是F呢?它有两个选择。
默认情况下,Git会选择具有较晚提交日期的那个。这有点不幸,因为它默认显示的日期是作者日期。但你可以根据自己的需要进行处理。 git log命令有许多选项可以更改它选择先展示D还是F的方式。其中包括--author-date-order--topo-order
一旦Git已经展示了DF中的一个,它就会将CE放入列表中。也就是说,它将展示的提交的父提交放入列表中。现在列表中显示要么C F要么D E。与之前一样,它会根据你告诉它使用的规则集中的任何一个来选择,并展示它。CD的父提交是B,所以如果它刚展示了其中任何一个,现在就会将B放入列表中。这样一遍遍地重复,直到列表收缩到只有一个条目为止——由于规则往往倾向于完成C-DE-F链,然后再回到B,因此这通常会很快发生。此外,一些规则(如--topo-order)告诉Git,即使B上的日期很奇怪,它也必须让它发生。
如果你发现Git以奇怪的顺序列出事物,请使用git log --graph(也许还要加上--oneline)。--graph选项告诉git log两件事:
  1. 绘制提交日志的粗略基于ASCII的文本图形。它是垂直定向的,而不是像我在StackOverflow帖子中通常做的那样水平定向的,但对于简单的图形或图形片段,这样做没问题。

  2. 在进行图形遍历时使用--topo-order。也就是说,一旦Git开始沿着C-D路径,它将在开始E-F路径之前完成该路径。

你可以用--date-order--author-date-order等参数来覆盖默认的--topo-order

在合并时,你经常会看到这种非线性行为

请注意,无论提交的日期顺序如何,如果Git只有一个提交记录(例如你输入了git log br1以便从D开始),它只会显示那个提交记录。然后清空其要显示的提交列表,将D的父提交放入列表中。现在列表中列出了C,因此Git会显示C,然后再次清空列表,但是将B放入列表中。所以现在Git会显示B,然后再次清空列表,但是将B的父提交放入其中,以此类推。结果是一个简单的、线性的、向后的遍历。因此,如果没有合并提交,并且你从分支的末尾开始Git,你只会看到该分支:

...--o--o--o--tip   <-- branch

但如果存在合并提交

最初的回答:

          C--D
         /    \
...--o--o      G--o--...--tip  <-- branch
         \    /
          E--F

当Git显示G时,它将DF放入其列表中。现在你处于两个提交在列表中的情况下,你需要考虑先显示哪个提交,就像使用git log --all一样。
如果你使用--first-parent强制Git不要跟随合并的另一个分支,这个问题就会完全消失。有时这是好事,有时不是。如果你使用--graph让Git画出图形,有时这很有帮助,但有时图形会变得非常复杂。

GitHub有时很烦人

虽然这与Git无关,但值得在此提及的是,一旦GitHub开始在拉取请求中显示提交,GitHub开始使用自己的提交排序规则,而不是所有正常的Git规则。这些规则对GitHub的工作人员来说是有意义的,但对许多GitHub用户来说却不是那么合理。在这里,您需要与GitHub的工作人员交流。

谢谢,这是一篇非常详细的关于Git如何处理它们之间差异的解释。然而,也许我在使用“语义”这个词时有些模糊。你在最后一段中提到了它(GitHub)。我的意思是“传达的意图”,而不仅仅是Git客户端行为的变化。你能否再加点关于这方面的内容呢?这将使你的回答更加全面!我也会更新我的问题。谢谢! - NiNEngine
很难进一步概括:如果有人(或某些软件)确实使用日期进行某些操作,那么使用哪个日期(或日期,因为有两个日期),以及用于什么目的,取决于使用者。我在GitHub部分提到的排序并不是由任何日期强制执行的顺序。作为一个实验,我创建了具有奇数日期排序的提交,并将它们放入拉取请求中,它们按照提交图形顺序而不是日期顺序显示。似乎GitHub有一些晦涩的算法(我无法推断出来),他们试图“锁定”[继续] - torek
一旦人们开始在拉取请求上发表评论,您可以“锁定”提交的顺序。如果您进行了变基并重写了某些提交,包括更改它们的图形顺序,并将其推送到正在进行的拉取请求中,GitHub有时会重新排列它们以匹配原始显示的排列顺序,而不是修订后的图形顺序。他们如何做到这一点仍然是个谜。 - torek
在GitHub部分提到的排序并不是基于任何日期强制执行的顺序。是的,我理解这一点。我之所以问这个问题,是因为我希望GitHub能够根据自己的理解尝试逻辑使用日期,但没有强制规定。现在我明白其他标准也可能被考虑进来。关于主要问题,这真是遗憾,因为在那些不太常见的情况下,事情可能会变得很糟糕。非常感谢您的一切! - NiNEngine
奇怪的是,GitHub网页上说它根据在提交中发表的评论的时间顺序对拉取请求进行排序,但这也不可能,因为您可以强制推送并拥有不同的提交集。 - torek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接