钩子介绍

自定义钩子分为:项目钩子和全局钩子

自定义全局钩子:

全局钩子目录结构:

(注意:excludes目录结构是我们自定义的目录,规则逻辑在update.d/update.py脚本里实现的,非gitlab官方提供功能)

/opt/gitlab/embedded/service/gitlab-shell/custom_hooks

├── excludes

│            └── excludes.txt

└── update.d

└── update.py

钩子目录:

自定全局钩子目录: /opt/gitlab/embedded/service/gitlab-shell/custom_hooks  ,其中 update.d/update.py  是我们自定义的钩子脚本, 脚本使用python语言。

如何扩展和修改全局钩子指定目录?

1.修改 /etc/gitlab/gitlab.rb  配置文件中的配置项:gitlab_shell['custom_hooks_dir'] = "/opt/gitlab/embedded/service/gitlab-shell/custom_hooks"

2. 执行 sudo gitlab-ctl reconfigure 命令来使配置生效。

Tips:不要尝试直接修改 /config.yml 的文件内容,文件中有说明:

This file is managed by gitlab-ctl. Manual changes will be erased! To change the contents below, edit /etc/gitlab/gitlab.rb and runsudo gitlab-ctl reconfigure.

3.在自定的 custom_hooks_dir 目录(即我们的custom_hooks目录)下可创建三个文件夹对应三类 server hook name :

pre-receive.d

update.d

post-receive.d

在每个文件夹下可创建任意文件,在对应的 hook 时期,gitlab 就会主动调用

文件名以 ~ 结尾的文件会被忽略

如果想看这部分的实现细节可以看 /lib/gitlab_custom_hook.rb 文件

如何对单个项目排除全局钩子?

在 /opt/gitlab/embedded/service/gitlab-shell/custom_hooks/excludes/excludes.txt   文件中新加一行你要排除的git的地址即可:例如:

自定义项目钩子

项目钩子的目录为固定目录:

.git/custom_hooks/   例如我们的项目自定义目录为: /var/opt/gitlab/git-data/repositories/frontend/testWeb.git/custom_hooks/update   ,update是我们自定义的钩子脚本。

钩子的执行顺序

钩子将按照以下的顺序执行

.git/hooks/ - symlink to gitlab-shell/hooks global dir

.git/hooks/ - executed by git itself, this is gitlab-shell/hooks/

.git/custom_hooks/ - per project hook (this is already existing behavior)

