在团队开发中,保证团队维持一致的代码管理策略,避免在同样的问题上重复挖坑和踩坑,有时是一件非常困难的事情。
比如,在上一篇文章,我们自己定义了一个 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
这些文件就是钩子的模板文件。每个模板文件的文件名