我试图从"git log"输出创建一个线性顺序,但我的所有尝试都失败了.我需要做的是将提交映射到包含该提交的下一个版本.我跑不了
git tag --contains <commit>
Run Code Online (Sandbox Code Playgroud)
对于每个提交,因为我们的存储库包含非常大量的提交(超过300,000).
首先我尝试使用
git log --pretty=format:"%ct%H" | sort --key=1,10
Run Code Online (Sandbox Code Playgroud)
根据提交时间获得线性顺序.但是,这似乎不会产生100%准确的结果.这导致了我的第一个问题:
Q1)当提交被推入主存储库时,git存储提交时间如何?它是否以UTC格式存储每次提交的当前计算机时间?
我还查看了"git help log",文档说明默认情况下,git log按时间顺序列出提交.在我的项目中,我检查了是否引入了任何错误,但据我所知,代码是正确的,并且git log给出的时间顺序不是线性顺序.最后,我的问题是?
Q2)如果git不存储修订号,怎样才能从"git log"获得线性顺序?
谢谢 :)
sim*_*ont 11
Git内部格式
它是[unix timestamp] [timezone offset],其中[unix timestamp]是自UNIX纪元以来的秒数.[timezone offset]是UTC的正偏移或负偏移.
基于此,git内部使用的时间格式是UNIX纪元时间,包括机器UTC偏移量.
您使用过的方法(git log --pretty=format:"%ct%H")将从已合并到当前分支的所有分支中提取数据.
这使得"线性顺序"有些困难.考虑以下[ 来源:git-scm.org ]:

所以,在这里我们已经有几个'主题分支'正在进行中.然后我们决定保留一些(dumbidea和iss91v2),丢弃其他人(iss91).所以我们丢弃C5并C6保留其他提交,我们的合并后历史看起来像这样[ 来源:git-scm.org ]:

(箭头指向从 children 到 parents ; C14是孩子的提交C13和C11).
所以现在我们有一个HEAD提交,为了论证,我们假设我们将作为一个RELEASE1或一个东西发布.那么,对于这样一个问题:我们现在怎样才能拥有这段历史,提取一个线性的,按时间顺序排列的正确提交列表?
简单回答:我不相信你可以 - 或者,如果你这样做,我不相信它会是你想要的.
您可以按时间线性地对提交进行排序:
git log --pretty=format:"%ct %H" | sort --key=1,10
Run Code Online (Sandbox Code Playgroud)
那会给你一个对应的列表:
C1
C2
... snip ...
C13
C14
Run Code Online (Sandbox Code Playgroud)
但请注意,这实际上不是线性历史记录!这是因为我们将一些分支合并在一起,这些分支是在同一时间创建的.我们无法提取C14(我们的HEAD)父母的线性历史,因为没有一个 - 它是两个分支的子代,而不是单个提交的子代,并且不是线性关系.
所以,你说,或许我可以得到一个分支的线性历史?C14 -> C13 ... C3 -> C1, 例如?
这也至少非常困难并且(更可能)不可能.
当我们有多个分支加入(三向或多向合并)时,这个问题变得更加复杂.这个问题进一步详细说明了无法提取"单一分支"历史的原因 - 当您查看合并提交的父项时,您如何确定哪个是"单个分支",哪个是哪个?是'加入'分支?
说了这么多,例如,如果你用图形格式检查这个小存储库的日志:(我做了一些没用的提交)
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)
Run Code Online (Sandbox Code Playgroud)
请注意,这段历史是按照时间顺序; 然而,分支并没有"扁平"成一个,所以它看起来有点时髦.每个提交都包含在当前HEAD(master,origin/master)中.这是显而易见的,因为历史记录中的两个分叉已合并在一起(合并处于f08bc1e).
如果您对单个提交感兴趣,此问题或者如果您的版本被标记将有所帮助.
阅读问题,您似乎可能希望将每个提交映射到一个版本; 这是很多工作,我对此无能为力 - 我认为你不需要检查每个提交,因为分支将被合并,如果线性分支的头部在发布中,线性父母也将.除非你做过樱桃采摘或类似的.
如果按时间排序,则检查所有早于旧版本的提交,记录该提交ID(如果它包含在最旧的,然后是第二个最旧的等),并在找到包含它的版本时从列表中删除提交,你最多必须检查number of releases*number of commits; 在最坏的情况下,任何版本都没有提交.最好的情况,版本包含比自身更早的每个提交,这是300,000检查.仍然很多,但(对我天真的头脑),可行.
(长期答复道歉).