bugs-fixed-since: support --easy-backport argument

This argument will make the tool to ignore master patches that don't
cherry-pick cleanly into each stable branch. This is sometimes useful to
distinguish between backport candidates that are easy to process, and
those that will require some more work to resolve git conflicts.

Change-Id: I9f0d1803fc753bad4e31dbd14244f18ba1672625
This commit is contained in:
Ihar Hrachyshka 2017-02-01 13:38:47 -08:00
parent dfa2b9185c
commit c867e240db
2 changed files with 41 additions and 0 deletions

View File

@ -955,6 +955,13 @@ Example::
./bugs-fixed-since.py -B -r ../neutron --start=8.0.0
Use ``-e`` option to ignore patches that don't apply cleanly to one of stable
branches.
Example::
./bugs-fixed-since.py -e -r ../neutron --start=8.0.0
lp-filter-bugs-by-importance.py
-------------------------------

View File

@ -19,6 +19,7 @@ This tool will list bugs that were fixed in project master.
import argparse
import re
from git import cmd
from git import Repo
@ -42,6 +43,12 @@ def _parse_args():
action='store_true',
help='whether to skip patches backported to all stable branches',
)
parser.add_argument(
'--easy-backport', '-e',
action='store_true',
default=False,
help='whether to include easy (no git conflicts) backports only',
)
return parser.parse_args()
@ -62,6 +69,28 @@ def _extract_changeid(commit):
return id_
def _is_easy_backport(repo, commit):
g_cmd = cmd.Git(working_dir=repo.working_tree_dir)
for ref in repo.refs:
# consider a patch easy to backport if only it cleanly applies to all
# stable branches; otherwise it will potentially require more work to
# resolve git conflicts
if ref.name.startswith('origin/stable/'):
# before applying any patches, make sure the tree is clean and
# fully reflects remote head
g_cmd.clean(force=True, d=True, x=True)
g_cmd.reset(hard=True)
g_cmd.checkout(ref.name)
try:
g_cmd.cherry_pick(commit.hexsha)
except cmd.GitCommandError:
# cherry-pick does not have a 'dry run' mode, so we need to
# actually clean up after a failure
g_cmd.cherry_pick(abort=True)
return False
return True
def main():
args = _parse_args()
@ -87,6 +116,11 @@ def main():
_backported_to_all_stable_branches(repo, id_)):
continue
# skip patches that result in git conflicts in any of stable branches
if (args.easy_backport and
not _is_easy_backport(repo, commit)):
continue
# collect every bug number mentioned in the message
for match in re.finditer(BUG_PATTERN, commit.message):
bugs.add(match.group('bugnum'))