#!/usr/bin/python3 import datetime import getopt import sys import os import dateutil.parser NOW = datetime.datetime.now() FIVE_HOUR = datetime.datetime(NOW.year, NOW.month, NOW.day, 5, 0, 0, 0) SEVEN_HOUR = datetime.datetime(NOW.year, NOW.month, NOW.day, 7, 0, 0, 0) def get_date_option_value(msg_blocks): # 否则会抛异常,然后我们不希望填如-amend=""之类的抛异常,所以这里try一下 for opt in msg_blocks[1:]: if opt.startswith("--date"): # 这里其实已经不会报GetoptError错了,不过为了熟悉下异常处理就留着吧 try: # 如果没有短格式,这里用空字符即可;这种写法最终会导致要么不填Option,要么填的必须是--date="sfjl" opts, args = getopt.getopt([opt], "", ["date="]) except getopt.GetoptError: # 产生了这种异常啥也不做 pass except Exception as err: # 捕获其它异常(Exception是所有异常的基类) print("Python hook执行时产生其他异常:", err) # sys.exit(1)则commit不会继续,0会执行commit sys.exit(1) else: # try执行成功才执行这里(还有个finally关键字) if len(opts) > 0 and len(opts[0][1]) > 0: return (True, opts[0][1]) return (False, "") # 目前git hook无法获取--date之类的参数,而用shell或python也无法获取上一次命令 # 因此退而求其次,发现如果提交时间是符合条件的,则直接通过,如果提交时间不符合条件 # ,那么需要在msg里通过在最后##date来设置--date的数据,然后在这里重新commit if __name__ == "__main__": """# 如果配置了--date="xxx",且xxx的长度大于0,则可以commit(至于瞎填这个不管) if get_date_option_value() is True: sys.exit(0) else: # 这个就需要判断当前提交时间是否符合条件了""" if NOW < SEVEN_HOUR and NOW > FIVE_HOUR: sys.exit(0) else: # commit-msg这个hook执行时的第二个参数是存储-m信息的临时文件路径,这里以只读打开 # with语句和C#的using,java的try()类似,能自动关闭文件 with open(sys.argv[1], 'r') as f: msg = f.readlines() # map()的在Python3里返回的是迭代器,这里需要用list来转换一下,否则join的还是原来的 msg = "".join(list(map(lambda e: e.rstrip(), msg))) msg = msg.split("##") # python里存在变量作用域提升(和js的var一样),因此这里可以用msg,除非前面手动用del删了msg msg_back = msg msg = get_date_option_value(msg) if not msg[0]: print("这个时间点不建议提交代码,如果确实需要现在提交 请在消息最后加上##--date=xxx来填写日期参数") else: try: dateutil.parser.parse(msg[1]) except Exception: print('日期格式有误,请填写正确的格式') else: # 要接一个except,否则提示潜在问题 # print('将转为内在执行') date = msg[1].strip() msg = msg_back[0] os.system('git commit --date="{}" -am "{}" --no-verify'.format(date, msg)) sys.exit(1)