|
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() |
|
|