diff options
author | Konstantin Ryabitsev <konstantin@linuxfoundation.org> | 2022-06-16 11:31:35 -0400 |
---|---|---|
committer | Konstantin Ryabitsev <konstantin@linuxfoundation.org> | 2022-06-16 11:31:35 -0400 |
commit | 0bff0fb4375a40755ec0ffcc3eb6c67e195baefc (patch) | |
tree | f05a6c8308122fc3304e0eb0167a12adf0b04ac6 /b4 | |
parent | 6e1452d7e5008a1712aac0fb95bc4e377f95821b (diff) | |
download | b4-0bff0fb4375a40755ec0ffcc3eb6c67e195baefc.tar.gz |
Allow breaking threads using --no-parent
It is a common request to be able to get a partial thread in case
someone submitted an auxiliary standalone patch in the middle of a
larger patch series. Passing the msgid of the start of the thread along
with --no-parent should tell b4 to break the thread at the start of the
message-id specified and only consider that message and its children.
Suggested-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/tools/YpTI9lhCfA7shi6j@sirena.org.uk/
Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Diffstat (limited to 'b4')
-rw-r--r-- | b4/__init__.py | 19 | ||||
-rw-r--r-- | b4/command.py | 2 | ||||
-rw-r--r-- | b4/mbox.py | 12 |
3 files changed, 24 insertions, 9 deletions
diff --git a/b4/__init__.py b/b4/__init__.py index 1ac7eb1..bc4dd36 100644 --- a/b4/__init__.py +++ b/b4/__init__.py @@ -2148,8 +2148,9 @@ def get_msgid(cmdargs) -> Optional[str]: return msgid -def get_strict_thread(msgs, msgid): +def get_strict_thread(msgs, msgid, noparent=False): want = {msgid} + ignore = set() got = set() seen = set() maybe = dict() @@ -2157,6 +2158,8 @@ def get_strict_thread(msgs, msgid): while True: for msg in msgs: c_msgid = LoreMessage.get_clean_msgid(msg) + if c_msgid in ignore: + continue seen.add(c_msgid) if c_msgid in got: continue @@ -2168,7 +2171,16 @@ def get_strict_thread(msgs, msgid): msgrefs += email.utils.getaddresses([str(x) for x in msg.get_all('in-reply-to', [])]) if msg.get('References', None): msgrefs += email.utils.getaddresses([str(x) for x in msg.get_all('references', [])]) + # If noparent is set, we pretend the message we got passed has no references, and add all + # parent references of this message to ignore + if noparent and msgid == c_msgid: + logger.info('Breaking thread to remove parents of %s', msgid) + ignore = set([x[1] for x in msgrefs]) + msgrefs = list() + for ref in set([x[1] for x in msgrefs]): + if ref in ignore: + continue if ref in got or ref in want: want.add(c_msgid) elif len(ref): @@ -2206,7 +2218,7 @@ def get_strict_thread(msgs, msgid): return None if len(msgs) > len(strict): - logger.debug('Reduced mbox to strict matches only (%s->%s)', len(msgs), len(strict)) + logger.debug('Reduced thread to requested matches only (%s->%s)', len(msgs), len(strict)) return strict @@ -2266,7 +2278,8 @@ def get_pi_thread_by_url(t_mbx_url, nocache=False): return list(deduped.values()) -def get_pi_thread_by_msgid(msgid, useproject=None, nocache=False, onlymsgids: Optional[set] = None): +def get_pi_thread_by_msgid(msgid: str, useproject: Optional[str] = None, nocache: bool = False, + onlymsgids: Optional[set] = None) -> Optional[list]: qmsgid = urllib.parse.quote_plus(msgid) config = get_main_config() loc = urllib.parse.urlparse(config['midmask']) diff --git a/b4/command.py b/b4/command.py index 6d3c899..aa307da 100644 --- a/b4/command.py +++ b/b4/command.py @@ -55,6 +55,8 @@ def cmd_am_common_opts(sp): '"-P *globbing*" to match on commit subject)') sp.add_argument('--cc-trailers', dest='copyccs', action='store_true', default=False, help='Copy all Cc\'d addresses into Cc: trailers') + sp.add_argument('--no-parent', dest='noparent', action='store_true', default=False, + help='Break thread at the msgid specified and ignore any parent messages') sp.add_argument('--allow-unicode-control-chars', dest='allowbadchars', action='store_true', default=False, help='Allow unicode control characters (very rarely legitimate)') @@ -656,12 +656,9 @@ def get_msgs(cmdargs) -> Tuple[Optional[str], Optional[list]]: sys.exit(1) pickings = set() - try: - if cmdargs.cherrypick == '_': - # Just that msgid, please - pickings = {msgid} - except AttributeError: - pass + if 'cherrypick' in cmdargs and cmdargs.cherrypick == '_': + # Just that msgid, please + pickings = {msgid} msgs = b4.get_pi_thread_by_msgid(msgid, useproject=cmdargs.useproject, nocache=cmdargs.nocache, onlymsgids=pickings) if not msgs: @@ -693,6 +690,9 @@ def get_msgs(cmdargs) -> Tuple[Optional[str], Optional[list]]: logger.critical('Mailbox %s does not exist', cmdargs.localmbox) sys.exit(1) + if msgid and 'noparent' in cmdargs and cmdargs.noparent: + msgs = b4.get_strict_thread(msgs, msgid, noparent=True) + if not msgid and msgs: for msg in msgs: msgid = msg.get('Message-ID', None) |