def create_commit(apiurl, tree_sha1, revision, parents): """Create a git commit from a tree object and a build service revision.""" cmd = [opt_git, 'commit-tree', tree_sha1] for commit_sha1 in parents: cmd.extend(['-p', commit_sha1]) try: user = revision['user'] except KeyError: user = '******' if user == '_service': user = '******' encoding = getpreferredencoding() name, email = map_login_to_user(apiurl, user) time = revision['time'] environ['GIT_AUTHOR_NAME'] = name.encode(encoding) environ['GIT_COMMITTER_NAME'] = name.encode(encoding) environ['GIT_AUTHOR_EMAIL'] = email.encode(encoding) environ['GIT_COMMITTER_EMAIL'] = email.encode(encoding) environ['GIT_AUTHOR_DATE'] = time environ['GIT_COMMITTER_DATE'] = time proc = subprocess.Popen(cmd, stdin=PIPE, stdout=PIPE) if 'comment' in revision: proc.stdin.write(revision['comment']) proc.stdin.close() commit_sha1 = proc.stdout.read().rstrip('\n') check_proc(proc, cmd) return commit_sha1
def fetch_new_file(apiurl, project, package, srcmd5, name, md5): """Fetch a file. https://api.opensuse.org/source/PROJECT/PACKAGE/FILE&rev=REV """ query = 'rev=' + srcmd5 url = osc.core.makeurl(apiurl, ['source', project, package, name], query=query) if opt_verbose: print "-- GET " + url file = osc.core.http_GET(url) cmd = [opt_git, 'hash-object', '-w', '--stdin'] proc = subprocess.Popen(cmd, stdin=PIPE, stdout=PIPE) hasher = hashlib.md5() while True: data = file.read(16384) if len(data) == 0: break proc.stdin.write(data) hasher.update(data) if hasher.hexdigest() != md5: proc.kill() raise IOError('MD5 checksum mismatch') proc.stdin.close() sha1 = proc.stdout.read().rstrip('\n') check_proc(proc, cmd) return sha1
def git_get_commit(sha1): info = {} cmd = [opt_git, 'cat-file', 'commit', sha1] proc = subprocess.Popen(cmd, stdout=PIPE) while True: line = proc.stdout.readline() if line == '': break elif line == '\n': info['message'] = proc.stdout.read().rstrip('\n') break else: token, value = line.rstrip('\n').split(' ', 1) if token == 'tree': if token in info: raise IOError("Commit %s: parse error in headers" % sha1) info[token] = value elif token == 'parent': if 'parents' not in info: info['parents'] = [] info['parents'].append(value) elif token in ('author', 'committer'): match = re.match('(.*) <([^<>]+)> (\d+) ([-+]\d{4})$', value) if not match or token in info: raise IOError("Commit %s: parse error in headers" % sha1) name, email, time, timezone = match.groups() info[token] = {'name': name, 'email': email, 'time': time, 'timezone': timezone} else: raise IOError("Commit %s: parse error in headers" % sha1) check_proc(proc, cmd) return info
def create_tree(files): """Create a git tree object from a list of files.""" # FIXME: Use NUL-terminated format (-z) for newlines in filenames. cmd = [opt_git, 'mktree'] proc = subprocess.Popen(cmd, stdin=PIPE, stdout=PIPE) for file in sorted(files, cmp=lambda a,b: cmp(a['name'], b['name'])): line = '100644 blob %s\t%s\n' % (file['sha1'], file['name']) proc.stdin.write(line) proc.stdin.close() tree_sha1 = proc.stdout.read().rstrip('\n') check_proc(proc, cmd) return tree_sha1