aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Ryabitsev <konstantin@linuxfoundation.org>2022-06-16 16:22:55 -0400
committerKonstantin Ryabitsev <konstantin@linuxfoundation.org>2022-06-16 16:22:55 -0400
commit797fc250c7dd64550f2283bdc749eda7555e3fa3 (patch)
tree24293cea445b68bd4a03e7906ff649a7f7c63781
parent70bf7e4c8563576241e15fcea9380d491d7e5cd7 (diff)
downloadb4-797fc250c7dd64550f2283bdc749eda7555e3fa3.tar.gz
Implement "b4 shazam -M" that execs git-merge
In addition to just being able to fetch a series into FETCH_HEAD, also add an option to exec git-merge automatically so that people don't have to cut-and-paste the merge command to use with paths to the cover letter. Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
-rw-r--r--b4/command.py11
-rw-r--r--b4/mbox.py87
-rw-r--r--man/b4.5.rst60
-rw-r--r--shazam-merge-template.example6
4 files changed, 115 insertions, 49 deletions
diff --git a/b4/command.py b/b4/command.py
index aa307da..4f69231 100644
--- a/b4/command.py
+++ b/b4/command.py
@@ -152,15 +152,18 @@ def cmd():
sp_sh = subparsers.add_parser('shazam', help='Like b4 am, but applies the series to your tree')
cmd_retrieval_common_opts(sp_sh)
cmd_am_common_opts(sp_sh)
- sp_sh.add_argument('-H', '--make-fetch-head', dest='makefetchhead', action='store_true', default=False,
- help='Attempt to treat series as a pull request and fetch it into FETCH_HEAD')
+ sh_g = sp_sh.add_mutually_exclusive_group()
+ sh_g.add_argument('-H', '--make-fetch-head', dest='makefetchhead', action='store_true', default=False,
+ help='Attempt to treat series as a pull request and fetch it into FETCH_HEAD')
+ sh_g.add_argument('-M', '--merge', dest='merge', action='store_true', default=False,
+ help='Attempt to merge series as if it were a pull request (execs git-merge)')
sp_sh.add_argument('--guess-lookback', dest='guessdays', type=int, default=21,
- help=('(use with -H) When guessing base, go back this many days from the patch date '
+ help=('(use with -H or -M) When guessing base, go back this many days from the patch date '
'(default: 3 weeks)'))
sp_sh.set_defaults(func=cmd_shazam)
# b4 attest
- sp_att = subparsers.add_parser('attest', help='Create cryptographic attestation for a set of patches')
+ sp_att = subparsers.add_parser('attest', help='(DEPRECATED) Create cryptographic attestation for a set of patches')
sp_att.add_argument('-f', '--from', dest='sender', default=None,
help='OBSOLETE: this option does nothing and will be removed')
sp_att.add_argument('-n', '--no-submit', dest='nosubmit', action='store_true', default=False,
diff --git a/b4/mbox.py b/b4/mbox.py
index 4ac2c29..277df89 100644
--- a/b4/mbox.py
+++ b/b4/mbox.py
@@ -34,9 +34,9 @@ logger = b4.logger
DEFAULT_MERGE_TEMPLATE = """Merge ${patch_or_series} "${seriestitle}"
${authorname} <${authoremail}> says:
-====================
-${coverletter}
-====================
+
+${covermessage}
+
Link: ${midurl}
"""
@@ -263,7 +263,7 @@ def make_am(msgs, cmdargs, msgid):
b4.save_git_am_mbox(am_msgs, ifh)
ambytes = ifh.getvalue().encode()
if not cmdargs.makefetchhead:
- amflags = config.get('git-am-flags', '')
+ amflags = config.get('shazam-am-flags', '')
sp = shlex.shlex(amflags, posix=True)
sp.whitespace_split = True
amargs = list(sp)
@@ -332,44 +332,59 @@ def make_am(msgs, cmdargs, msgid):
logger.critical(out.strip())
sys.exit(ecode)
mmf = os.path.join(fhf.rstrip(), 'b4-cover')
+ merge_template = DEFAULT_MERGE_TEMPLATE
+ if config.get('shazam-merge-template'):
+ # Try to load this template instead
+ try:
+ merge_template = b4.read_template(config['shazam-merge-template'])
+ except FileNotFoundError:
+ logger.critical('ERROR: shazam-merge-template says to use %s, but it does not exist',
+ config['shazam-merge-template'])
+ sys.exit(2)
+
+ # Write out a sample merge message using the cover letter
+ if os.path.exists(mmf):
+ # Make sure any old cover letters don't confuse anyone
+ os.unlink(mmf)
+
if lser.has_cover:
- merge_template = DEFAULT_MERGE_TEMPLATE
- if config.get('shazam-merge-template'):
- # Try to load this template instead
- try:
- merge_template = b4.read_template(config['shazam-merge-template'])
- except FileNotFoundError:
- logger.critical('ERROR: shazam-merge-template says to use %s, but it does not exist',
- config['shazam-merge-template'])
- sys.exit(2)
-
- # Write out a sample merge message using the cover letter
cmsg = lser.patches[0]
parts = b4.LoreMessage.get_body_parts(cmsg.body)
- tptvals = {
- 'seriestitle': cmsg.subject,
- 'authorname': cmsg.fromname,
- 'authoremail': cmsg.fromemail,
- 'coverletter': parts[1],
- 'midurl': linkurl,
- }
- if len(am_msgs) > 1:
- tptvals['patch_or_series'] = 'patch series'
- else:
- tptvals['patch_or_series'] = 'patch'
+ covermessage = parts[1]
+ else:
+ cmsg = lser.patches[1]
+ covermessage = ('NOTE: No cover letter provided by the author.\n'
+ ' Add merge commit message here.')
+ tptvals = {
+ 'seriestitle': cmsg.subject,
+ 'authorname': cmsg.fromname,
+ 'authoremail': cmsg.fromemail,
+ 'covermessage': covermessage,
+ 'midurl': linkurl,
+ }
+ if len(am_msgs) > 1:
+ tptvals['patch_or_series'] = 'patch series'
+ else:
+ tptvals['patch_or_series'] = 'patch'
- body = Template(merge_template).safe_substitute(tptvals)
- with open(mmf, 'w') as mmh:
- mmh.write(body)
+ body = Template(merge_template).safe_substitute(tptvals)
+ with open(mmf, 'w') as mmh:
+ mmh.write(body)
- elif os.path.exists(mmf):
- # Make sure any old cover letters don't confuse anyone
- os.unlink(mmf)
+ mergeflags = config.get('shazam-merge-flags', '--signoff')
+ sp = shlex.shlex(mergeflags, posix=True)
+ sp.whitespace_split = True
+ mergeargs = ['merge', '--no-ff', '-F', mmf, '--edit', 'FETCH_HEAD'] + list(sp)
+ mergecmd = ['git'] + mergeargs
- logger.info('You can now merge or checkout FETCH_HEAD')
- if lser.has_cover:
- logger.info(' e.g.: git merge -F $(git rev-parse --git-dir)/b4-cover --signoff --edit FETCH_HEAD')
thanks_record_am(lser, cherrypick=cherrypick)
+ if cmdargs.merge:
+ # We exec git-merge and let it take over
+ logger.info('Invoking: %s', ' '.join(mergecmd))
+ os.execvp(mergecmd[0], mergecmd)
+
+ logger.info('You can now merge or checkout FETCH_HEAD')
+ logger.info(' e.g.: %s', ' '.join(mergecmd))
return
if not base_commit:
@@ -711,6 +726,8 @@ def main(cmdargs):
cmdargs.nopartialreroll = False
cmdargs.outdir = '-'
cmdargs.guessbranch = None
+ if cmdargs.merge:
+ cmdargs.makefetchhead = True
if cmdargs.makefetchhead:
cmdargs.guessbase = True
else:
diff --git a/man/b4.5.rst b/man/b4.5.rst
index 246d224..7bda7db 100644
--- a/man/b4.5.rst
+++ b/man/b4.5.rst
@@ -46,6 +46,12 @@ SUBCOMMAND OPTIONS
------------------
b4 mbox
~~~~~~~
+
+This command allows retrieving entire threads from a remote public-inbox
+instance. The resulting mbox file can then be opened with most MUA
+clients for actions like replying to conversations or reviewing patch
+submissions.
+
usage:
b4 mbox [-h] [-p USEPROJECT] [-m LOCALMBOX] [-C] [-o OUTDIR] [-c] [-n WANTNAME] [-M] [-f] [msgid]
@@ -76,6 +82,25 @@ options:
b4 am
~~~~~
+
+This command allows retrieving threads from a public-inbox instance and
+preparing them for applying to a git repository using the "git am"
+command. It will automatically perform the following operations:
+
+* pick the latest submitted version of the series (it can check for
+ newer threads using ``-c`` as well)
+* check DKIM signatures and patatt attestation on all patches and code
+ review messages
+* collate all submitted code-review trailers (Reviewed-by, Acked-by,
+ etc) and put them into the commit message
+* add your own Signed-off-by trailer (with ``-s``)
+* reroll series from partial updates (e.g. someone submits a v2 of a
+ single patch instead of rerolling the entire series)
+* guess where in the tree history the patches belong, if the exact
+ commit-base is not specified (with ``-g``)
+* prepare the tree for a 3-way merge (with ``-3``)
+* cherry-pick a subset of patches from a large series (with ``-P``)
+
usage:
b4 am [-h] [-p USEPROJECT] [-m LOCALMBOX] [-C] [-o OUTDIR] [-c] [-n WANTNAME] [-M] [-v WANTVER] [-t] [-S] [-T] [-s] [-l] [-P CHERRYPICK] [--cc-trailers] [--no-parent] [--allow-unicode-control-chars] [-Q] [-g] [-b GUESSBRANCH [GUESSBRANCH ...]] [--guess-lookback GUESSDAYS] [-3] [--no-cover] [--no-partial-reroll] [msgid]
@@ -137,11 +162,20 @@ options:
*Example*: b4 am 20200313231252.64999-1-keescook@chromium.org
-
b4 shazam
---------
+
+This is very similar to **b4 am**, but will also apply patches
+directly to the current git tree using ``git am``. Alternatively, when
+used with ``-H``, it can fetch the patch series into ``FETCH_HEAD`` as
+if it were a pull request, so it can be reviewed and merged. In this
+case, the cover letter is used as a template for the merge commit.
+
+If you want to automatically invoke git-merge, you can use ``-M``
+instead of ``-H``.
+
usage:
- b4 shazam [-h] [-p USEPROJECT] [-m LOCALMBOX] [-C] [-v WANTVER] [-t] [-S] [-T] [-s] [-l] [-P CHERRYPICK] [--cc-trailers] [--no-parent] [--allow-unicode-control-chars] [-H] [--guess-lookback GUESSDAYS] [msgid]
+ b4 shazam [-h] [-p USEPROJECT] [-m LOCALMBOX] [-C] [-v WANTVER] [-t] [-S] [-T] [-s] [-l] [-P CHERRYPICK] [--cc-trailers] [--no-parent] [--allow-unicode-control-chars] [-H | -M] [--guess-lookback GUESSDAYS] [msgid]
positional arguments:
msgid Message ID to process, or pipe a raw message
@@ -171,15 +205,15 @@ options:
Allow unicode control characters (very rarely legitimate)
-H, --make-fetch-head
Attempt to treat series as a pull request and fetch it into FETCH_HEAD
+ -M, --merge
+ Attempt to merge series as if it were a pull request (execs git-merge)
--guess-lookback GUESSDAYS
- (use with -H) When guessing base, go back this many days from the patch date (default: 3 weeks)
+ (use with -H or -M) When guessing base, go back this many days from the patch date (default: 3 weeks)
*Example*: b4 shazam -H 20200313231252.64999-1-keescook@chromium.org
b4 attest
~~~~~~~~~
-usage: b4 attest [-h] patchfile [patchfile ...]
-
.. note::
**This subcommand is deprecated and will be removed in a future
@@ -189,6 +223,9 @@ usage: b4 attest [-h] patchfile [patchfile ...]
"patatt". You may instead install and use patatt directly with the
same results.
+usage:
+ b4 attest [-h] patchfile [patchfile ...]
+
positional arguments:
patchfile Patches to attest
@@ -196,6 +233,9 @@ positional arguments:
b4 pr
~~~~~
+This command is for working with pull requests submitted using
+``git-request-pull``.
+
usage:
command.py pr [-h] [-g GITDIR] [-b BRANCH] [-c] [-e] [-o OUTMBOX] [msgid]
@@ -251,7 +291,8 @@ optional arguments:
b4 diff
~~~~~~~
-usage: b4 diff [-h] [-g GITDIR] [-p USEPROJECT] [-C] [-v WANTVERS [WANTVERS ...]] [-n] [-o OUTDIFF] [-c] [-m AMBOX AMBOX] [msgid]
+usage:
+ b4 diff [-h] [-g GITDIR] [-p USEPROJECT] [-C] [-v WANTVERS [WANTVERS ...]] [-n] [-o OUTDIFF] [-c] [-m AMBOX AMBOX] [msgid]
positional arguments:
msgid Message ID to process, pipe a raw message, or use -m
@@ -283,7 +324,8 @@ optional arguments:
b4 kr
~~~~~
-usage: b4 kr [-h] [-p USEPROJECT] [-m LOCALMBOX] [-C] [--show-keys] [msgid]
+usage:
+ b4 kr [-h] [-p USEPROJECT] [-m LOCALMBOX] [-C] [--show-keys] [msgid]
positional arguments:
msgid Message ID to process, or pipe a raw message
@@ -370,6 +412,10 @@ Default configuration, with explanations::
thanks-pr-template = None
# See thanks-am-template.example. If not set, a default template will be used.
thanks-am-template = None
+ # additional flags to pass to "git am" when we run "b4 shazam"
+ shazam-am-flags = None
+ # additional flags to pass to "git merge" when we run "b4 shazam -M"
+ shazam-merge-flags = --signoff
# Used when preparing merge messages from cover letters. See shazam-merge-template.example
shazam-merge-template = None
# Use to exclude certain mail addresses from ever being added to auto-generated mail
diff --git a/shazam-merge-template.example b/shazam-merge-template.example
index ab735b4..e4d49d2 100644
--- a/shazam-merge-template.example
+++ b/shazam-merge-template.example
@@ -7,12 +7,12 @@
Merge ${patch_or_series} "${seriestitle}"
${authorname} <${authoremail}> says:
-====================
+
# This will be the entirety of the cover letter minus anything
# below the "-- \n" signature line. You will almost certainly
# want to edit it down to only include the relevant info.
-${coverletter}
-====================
+${covermessage}
+
# This will contain a lore link to the patches in question
Link: ${midurl}
# git-merge will append any additional information here, depending