详解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日进行了一些修订。

目录
相关文章
|
3月前
|
开发工具 git
GIT:如何合并已commit的信息并进行push操作
通过上述步骤,您可以有效地合并已提交的信息,并保持项目的提交历史整洁。记得在执行这些操作之前备份当前工作状态,以防万一。这样的做法不仅有助于项目维护,也能提升团队协作的效率。
156 4
|
3月前
|
开发工具 git
GIT:如何合并已commit的信息并进行push操作
通过上述步骤,您可以有效地合并已提交的信息,并保持项目的提交历史整洁。记得在执行这些操作之前备份当前工作状态,以防万一。这样的做法不仅有助于项目维护,也能提升团队协作的效率。
272 3
|
4月前
|
开发工具 git
Git——commit的提交规范
Git——commit的提交规范
110 4
|
4月前
|
测试技术 持续交付 开发工具
[译] 为何每次 Git Commit 要尽可能小?
[译] 为何每次 Git Commit 要尽可能小?
|
4月前
|
Java 开发工具 Android开发
Android Studio利用Build.gradle导入Git commit ID、Git Branch、User等版本信息
本文介绍了在Android Studio项目中通过修改`build.gradle`脚本来自动获取并添加Git的commit ID、branch名称和用户信息到BuildConfig类中,从而实现在编译时将这些版本信息加入到APK中的方法。
88 0
|
5月前
|
前端开发 JavaScript 开发工具
前端优化之路:git commit 校验拦截
前面在git分支规范那篇文章里,介绍了commit提交规范,但是想要做到高效落地执行,就需要做些别的功课。
|
4月前
|
IDE 开发工具 git
我是怎么写 Git Commit message 的?
我是怎么写 Git Commit message 的?
55 0
|
6天前
|
机器学习/深度学习 Shell 网络安全
【Git】Git 命令参考手册
Git 命令参考手册的扩展部分,包含了从基础操作到高级功能的全面讲解。
19 3
|
1月前
|
缓存 Java Shell
[Git]入门及其常用命令
本文介绍了 Git 的基本概念和常用命令,包括配置、分支管理、日志查看、版本回退等。特别讲解了如何部分拉取代码、暂存代码、删除日志等特殊需求的操作。通过实例和图解,帮助读者更好地理解和使用 Git。文章强调了 Git 的细节和注意事项,适合初学者和有一定基础的开发者参考。
48 1
[Git]入门及其常用命令
|
2月前
|
开发工具 git
git学习四:常用命令总结,包括创建基本命令,分支操作,合并命令,压缩命令,回溯历史命令,拉取命令
这篇文章是关于Git常用命令的总结,包括初始化配置、基本提交、分支操作、合并、压缩历史、推送和拉取远程仓库等操作的详细说明。
133 1
git学习四:常用命令总结,包括创建基本命令,分支操作,合并命令,压缩命令,回溯历史命令,拉取命令