Skip to content

Commit 1cb66f1

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 1cb66f1

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-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: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env python
2+
#
3+
# Describe a commit in terms of refs
4+
#
5+
# Copyright 2017 Dan Nicholson <nicholson@endlessm.com>
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=True):
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+
break
29+
refmap[rev].append((depth, ref + depth * '^'))
30+
31+
# Get the parent
32+
rev = OSTree.commit_get_parent(commit)
33+
if rev is None:
34+
break
35+
depth += 1
36+
37+
# Sort by depth then ref name
38+
matches = sorted(refmap[checksum])
39+
if not all_refs:
40+
matches = matches[:1]
41+
return [ref for depth, ref in matches]
42+
43+
aparser = ArgumentParser(
44+
description='Describe a commit in terms of refs'
45+
)
46+
aparser.add_argument('--repo', help='repository path')
47+
aparser.add_argument('--all', action='store_true',
48+
help='show all descriptions')
49+
aparser.add_argument('commit', help='commit checksum or ref')
50+
args = aparser.parse_args()
51+
52+
if args.repo is None:
53+
repo = OSTree.Repo.new_default()
54+
else:
55+
repo_file = Gio.File.new_for_path(args.repo)
56+
repo = OSTree.Repo.new(repo_file)
57+
repo.open()
58+
59+
_, rev = repo.resolve_rev(args.commit, False)
60+
matches = commit_describe(repo, rev, all_refs=args.all)
61+
if len(matches) > 0:
62+
print(*matches, sep='\n')

0 commit comments

Comments
 (0)