Skip to content

Instantly share code, notes, and snippets.

@dbnicholson
Created September 24, 2018 11:55
Show Gist options
  • Save dbnicholson/f5edddf0a425334afaead02b7f8dcee1 to your computer and use it in GitHub Desktop.
Save dbnicholson/f5edddf0a425334afaead02b7f8dcee1 to your computer and use it in GitHub Desktop.
#!/usr/bin/python3 -u
from argparse import ArgumentParser
from collections import defaultdict
from gi import require_version
require_version('OSTree', '1.0')
from gi.repository import GLib, Gio, OSTree
import sys
def commit_describe(repo, checksum, all_refs=True):
refmap = defaultdict(list)
_, ref_info = repo.list_refs()
for ref, rev in ref_info.items():
depth = 0
# Add an entry for the ref itself (depth 0)
refmap[rev].append((depth, ref))
# Walk the parents
while True:
_, commit = repo.load_variant_if_exists(OSTree.ObjectType.COMMIT, rev)
if commit is None:
break
rev = OSTree.commit_get_parent(commit)
if rev is None:
break
depth += 1
refmap[rev].append((depth, ref))
# Sort by depth then ref name
matches = sorted(refmap[checksum])
if not all_refs:
matches = matches[:1]
return [ref + '^' * depth for depth, ref in matches]
aparser = ArgumentParser(
description='Find the commit that contains a specific object'
)
aparser.add_argument('--repo', help='repository path')
aparser.add_argument('object', help='object filename')
args = aparser.parse_args()
if args.repo is None:
repo = OSTree.Repo.new_default()
else:
repo_file = Gio.File.new_for_path(args.repo)
repo = OSTree.Repo.new(repo_file)
repo.open(None)
checksum, objtype = OSTree.object_from_string(args.object)
wanted_obj = OSTree.object_name_serialize(checksum, objtype)
#print(wanted_obj)
#objtype = OSTree.object_type_from_string(args.objtype)
_, all_objects = repo.list_objects(OSTree.RepoListObjectsFlags.ALL, None)
#ret = repo.list_objects(OSTree.RepoListObjectsFlags.ALL)
#del objects
# checksums = set()
# for key in objects:
# checksum, objtype = OSTree.object_name_deserialize(key)
# checksums.add(checksum)
# #print(checksum, objtype)
if wanted_obj not in all_objects:
print('Could not find object', args.object, file=sys.stderr)
exit(1)
for objname in all_objects:
checksum, objtype = OSTree.object_name_deserialize(objname)
if objtype != OSTree.ObjectType.COMMIT:
continue
_, commit_objects = repo.traverse_commit(checksum, 0)
if wanted_obj in commit_objects:
print(OSTree.object_to_string(checksum, objtype))
print('\n'.join(commit_describe(repo, checksum)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment