All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: u-boot@lists.denx.de
Subject: [RFC PATCH 15/16] patman: Support updating a branch with review tags
Date: Sun,  5 Jul 2020 21:42:02 -0600	[thread overview]
Message-ID: <20200706034203.2171077-16-sjg@chromium.org> (raw)
In-Reply-To: <20200706034203.2171077-1-sjg@chromium.org>

It is tedious to add review tags into the local branch and errors can
sometimes be made. Add an option to create a new branch with the review
tags obtained from patchwork.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/patman/README     | 17 +++++++++++--
 tools/patman/control.py |  9 ++++---
 tools/patman/main.py    |  7 +++++-
 tools/patman/status.py  | 54 ++++++++++++++++++++++++++++++++++++++---
 4 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/tools/patman/README b/tools/patman/README
index a85974740f..595a0d616b 100644
--- a/tools/patman/README
+++ b/tools/patman/README
@@ -11,11 +11,13 @@ This tool is a Python script which:
 - Runs the patches through checkpatch.pl and its own checks
 - Optionally emails them out to selected people
 
-It also shows review tags from Patchwork so you can update your local patches.
+It also has some Patchwork features:
+- shows review tags from Patchwork so you can update your local patches
+- pulls these down into a new branch on request
 
 It is intended to automate patch creation and make it a less
 error-prone process. It is useful for U-Boot and Linux work so far,
-since it uses the checkpatch.pl script.
+since they use the checkpatch.pl script.
 
 It is configured almost entirely by tags it finds in your commits.
 This means that you can work on a number of different branches at
@@ -378,6 +380,17 @@ attracted another review each. If the series needs changes, you can update
 these commits with the new review tag before sending the next version of the
 series.
 
+To automatically pull into these tags into a new branch, use the -d option:
+
+    patman status -d mtrr4
+
+This will create a new 'mtrr4' branch which is the same as your current branch
+but has the new review tags in it. You can check that this worked with:
+
+    patman -b mtrr4 status
+
+which should show that there are no new responses compared to this new branch.
+
 
 Example Work Flow
 =================
diff --git a/tools/patman/control.py b/tools/patman/control.py
index 3bb3c236e4..b6ba0a56c0 100644
--- a/tools/patman/control.py
+++ b/tools/patman/control.py
@@ -174,11 +174,11 @@ def send(args):
             args.limit, args.dry_run, args.in_reply_to, args.thread,
             args.smtp_server)
 
