在git中,有没有一种方法可以获取给定提交的推送日期?

116

我想知道在git日志中是否有一种方法可以查看与每个提交相关联的推送日期。如果不可能,是否有一种方法可以查看某次推送下的所有提交。

我正在编写一个需要跟踪提交的程序。由于git日志是按提交日期而不是推送日期排序的,因此我无法查看最近推送的提交。例如,如果用户在推送到主分支之前将提交推送到本地存储库2天,那么该提交将被放置在主存储库日志中2天其他提交的后面。

9个回答

91

我花了很长时间来收集分散的信息,最后找到了这个问题的最佳答案,现在我知道了。只需要两行代码,没有任何钩子:

# required for a bare repo
git config core.logAllRefUpdates true

git reflog --date=local master

最终变得简单。

警告:您可能想要覆盖gc.reflogExpiregc.reflogExpireUnreachable的默认值。有关详细信息以及了解此操作的原因和方式,请查看git help reflog

上述两个命令必须在您推送到的克隆中内部运行。如果不可能,那么在另一个永久性克隆中运行是一个近似方法

git fetch               origin        # often and *regularly*
git reflog --date=local origin/master

千万不要删除这个永久克隆,否则您将会失去日期信息。


2
我想补充一下,在我的情况下,我必须执行 git reflog --date=local origin/master(注意 origin/)才能看到推送列表。否则,只有提交、检出和拉取在列表中(这也很有用)。实际上,我是通过 @JonathanDay 的回答 才找到这个方法的。 - NIA
@NIA:origin/master 只能给你一个近似值。我已经根据你的评论更新了我的答案,这样清楚了吗? - MarcH

39

Git是一种分布式版本控制系统,因此您必须仔细定义“推送日期”的含义。例如,假设用户A将某些提交推送到用户B的存储库中。较晚的某个时间点,用户B将这些相同的提交推送到第三个存储库。您对哪个日期感兴趣?

我猜测您拥有一个共享存储库,并希望该共享存储库的用户能够确定何时发布了某些内容到该存储库中。如果是这样,您将不得不在共享存储库中收集该信息。

坏消息

不幸的是,无法将日期附加到提交消息中。这将更改提交ID(它是内容的SHA1哈希),从而引起各种问题。

好消息

幸运的是,Git有一个(相对较新的)功能叫做notes。此功能允许您向提交附加任意文本,git log可以显示这些注释。注释可以编辑并与他人共享。

您可以使用注释功能将“此提交于[date]接收”消息附加到每个提交上,当共享存储库接收提交时。

有关详细信息,请参见git help notes

如何记录日期

以下是我推荐的方法:

  1. 修改共享存储库上的post-receive钩子,以便针对每个更新的引用遍历每个新可达提交。
  2. 对于每个提交,在其注释中添加类似“[user]在[date]将此提交添加到[ref]的[repository_url]”的内容。

    您可以使用专用于此目的的注释引用(例如refs/notes/received-on),而不是默认的refs/notes/commits。这将防止与为其他目的创建的注释发生冲突。

  3. 修改您的receive钩子,以拒绝更新您的注释引用(以防止用户意外或有意地更改注释)。
  4. 告诉所有用户从其工作树内运行以下命令:

    # Fetch all notes from the shared repository.
    # Assumes the shared repository remote is named 'origin'.
    git config --add remote.origin.fetch '+refs/notes/*:refs/remote-notes/origin/*'
    
    # Show all notes from the shared repository when running 'git log'
    git config --add notes.displayRef 'refs/remote-notes/origin/*'
    

    之所以需要这一步,是因为Git默认情况下会忽略上游存储库中的非分支、非标签引用。

  5. 以上假设引用只会被推进而不会被删除或强制更新。您可能还想让post-receive钩子在处理这些情况时附加“于[date]删除”的说明。


我在我的博客http://mnaoumov.wordpress.com/2013/01/31/git-get-push-date/中使用了你的想法。 - mnaoumov

12
git reflog show origin/master --pretty='%h %gd %gs %s' --date=iso

