设为首页 收藏本站
查看: 1002|回复: 0

[经验分享] git自定义项目钩子和全局钩子

[复制链接]

尚未签到

发表于 2018-1-12 13:12:56 | 显示全部楼层 |阅读模式
1 #!/usr/bin/env python  
  2 # coding=utf-8
  
  3 '''
  
  4 该脚本在pre-receive或post-receive钩子中被调用,也可以直接将该文件作为git的钩子使用
  
  5 若钩子为shell脚本,则需要加入以下代码调用该脚本:
  
  6 while read line;do
  
  7         echo $line | python $PATH/pre-receive.py
  
  8 done
  
  9 当用户执行git push的时候会在远程版本库上触发此脚本
  
10 该脚本的主要作用:获取用户提交至版本库的文件列表,提交者及时间信息
  
11 '''
  
12
  
13 import sys, subprocess
  
14 import re
  
15 import os
  
16
  
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>  
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 in lines:
  
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 in pushList]
  
77         # 循环获取每次提交的文件列表
  
78         for pObject in pushList:
  
79             p = subprocess.Popen('git show ' + pObject, shell=True, stdout=subprocess.PIPE)
  
80             pipe = p.stdout.readlines()
  
81             pipe = [x.strip() for x in pipe]
  
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' % uBranch
  
90         print '提交变动from:%s to:%s' % (self.oldObject, self.newObject)
  
91         print '提交的commit:%s' % pushList
  
92         # if uBranch == 'dev':
  
93         #    return
  
94         # 循环获取每次提交的文件列表
  
95         for pObject in pushList:
  
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 in pipe]
  
101             i = 0
  
102             for branch in pipe:
  
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             print msgLine
  
111             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 in pipe]
  
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 in pipe:
  
124                     print '\033[1;35m 合并到master的分支必须先在dev、test上经过验证合并才能提交,具体错误提交的hash:%s \033[0m' % pObject
  
125                     exit(-1)
  
126             elif 'test' == uBranch:
  
127                 if 'dev' not in pipe:
  
128                     print '\033[1;35m 合并到test的分支必须先在dev上经过验证合并才能提交,具体错误提交的hash:%s \033[0m' % pObject
  
129                     exit(-1)
  
130             branchs = set()
  
131             isMaster = True
  
132             for branch in pipe:
  
133                 branch = branch.replace('* ', '')
  
134                 if 'master' == branch:
  
135                     isMaster = False
  
136                     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 and isMaster:
  
144                 print '\033[1;35m 提交失败!你合并提交的分支来自于多个分支,请确认%s \033[0m' % pipe
  
145                 exit(-1)
  
146
  
147     def getGitPushInfo(self):
  
148         '''
  
149         返回文件列表信息,提交者信息,提交时间
  
150         '''
  
151         self.__getGitInfo()
  
152         self._skipExcludeProjects_()
  
153         self.__getPushInfo()
  
154         print '========================================='
  
155         print "Time:", self.pushTime
  
156         print "Author:", self.pushAuthor
  
157         print "Ref:", self.ref
  
158         print "Files:", self.fileList
  
159         print '========================================='
  
160
  
161
  
162 if __name__ == "__main__":
  
163     t = Trigger()
  
164     t.getGitPushInfo()

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-434256-1-1.html 上篇帖子: salt使用 下篇帖子: git初使用总结感悟
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表