详解git commit --date的参数格式

简介: 你知道git commit --date除了官方指定的那几种,还可以填哪些参数吗?其实还有不少呢,甚至可以填入相对时间!

一想到日期格式,不免得想起java类SimpleDateFormat中经典的yyyy-MM-dd hh:mm:ss格式,但可惜--date并不支持这种格式

想查查git的命令参数,自然是先上官方文档,跳到https://git-scm.com/docs一看,很快就找到Basic Snapshotting下的commit,点进去翻到OPTIONS里找到--date=<date>项,发现只写了句

Override the author date used in the commit.

这没有细说格式,就这么草草一句介绍,只能看看是不是下面有附录说明,果然找到了DATE FORMATS,https://git-scm.com/docs/git-commit#_date_formats

The GIT_AUTHOR_DATE, GIT_COMMITTER_DATE environment variables and the --date option support the following date formats:

Git internal format
It is <unix timestamp> <time zone offset>, where <unix timestamp> is the number of seconds since the UNIX epoch. <time zone offset> is a positive or negative offset from UTC. For example CET (which is 1 hour ahead of UTC) is +0100.

RFC 2822:
The standard email format as described by RFC 2822, for example Thu, 07 Apr 2005 22:13:13 +0200.

ISO 8601:
Time and date specified by the ISO 8601 standard, for example 2005-04-07T22:13:13. The parser accepts a space instead of the T character as well. Fractional parts of a second will be ignored, for example 2005-04-07T22:13:13.019 will be treated as 2005-04-07T22:13:13.

Note:
In addition, the date part is accepted in the following formats: YYYY.MM.DD, MM/DD/YYYY and DD.MM.YYYY.

这里提到了三种格式

“内部”格式

这个“内部”格式又分为两种,一是unix timestamp,二是time zone offset。

其中,unix timestamp指的其实就是timestamp,时间戳一般都特指unix timestamp,这种表示方法很科学,其他系统平台都是照搬的,其实并不分什么Unix,只是因为Unix系统最初使用这种long表示date的格式罢了,java的System.currentTimeMillis(),javascript的+new Date()取出的值都是unix timestamp。

而time zone offset,其实就是在unix timestamp后加上时区,例如1599020738028 +0800,仅此而已

RFC 2822格式

RFC互联网标准,虽然RFC中没有单独的规定一个日期应该怎么表示,但RFC制定了邮件消息格式,其中3.3规定了邮件中如何表示日期的格式,翻到https://tools.ietf.org/html/rfc2822#section-3.3有极为详尽的介绍,格式是"周,日 月 年 时:分:秒 时区",例如Wed, 02 Sep 2020 13:09:52 +0800,在国内其实比较少见,不太符合我们的文法

ISO 8601格式

国际标准ISO制定的8601很好看,年月日时分秒,符合大多数人的习惯,例如2020-09-02T13:11:11+08:00,还可以简写为20200902T131111+08,用T隔开日期和时间

看了文档又想看看源码到底怎么写的,这几年会不会有些新格式兼容了又没改文档,众所周知文档写完万年不改的,我翻到合并这个功能修改的commit,https://github.com/git/git/commit/d939af12bd96db7ad3e671a0585ad8570aa7e9d3

一看前面的几个文件,发现这个contributors把一个公用常量从枚举改成了struct,随后有一系列伴随这个改动的修改,我直接查找DATE_ISO8601_STRICT看看有没有测试用例,遗憾的是并没有专门测试这些字符串的用例,但在builtin/blame.c里发现居然是有一些用例,这个switch并不是parse时间的,但是是用来获取不同时间格式对应的字符串长度的,但应该也是一样的,直接转到这一行最新的master分支,https://github.com/git/git/blob/aa9166bcc0ba654fc21f198a30647ec087f733ed/builtin/blame.c#L993

这个switch从993行到1034行,一共10个case,果然文档还是有所遗漏。这10个case每一项都直接有用例了,源码部分如下(这也是一段祖传代码了):

switch (blame_date_mode.type) {
   
    case DATE_RFC2822:
            blame_date_width = sizeof("Thu, 19 Oct 2006 16:00:04 -0700");
            break;
    case DATE_ISO8601_STRICT:
            blame_date_width = sizeof("2006-10-19T16:00:04-07:00");
            break;
    case DATE_ISO8601:
            blame_date_width = sizeof("2006-10-19 16:00:04 -0700");
            break;
    case DATE_RAW:
            blame_date_width = sizeof("1161298804 -0700");
            break;
    case DATE_UNIX:
            blame_date_width = sizeof("1161298804");
            break;
    case DATE_SHORT:
            blame_date_width = sizeof("2006-10-19");
            break;
    case DATE_RELATIVE:
            /*
             * TRANSLATORS: This string is used to tell us the
             * maximum display width for a relative timestamp in
             * "git blame" output.  For C locale, "4 years, 11
             * months ago", which takes 22 places, is the longest
             * among various forms of relative timestamps, but
             * your language may need more or fewer display
             * columns.
             */
            blame_date_width = utf8_strwidth(_("4 years, 11 months ago")) + 1; /* add the null */
            break;
    case DATE_HUMAN:
            /* If the year is shown, no time is shown */
            blame_date_width = sizeof("Thu Oct 19 16:00");
            break;
    case DATE_NORMAL:
            blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700");
            break;
    case DATE_STRFTIME:
            blame_date_width = strlen(show_date(0, 0, &blame_date_mode)) + 1; /* add the null */
            break;
}

可以学习其中的用例进行一些测试:

git commit --date="2012-12-12"
git commit --date="2012-12-12 12:12:12 0800"
git commit --date="2012-12-12T12:12:12+08:00"
git commit --date="2 minutes ago"

测试发现都是可以的,关于第一种格式要注意的是只写年份不写时间的话,时间是会跟着走的,不会设个默认的0点0分之类的操作。例如现在是5点半,时间设为2012年12月12日,完整的时间戳就会表现为2012年12月12日五点半。

写于2021年4月13日,于2023年7月11日进行了一些修订。

目录
相关文章
|
5天前
|
人工智能 缓存 开发工具
结合企业实践来规范你的Git commit(含插件使用指南)
结合企业实践来规范你的Git commit(含插件使用指南)
结合企业实践来规范你的Git commit(含插件使用指南)
|
4天前
|
JSON 开发工具 git
git rebase 合并当前分支的多个commit记录
git rebase 合并当前分支的多个commit记录
|
5天前
|
程序员 开发工具 git
【程序员英语 代码提交】C++工程师的代码提交艺术:git commit 时 精确表达与最佳实践
【程序员英语 代码提交】C++工程师的代码提交艺术:git commit 时 精确表达与最佳实践
120 1
|
5天前
|
前端开发 算法 开发工具
如何将git的多个commit合成一个
如何将git的多个commit合成一个
93 0
|
5天前
|
前端开发 测试技术 持续交付
【开发规范】Git Commit 规范
【1月更文挑战第26天】【开发规范】Git Commit 规范
|
5天前
|
JavaScript 测试技术 持续交付
2020你应该知道的git commit规范
2020你应该知道的git commit规范
96 0
|
5天前
|
开发工具 git
git撤销推送到远端仓库的提交commit信息
git撤销推送到远端仓库的提交commit信息
|
开发工具 git
Git命令集之一——配置参数
Git命令集之一——配置参数
99 0
|
5天前
|
缓存 数据可视化 网络安全
Git命令大全
Git命令大全
62 1
|
5天前
|
开发工具 git
Git教程:深入了解删除分支的命令
【4月更文挑战第3天】
68 0
Git教程:深入了解删除分支的命令

相关实验场景

更多