我试图从“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”获得线性顺序?
谢谢:)
答案 0 :(得分:11)
Git内部格式
它是[unix timestamp] [timezone offset],其中[unix timestamp]是自UNIX纪元以来的秒数。 [timezone offset]是UTC的正偏移或负偏移。
基于此,git内部使用的时间格式为UNIX epoch time,包括机器UTC偏移量。
您使用的方法(git log --pretty=format:"%ct%H"
)将从已合并到当前分支的所有分支中提取数据。
这使得“线性顺序”有些困难。请考虑以下[source: git-scm.org]:
所以,在这里,我们已经有几个'主题分支'正在进行中。然后我们决定保留一些(dumbidea
和iss91v2
),丢弃其他人(iss91
)。因此,我们放弃C5
和C6
,保留其他提交,我们的合并后历史记录如下[source: git-scm.org]:
(箭头从 children
指向 parents
; C14
是提交的子 C13
和C11
)。
所以现在我们有一个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)
请注意,此历史记录按时间顺序;然而,分支并没有“扁平”成一个,所以它看起来有点时髦。每个提交都包含在当前HEAD
(master
,origin/master
)中。这很明显,因为历史记录中的两个叉子已合并在一起(合并位于f08bc1e
)。
如果您对个人提交感兴趣,this question或if your releases are tagged会有所帮助。
阅读问题时,您似乎可能想要将每个提交映射到一个版本;这是很多工作,我对此无能为力 - 我认为你不需要检查每个提交,因为分支将被合并,如果线性分支的头部在发布中,线性父母也将。除非你做过樱桃采摘或类似的。
如果按时间排序,则检查所有早于旧版本的提交,记录该提交ID(如果它包含在最旧的,然后是第二个最旧的等),并在找到发布时从列表中删除提交如果包含它,您最多只需检查number of releases
* number of commits
;在最坏的情况下,任何版本都没有提交。最好的情况,版本包含比自身更早的每个提交,这是300,000
检查。仍然很多,但(对我天真的头脑),可行。
(长篇回复道歉)。