Utilizamos Gitlab, por lo que tiene sentido para nosotros validar autores en contra de los miembros del grupo Gitlab.
La siguiente secuencia de comandos (en base a la respuesta de @ dsvensson) que debe ser instalado como pre-recepción de gancho hace exactamente eso:
from __future__ import print_function
from __future__ import unicode_literals
import sys
import os
import subprocess
import urllib2
import json
import contextlib
import codecs
from itertools import islice, izip
GITLAB_SERVER = 'https://localhost'
GITLAB_TOKEN = 'SECRET'
GITLAB_GROUP = 4
EMAIL_DOMAIN = 'example.com'
def main():
commits = get_commits_from_push()
authors = get_gitlab_group_members()
for commit, author, email in commits:
if author not in authors:
die('Unknown author', author, commit, authors)
if email != authors[author]:
die('Unknown email', email, commit, authors)
def get_commits_from_push():
old, new, branch = sys.stdin.read().split()
rev_format = '--pretty=format:%an%n%ae'
command = ['git', 'rev-list', rev_format, '{0}..{1}'.format(old, new)]
# branch delete, let it through
if new == '0000000000000000000000000000000000000000':
sys.exit(0)
# new branch
if old == '0000000000000000000000000000000000000000':
command = ['git', 'rev-list', rev_format, new, '--not', '--branches=*']
output = subprocess.check_output(command)
commits = [line.strip() for line in unicode(output, 'utf-8').split('\n') if line.strip()]
return izip(islice(commits, 0, None, 3),
islice(commits, 1, None, 3),
islice(commits, 2, None, 3))
def get_gitlab_group_members():
url = '{0}/api/v3/groups/{1}/members'.format(GITLAB_SERVER, GITLAB_GROUP)
headers = {'PRIVATE-TOKEN': GITLAB_TOKEN}
request = urllib2.Request(url, None, headers)
with contextlib.closing(urllib2.urlopen(request)) as response:
members = json.load(response)
return dict((member['name'], '{}@{}'.format(member['username'], EMAIL_DOMAIN))
for member in members)
def die(reason, invalid_value, commit, authors):
message = []
message.append('*' * 80)
message.append("ERROR: {0} '{1}' in {2}"
.format(reason, invalid_value, commit))
message.append('-' * 80)
message.append('Allowed authors and emails:')
print('\n'.join(message), file=sys.stderr)
for name, email in authors.items():
print(u" '{0} <{1}>'".format(name, email), file=sys.stderr)
sys.exit(1)
def set_locale(stream):
return codecs.getwriter('utf-8')(stream)
if __name__ == '__main__':
# avoid Unicode errors in output
sys.stdout = set_locale(sys.stdout)
sys.stderr = set_locale(sys.stderr)
# you may want to skip HTTPS certificate validation:
# import ssl
# if hasattr(ssl, '_create_unverified_context'):
# ssl._create_default_https_context = ssl._create_unverified_context
main()
Ver GitLab custom Git hooks docs las instrucciones de instalación.
Solo get_gitlab_group_members()
es específico de Gitlab, otra lógica se aplica a cualquier gancho de pre-recepción (incluido el manejo de eliminaciones y creaciones de ramas).
La secuencia de comandos ahora es available in GitHub, no dude en enviar solicitudes de extracción para cualquier error/mejora.
Posible duplicado de [Impedir a otros autores de git] (http://stackoverflow.com/questions/28401926/prevent-other-git-authors) –
La respuesta aceptada no es realmente segura. La gente está haciendo bromas ahora: https://github.com/jayphelps/git-blame-someone-else –