--- /dev/null
+#! /usr/bin/python
+# -*- Python -*-
+
+"""HG ALSA Tool
+
+Do operations on ALSA GIT repositories.
+
+Usage:
+ %(PROGRAM)s [options] command
+"""
+
+import os
+import sys
+import getopt
+
+VERSION="2.0"
+
+PROGRAM = sys.argv[0]
+ROOT = os.path.abspath(os.getcwd())
+USER = os.getenv('USER')
+VERBOSE = False
+REPOSITORIES = [
+ 'alsa', 'alsa-driver', 'alsa-kmirror', 'alsa-lib', 'alsa-utils',
+ 'alsa-tools', 'alsa-firmware', 'alsa-oss', 'alsa-plugins',
+ 'alsa-python'
+]
+
+def eprint(msg):
+ sys.stderr.write(msg + '\n')
+
+def selectrepos(repos):
+ if repos == None or len(repos) == 0:
+ return REPOSITORIES[:]
+ else:
+ neg = repos[0][0] == '-'
+ for repo in repos:
+ if (neg and repo[0] != '-') or \
+ (not neg and repo[0] == '-'):
+ raise ValueError, "inverted and non-inverted repo specifications cannot be mixed!"
+ if neg:
+ res = REPOSITORIES
+ for repo in repos:
+ res.remove(repo[1:])
+ return res
+ for repo in repos:
+ if not repo in REPOSITORIES:
+ raise ValueError, "repository '%s' is unknown" % repo
+ return repos
+
+def xlist(argv=None):
+ s = ''
+ for i in REPOSITORIES:
+ s += i + ' '
+ print s[:-1]
+
+def git(repo):
+ dir = ROOT + '/' + repo
+ return "git --work-tree=%s --git-dir=%s" % (dir, dir + '/.git')
+
+def clone(argv=None):
+ repos = selectrepos(argv)
+ for repo in repos:
+ print "clone", repo
+
+def diff(argv=None):
+ repos = selectrepos(argv)
+ for repo in repos:
+ pull([repo])
+ if os.system("%s --no-pager diff origin/master..master" % git(repo)):
+ raise ValueError, "diff %s" % repo
+
+def pull(argv=None):
+ repos = selectrepos(argv)
+ for repo in repos:
+ if os.system("%s checkout master" % git(repo)):
+ raise ValueError, "checkout %s" % repo
+ os.chdir(ROOT + '/' + repo)
+ if os.system("%s pull" % git(repo)):
+ raise ValueError, "pull %s" % repo
+
+def push(argv=None):
+ repos = selectrepos(argv)
+ for repo in repos:
+ if os.system("%s checkout master" % git(repo)):
+ raise ValueError, "checkout %s" % repo
+ if os.system("%s push master:refs/heads/master" % git(repo)):
+ raise ValueError, "push %s" % repo
+
+def version_sort(tags):
+ tags1 = []
+ tags2 = {}
+ for tag in tags:
+ tag = tag.strip()
+ if tag == "tip":
+ continue
+ try:
+ a, b, c = tag.split('.')
+ if a[0] != 'v':
+ raise ValueError
+ a = int(a[1:])
+ b = int(b)
+ idx = 0
+ while idx < len(c) and ord(c[idx]) <= ord('9'):
+ idx += 1
+ c1 = int(c[:idx])
+ c2 = c[idx:]
+ str = "%08i.%08i.%08i.%s" % (a, b, c1, c2)
+ tags1.append(str)
+ tags2[str] = tag
+ except:
+ from traceback import print_exc
+ print_exc()
+ pass
+ tags1.sort()
+ res = []
+ for tag in tags1:
+ res.append(tags2[tag])
+ if len(res) > 0:
+ return res
+ return None
+
+def showchanges1(repos):
+ res = {}
+ for repo in repos:
+ if repo == 'alsa':
+ continue
+ res[repo] = []
+ tags = version_sort(os.popen("%s tag" % git(repo)).readlines())
+ if not tags:
+ raise ValueError, "cannot obtain tags for repo %s" % repo
+ fp = os.popen("%s diff --stat %s..HEAD" % (git(repo), tags[-1]))
+ while 1:
+ line = fp.readline()
+ if not line or line.find('|') <= 0:
+ break
+ a, b = line.split('|')
+ a = a.strip()
+ if a in ['.hgignore', '.hgtags']:
+ continue
+ if a.endswith('.gitignore'):
+ continue
+ if VERBOSE:
+ print ' ', line.strip()
+ res[repo].append(a)
+ del fp
+ return res
+
+def showchanged(argv=None):
+ if argv == None:
+ tag = "last"
+ repos = selectrepos(None)
+ else:
+ tag = argv[0]
+ repos = selectrepos(argv[1:])
+ res = showchanges1(repos)
+ for repo in res:
+ print 'Repository %s has %s changed files' % (repo, len(res[repo]))
+ if VERBOSE:
+ print ' ', line.strip()
+
+def release1(repo, tag):
+ print
+ print 'Repository %s' % repo
+ print ''.rjust(11 + len(repo), '*')
+ version = tag[1:]
+ pull([repo])
+ if repo == 'alsa-driver':
+ pull(['alsa-kmirror'])
+ if repo == 'alsa-driver':
+ lines = open(ROOT + '/' + repo + '/configure.in').readlines()
+ for idx in range(0, len(lines)):
+ if lines[idx].startswith('CONFIG_SND_VERSION="'):
+ lines[idx] = 'CONFIG_SND_VERSION="%s"\n' % version
+ print lines[idx][:-1]
+ break
+ open(ROOT + '/' + repo + '/configure.in', "w+").write(''.join(lines))
+ os.chdir(ROOT + '/' + repo)
+ if os.path.exists('include/version.h'):
+ os.remove('include/version.h')
+ if os.path.exists('alsa-kernel/include/version.h'):
+ os.remove('alsa-kernel/include/version.h')
+ if os.system("make ALSAKERNELDIR=../alsa-kernel all-deps"):
+ raise ValueError, "make"
+ if os.system("aclocal"):
+ raise ValueError, "aclocal"
+ if os.system("autoconf"):
+ raise ValueError, "autoconf"
+ if os.system("./configure --with-debug=full --with-isapnp=yes --with-sequencer=yes --with-kernel=%s" % (ROOT + '/alsa-kernel')):
+ raise ValueError, "configure"
+ if os.system("make include/sound/version.h"):
+ raise ValueError, "include/sound/version.h"
+ elif repo in ['alsa-lib', 'alsa-plugins', 'alsa-utils',
+ 'alsa-firmware', 'alsa-oss']:
+ lines = open(ROOT + '/' + repo + '/configure.in').readlines()
+ for idx in range(0, len(lines)):
+ if lines[idx].startswith('AM_INIT_AUTOMAKE(%s, ' % repo):
+ lines[idx] = 'AM_INIT_AUTOMAKE(%s, %s)"\n' % (repo, version)
+ print lines[idx][:-1]
+ break
+ open(ROOT + '/' + repo + '/configure.in', "w+").write(''.join(lines))
+ elif repo == 'alsa-tools':
+ lines = open(ROOT + '/' + repo + '/Makefile').readlines()
+ for idx in range(0, len(lines)):
+ if lines[idx].startswith("VERSION = "):
+ lines[idx] = "VERSION = %s\n" % version
+ print lines[idx][:-1]
+ break
+ open(ROOT + '/' + repo + '/Makefile', "w+").write(''.join(lines))
+ elif repo == 'alsa-python':
+ lines = open(ROOT + '/' + repo + '/setup.py').readlines()
+ for idx in range(0, len(lines)):
+ if lines[idx].startswith("VERSION='"):
+ lines[idx] = "VERSION='%s'\n" % version
+ print lines[idx][:-1]
+ break
+ open(ROOT + '/' + repo + '/setup.py', "w+").write(''.join(lines))
+ lines = open(ROOT + '/' + repo + '/PKG-INFO').readlines()
+ for idx in range(0, len(lines)):
+ if lines[idx].startswith("Version: "):
+ lines[idx] = "Version: %s\n" % version
+ print lines[idx][:-1]
+ break
+ open(ROOT + '/' + repo + '/PKG-INFO', "w+").write(''.join(lines))
+
+def release(argv):
+ if argv == None or argv[0][0] != 'v':
+ raise ValueError, "specify release version in tag form"
+ tag = argv[0]
+ argv = argv[1:]
+ if len(argv) == 0:
+ repos = selectrepos(None)
+ elif argv[0] == 'auto':
+ res = showchanges1(selectrepos(None))
+ repos = res.keys()
+ else:
+ repos = selectrepos(argv)
+ if 'alsa' in repos:
+ repos.remove('alsa')
+ if 'alsa-kmirror' in repos:
+ repos.remove('alsa-kmirror')
+ print 'Doing release for: %s' % ','.join(repos)
+ for repo in repos:
+ release1(repo, tag)
+
+def changes(argv):
+
+ def rev_to_dot(rev):
+ if rev[0] == 'v':
+ return rev[1:]
+ else:
+ return rev
+
+ def print_underline(c, str):
+ i = len(str)
+ while i > 0:
+ sys.stdout.write(c)
+ i -= 1
+ print
+
+ def store_changes(changes, logs, module, xrev):
+ if module == 'alsa-kernel':
+ module = 'alsa-driver'
+ for a in logs:
+ if a.has_key('branch'):
+ return
+ already = False
+ idx1 = 0
+ for change in changes:
+ if a['user'] == change['user'] and \
+ a['description'] == change['description']:
+ # print 'SAME!!!'
+ already = True
+ break
+ if a['date'] < change['date']:
+ a['xrev'] = xrev
+ a['module'] = module
+ changes.insert(idx1, a)
+ # print 'INSERTED!!!'
+ already = True
+ break
+ idx1 += 1
+ if not already:
+ a['xrev'] = xrev
+ a['module'] = module
+ changes.append(a)
+
+ def merge_members(changes):
+ global GERRORS
+
+ res = {}
+ try:
+ os.remove("/tmp/changes-log.txt")
+ except OSError:
+ pass
+ for change in changes:
+ module = change['module']
+ if not res.has_key(module):
+ res[module] = {}
+ members = cvsps_merge_members(change['files'], module)
+ if len(members) == 0:
+ continue
+ members = members[0]
+ mems = string.split(members, ',')
+ for mem in mems:
+ if mem == 'IGNORE':
+ continue
+ if not res[module].has_key(mem):
+ res[module][mem] = []
+ res[module][mem].append(change)
+ if GERRORS > 0:
+ print 'Bailing out...'
+ sys.exit(1);
+ return res
+
+ def get_items(allitems):
+ items = []
+ idx = 0
+ for item in ['Sound Core', 'ALSA Core']:
+ items.append([item])
+ idx += 1
+ core = idx
+ items.append([]) # Core
+ midlevel = idx + 1
+ items.append([]) # Midlevel
+ all = idx + 2
+ items.append(allitems)
+ items[all].sort()
+ for item in items[all]:
+ if string.find(item, 'Core') >= 0:
+ items[core].append(item)
+ if string.find(item, 'Midlevel') >= 0:
+ items[midlevel].append(item)
+ if string.find(item, 'API') >= 0:
+ items[midlevel].append(item)
+ idx1 = core
+ while idx1 < all:
+ for item in items[idx1]:
+ items[all].remove(item)
+ idx1 += 1
+ for items1 in items[:idx]:
+ for item in items1:
+ idx1 = idx
+ while idx1 < len(items):
+ if item in items[idx1]:
+ items[idx1].remove(item)
+ idx1 += 1
+ return items
+
+ def check_tag(tags, rev):
+ for tag in tags:
+ a = tag[41:-1]
+ if len(a) != len(rev):
+ continue
+ if a == rev:
+ return True
+ return False
+
+ try:
+ rev1 = argv[0]
+ rev2 = argv[1]
+ except:
+ sys.stderr.write('Please, specify oldtag and newtag\n')
+ sys.exit(1)
+
+ changes = []
+ fullset = REPOSITORIES
+ fromrev = {}
+ for module in fullset:
+ xrev = rev1
+ fp = os.popen("%s tag" % git(module))
+ tags = fp.readlines()
+ fp.close()
+ if not check_tag(tags, rev2):
+ continue
+ tags1 = []
+ base = rev2
+ while not check_tag(tags, xrev):
+ if rev2[-3:-1] == "rc":
+ base = rev2[:-3]
+ elif rev2[-1:] >= "a":
+ base = rev2[:-1]
+ for tag in tags:
+ a = tag[41:-1].strip()
+ if a >= rev2:
+ continue
+ tags1.append(tag[40:-1].strip())
+ tags1 = version_sort(tags1)
+ if len(tags1) != 0:
+ xrev = tags1[len(tags1)-1]
+ break
+ major, minor, subminor = base.split('.')
+ subminor = int(subminor) - 1
+ if subminor < 0:
+ raise ValueError
+ base = "%s.%s.%s" % (major, minor, subminor)
+ fromrev[module] = xrev
+ lines = my_popen("hg log -r %s:%s -v" % (xrev, rev2))
+ store_changes(changes, parse_hg_log(lines, module), module, xrev)
+ res = merge_members(changes)
+ modules1 = res.keys()
+ modules = []
+ groups = {}
+ for module in fullset:
+ if module in modules1:
+ modules.append(module)
+ rev = fromrev[module]
+ if not groups.has_key(rev):
+ groups[rev] = []
+ groups[rev].append(module)
+ print '{| align="right"\n| __TOC__\n|}'
+ for rev in groups:
+ str = '=Changelog between %s and %s releases=' % (rev_to_dot(rev), rev_to_dot(rev2))
+ print str
+ for module in groups[rev]:
+ print '==%s==' % module
+ items = get_items(res[module].keys())
+ for items1 in items:
+ for b in items1:
+ if not res[module].has_key(b):
+ continue
+ print '===%s===' % b
+ for a in res[module][b]:
+ log = a['description'][0]
+ if log[:9] == 'Summary: ':
+ log = log[9:]
+ elif log[:8] == 'Summary:':
+ log = log[8:]
+ print ': %s' % log[:-1]
+ for rev in groups:
+ str = '=Detailed changelog between %s and %s releases=' % (rev_to_dot(rev), rev_to_dot(rev2))
+ print str
+ for module in groups[rev]:
+ print '==%s==' % module
+ items = get_items(res[module].keys())
+ for items1 in items:
+ for b in items1:
+ if not res[module].has_key(b):
+ continue
+ print '===%s===' % b
+ for a in res[module][b]:
+ log = a['description']
+ first = "-"
+ for l in log:
+ if l[:13] == "Patch-level: ":
+ continue
+ if l[:13] == "Patch-Level: ":
+ continue
+ print ': %s %s' % (first, l[:-1])
+ first = " "
+
+def usage(code=0, msg=''):
+ print __doc__ % globals()
+ print 'Where options is:'
+ for opt in OPTS:
+ print
+ print "\t-%s %s" % (opt[0].replace(':', ''), opt[3])
+ print "\t--%s %s" % (opt[1].replace('=', ''), opt[3])
+ print "\t\t%s" % opt[4]
+ print
+ print 'Where command is:'
+ for cmd in CMDS:
+ print
+ print "\t%s %s" % (cmd[0], cmd[2])
+ print "\t\t%s" % cmd[3]
+ if msg:
+ print
+ print msg
+ sys.exit(code)
+
+def root(argv):
+ global ROOT
+ if argv == None:
+ eprint('Specify root directory.')
+ sys.exit(1)
+ ROOT=os.path.abspath(argv[0])
+
+def verbose(argv):
+ global VERBOSE
+ VERBOSE=True
+
+OPTS=[
+ ['h', 'help', usage, '', 'Print this help'],
+ ['r', 'root', root, '<GIT root dir>', 'Set GIT root directory (default is %s)' % ROOT],
+ ['v', 'verbose', verbose, '', 'Set verbose mode']
+]
+CMDS=[
+ ['list', xlist, '', 'Show ALSA repository names'],
+ ['clone', clone, '[repo]', 'Clone all (default) or selected repositories'],
+ ['diff', diff, '[repo]', 'Do diff on selected or all (default) repositories'],
+ ['pull', pull, '[repo]', 'Do pull on selected or all (default) repositories'],
+ ['push', push, '[repo]', 'Do push on selected or all (default) repositories'],
+ ['showchanged', showchanged, 'tag [repo]', 'Show which repositories were changed since tag'],
+ ['release', release, 'tag [repo]', 'Do an ALSA release (auto = automatic change control)'],
+ ['changes', changes, 'oldtag newtag', 'Show changes between oldtag and newtag']
+]
+
+def main():
+ global ROOT
+ if os.path.exists(ROOT + '/../alsa-kernel'):
+ ROOT = os.path.abspath(ROOT + '/..')
+ opts = ''
+ lopts = []
+ for opt in OPTS:
+ opts += opt[0]
+ lopt = opt[1]
+ if opt[3] != '':
+ opts += ':'
+ lopt += '='
+ lopts.append(lopt)
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], opts, lopts)
+ except getopt.error, msg:
+ usage(1, msg)
+ for opt, arg in opts:
+ for xopt in OPTS:
+ if opt in ("-" + xopt[0], "-" + xopt[1]):
+ xopt[2](arg)
+ if not args:
+ eprint("Command not specified, for help type '%s -h'" % PROGRAM[PROGRAM.rfind('/')+1:])
+ sys.exit(1)
+ for cmd in CMDS:
+ if cmd[0] == args[0]:
+ if len(args) < 2:
+ cmd[1]()
+ else:
+ cmd[1](args[1:])
+ sys.exit(0)
+ usage(1, 'Unknown command "%s"' % args[0])
+
+if __name__ == '__main__':
+ main()
+ sys.exit(0)
--- /dev/null
+#!/usr/bin/python
+
+from sys import exit, stdin, stderr, stdout
+from os import popen, mkdir, system, chdir, getcwd, remove
+from os.path import isdir, exists
+from shutil import rmtree
+import re
+
+TMP_PATH = '/dev/shm'
+
+REPO_DIR = '/home/alsa-server/home/repositories'
+KMIRROR_REPO = REPO_DIR + '/alsa-kmirror.git'
+KERNEL_REPO = REPO_DIR + '/alsa-kernel.git'
+
+VALID_COMMITERS = (
+ 'Jaroslav Kysela <perex@perex.cz>',
+ 'Takashi Iwai <tiwai@suse.de>',
+ 'Clemens Ladisch <clemens@ladisch.de>',
+ 'James Courtier-Dutton <James@superbug.demon.co.uk>',
+ 'Linus Torvalds <torvalds@linux-foundation.org>',
+)
+
+ALSA_FILES = (
+ 'Documentation/sound/alsa/',
+ 'sound/',
+ 'include/sound/'
+)
+
+NOT_ALSA_FILES = (
+ 'sound/sound_core.c',
+ 'sound/sound_firmware.c',
+ 'sound/oss/',
+)
+
+ALSA_FILES1 = {
+ 'Documentation/sound/alsa/': 'Documentation/',
+ 'sound/': '',
+ 'include/sound/': 'include/'
+}
+
+ALSA_COMMITS = {}
+ALSA_OK_COMMITS = []
+ALSA_LAST_COMMIT = ''
+UPSTREAM_COMMITS = []
+
+def error(lines, msg, *args):
+ for line in lines:
+ stderr.write('===> %s' % line)
+ stderr.write('PRE-RECEIVE ERROR: ' + msg % args)
+
+def fail():
+ if ALSA_LAST_COMMIT:
+ stderr.write('PRE-RECEIVE: Reverting alsa-kmirror.git repo to original state\n')
+ if system('git --git-dir=%s update-ref HEAD "refs/heads/master"' % KMIRROR_REPO):
+ raise ValueError, "update-ref failed"
+ if system('git --git-dir=%s reset -q --mixed %s > /dev/null' % (KMIRROR_REPO, ALSA_LAST_COMMIT)):
+ raise ValueError, "reset failed"
+ exit(1)
+
+def is_alsa_file(file):
+ for i in NOT_ALSA_FILES:
+ if file.startswith(i):
+ return False
+ for i in ALSA_FILES:
+ if file.startswith(i):
+ return True
+ return False
+
+def to_alsa_file(gitfile, prefix=''):
+ if gitfile == '/dev/null':
+ return '/dev/null'
+ if prefix and gitfile.startswith(prefix):
+ gitfile = gitfile[len(prefix):]
+ for i in ALSA_FILES1:
+ if gitfile.startswith(i):
+ return prefix + ALSA_FILES1[i] + gitfile[len(i):]
+ raise ValueError, repr(gitfile)
+
+def check_email(lines, fullemail, commit = False):
+ #print 'E-mail: "%s"' % fullemail
+ name, email = fullemail.split('<')
+ name = name.strip()
+ email = email.strip()
+ if not email.endswith('>'):
+ error(lines, 'E-mail address "%s" is not valid...\n' % (line))
+ return False
+ email = email[:-1]
+ if email.find('@') <= 0 or len(name) < 5 or fullemail.find('root@') >= 0:
+ error(lines, 'E-mail address "%s" is not valid...\n' % (line))
+ return False
+ if not commit:
+ return True
+ full = name + ' <' + email + '>'
+ if not full in VALID_COMMITERS:
+ error(lines, 'Commiter "%s" e-mail unknown. We know only these committers:\n' % full)
+ for line in VALID_COMMITERS:
+ stderr.write('***** %s\n' % line)
+ return False
+ return True
+
+def read_kmirror_commits():
+ global ALSA_LAST_COMMIT
+ if ALSA_COMMITS:
+ return
+ stderr.write('PRE-RECEIVE: Analyzing alsa-kmirror commits\n')
+ fp = popen("git --git-dir=%s log --pretty=fuller --date=iso" % KMIRROR_REPO)
+ commitref = ''
+ commit = {}
+ while 1:
+ line = fp.readline()
+ if not line:
+ break
+ if line.startswith('commit '):
+ if commitref:
+ ALSA_COMMITS[commitref] = commit
+ commit = {}
+ commitref = line[7:].strip()
+ if not ALSA_LAST_COMMIT:
+ ALSA_LAST_COMMIT = commitref
+ elif line.startswith('Author:') or line.startswith('AuthorDate:') or \
+ line.startswith('Commit:') or line.startswith('CommitDate:'):
+ a, b = line.split(': ')
+ commit[a.strip()] = b.strip()
+ if commitref:
+ ALSA_COMMITS[commitref] = commit
+ fp.close()
+
+ worktree = TMP_PATH + '/alsa-kmirror-repo'
+ rmtree(worktree, ignore_errors=True)
+ mkdir(worktree)
+ if system("git --work-tree=%s --git-dir=%s checkout -q master scripts" % (worktree, KMIRROR_REPO)):
+ raise ValueError, 'git checkout'
+ if exists(worktree + '/scripts/git-ok-commits'):
+ fp = open(worktree + '/scripts/git-ok-commits')
+ while 1:
+ line = fp.readline()
+ if not line:
+ break
+ if line.startswith('#'):
+ continue
+ ALSA_OK_COMMITS.append(line.strip())
+ fp.close()
+ rmtree(worktree, ignore_errors=True)
+
+def check_alsa_commit(commit):
+ subject = commit['comment'][0][:-1]
+ if not ALSA_COMMITS:
+ read_kmirror_commits()
+ for c in ALSA_COMMITS:
+ if ALSA_COMMITS[c]['AuthorDate'] == commit['AuthorDate'] and \
+ ALSA_COMMITS[c]['Author'] == commit['Author'] and \
+ ALSA_COMMITS[c]['CommitDate'] == commit['CommitDate'] and \
+ ALSA_COMMITS[c]['Commit'] == commit['Commit']:
+ stderr.write('PRE-RECEIVE: Already merged %s %s\n' % (commit['commit'][:7], subject))
+ return True
+ okstr = '"' + commit['Author'] + '" "' + commit['AuthorDate'] + '" "' + commit['Commit'] + '" "' + commit['CommitDate'] + '"'
+ if okstr in ALSA_OK_COMMITS:
+ stderr.write('PRE-RECEIVE: Already merged (manually) %s %s\n' % (commit['commit'][:7], subject))
+ return True
+ return False
+
+def read_upstream_commits(old):
+ stderr.write('PRE-RECEIVE: Analyzing alsa-kernel#linux-2.6 commits\n')
+ head = popen("git rev-parse linux-2.6").readline().strip()
+ stderr.write('PRE-RECEIVE: linux-2.6 head %s old %s\n' % (head, old))
+ if head == old:
+ return
+ fp = popen("git log --pretty=oneline --date=iso %s..%s" % (old, head))
+ while 1:
+ line = fp.readline()
+ if not line:
+ break
+ a = line.split(' ')
+ UPSTREAM_COMMITS.append(a[0])
+ del fp
+ stderr.write('PRE-RECEIVE: linux-2.6 has %s new commits\n' % len(UPSTREAM_COMMITS))
+
+def try_to_merge(commit):
+ stderr.write('PRE-RECEIVE: Merging %s %s' % (commit['commit'][:7], commit['comment'][0]))
+
+ ref = commit['commit']
+ fp = popen("git diff %s~1..%s" % (ref, ref))
+ rlines = []
+ ok = False
+ addfiles = []
+ rmfiles = []
+ while 1:
+ line = fp.readline()
+ if not line:
+ break
+ if line.startswith('diff --git a/'):
+ file1, file2 = line[11:].split(' ')
+ file1 = file1.strip()
+ file2 = file2.strip()
+ ok1 = is_alsa_file(file1[2:])
+ ok2 = is_alsa_file(file2[2:])
+ if ok1 or ok2:
+ afile1 = to_alsa_file(file1, 'a/')
+ afile2 = to_alsa_file(file2, 'b/')
+ rlines.append('diff --git %s %s\n' % (afile1, afile2))
+ if ok2:
+ addfiles.append(afile2[2:])
+ elif ok1:
+ rmfiles.append(afile1[2:])
+ ok = True
+ elif ok and (line.startswith('--- a/') or line.startswith('+++ b/')):
+ rlines.append(line[:6] + to_alsa_file(line[6:].strip()) + '\n')
+ elif ok:
+ rlines.append(line)
+ fp.close()
+
+ patchfile = TMP_PATH + '/alsa-kmirror-patch'
+ fp = open(patchfile, 'w+')
+ fp.write(''.join(rlines))
+ fp.close()
+
+ commentfile = TMP_PATH + '/alsa-kmirror-comment'
+ fp = open(commentfile, 'w+')
+ fp.write(''.join(commit['comment']))
+ fp.close()
+
+ elems = re.compile('(.*?)\s+<(.*)>').match(commit['Author'])
+ exports = 'export GIT_AUTHOR_NAME="%s" ; ' % elems.group(1)
+ exports += 'export GIT_AUTHOR_EMAIL="%s" ; ' % elems.group(2)
+ exports += 'export GIT_AUTHOR_DATE="%s" ; ' % commit['AuthorDate']
+ elems = re.compile('(.*?)\s+<(.*)>').match(commit['Commit'])
+ exports += 'export GIT_COMMITER_NAME="%s" ; ' % elems.group(1)
+ exports += 'export GIT_COMMITER_EMAIL="%s" ; ' % elems.group(2)
+ exports += 'export GIT_COMMITER_DATE="%s" ; ' % commit['CommitDate']
+ exports += 'export GIT_COMMITTER_NAME="%s" ; ' % elems.group(1)
+ exports += 'export GIT_COMMITTER_EMAIL="%s" ; ' % elems.group(2)
+ exports += 'export GIT_COMMITTER_DATE="%s" ; ' % commit['CommitDate']
+
+ curdir = getcwd()
+ worktree = TMP_PATH + '/alsa-kmirror-repo'
+ rmtree(worktree, ignore_errors=True)
+ mkdir(worktree)
+ if system("git --work-tree=%s --git-dir=%s checkout -f -q master" % (worktree, KMIRROR_REPO)):
+ raise ValueError, 'git checkout'
+ chdir(worktree)
+ if system("patch -p 1 --dry-run < %s" % patchfile):
+ chdir(curdir)
+ error(rlines, "Patch failed - is it already merged?\n")
+ error([], "You may consider to add this commit to alsa-kmirror.git/scripts/git-ok-commits .\n")
+ error([], "Please, check if patch was merged to alsa-kmirror.git at first!\n")
+ error([], 'line: "%s" "%s" "%s" "%s"\n' % (commit['Author'], commit['AuthorDate'], commit['Commit'], commit['CommitDate']))
+ fail()
+ if system("git --work-tree=%s --git-dir=%s apply -v %s" % (worktree, KMIRROR_REPO, patchfile)):
+ chdir(curdir)
+ raise ValueError, 'git apply'
+ if addfiles and system("git --work-tree=%s --git-dir=%s add %s" % (worktree, KMIRROR_REPO, ' '.join(addfiles))):
+ chdir(curdir)
+ raise ValueError, 'git add'
+ if rmfiles and system("git --work-tree=%s --git-dir=%s rm %s" % (worktree, KMIRROR_REPO, ' '.join(rmfiles))):
+ chdir(curdir)
+ raise ValueError, 'git rm'
+ if system("%sgit --work-tree=%s --git-dir=%s commit -F %s" % (exports, worktree, KMIRROR_REPO, commentfile)):
+ chdir(curdir)
+ raise ValueError, 'git commit'
+ chdir(curdir)
+ rmtree(worktree, ignore_errors=True)
+ stderr.write('PRE-RECEIVE: Merge complete %s %s' % (ref[:7], commit['comment'][0]))
+
+def do_check_commit(lines):
+ alsafiles = 0
+ otherfiles = 0
+ header = True
+ commit = {'comment':[], 'files':[]}
+ for line in lines:
+ if header:
+ if line.startswith('commit '):
+ commit['commit'] = line[7:].strip()
+ elif line.startswith('Merge:') or line.startswith('Author:') or \
+ line.startswith('AuthorDate:') or line.startswith('Commit:') or \
+ line.startswith('CommitDate:'):
+ a, b = line.split(': ')
+ commit[a.strip()] = b.strip()
+ elif line.startswith(' '):
+ header = False
+ if line.startswith(' '):
+ commit['comment'].append(line[4:])
+ elif not header and line != '\n':
+ commit['files'].append(line[:-1])
+ check = is_alsa_file(line[:-1])
+ if check:
+ alsafiles += 1
+ else:
+ otherfiles += 1
+ while commit['comment'][-1] == '\n':
+ del commit['comment'][-1]
+ if not alsafiles:
+ return
+ if check_alsa_commit(commit):
+ return
+ try_to_merge(commit)
+ if commit['commit'] in UPSTREAM_COMMITS:
+ stderr.write('PRE-RECEIVE: Upstream patch %s %s\n' % (commit['commit'][:7], lines[6][4:]))
+ return
+ if otherfiles:
+ stderr.write('PRE-RECEIVE: ALSA files %s other files %s\n' % (alsafiles, otherfiles))
+ return
+ if not check_email(lines, commit['Author']) or \
+ not check_email(lines, commit['Commit']):
+ fail()
+ #if not check_email(lines, committer, commit=True):
+ # exit(1)
+ if not lines[6][4:].upper().startswith('[ALSA] ') and \
+ not lines[6][4:].upper().startswith('ALSA: '):
+ error(lines, 'First log line does not start with "[ALSA] "\n')
+ fail()
+ lastsigned = ''
+ for line in lines[6:]:
+ if not line.startswith(' '):
+ break
+ line = line[4:-1]
+ line1 = line.lower()
+ if line1.startswith('signed-off-by:'):
+ if not line.startswith('Signed-off-by:'):
+ error(lines, 'Wrong Signed-off-by: line: "%s"\n' % line)
+ fail()
+ lastsigned = line[15:].strip()
+ if not lastsigned:
+ error(lines, 'Commit has no Signed-off-by: line\n')
+ fail()
+ if not lastsigned in VALID_COMMITERS:
+ error(lines, 'Last Signed-off-by: line has an invalid ALSA committer\n')
+ fail()
+
+def do_check(sha1old, sha1new, refname):
+ lines = popen("git log --reverse --name-only --pretty=fuller --date=iso %s..%s" % (sha1old, sha1new)).readlines()
+ count = len(lines)
+ idx = 1
+ while idx < count:
+ oldidx = idx - 1
+ commit = []
+ while idx < count and not lines[idx].startswith('commit '):
+ idx += 1
+ do_check_commit(lines[oldidx:idx])
+ idx += 1
+
+def compare_trees(lastref):
+ stderr.write('PRE-RECEIVE: comparing alsa-kmirror (old) and alsa-kernel (new) repos\n')
+ worktree = TMP_PATH + '/alsa-kmirror-repo'
+ worktreek = TMP_PATH + '/alsa-kernel-repo'
+ rmtree(worktree, ignore_errors=True)
+ rmtree(worktreek, ignore_errors=True)
+ mkdir(worktree)
+ mkdir(worktreek)
+ if system("git --work-tree=%s --git-dir=%s checkout -f -q master" % (worktree, KMIRROR_REPO)):
+ raise ValueError, 'git checkout (kmirror)'
+ if system("git --work-tree=%s --git-dir=%s checkout -q %s sound include/sound Documentation/sound/alsa" % (worktreek, KERNEL_REPO, lastref)):
+ raise ValueError, 'git checkout (kernel)'
+ curdir = getcwd()
+ chdir(TMP_PATH)
+ system("mv alsa-kernel-repo/sound/* alsa-kernel-repo")
+ rmtree("alsa-kernel-repo/sound")
+ system("mv alsa-kernel-repo/include/sound/* alsa-kernel-repo/include")
+ rmtree("alsa-kernel-repo/include/sound")
+ system("mv alsa-kernel-repo/Documentation/sound/alsa/* alsa-kernel-repo/Documentation")
+ rmtree("alsa-kernel-repo/Documentation/sound")
+ for i in ['.git-ok-commits', '.hgignore', '.hgtags', '.gitignore', 'kernel', 'scripts', 'oss']:
+ if isdir("alsa-kmirror-repo/%s" % i):
+ rmtree("alsa-kmirror-repo/%s" % i)
+ elif exists("alsa-kmirror-repo/%s" % i):
+ remove("alsa-kmirror-repo/%s" % i)
+ for i in ['oss']:
+ if isdir("alsa-kernel-repo/%s" % i):
+ rmtree("alsa-kernel-repo/%s" % i)
+ elif exists("alsa-kernel-repo/%s" % i):
+ remove("alsa-kernel-repo/%s" % i)
+ fp = popen("diff -ruNp alsa-kmirror-repo alsa-kernel-repo")
+ notempty = False
+ while 1:
+ line = fp.readline()
+ if not line:
+ break
+ stderr.write(line)
+ notempty = True
+ if notempty:
+ stderr.write('\n')
+ rmtree(worktree, ignore_errors=True)
+ rmtree(worktreek, ignore_errors=True)
+ if notempty:
+ stderr.write('PRE-RECEIVE: repositories does not match, please, fix it\n')
+ fail()
+
+lines = stdin.readlines()
+read_upstream_commits(lines[0][:-1].split(' ')[0])
+lastref = ''
+for line in lines:
+ sha1old, sha1new, refname = line[:-1].split(' ')
+ if refname in ['refs/heads/linux-2.6', 'refs/heads/for-linus']:
+ continue
+ elif refname.startswith('refs/tags/') or \
+ refname.startswith('refs/heads/private-') or \
+ refname.startswith('refs/heads/stable-2.6.'):
+ continue
+ elif refname != 'refs/heads/master':
+ stderr.write('PRE-RECEIVE: invalid branch "%s"\n' % refname)
+ fail()
+ do_check(sha1old, sha1new, refname)
+ lastref = sha1new
+if lastref:
+ compare_trees(lastref)
+ stderr.write('PRE-RECEIVE: Trees match...\n')
+stderr.write('PRE-RECEIVE: All done\n')
+if 0:
+ stderr.write('PRE-RECEIVE: Test mode active (try later)...\n')
+ fail()
+exit(0)