这对我来说似乎运作得相当不错。 提交者日期(%cd)是误导性的,因为它不一定与推送日期相同。 然而,--date=iso选项将输出推送/拉取日期

请注意,如果您从origin/master获取,则会打印您获取它的日期; 而不是其他人推送提交的日期。

 - %h:  abrev. hash
 - %gd: human readable reflog selector
 - %gs: reflog subject
 - %s:  subject/commit message

奖励:当然,您可以进行更漂亮的格式设置。到目前为止,我喜欢这种颜色编码。不过敲起来有点麻烦。这将输出SHA为红色,reflog选择器为青色,reflog主题为绿色。

git reflog show origin/master --pretty='format:%C(red)%h%Creset %C(cyan)%gd%Creset %C(green)%gs%Creset: %s' --date=iso

嗨V.C,这是否意味着如果命令“reflog show origin/master --pretty ='%Cred%h%Creset - %C(yellow)%gd%Creset %Cblue(%gs)%Creset %s' --date = iso”的输出是“da4c192cd-origin / master @ {2019-02-07 08:13:40 +0100}(pull:fast-forward)JIRA-2542增强测试报告”,那么这意味着我的分支JIRA-2542的内容是通过快进在2019-02-07 08:13:40合并到origin/master吗? - Simon
嗨,Simon。是的,你在你的分支上进行了git pull操作,并且当时它通过快进方式合并到了origin/master分支上。 - V.C.
它只在作者的代码库上工作。如果我克隆一个代码库,该值为空。你无法看到其他人的推送时间。 - ramwin
我可以确认,在新克隆的版本中它是空的。 - Nikolai Ehrhardt

5

这个关于检查远程 reflog 的答案可能会有所帮助 (https://dev59.com/hWoy5IYBdhLWcg3wEKBn#8791295),它可以告诉您分支是如何被推送的,即使它没有显示哪些提交被推送了,但您可以通过找到本地提交日期之后的下一次推送来进行交叉验证。虽然不是绝对可靠的,但如果您还没有实现 @RichardHansen 先前发布的出色的笔记建议,那么它仍然很方便。


2
请注意,origin/branch 的 reflog 仅显示在 当前 机器上做出的更改,这非常有用!对于日常使用,我不想实现任何钩子,因此对于一个简单的问题“嗯,上周我推送了那个提交?”——它非常好用。 - NIA

4

请看git reflog show master。这可能不是您想要的确切格式,但应指向正确的方向。

另一个想法是在推送挂钩内运行脚本。


我考虑运行推送钩子,但这似乎应该是最后的努力。使用钩子似乎每个用户都必须在他们的每个存储库中拥有该钩子。你能更具体地说明 git reflog show master 吗?我想能够查看每个用户单独提交的推送日期。 - justkikuchi
1
git reflog 显示了在任何存储库中运行它时更改的顺序。我不确定是否有直接的方法来获取日期,但在.git/logs/refs/heads/master中显示了一个时间戳。 - Karl Bielefeldt
3
关于钩子(hooks),有一些接收钩子(receive hooks)需要在你推送到的机器上运行。由于推送(push)只与特定仓库(repo)相关,我假设你有一个特定的“受保护”的仓库想要在其上运行钩子。git reflog同理。 - Karl Bielefeldt

4
您还可以查看服务器上git仓库中“objects”目录中提交对象文件的修改时间。

4

为什么git的AuthorDate和CommitDate不同?

  • AuthorDate是提交首次创建时的时间。
  • CommitDate是提交被最后修改(如rebase)的时间。

您可以使用--pretty格式选项来获取这些信息:

       o    %cd: committer date
       o    %cD: committer date, RFC2822 style
       o    %cr: committer date, relative
       o    %ct: committer date, UNIX timestamp
       o    %ci: committer date, ISO 8601 format

因此,如果您和其他开发人员在git push之前进行git rebase操作,则最终提交的日期将晚于作者创建的日期(author date)

以下命令用于显示提交日期:git log --pretty=fuller


1

我猜你可以使用下面的命令来获取推送日期: git log -g --date=local


它将打印提交日期。 - Nikolai Ehrhardt

0

试一试。

git log {hash} -1 --format=%cd --date=local 

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