背景
项目在电脑上运行时经常需要调整本地时间做调试,而提交代码的时候又经常忘记将时间调整回来。这就导致 git 提交时间经常是错乱的,看起来很不爽,也不便于以后查找问题。所以就想能不能在 commit
之前能检查一下电脑本地时间和网络时间是不是一致的呢?如果时间不一致的话就不允许提交。
pre-commit
经查找发现 git 中有个叫 pre-commit
的钩子可以在 commit
之前自动执行脚本做一些事情,所以我们的上面的问题就可以解决了。
在 git
项目根目录下有一个 .git/hooks
文件夹是放置所有钩子脚本的。打开目录我们会发现里面有很多 .sample
后缀的文件,这些都是 git
自带的钩子 demo,都不会执行。想要执行的话需要重命名去掉 .sample
后缀。
本次我们需要的是 pre-commit
。
开始写代码
工具有了,那接下来就是写脚本检查本地时间是否与网络时间一致了。
由于 pre-commit
是 shell
脚本,解析网络请求时间比较麻烦(其实是我不会),所以检查网络时间部分用简单方便的 python
脚本来实现,然后在 pre-commit
脚本中调用。
检查本地时间与网络时间是否一致
首先是获取准确的网络时间。大型网站的时间都是准确的,而且都可以在请求头 header
中都会得到当前 GMT 时间,我们选择用百度首页,速度很快很稳定。
本地时间好获取,几乎所有语言都有自带的获取方法吧。
检查时间脚本文件 check_localtime_with_net_time.py
如下:
#!/usr/bin/python
# -*- coding: utf-8
import sys
import time
import urllib2
def get_beijing_time_from_web(url):
response = urllib2.urlopen(url)
# 获取http头date部分
ts = response.headers['date']
# 将日期时间字符转化为time
gmt_time = time.strptime(ts[5:25], "%d %b %Y %H:%M:%S")
# 将GMT时间转换成北京时间
long_time = time.mktime(gmt_time) + 8 * 3600
return long_time
def check_localtime_with_internet(url):
threshold = 60 # 最大允许 60 秒误差
net_time = get_beijing_time_from_web(url)
local_time = time.time()
if abs(local_time - net_time) <= threshold:
return 1
else:
return 0
if __name__ == '__main__':
url = 'http://www.baidu.com'
is_on_time = check_localtime_with_internet(url)
print is_on_time
钩子 pre-commit 脚本如下
exit 0
以 0 退出表示检查通过,没有问题。
exit 1
以非 0 退出,表示检查有问题,不允许执行 commit
。
#!/usr/bin/env bash
# 检查本地时间和网络时间是否一致, 不一致的话不让提交, 防止修改本地时间后提交导致提交历史混乱
on_time=$(.git/hooks/check_localtime_with_net_time.py)
if [[ "$on_time" == "1" ]] ; then
exit 0
fi
echo "本地时间与网络时间不同步, 请先调整下本地时间, 或跳过 pre-commit 检查"
exit 1
都添加可执行权限:
chmod +x check_localtime_with_net_time.py
chmod +x pre-commit
使用
将写好的两个脚本文件 pre-commit
和 check_localtime_with_net_time.py
放在 .git/hooks
文件夹下。
好了,现在执行 commit
命令的时候 pre-commit
就会自动执行了。如果本地时间和网络时间不一致(最大允许误差为 60 秒),就会提交失败,提示我们去把本地时间修改正确,时间正常则没有任何反应,完美!
如果不想要检查呢?
长期不想要检查就不要加这俩脚本了,删除文件或重命名 pre-commit
为其他名称都可以。
如果只想某一次不想要检查,那可以在 commit
命令后面添加 –no-verify
参数来跳过检查。
另外
pre-commit
还可以做代码检查之类的操作,比如 eslint
。感兴趣的可以自己去查。