-def patchwork_status(branch, count, start, end):
+def patchwork_status(branch, count, start, end, dest_branch, force):
     """Check the status of patches in patchwork
 
     This finds the series in patchwork using the Series-link tag, checks for new
-    comments / review tags and displays them
+    review tags, displays then and creates a new branch with the review tags.
 
     Args:
         branch (str): Branch to create patches from (None = current)
@@ -187,6 +187,9 @@ def patchwork_status(branch, count, start, end):
         start (int): Start partch to use (0=first / top of branch)
         end (int): End patch to use (0=last one in series, 1=one before that,
             etc.)
+        dest_branch (str): Name of new branch to create with the updated tags
+            (None to not create a branch)
+        force (bool): With dest_branch, force overwriting an existing branch
 
     Raises:
         ValueError: if the branch has no Series-link value
@@ -203,4 +206,4 @@ def patchwork_status(branch, count, start, end):
     # Import this here to avoid failing on other commands if the dependencies
     # are not present
     from patman import status
-    status.check_patchwork_status(series, link, branch)
+    status.check_patchwork_status(series, link, branch, dest_branch, force)
diff --git a/tools/patman/main.py b/tools/patman/main.py
index 227eb3b228..c8fc035c10 100755
--- a/tools/patman/main.py
+++ b/tools/patman/main.py
@@ -90,6 +90,10 @@ AddCommonArgs(test_parser)
 
 status = subparsers.add_parser('status',
                                help='Check status of patches in patchwork')
+status.add_argument('-d', '--dest-branch', type=str,
+                    help='Name of branch to create with collected responses')
+status.add_argument('-f', '--force', action='store_true',
+                    help='Force overwriting an existing branch')
 AddCommonArgs(status)
 
 # Parse options twice: first to get the project and second to handle
@@ -156,7 +160,8 @@ elif args.cmd == 'send':
 elif args.cmd == 'status':
     ret_code = 0
     try:
-        control.patchwork_status(args.branch, args.count, args.start, args.end)
+        control.patchwork_status(args.branch, args.count, args.start, args.end,
+                                 args.dest_branch, args.force)
     except Exception as e:
         print('patman: %s: %s' % (type(e).__name__, e))
         if args.debug:
diff --git a/tools/patman/status.py b/tools/patman/status.py
index c2e98a5d11..71124d6e5e 100644
--- a/tools/patman/status.py
+++ b/tools/patman/status.py
@@ -304,7 +304,48 @@ def ShowResponses(rtags, indent, is_new):
             count += 1
     return count
 
-def check_patchwork_status(series, url, branch):
+def CreateBranch(series, new_rtag_list, branch, dest_branch, overwrite):
+    if branch == dest_branch:
+        raise ValueError(
+            'Destination branch must not be the same as the original branch')
+    repo = pygit2.Repository('.')
+    count = len(series.commits)
+    old_br = repo.branches[branch]
+    new_br = repo.branches.get(dest_branch)
+    if new_br:
+        if not overwrite:
+            raise ValueError("Branch '%s' already exists (-f to overwrite)" %
+                             dest_branch)
+        new_br.delete()
+    target = repo.revparse_single('%s~%d' % (branch, count))
+    repo.branches.local.create(dest_branch, target)
+
+    num_added = 0
+    for seq in range(count):
+        basket = repo.branches.get(dest_branch)
+        cherry = repo.revparse_single('%s~%d' % (branch, count - seq - 1))
+
+        base = repo.merge_base(cherry.oid, basket.target)
+        base_tree = cherry.parents[0].tree
+
+        index = repo.merge_trees(base_tree, basket, cherry)
+        tree_id = index.write_tree(repo)
+
+        author    = cherry.author
+        committer = cherry.committer
+        lines = []
+        for tag, people in new_rtag_list[seq].items():
+            for who in people:
+                lines.append('%s: %s' % (tag, who))
+                num_added += 1
+        message = cherry.message + '\n'.join(lines)
+
+        basket = repo.create_commit(
+            basket.name, cherry.author, cherry.committer, message, tree_id,
+            [basket.target])
+    return num_added
+
+def check_patchwork_status(series, url, branch, dest_branch, force):
     patches = CollectPatches(series, url)
     col = terminal.Color()
     count = len(patches)
@@ -330,5 +371,12 @@ def check_patchwork_status(series, url, branch):
         ShowResponses(base_rtags, indent, False)
         num_to_add += ShowResponses(new_rtags, indent, True)
 
-    print("%d new response%s available in patchwork" %
-          (num_to_add, 's' if num_to_add != 1 else ''))
+    print("%d new response%s available in patchwork%s" %
+          (num_to_add, 's' if num_to_add != 1 else '',
+           '' if dest_branch else ' (use -d to write them to a new branch)'))
+
+    if dest_branch:
+        num_added = CreateBranch(series, new_rtag_list, branch,
+                                 dest_branch, force)
+        print("%d response%s added from patchwork into new branch '%s'" %
+              (num_added, 's' if num_added != 1 else '', dest_branch))
-- 
2.27.0.212.ge8ba1cc988-goog

  parent reply	other threads:[~2020-07-06  3:42 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-06  3:41 [RFC PATCH 00/16] RFC: patman: Collect review tags and comments from Patchwork Simon Glass
2020-07-06  3:41 ` [RFC PATCH 01/16] patman: Use test_util to show test results Simon Glass
2020-07-06  4:46   ` Daniel Axtens
2020-07-06  4:50     ` Daniel Axtens
2020-07-06 14:52       ` Simon Glass
2020-07-07  1:09         ` Daniel Axtens
2020-07-08 17:42           ` Stephen Finucane
2020-07-19 20:49           ` Simon Glass
2020-07-06  3:41 ` [RFC PATCH 02/16] patman: Move main code out to a control module Simon Glass
2020-07-06  3:41 ` [RFC PATCH 03/16] patman: Add a test that uses gitpython Simon Glass
2020-07-06  3:41 ` [RFC PATCH 04/16] patman: Allow creating patches for another branch Simon Glass
2020-07-06  3:41 ` [RFC PATCH 05/16] patman: Allow skipping patches at the end Simon Glass
2020-07-06  3:41 ` [RFC PATCH 06/16] patman: Convert to ArgumentParser Simon Glass
2020-07-06  3:41 ` [RFC PATCH 07/16] patman: Allow different commands Simon Glass
2020-07-06  3:41 ` [RFC PATCH 08/16] patman: Add a 'test' subcommand Simon Glass
2020-07-06  3:41 ` [RFC PATCH 09/16] patman: Allow disabling 'bright' mode with Print output Simon Glass
2020-07-06  3:41 ` [RFC PATCH 10/16] patman: Support collecting response tags in Patchstream Simon Glass
2020-07-06  3:41 ` [RFC PATCH 11/16] patman: Allow linking a series with patchwork Simon Glass
2020-07-06  3:41 ` [RFC PATCH 12/16] patman: Add a -D option to enable debugging Simon Glass
2020-07-06  3:42 ` [RFC PATCH 13/16] patchstream: Support parsing of review snippets Simon Glass
2020-07-06  3:42 ` [RFC PATCH 14/16] patman: Support checking for review tags in patchwork Simon Glass
2020-07-06  3:42 ` Simon Glass [this message]
2020-07-06  3:42 ` [RFC PATCH 16/16] patman: Support listing comments from patchwork Simon Glass
2020-07-15  9:10 ` [RFC PATCH 00/16] RFC: patman: Collect review tags and comments from Patchwork Michal Simek
2020-07-19 20:49 ` [RFC PATCH 10/16] patman: Support collecting response tags in Patchstream Simon Glass
2020-07-19 20:49 ` [RFC PATCH 09/16] patman: Allow disabling 'bright' mode with Print output Simon Glass
2020-07-19 20:49 ` [RFC PATCH 08/16] patman: Add a 'test' subcommand Simon Glass
2020-07-19 20:49 ` [RFC PATCH 07/16] patman: Allow different commands Simon Glass
2020-07-19 20:49 ` [RFC PATCH 06/16] patman: Convert to ArgumentParser Simon Glass
2020-07-19 20:49 ` [RFC PATCH 05/16] patman: Allow skipping patches at the end Simon Glass
2020-07-19 20:49 ` [RFC PATCH 04/16] patman: Allow creating patches for another branch Simon Glass
2020-07-19 20:49 ` [RFC PATCH 03/16] patman: Add a test that uses gitpython Simon Glass
2020-07-19 20:49 ` [RFC PATCH 02/16] patman: Move main code out to a control module Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200706034203.2171077-16-sjg@chromium.org \
    --to=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.