.git/custom_hooks/.d/* - per project hooks

.git/hooks/.d/* OR //* - global hooks: all executable files (minus editor backup files)

钩子校验规则

1、提交合并代码到test分支前,需要先合并代码到dev验证通过后方能push到test

2、提交合并代码到master分支前,需要先合并代码到dev、test验证通过后方能push到master

3、不同分支不能相互合并(如果需要合并,请合并后删除一个不需要的分支方能提交)

4、合并代码到dev、test、master,merge过程出错了怎么办?

可以直接在dev、test、master分支上修改代码,但是需要在备注comment里填写FIX_MERGE_ERROR 就可以直接提交(但请不要正常的代码也使用这个命令!!!!!否则后果很严重)

git钩子原理

在编写钩子的过程中发现钩子原理如下:

1.gitlab默认安装完毕后在server端会有两个比较重要的目录。

.git 目录例如:/var/opt/gitlab/git-data/repositories/test/automation.git (我们称这个目录为git的project) 目录树结构如下:

├── branches

├── config

├── description

├── HEAD

├── hooks -> /opt/gitlab/embedded/service/gitlab-shell/hooks

├── hooks.old.1500269284

│   ├── applypatch-msg.sample

│   ├── commit-msg.sample

│   ├── post-update.sample

│   ├── pre-applypatch.sample

│   ├── pre-commit.sample

│   ├── prepare-commit-msg.sample

│   ├── pre-push.sample

│   ├── pre-rebase.sample

│   ├── pre-receive.sample

│   └── update.sample

├── info

│   └── exclude

├── objects

│   ├── info

│   └── pack

└── refs

├── heads

└── tags

这个目录结构和git本地项目.git 的目录结构相似。目录中保存了git操作相关的版本信息。在git本地修改的元数据信息提交后都会保存在该目录中。

/opt/gitlab/embedded/service/gitlab-shell/hooks

改目录是git默认钩子的目录。在git的低版本( GitLab 8.15.以下)中扩展全局钩子可以该目录的hooks目录中直接修改或新加,但是可能影响到原有的钩子,因此不建议使用,推荐方式见本章1.3 如何修改全局钩子。

2.git 钩子的脚本代码中:0 正常退出,用户可以 push;非 0 异常退出,中断提交(pre-receive 和 update)

3.通过本人研究发下,钩子(脚本中调用的shell的命令)其实是在server端的 .git  git目录 执行的。举例:当执行automation项目的全局钩子时钩子内执行的shell命令会在/var/opt/gitlab/git-data/repositories/test/automation.git 目录中执行,可以通过在钩子中pwd来打印当前钩子的执行目录发现的。

示例代码的目的:这个功能本身就是只有已经提交到dev或者test分支的过的才允许merge到master分支。如果本地分支没有提交道过dev或者test分支是不允许merge到master的。这样是为了保护master分支的功能都是经过测试通过的,从而避免误(将未测试通过的代码)提交到master。

钩子的python代码:

1 #!/usr/bin/env python

2 #coding=utf-8

3 '''

4 该脚本在pre-receive或post-receive钩子中被调用,也可以直接将该文件作为git的钩子使用5 若钩子为shell脚本,则需要加入以下代码调用该脚本:6 while read line;do7 echo $line | python $PATH/pre-receive.py8 done9 当用户执行git push的时候会在远程版本库上触发此脚本10 该脚本的主要作用:获取用户提交至版本库的文件列表,提交者及时间信息11 '''

12

13 importsys, subprocess14 importre15 importos16

17 __author__ = "zhanghuiwen"

18 excludPath ="/opt/gitlab/embedded/service/gitlab-shell/custom_hooks/excludes/excludes.txt";19 baseGitUrl="http://172.26.0.80:8081"

20

21

22 classTrigger(object):23

24

25 def __init__(self):26 '''

27 初始化文件列表信息,提交者信息,提交时间,当前操作的分支28 '''

29 self.pushAuthor = ""

30 self.pushTime = ""

31 self.fileList =[]32 self.ref = ""

33

34

35

36 def __getGitInfo(self):37 '''

38 '''

39 self.oldObject = sys.argv[2]40 self.newObject = sys.argv[3]41 self.ref = sys.argv[1]42

43 #跳过排除的项目

44 def_skipExcludeProjects_(self):45 '''

46 跳过扫描的项目47 '''

48 rev = subprocess.Popen("pwd", shell=True, stdout=subprocess.PIPE);49 gitServerRepoPath = rev.stdout.readline(); #路径'/var/opt/gitlab/git-data/repositories/alpha/testhook.git'

50 paths = gitServerRepoPath.split("repositories");51 projectPath = paths[1]; #/alpha/testhook.git

52 rev.stdout.close();53

54 #读取配置中的文件

55 lines = open(excludPath, "r");56 for line inlines:57 realLine = line.strip("\n");58 result = realLine.replace(baseGitUrl,"")59 if projectPath.strip(" ").strip("\n") == result.strip(" ").strip("\n"):60 lines.close()61 print ("例外项目允许不经过dev和test直接提交")62 exit(0)63 else:64 pass

65 lines.close()66 #继续执行

67

68 def __getPushInfo(self):69 '''

70 git show命令获取push作者,时间,以及文件列表71 文件的路径为相对于版本库根目录的一个相对路径72 '''

73 rev = subprocess.Popen('git rev-list' + self.oldObject + '..' + self.newObject, shell=True,74 stdout=subprocess.PIPE)75 pushList =rev.stdout.readlines()76 pushList = [x.strip() for x inpushList]77 #循环获取每次提交的文件列表

78 for pObject inpushList:79 p = subprocess.Popen('git show' + pObject, shell=True, stdout=subprocess.PIPE)80 pipe =p.stdout.readlines()81 pipe = [x.strip() for x inpipe]82 self.pushAuthor = pipe[1].strip("Author:").strip()83 self.pushTime = pipe[2].strip("Date:").strip()84

85 self.fileList.extend(['/'.join(fileName.split("/")[1:]) for fileName in pipe if

86 fileName.startswith("+++") and not fileName.endswith("null")])87

88 uBranch = self.ref.split('/')[len(self.ref.split('/')) - 1]89 print '提交分支: %s' %uBranch90 print '提交变动from:%s to:%s' %(self.oldObject, self.newObject)91 print '提交的commit:%s' %pushList92 #if uBranch == 'dev':

93 #return

94 #循环获取每次提交的文件列表

95 for pObject inpushList:96 #判断是否是merge commit,如果是merge commit则忽略

97 gitCatFileCmd = ('git cat-file -p %s') %(pObject)98 p = subprocess.Popen(gitCatFileCmd, shell=True, stdout=subprocess.PIPE)99 pipe =p.stdout.readlines()100 pipe = [x.strip() for x inpipe]101 i =0102 for branch inpipe:103 if branch.startswith('parent'):104 i += 1

105 if i >= 2:106 continue

107

108 #如果提交的带上的msg是FIX_MERGE_ERROR则可以通行(避免合错分支引起的问题)

109 msgLine = pipe[-1]110 printmsgLine111 if msgLine == 'FIX_MERGE_ERROR':112 continue

113 #if not re.match(r'^(\w+)-(\d+)', msgLine):

114 #print '\033[1;35m %s 提交的信息没有带上jira编号,请确认添加 \033[0m' % pObject

115 #exit(-1)

116 listCmd = ('git branch --contains %s') %(pObject)117 p = subprocess.Popen(listCmd, shell=True, stdout=subprocess.PIPE)118 pipe =p.stdout.readlines()119 pipe = [x.strip() for x inpipe]120 print 'commit:%s->所属分支:%s' %(pObject, pipe)121 #如果是master分支push提交,必须先提交dev、test

122 if 'master' ==uBranch:123 if 'dev' not in pipe or 'test' not inpipe:124 print '\033[1;35m 合并到master的分支必须先在dev、test上经过验证合并才能提交,具体错误提交的hash:%s \033[0m' %pObject125 exit(-1)126 elif 'test' ==uBranch:127 if 'dev' not inpipe:128 print '\033[1;35m 合并到test的分支必须先在dev上经过验证合并才能提交,具体错误提交的hash:%s \033[0m' %pObject129 exit(-1)130 branchs =set()131 isMaster =True132 for branch inpipe:133 branch = branch.replace('*', '')134 if 'master' ==branch:135 isMaster =False136 break

137 if 'test' == branch or 'dev' == branch or 'dev-permission' == branch or 'test-permission' ==branch:138 continue

139 #elif uBranch != 'master' and uBranch != 'test' and uBranch != 'dev' and branch != uBranch:

140 #print '\033[1;35m 提交失败!你合并提交的分支来自于多个分支,请确认,你的分支%s,其他分支%s \033[0m' % (uBranch, branch)

141 #exit(-1)

142 branchs.add(branch)143 if len(branchs) >= 2 andisMaster:144 print '\033[1;35m 提交失败!你合并提交的分支来自于多个分支,请确认%s \033[0m' %pipe145 exit(-1)146

147 defgetGitPushInfo(self):148 '''

149 返回文件列表信息,提交者信息,提交时间150 '''

151 self.__getGitInfo()152 self._skipExcludeProjects_()153 self.__getPushInfo()154 print '========================================='

155 print "Time:", self.pushTime156 print "Author:", self.pushAuthor157 print "Ref:", self.ref158 print "Files:", self.fileList159 print '========================================='

160

161

162 if __name__ == "__main__":163 t =Trigger()164 t.getGitPushInfo()

View Code

git 客户端 所有客户端 钩子_git自定义项目钩子和全局钩子相关推荐

  1. VC++ Hook截取鼠标点击窗口消息的问题!全局钩子

    VC++ Hook截取鼠标点击窗口消息的问题!全局钩子,高手进! 悬赏分:0 - 提问时间: 2010年05月19日 06时20分 我在做毕业设计,现在遇到一个问题,像求教高手: 我想实现如下功能,当 ...

  2. MFC 全局钩子dll注入监听键盘消息

    MFC自带的键盘监听功能只有焦点在MFC程序界面时才能监听键盘消息,要想在MFC程序界面外监听键盘消息,可以通过DLL注入使用全局钩子来监听.首先,通过Visual Studio生成全局钩子的动态库, ...

  3. 【C++】代码实现:全局钩子注入技术

    一.概述 在 Windows  中大部分的应用程序都是基于消息机制的,它们都有一个过程函数,根据不同的消息完成不同的功能. Windows 操作系统提供的钩子机制就是用来截获和监视系统中这些消息的. ...

  4. 推荐几款好用的 Git 图形化客户端

    最近公司全面转向 GitLab 管理代码,很多同学都不太习惯,问我有没有好用的 Git 图形化客户端推荐?我说:有! Gitk Gitk 是 Git 提供的一个 GUI 工具,现在安装 Git 的时候 ...

  5. git服务器与客户端的安装与使用

    首先准备环境 centos7,最小化安装,配置网络,能访问外网,关闭防火墙selinux,配置yum源 设置好网络和防火墙  网络需要能访问外网, ip 192.168.1.8 下面关闭防火墙 set ...

  6. 【分布式版本控制系统】GIT 托管网站 客户端

    上传到远程库 第一次上传 git add . git commit -m"备注信息" 之后上传 git add . git commit -m"备注信息" gi ...

  7. 仿百度壁纸客户端(二)——主页自定义ViewPager广告定时轮播图

    仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度壁纸客户端( ...

  8. Git及Github客户端无法下载问题解决以及快速下载办法

    一般当选择选择浏览器自动下载Git或者github客户端的时候经常出现下载失败或者下载网速过慢的原因. 此时可以选择查找下载时电脑转入的网址,然后复制后用迅雷下载,具体办法如下. 关于git的下载,首 ...

  9. git前端工程实现ci_大前端项目代码重用,也许lerna是最好的选择

    我前段时间参与了一个react为主的大前端项目,覆盖Web.Android.Ios三个平台.由于整个业务逻辑侧重在手机端,且Web端也是到了项目中期才开始启动,我在搭底层框架时就没有考虑用类似reac ...

最新文章

  1. 在Putty或mRemote下输入和显示中文
  2. String类中常用的方法
  3. 面部识别辅助监控系统 人工智能为城市安全保驾护航
  4. pytorch 三维点分类_三维点云分类与分割-PointNet
  5. PLSQL_性能优化系列20_Oracle Result Cash结果缓存
  6. 使用goJenkins create job 返回500
  7. WorkManager从入门到实践,有这一篇就够了
  8. 林斌宣布好消息!语音识别大佬、Kaldi之父加盟小米
  9. php判断长度函数是,php判断字符串长度 strlen()与mb_strlen()函数
  10. 日语五十音平假名 识读卡片 笔顺
  11. Kali Linux信息收集工具全集
  12. 物业服务的品质、成本与四保一服的数字化方法
  13. 钛资本研究院:保险科技行业现状及趋势分析
  14. Vue中的SEO优化
  15. [语义分割]CTNet: Context-based Tandem Network for Semantic Segmentation
  16. Windows搭建Deepmind的星际争霸2平台
  17. 数据库服务器的安装与配置
  18. python小数转分数_NumPy:将小数转换为分数
  19. 2019杭电多校第七场 HDU - 6656 Kejin Player 期望
  20. WorldFirst公布本地化品牌名称,跨境收款万里汇!

热门文章

  1. 正弦函数泰勒展开c语言,C++ 学习笔记_0012_函数(泰勒展开式、三角函数表)
  2. 神经网络中的对抗攻击与对抗样本
  3. 神经网络中的对抗样本
  4. 破解长虹电视不能安装u盘app,快速安装第三方软件
  5. 关于Hystrix整合ribbon调用其他服务时 首次进入回退
  6. solr(4)solr7.3.1 使用DIH上传结构化数据
  7. 概率统计Python计算:样本数据的经验分布函数
  8. print list Reversely
  9. 一周疫情对行业影响观察 | 对香港IPO冲击大于内地,纺织服装新增企业同比下滑超五成...
  10. 计算机图形学--扫描线填充算法