Skip to content

Commit 31ffe53

Browse files
Denis TikhomirovMichele Bertasi
authored andcommitted
Add git bc-show-eligible
1 parent ac94495 commit 31ffe53

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

bin/git-bc-show-eligible

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env python
2+
3+
import pygit2
4+
import re
5+
import argparse
6+
import sys
7+
8+
9+
def find_unpicked(repo, from_commit, to_commit, since_commit, show_all):
10+
base_id = repo.merge_base(from_commit.id, to_commit.id)
11+
12+
cherrypick_re = re.compile('(cherry picked from commit|with child) ([0-9a-fA-F]+)')
13+
cherrypicked_commits = set()
14+
15+
for commit in repo.walk(to_commit.id, pygit2.GIT_SORT_TOPOLOGICAL):
16+
if commit.id == base_id:
17+
break
18+
19+
for match in cherrypick_re.findall(commit.message):
20+
cherrypicked_commits.add(match[1])
21+
22+
user_name = repo.config.get_multivar('user.name').next()
23+
user_email = repo.config.get_multivar('user.email').next()
24+
25+
for commit in repo.walk(from_commit.id, pygit2.GIT_SORT_TOPOLOGICAL):
26+
# we walk from newest commits to oldest
27+
if commit.id == base_id:
28+
break
29+
30+
if str(commit.id) not in cherrypicked_commits and \
31+
(show_all or commit.author.name == user_name or
32+
commit.author.email == user_email):
33+
yield(commit)
34+
35+
if since_commit and commit.id == since_commit.id:
36+
break
37+
38+
parser = argparse.ArgumentParser(description='Show commits, eligible for cherry-picking')
39+
parser.add_argument('branch', metavar='BRANCH', help='Name for the branch to check against')
40+
parser.add_argument('target_branch', metavar='TARGET_BRANCH', help='Name for the target branch',
41+
default='HEAD', nargs='?')
42+
parser.add_argument('--since', metavar='COMMIT', help='Start checking since specified commit')
43+
parser.add_argument('--all', action='store_true', help='Show commits from all users')
44+
45+
args = parser.parse_args()
46+
repo = pygit2.Repository('.')
47+
48+
try:
49+
from_commit = repo.revparse_single(args.branch)
50+
except:
51+
print('Invalid branch %s' % args.branch)
52+
sys.exit(1)
53+
54+
try:
55+
to_commit = repo.revparse_single(args.target_branch)
56+
except:
57+
print('Invalid target branch %s' % args.target_branch)
58+
sys.exit(1)
59+
60+
if not repo.merge_base(from_commit.id, to_commit.id):
61+
print('%s and %s does not have common ancestor' % (args.branch, args.target_branch))
62+
sys.exit(1)
63+
64+
since_commit = None
65+
if args.since:
66+
try:
67+
since_commit = repo.revparse_single(args.since)
68+
except:
69+
print('Invalid since %s' % args.since)
70+
sys.exit(1)
71+
72+
author_format_str = ' | %s <%s>'
73+
commit_format_str = '%s %s%s'
74+
75+
if sys.stdout.isatty():
76+
author_format_str = ' \033[31m| %s <%s>\033[0m'
77+
commit_format_str = '\033[33m%s\033[0m %s%s'
78+
79+
for commit in find_unpicked(repo, from_commit, to_commit, since_commit, args.all):
80+
author_info = ''
81+
if args.all:
82+
author_info = author_format_str % (commit.author.name, commit.author.email)
83+
84+
print(commit_format_str % (str(commit.id), commit.message[:commit.message.index('\n')],
85+
author_info))

0 commit comments

Comments
 (0)