Git和日志顺序

时间:2012-06-04 18:09:10

标签: git

我试图从“git log”输出创建一个线性顺序,但我的所有尝试都失败了。我需要做的是将提交映射到包含该提交的下一个版本。我无法运行

git tag --contains <commit>

对于每个提交,因为我们的存储库包含非常大量的提交(超过300,000)。

首先我尝试使用

git log --pretty=format:"%ct%H" | sort --key=1,10 

根据提交时间获取线性顺序。但是,这似乎不会产生100%准确的结果。这引出了我的第一个问题:

Q1)当提交被推送到主存储库时,git如何提交提交时间?它是否以UTC格式存储每次提交的当前机器时间?

我还查看了“git help log”,文档说明默认情况下,git log按时间顺序列出提交。在我的项目中,我检查了是否引入了任何错误,但据我所知,代码是正确的,并且git log给出的时间顺序不是线性顺序。最后,我的问题是?

Q2)如果git不存储修订号,怎样才能从“git log”获得线性顺序?

谢谢:)

1 个答案:

答案 0 :(得分:11)

#1:当提交被推入主存储库时,git存储提交时间如何?它是否以UTC格式存储每次提交的当前机器时间?

来自man git-commit

  

Git内部格式
  它是[unix timestamp] [timezone offset],其中[unix timestamp]是自UNIX纪元以来的秒数。 [timezone offset]是UTC的正偏移或负偏移。

基于此,git内部使用的时间格式为UNIX epoch time,包括机器UTC偏移量。

#2:如果git不存储修订号,怎么能从“git log”获得线性顺序?

您使用的方法(git log --pretty=format:"%ct%H")将从已合并到当前分支的所有分支中提取数据。

这使得“线性顺序”有些困难。请考虑以下[source: git-scm.org]:

Multiple branches, pre-merge

所以,在这里,我们已经有几个'主题分支'正在进行中。然后我们决定保留一些(dumbideaiss91v2),丢弃其他人(iss91)。因此,我们放弃C5C6,保留其他提交,我们的合并后历史记录如下[source: git-scm.org]:

Post-merge

(箭头 children 指向 parents; C14是提交的 C13C11)。

所以现在我们有一个HEAD提交,为了论证,我们假设我们将以RELEASE1或其他方式发布。那么,对于这样一个问题:我们现在怎样才能提供一个线性,按时间顺序排列的正确提交列表?

简单回答:我不相信你可以 - 或者,如果你这样做,我不相信它会是你想要的。

可以按时间线性地对提交进行排序:

git log --pretty=format:"%ct %H" | sort --key=1,10

那会给你一个对应的列表:

C1
C2
... snip ...
C13
C14

但请注意,此实际上并不是线性历史记录!这是因为我们将一些分支合并在一起,这些分支是同时创建的 。我们无法提取C14(我们的HEAD)父母的线性历史记录,因为没有一个 - 它是两个分支的子代,而不是单个提交的子代,并且不是线性关系。

所以,你说,或许我可以得到一个分支的线性历史?例如C14 -> C13 ... C3 -> C1

这也至少非常困难并且(更有可能)不可能。

当我们有多个分支加入(三向或多向合并)时,这个问题更加复杂。 This question详细介绍了无法提取“单个分支”历史的原因 - 当您查看合并提交的父级时,如何确定哪个是“单个分支” '和'加入'分支是哪个?


说了这么多,如果你用图表格式检查这个小存储库的日志:(我确实剪了一些没用的提交)


zsh% git log --graph --all --format=format:'%C(blue)%h%C(reset) - %C(green)(%cr)%C(reset)                %C(yellow)%d%C(reset)' --abbrev-commit --date=relative
* 3cf5f06 - (8 weeks ago)  (origin/master, origin/HEAD, master)
* a3a3205 - (4 months ago) 
* c033bf9 - (4 months ago)  (origin/svg)
* ccee435 - (4 months ago) 
*   f08bc1e - (4 months ago) 
|\  
| * 48c4406 - (5 months ago) 
* | 203eeaa - (4 months ago) 
* | 5fb0ea9 - (5 months ago) 
|/  
* 39bccb8 - (5 months ago)

请注意,此历史记录按时间顺序;然而,分支并没有“扁平”成一个,所以它看起来有点时髦。每个提交都包含在当前HEADmasterorigin/master)中。这很明显,因为历史记录中的两个叉子已合并在一起(合并位于f08bc1e)。

#3:我需要做的是将提交映射到包含该提交的下一个版本

如果您对个人提交感兴趣,this questionif your releases are tagged会有所帮助。

阅读问题时,您似乎可能想要将每个提交映射到一个版本;这是很多工作,我对此无能为力 - 我认为你不需要检查每个提交,因为分支将被合并,如果线性分支的头部在发布中,线性父母也将。除非你做过樱桃采摘或类似的。

如果按时间排序,则检查所有早于旧版本的提交,记录该提交ID(如果它包含在最旧的,然后是第二个最旧的等),并在找到发布时从列表中删除提交如果包含它,您最多只需检查number of releases * number of commits;在最坏的情况下,任何版本都没有提交。最好的情况,版本包含比自身更早的每个提交,这是300,000检查。仍然很多,但(对我天真的头脑),可行。

(长篇回复道歉)。