#!/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)