在团队开发中,保证团队维持一致的代码管理策略,避免在同样的问题上重复挖坑和踩坑,有时是一件非常困难的事情。
比如,在上一篇文章,我们自己定义了一个 modules.json 文件,用来定义每个子模块应该使用什么分支。但即使是这样一个简单的文件,在实际开发过程中都会闹出各种让人哭笑不得的奇葩笑话:
为了避免在这类低级的问题上重复踩坑,我们将钩子应用在开发的各个阶段中,在一些重要的动作发生时触发自定义脚本进行若干检查,并在完成若干动作后执行一些后续指令。这些钩子对推进团队代码管理起到了非常有效的作用。
下面我将
Git 能在特定的重要动作发生时触发自定义脚本,要达到这个目的就是利用钩子。
如果按照钩子安装的位置来划分,钩子可以分为如下两种:
# coding: utf-8 # author: panweizhou  importsys,os,io,subprocess,json,re  defgetSubmoduleNameAndPath(): '''获取子模块信息'''  root_path = getRootPath() ifroot_path !=None:  output = subprocess.Popen(['git submodule --quiet foreach --recursive /'echo $toplevel/$path/''], stdout=subprocess.PIPE, shell=True)  oc = output.communicate() #取出output中的字符串  submodule_dict = {} forelementinoc: ifelement !=None:  sb_list = element.split('/n') foreleminsb_list: if(elem !=""):  path = elem.strip()  name = path.replace(root_path+"/",'')  submodule_dict[name] = path returnsubmodule_dict else:  print(warning_color)  print(''' 警告:检测到当前工程不是 .git 工程,文件目录可能已经损坏! ''')  print(normal_color)  os.chdir(pwd) returnFalse  defgetRootPath(): ''' 找到工程根目录 '''  git_path = ".git"  pwd = os.getcwd() whileTrue: ifos.path.exists(os.path.join(pwd, git_path))andos.path.isdir(os.path.join(pwd, git_path)): returnos.path.abspath(pwd) else: if(os.path.exists(os.path.join(pwd,"../"))):  pwd = os.path.join(pwd, "../") else: returnNone   defgetModulePath(): ''' 找到当前模块的根目录  如果当前是主工程,则返回主工程的根目录'''  git_path = ".git"  pwd = os.getcwd() whileTrue: ifos.path.exists(os.path.join(pwd, git_path)): returnos.path.abspath(pwd) else: if(os.path.exists(os.path.join(pwd,"../"))):  pwd = os.path.join(pwd, "../") else: returnNone   defisRootProject(): ''' 判断当前是否处于主工程 '''  module_path = getModulePath()  git_path = ".git" ifos.path.isdir(git_path): returnTrue else: returnFalse   defaddress_comp(repo1, repo2): ''' 比较两个地址是否相同 '''  pos = repo1.find("://") ifpos >0:  repo1 = repo1[pos:]  pos = repo2.find("://") ifpos >0:  repo2 = repo2[pos:] returnrepo1 == repo2  defisRepo(repo_address): '''判断当前是否处于某个模块'''  output = subprocess.Popen(["git remote -v | grep 'fetch' | awk '{print $2}'"], stdout=subprocess.PIPE, shell=True)  oc = output.communicate()  repo = oc[0].strip() ifaddress_comp(repo, repo_address): returnTrue else: returnFalse    打开任意一个本地 Git 仓库的 .git/hooks 目录,你会发现有一堆文件:
[-] YOUR_REPO/.git/hooks/ |- applypatch-msg.sample |- commit-msg.sample |- post-update.sample |- pre-applypatch.sample |- pre-commit.sample |- pre-push.sample |- pre-rebase.sample |- prepare-commit-msg.sample `- update.sample
这些文件就是钩子的模板文件。每个模板文件的文件名