#!/usr/bin/python3 # -*- coding: utf-8 -*- # Copyright (C) 2018 SUSE LLC # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. from git_sort import pygit2_wrapper as pygit2 from git_sort.git_sort import * import argparse import pprint import sys parser = argparse.ArgumentParser( description="Sort input lines according to the upstream order of " "commits that each line represents, with the first word on the line " "taken to be a commit id.") parser.add_argument("-d", "--dump-heads", action="store_true", help="Print the branch heads used for sorting " "(debugging).") args = parser.parse_args() try: path = os.environ["GIT_DIR"] except KeyError: try: # depending on the pygit2 version, discover_repository() will either # raise KeyError or return None if a repository is not found. path = pygit2.discover_repository(os.getcwd()) except KeyError: path = None if path is None: print("Error: Not a git repository", file=sys.stderr) sys.exit(1) repo = pygit2.Repository(path) if args.dump_heads: needs_rebuild = False try: with Cache() as cache: try: print("Cached heads (version %d):" % cache["version"]) except CKeyError: print("No usable cache") needs_rebuild = True else: try: history = cache["history"] except CUnsupported: print("Unsupported cache version") needs_rebuild = True except CInconsistent: print("Inconsistent cache content") needs_rebuild = True else: pprint.pprint(list(history.keys())) except CAbsent: print("No usable cache") needs_rebuild = True except CNeedsRebuild: needs_rebuild = True except CError as err: print("Error: %s" % (err,), file=sys.stderr) sys.exit(1) try: repo_heads = get_heads(repo) except GSError as err: print("Error: %s" % (err,), file=sys.stderr) sys.exit(1) if not needs_rebuild and list(history.keys()) != list(repo_heads.items()): needs_rebuild = True print("Current heads (version %d):" % Cache.version) pprint.pprint(list(repo_heads.items())) if needs_rebuild: action = "Will" else: action = "Will not" print("%s rebuild history" % (action,)) sys.exit(0) index = SortIndex(repo) dest = {} oot = [] num = 0 for line in sys.stdin.readlines(): num = num + 1 tokens = line.strip().split(None, 1) if not tokens: continue try: commit = repo.revparse_single(tokens[0]) except ValueError: print("Error: did not find a commit hash on line %d:\n%s" % (num, line.strip(),), file=sys.stderr) sys.exit(1) except KeyError: print("Error: commit hash on line %d not found in the repository:\n%s" % (num, line.strip(),), file=sys.stderr) sys.exit(1) h = str(commit.id) if h in dest: dest[h][1].append(line) else: try: ic = index.lookup(h) except GSKeyError: oot.append(line) else: dest[h] = (ic, [line],) print("".join([line for ic, lines in sorted(dest.values(), key=operator.itemgetter(0)) for line in lines ]), end="") if oot: print("Error: the following entries were not found in the indexed heads:", file=sys.stderr) print("".join(oot), end="") sys.exit(1)