【问题标题】:How do I find the date of a git commit using only plumbing commands?如何仅使用管道命令找到 git 提交的日期?
【发布时间】:2018-10-08 19:01:42
【问题描述】:

已经有一个question 询问如何在 Git 中找到提交的日期。但是,该问题的所有答案都使用git showgit log 命令,它们都是porcelain commands;瓷器命令的标准智慧似乎是它们的output format may change,因此应尽可能避免在脚本中使用它们。

有没有办法只使用管道命令来获取 git 提交的时间戳?

【问题讨论】:

  • 有什么理由需要一个管道命令而不是简单地强制一个瓷器命令的格式?例如。 git log --pretty=format:%aD | head -1git show --format="format:%aD" --no-patch HEAD.
  • @pepak 只是,据我了解,不能保证这些命令在未来的 git 版本中会继续提供相同的输出。例如,git 2.7.4 以%aD 格式给我Mon, 8 Oct 2018 日期,但我不知道我是否可以合理地预期某些未来版本不会为相同的提交生成Mon, 08 Oct 2018
  • 好吧,既然%aD 格式被指定为“作者日期,RFC2822 样式”,格式应该保持不变。要获得另一种固定格式,您可以使用%aI 或添加专用的--date=raw。这些都不应该比“管道”版本发生更大的变化。
  • @pepak RFC2822 允许但不需要前导零,因此“RFC2822 样式”不能保证任何一种变体。我同意%aI 似乎不太可能发生变化,但是由于 git 文档明确表示瓷器命令可能会发生变化并且不应在脚本中使用(当然,除非它们提供了 --porcelain 选项),我宁愿不依赖猜测他们未来的发展。

标签: git scripting git-plumbing


【解决方案1】:

提交对象的格式如下:

tree SP SHA_1_NAME_AS_HEX LF
parent SP SHA_1_NAME_AS_HEX LF
...
author SP any number of words SP <email_addr> SP TIMESTAMP SP TZ_OFFSET LF
committer SP any number of words SP <email_addr> SP TIMESTAMP SP TZ_OFFSET LF
LF
commit message LF
LF
extensive commit message

(其中SP 是 ASCII 空格字符,0x20,LF 是 ASCII 换行符,0x0a)。

所以基本上要实现你想要的,你:

  1. 致电git cat-file commit &lt;commitish_of_interest&gt;
  2. 迭代程序转储到其stdout 的内容 由LF-终止的行。
  3. 在以author SP 开头的行停止。
  4. 将其拆分为空格,然后取最后两个字段。 第一个是第二个字段定义的时区中自00:00 以来的秒数,其格式为 SHHMM 其中S 是一个符号,-+,它们相应地定义了在格林威治以西或以东的偏移量,HHMM 是在@987654334 中的偏移量时区的@小时和MM分钟。
  5. 处理这两个字段的值以格式化时间戳。

请注意,authorcommitter 字段的内容仅在“正常”提交时相同。在重新提交提交时,至少时间戳可能会有所不同,并且如果提交是由实际创作提交(其作者)以外的人重新确定的,则字段将有所不同。对于通过 git am 从补丁创建的提交也是如此。

【讨论】:

    【解决方案2】:

    git cat-file -p HASH_OF_COMMIT 将返回提交 blob 的内容。 因此,您将可以访问所有元数据,以及作者和创建日期。

    【讨论】:

      【解决方案3】:

      Git 在正确区分管道和瓷器方面有点松懈。在脚本中使用管道命令的建议很好,但有时一个命令(例如 git log)没有合适的管道变体,但 确实 有使其成为“管道”的选项,如果我可以造一个词。

      在这种情况下,适当的命令是(编辑,2019 年 3 月 21 日,comment from Josh):

      git -c log.showSignature=false log --pretty=format:%ad --no-walk <hash>
      

      (或与%cd 相同作为提交者日期的格式指令;添加各种日期格式选项,到git log 本身,或作为%aD,例如,更改日期格式)。没有什么可以确切地保证git log 可能不会添加新功能,例如log.decorate 设置,这可能会破坏这一点,Git 应该自行处理并将--porcelain 选项添加到行为类似于git status 的命令中。 (注意git status 现在有--porcelain--porcelain=v2,两者都将其转换为管道。不要问我为什么不拼写为--plumbing...)

      【讨论】:

      • 谢谢。我注意到status--porcelain 选项(以及showlog--word-diff 选项,但没有其他选项),但这当然只是让我更多 小心使用没有--porcelain 选项的瓷器命令:)。我想有些事情(例如--pretty=format:%at)特别不可能改变,但最好能以书面形式...
      • 现在 Git 人员也很容易添加,因为 git log --porcelain 可能只是暗示 忽略 log.decorate 和 ui.color 设置 或类似的东西...(哎呀,ui.color 是 Mercurial,color.* 是 Git。VCS 太多...)
      • 面对不寻常的用户配置,这没有弹性!如果用户设置了log.showSignature,那么这也会从 gpg 输出多行,这往往会破坏预期的单个日期。
      • @Josh:呃。那么git -c log.showSignature=false log --pretty=...。这就是为什么git log 应该有一个管道等价物。
      猜你喜欢
      • 2023-03-05
      • 2015-07-27
      • 2013-02-13
      • 2012-03-19
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 2015-08-23
      • 1970-01-01
      相关资源
      最近更新 更多