Skip to content

Commit 6c59562

Browse files
committed
describe-commit: New script to describe commits in terms of refs
This is similar to git-describe(1) in that it takes a commit checksum and describes the commit in terms of refs. This is useful if you have a repository with a lot of commits and need to do some non-standard pruning.
1 parent 69615c0 commit 6c59562

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,9 @@ Generate statistics on the files in a given commit.
5454
## write-ref
5555

5656
Directly change a given ref, with no verification.
57+
58+
## describe-commit
59+
60+
Describe a commit in terms of refs. This is similar to git-describe(1)
61+
except the description is always in terms of refs that the commit is
62+
contained in.

describe-commit

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python
2+
#
3+
# Describe a commit in terms of refs
4+
#
5+
# Copyright 2017 Dan Nicholson <[email protected]>
6+
# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
7+
8+
from __future__ import print_function
9+
10+
from argparse import ArgumentParser
11+
from collections import defaultdict
12+
from gi import require_version
13+
require_version('OSTree', '1.0')
14+
from gi.repository import GLib, Gio, OSTree
15+
import sys
16+
17+
def commit_describe(repo, checksum, all_refs=False):
18+
refmap = defaultdict(list)
19+
20+
_, ref_info = repo.list_refs()
21+
for ref, rev in ref_info.items():
22+
# Walk the ref
23+
depth = 0
24+
while True:
25+
_, commit = repo.load_variant_if_exists(OSTree.ObjectType.COMMIT,
26+
rev)
27+
if commit is None:
28+
if depth == 0:
29+
# The ref file is pointing to a non-existent commit
30+
print('Ref', ref, 'commit', rev, 'does not exist',
31+
file=sys.stderr)
32+
exit(1)
33+
else:
34+
# The commit's parent doesn't exist. Either it was
35+
# pruned out or never pulled in the first place.
36+
# Silently move on.
37+
break
38+
39+
# Add this commit to the map
40+
refmap[rev].append((depth, ref + depth * '^'))
41+
42+
# Get the parent
43+
rev = OSTree.commit_get_parent(commit)
44+
if rev is None:
45+
break
46+
depth += 1
47+
48+
# Sort by depth then ref name
49+
matches = sorted(refmap[checksum])
50+
if not all_refs:
51+
matches = matches[:1]
52+
return [ref for depth, ref in matches]
53+
54+
aparser = ArgumentParser(
55+
description='Describe a commit in terms of refs'
56+
)
57+
aparser.add_argument('--repo', help='repository path')
58+
aparser.add_argument('--all', action='store_true',
59+
help='show all descriptions')
60+
aparser.add_argument('commit', help='commit checksum or ref')
61+
args = aparser.parse_args()
62+
63+
if args.repo is None:
64+
repo = OSTree.Repo.new_default()
65+
else:
66+
repo_file = Gio.File.new_for_path(args.repo)
67+
repo = OSTree.Repo.new(repo_file)
68+
repo.open()
69+
70+
_, rev = repo.resolve_rev(args.commit, False)
71+
matches = commit_describe(repo, rev, all_refs=args.all)
72+
if len(matches) > 0:
73+
print(*matches, sep='\n')

0 commit comments

Comments
 (0)