最近,我fork了一个github托管的仓库,贡献者遍布世界各地,发现每个提交日志都包含提交者的时区信息。
2013-11-07 02:31:41 +0545 <-- This committer is living in Nepal. Surely.
2013-11-04 12:58:36 -0600 <-- This committer is living in CST or Ecuador or Chili or ...
2013-10-31 10:36:36 +0700 <-- This committer is living in Indonesia or Thai or Mongolia or Laos or Australia or ...
:
我知道可以通过编辑输出表单来隐藏它(例如git:时区和时间戳格式),但这隐藏了 github 存储库中实际保存的内容,只有我看不到。每个提交者的时区肯定都保存在 github 的服务器中。
所以我的问题:
您可以使用此命令以UTC时间提交:
git commit --date="`date --utc +%Y-%m-%dT%H:%M:%S%z`"
您还可以将其别名为方便的名称:
git config --global alias.commitutc '!git commit --date="$(date --utc +%Y-%m-%dT%H:%M:%S%z)"'
然后做
git commitutc
。
有关更详细的解释,请查看此博客文章。
提交时,git 存储 Unix 时间戳(自 1970 年 1 月 1 日 UTC 以来的秒数)和提交者的本地偏移量。 您可以覆盖偏移量,但您还必须提供日期。
git commit --date 1401179025 -0700
支持多种格式,如此处所述。 我更喜欢 ISO-8601 格式,如下所示:
git commit --date 2014-05-27T01:23:45-07:00
您可以根据需要设置偏移量。 使用零表示 UTC。 我个人认为这是没有必要的。 它实际上减少了日志中的信息量。 您可能只关心确切的时间点,但也许人们也可能关心特定提交者的时间。 例如,也许您想知道那个人是在清晨还是在深夜承诺。 如果您不存储本地偏移量,那么该信息就会丢失,并且存储它并没有什么坏处。
如果您主要担心的是查看 git 日志无法将所有提交对齐到单个时区,请考虑使用 log 命令上的
--date
选项调整日志输出:
git log --date=local
上面使用提交偏移量将提交日期调整为您自己的本地时区。
我没有看到任何可以直接将其调整为 UTC 的内容,但您可以将自己的时区设置为 UTC,然后使用此命令。
从信息安全的角度来说,在提交中省略时区也很重要。时区告诉每个人您居住在哪个时区,并且如果安全对您来说很重要,您应该忽略这些信息。
这个问题的其他答案集中在作者日期,但对于每个提交,Git 存储作者日期和提交日期。所以你必须省略两个日期的时区。
我在以下 Git 别名的帮助下自己解决了这个问题:
[alias]
co = "!f() { \
export GIT_AUTHOR_DATE=\"$(date -u +%Y-%m-%dT%H:%M:%S%z)\"; \
export GIT_COMMITTER_DATE=\"$(date -u +%Y-%m-%dT%H:%M:%S%z)\"; \
git commit $@; \
git log -n 1 --pretty=\"Autor: %an <%ae> (%ai)\"; \
git log -n 1 --pretty=\"Committer: %cn <%ce> (%ci)\"; \
}; f"
此别名还在提交后输出此提交的重要属性,以便我可以轻松检查它们。
结合一个完全不同的问题的答案和这个问题,我做了以下内容并将其添加到我的
~/.bashrc
(或~/.zshrc
,具体取决于系统)。
这将导致 所有 git 提交操作 以 UTC 运行:
git()
{
if [[ $# -ge 1 && "$1" == "commit" ]]
then
TZ=UTC command git "$@"
else
command git "$@"
fi
}
为什么提交需要提交者的时区?它有什么用? UTC时间还不够吗?
时区对于确定执行操作的作者/提交者的当地时间很有用。
根据https://git-scm.com/docs/git-commit-tree#_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.
要一劳永逸地将所有 git 命令的时区强制为 UTC,您可以使用以下命令向
.bashrc
文件添加别名:
# Append an alias to ~/.bashrc to turn all "git" commands into "TZ=UTC git"
echo "alias git='TZ=UTC git'" >> ~/.bashrc
# Reload the file for the current shell
source ~/.bashrc
如果您的目标是保持时区的私密性,请记住,只需犯一个错误,就会无意中将非零时区添加到“永远”保留的提交历史记录中。您可能忘记使用您设置的 git 别名,或者系统更新引起的一些细微变化可能会悄悄破坏您的时区隐藏代码。因此,为了使其更加充分证明,如果在我们的任何日期中检测到非零时区,这里有一种方法可以使任何
git commit
失败。
让我们安装一个全局预提交挂钩。预提交钩子在尝试提交之前由 git 自动执行。如果它们返回非零状态,git 就会停止。
首先,创建一个目录来存储全局提交钩子。我用的是
/home/chris/.config/git/hooks/
但是请适应你自己的系统,任何目录都可以。
mkdir -p /home/chris/.config/git/hooks/
配置 git 使用钩子:
git config --global core.hooksPath /home/chris/.config/git/hooks/
在该目录中创建一个名为
pre-commit
的文件并将以下代码粘贴到其中:
#!/usr/bin/env bash
ensure_timezone_is_zero() {
# See `man git commit` for the possible date formats
if echo "$1" | grep -q ' '; then # date has timezone
if echo "$1" | grep -vq '+0000'; then # timezone is not UTC
echo "Error: non-zero timezone in $2 date: $1"
return 1
fi
fi
return 0
}
# Retrieve commit details from the output of `git var GIT_AUTHOR_IDENT`
# and `git var GIT_COMMITTER_IDENT`. If any of them mentions our email,
# check the date and make sure it contains a zero timezone.
check_timezone() {
myemail="$(git config get user.email)"
for ident in GIT_AUTHOR_IDENT GIT_COMMITTER_IDENT; do
IFS="<>" read -r tmp email date < <(git var "$ident")
date="${date:1}"
if [ "$email" = "$myemail" ]; then
ensure_timezone_is_zero "$date" "$ident" || return $?
fi
done
return 0
}
global_precommit() {
check_timezone || return $?
}
# boilerplate just to have a global hook applied to all repositories
# while also executing any repository-specific pre-commit hook
if global_precommit; then
# Run local pre-commit hook if exists
if [ -e ./.git/hooks/pre-commit ]; then
./.git/hooks/pre-commit "$@"
else
exit 0
fi
else
echo "Global pre-commit hook $0 failed"
exit 1
fi
最后使钩子可执行:
chmod +x /home/chris/.config/git/hooks/pre-commit
以下是检测到非零时区时会发生的情况:
$ alias git=git
$ export TZ='America/Los_Angeles'
$ git commit
Error: non-zero timezone in GIT_AUTHOR_IDENT date: 1731932272 -0800
Global pre-commit hook /home/chris/.config/git/hooks/pre-commit failed