import pygit2 # using version 1.15.1 in this example import sys import os def walk_repo_files(repo, branch): tree = repo.revparse_single(branch).tree trees_and_paths = [(tree, [])] # keep going until there is no more data while len(trees_and_paths) != 0: tree, path = trees_and_paths.pop() # take the last entry new_trees = [] for entry in tree: if entry.filemode == pygit2.GIT_FILEMODE_TREE: next_tree = repo.get(entry.id) next_path = list(path) next_path.append(entry.name) new_trees.append((next_tree, next_path, entry.name)) else: yield path, entry # sort by the last element in the tuples, the name new_trees.sort(key = lambda x: x[2].lower()) trees_and_paths.extend( (a,b) for a, b, _ in new_trees) def walk_repo_files_reverse_sorted(repo, branch): walker = walk_repo_files(repo, branch) try: prev_path, entry = next(walker) except StopIteration: return # repo is empty accum = [entry] for path, entry in walker: if prev_path != path: # sort elements in reverse order by name accum.sort(key = lambda x: x.name.lower(), reverse=True) for i in accum: yield prev_path, i prev_path = path accum.clear() accum.append(entry) repo_path = sys.argv[1] branch_name = sys.argv[2] repo = pygit2.Repository(repo_path) all_files = list(walk_repo_files_reverse_sorted(repo, branch_name)) all_files.reverse() for path, entry in all_files: sys.stdout.write(os.path.join(*path, entry.name)) sys.stdout.write("\n")