我想知道是否有一种方法可以查看与 git 日志中每个提交相关的推送日期。如果那不可能,有没有办法查看某个推送下的所有提交。
我编写了一个程序,该程序需要在提交时跟踪提交。因为 git 日志是按提交日期而不是推送日期排序的,所以我无法看到推送的最新提交。例如,如果用户在推送到主存储库前 2 天提交到他的本地存储库,则该提交将被放置在主存储库日志中其他提交的 2 天之后。
我花了很长时间来收集零散的信息并最终找到这个问题的最佳答案,但现在我知道我有它了。只需两行,没有代码也没有钩子:
# required for a bare repo
git config core.logAllRefUpdates true
git reflog --date=local master
最后简单。
警告:您可能想要覆盖 和 的默认gc.reflogExpire
值gc.reflogExpireUnreachable
。检查git help reflog
详细信息并了解其工作原理和原因。
上面的两个命令必须在你推送到的克隆中运行。如果这是不可能的,那么一个近似值是在另一个永久克隆中运行:
git fetch origin # often and *regularly*
git reflog --date=local origin/master
切勿删除此永久克隆,否则您将丢失日期。
Git 是一个分布式版本控制系统,因此您必须仔细定义“推送日期”的含义。例如,假设用户 A 将一些提交推送到用户 B 的存储库。稍后,用户 B 将这些相同的提交推送到第三个存储库。您对哪个日期感兴趣?
我推测您有一个共享存储库,并希望该共享存储库的用户能够确定何时将某些内容发布到存储库。如果这是真的,您将不得不在共享存储库中收集该信息。
不幸的是,没有办法将日期附加到提交消息中。这会更改提交 ID(这是内容的 SHA1 哈希),从而导致各种问题。
幸运的是,Git 有一个(相对较新的)功能,称为notes。此功能允许您将任意文本附加到git log
可以显示的提交中。可以编辑笔记并与他人共享。
您可以使用注释功能将“此提交已在 [日期] 收到”消息附加到每个提交,因为它是由共享存储库接收的。
详情请参阅git help notes
。
这是我推荐的方法:
post-receive
共享存储库上的钩子以遍历每个更新的引用的每个新可达的提交。对于每个提交,将类似“[repository_url] 的 [user] 将此提交添加到 [日期] 的 [ref]”之类的内容添加到提交的注释中。
您可能希望使用专用于此目的的 notes ref(如refs/notes/received-on
)而不是 default refs/notes/commits
。这将防止与为其他目的创建的笔记发生冲突。
receive
钩子以拒绝更新您的笔记参考(以防止用户意外或故意弄乱笔记)。告诉所有用户从他们的工作树中运行以下命令:
# 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 在默认情况下会忽略上游存储库中的非分支、非标记引用。
以上假设引用只是高级的,从不删除或强制更新。您可能希望post-receive
钩子还附加“在 [日期] 删除”注释来处理这些情况。
git reflog show origin/master --pretty='%h %gd %gs %s' --date=iso
这对我来说似乎工作得很好。提交者日期 (%cd) 具有误导性,因为它不一定与推送日期相同。但是, --date=iso 选项将输出 push/fetch date。
请注意,如果您从 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
看看git reflog show master
。可能不是您想要的确切格式,但应该为您指明正确的方向。
另一个想法是在推送挂钩中运行脚本。
这个关于检查遥控器上的 reflog 的答案可能会有所帮助(https://stackoverflow.com/a/8791295/336905),它可以为您提供有关推送了哪些分支的信息,即使它没有显示推送了哪些提交,但是您可以通过在本地提交日期之后找到下一个推送来进行交叉关联。不是万无一失的,但如果您还没有实施之前发布的@RichardHansen 的优秀笔记建议,则很方便
为什么 git AuthorDate 与 CommitDate 不同?
AuthorDate
是首次创建提交的时间。CommitDate
是提交最后一次修改的时间(例如变基)。--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 rebase
之前都在这样做git push
,您最终会得到一个比作者日期晚的提交日期。
此命令显示提交日期:git log --pretty=fuller
您还可以查看服务器本身git存储库中“objects”目录中提交对象文件的文件修改时间。
我想您可以使用下一个表示法来获取推送日期: git log -g --date=local