Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package b4 for openSUSE:Factory checked in 
at 2022-09-27 20:13:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/b4 (Old)
 and      /work/SRC/openSUSE:Factory/.b4.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "b4"

Tue Sep 27 20:13:44 2022 rev:26 rq:1006295 version:0.10.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/b4/b4.changes    2022-09-19 16:03:54.230241255 
+0200
+++ /work/SRC/openSUSE:Factory/.b4.new.2275/b4.changes  2022-09-27 
20:13:49.169812302 +0200
@@ -1,0 +2,10 @@
+Tue Sep 27 04:55:59 UTC 2022 - Jiri Slaby <jsl...@suse.cz>
+
+- Update to version 0.10.1:
+  * Fixes the crash with "b4 ty" when using a local binary to send mail
+  * The "send" and "prep" commands now properly include diffstats into
+    generated patches
+  * Does not force single-patch series to have a cover letter.
+  * Does not force "v1" to be added to the prefixes
+
+-------------------------------------------------------------------

Old:
----
  b4-0.10.0.tar.gz

New:
----
  b4-0.10.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ b4.spec ++++++
--- /var/tmp/diff_new_pack.wiFha0/_old  2022-09-27 20:13:49.777813643 +0200
+++ /var/tmp/diff_new_pack.wiFha0/_new  2022-09-27 20:13:49.781813652 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           b4
-Version:        0.10.0
+Version:        0.10.1
 Release:        0
 Summary:        Helper scripts for kernel.org patches
 License:        GPL-2.0-or-later
@@ -25,8 +25,8 @@
 URL:            https://git.kernel.org/pub/scm/utils/b4/b4.git
 Source0:        
https://github.com/mricon/b4/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
 BuildArch:      noarch
-# SECTION test requirements
 BuildRequires:  fdupes
+# SECTION test requirements
 BuildRequires:  git-core
 BuildRequires:  python3-dkimpy >= 1.0.5
 BuildRequires:  python3-dnspython >= 2.0.0

++++++ b4-0.10.0.tar.gz -> b4-0.10.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/b4-0.10.0/b4/__init__.py new/b4-0.10.1/b4/__init__.py
--- old/b4-0.10.0/b4/__init__.py        2022-09-16 19:38:30.000000000 +0200
+++ new/b4-0.10.1/b4/__init__.py        2022-09-26 19:17:19.000000000 +0200
@@ -49,7 +49,7 @@
 except ModuleNotFoundError:
     can_patatt = False
 
-__VERSION__ = '0.10.0'
+__VERSION__ = '0.10.1'
 PW_REST_API_VERSION = '1.2'
 
 
@@ -864,7 +864,7 @@
     addr: Optional[Tuple[str, str]] = None
     lmsg = None
     # Small list of recognized utility trailers
-    _utility: Set[str] = {'fixes', 'link', 'buglink', 'obsoleted-by', 
'message-id', 'change-id'}
+    _utility: Set[str] = {'fixes', 'link', 'buglink', 'obsoleted-by', 
'message-id', 'change-id', 'base-commit'}
 
     def __init__(self, name: Optional[str] = None, value: Optional[str] = 
None, extinfo: Optional[str] = None,
                  msg: Optional[email.message.Message] = None):
@@ -1529,7 +1529,7 @@
     def find_trailers(body: str, followup: bool = False) -> 
Tuple[List[LoreTrailer], List[str]]:
         ignores = {'phone', 'email'}
         headers = {'subject', 'date', 'from'}
-        nonperson = {'fixes', 'subject', 'date', 'link', 'buglink', 
'obsoleted-by'}
+        nonperson = {'fixes', 'subject', 'date', 'link', 'buglink', 
'obsoleted-by', 'change-id', 'base-commit'}
         # Ignore everything below standard email signature marker
         body = body.split('\n-- \n', 1)[0].strip() + '\n'
         # Fix some more common copypasta trailer wrapping
@@ -1598,6 +1598,36 @@
         return trailers, others
 
     @staticmethod
+    def rebuild_message(headers: List[LoreTrailer], message: str, trailers: 
List[LoreTrailer],
+                        basement: str, signature: str) -> str:
+        body = ''
+        if headers:
+            for ltr in headers:
+                # There is no [extdata] in git headers, so we omit it
+                body += ltr.as_string(omit_extinfo=True) + '\n'
+            body += '\n'
+
+        if len(message):
+            body += message.rstrip('\r\n') + '\n'
+            if len(trailers):
+                body += '\n'
+
+        for ltr in trailers:
+            body += ltr.as_string() + '\n'
+
+        if len(basement):
+            if not len(trailers):
+                body += '\n'
+            body += '---\n'
+            body += basement.rstrip('\r\n') + '\n'
+
+        if len(signature):
+            body += '-- \n'
+            body += signature.rstrip('\r\n') + '\n'
+
+        return body
+
+    @staticmethod
     def get_body_parts(body: str) -> Tuple[List[LoreTrailer], str, 
List[LoreTrailer], str, str]:
         # remove any starting/trailing blank lines
         body = body.replace('\r', '')
@@ -1774,36 +1804,23 @@
             if not hasmysob:
                 logger.info('    + %s', sobtr.as_string(omit_extinfo=True))
 
-        # Reconstitute the message
-        self.body = ''
-        if bheaders:
-            for bltr in bheaders:
-                # There is no [extdata] in git headers, so we ignore bheader[2]
-                self.body += bltr.as_string(omit_extinfo=True) + '\n'
-            self.body += '\n'
+        if omit_trailers and fixtrailers:
+            for ltr in fixtrailers:
+                if ltr.lname in omit_trailers:
+                    fixtrailers.remove(ltr)
 
-        newmessage = ''
+        # Build the new commit message in case we're working directly
+        # on the tree.
+        self.message = self.subject + '\n\n'
         if len(message):
-            newmessage += message.rstrip('\r\n') + '\n'
+            self.message += message.rstrip('\r\n') + '\n'
             if len(fixtrailers):
-                newmessage += '\n'
-
+                self.message += '\n'
         if len(fixtrailers):
-            if omit_trailers is None:
-                omit_trailers = set()
             for ltr in fixtrailers:
-                if ltr.lname not in omit_trailers:
-                    newmessage += ltr.as_string() + '\n'
-
-        self.message = self.subject + '\n\n' + newmessage
-        self.body += newmessage
+                self.message += ltr.as_string() + '\n'
 
-        if len(basement):
-            self.body += '---\n'
-            self.body += basement.rstrip('\r\n') + '\n'
-        if len(signature):
-            self.body += '-- \n'
-            self.body += signature.rstrip('\r\n') + '\n'
+        self.body = LoreMessage.rebuild_message(bheaders, message, 
fixtrailers, basement, signature)
 
     def get_am_subject(self, indicate_reroll=True):
         # Return a clean patch subject
@@ -2263,7 +2280,7 @@
         # some options can be provided via the toplevel .b4-config file,
         # so load them up and use as defaults
         topdir = git_get_toplevel()
-        wtglobs = ['send-*', '*mask', '*template*', 'trailer*']
+        wtglobs = ['send-*', '*mask', '*template*', 'trailer*', 'pw-*']
         if topdir:
             wtcfg = os.path.join(topdir, '.b4-config')
             if os.access(wtcfg, os.R_OK):
@@ -2689,7 +2706,8 @@
         if commit in ignore_commits:
             logger.debug('Ignoring commit %s', commit)
             continue
-        ecode, out = git_run_command(gitdir, ['show', '--format=email', 
'--encoding=utf-8', commit], decode=False)
+        ecode, out = git_run_command(gitdir, ['show', '--format=email', 
'--patch-with-stat', '--encoding=utf-8',
+                                              commit], decode=False)
         if ecode > 0:
             raise RuntimeError(f'Could not get a patch out of {commit}')
         msg = email.message_from_bytes(out)
@@ -2701,9 +2719,60 @@
 
     startfrom = 1
     fullcount = len(patches)
-    patches.insert(0, (None, covermsg))
+    if fullcount == 0:
+        raise RuntimeError(f'Could not run rev-list {start}..{end}')
+
     if covermsg:
-        startfrom = 0
+        if fullcount == 1:
+            # Single-patch series, mix in the cover letter into the patch 
basement
+            pmsg = patches[0][1]
+            pbody = pmsg.get_payload()
+            pheaders, pmessage, ptrailers, pbasement, psignature = 
LoreMessage.get_body_parts(pbody)
+            cbody = covermsg.get_payload()
+            cheaders, cmessage, ctrailers, cbasement, csignature = 
LoreMessage.get_body_parts(cbody)
+            nbparts = list()
+            nmessage = ''
+            if len(cmessage.strip()):
+                cls = LoreSubject(covermsg.get('Subject'))
+                nmessage += cls.subject + '\n\n' + cmessage.rstrip('\r\n') + 
'\n'
+            for ctr in list(ctrailers):
+                if ctr in ptrailers:
+                    ctrailers.remove(ctr)
+            if ctrailers:
+                if nmessage:
+                    nmessage += '\n'
+                for ctr in ctrailers:
+                    nmessage += ctr.as_string() + '\n'
+            nbparts.append(nmessage)
+
+            # Find the section with changelogs
+            utility = None
+            for section in cbasement.split('---\n'):
+                if re.search(r'^change-id: ', section, flags=re.I | re.M):
+                    utility = section
+                    continue
+                if re.search(r'^changes in v\d', section, flags=re.I | re.M):
+                    nbparts.append(section.strip('\r\n') + '\n')
+
+            nbparts.append(pbasement.rstrip('\r\n') + '\n\n')
+            if utility:
+                nbparts.append(utility)
+
+            newbasement = '---\n'.join(nbparts)
+
+            pbody = LoreMessage.rebuild_message(pheaders, pmessage, ptrailers, 
newbasement, csignature)
+            pmsg.set_payload(pbody, charset='utf-8')
+            # Add any To: and Cc: headers from the cover_message
+            toh = covermsg.get('To')
+            if toh:
+                pmsg.add_header('To', toh)
+            cch = covermsg.get('Cc')
+            if cch:
+                pmsg.add_header('Cc', cch)
+            startfrom = 0
+        else:
+            patches.insert(0, (None, covermsg))
+            startfrom = 0
 
     # Go through and apply any outstanding fixes
     if prefixes:
@@ -2711,11 +2780,14 @@
     else:
         prefixes = ''
 
-    for counter in range(startfrom, fullcount+1):
+    for counter in range(startfrom, len(patches)):
         msg = patches[counter][1]
         subject = msg.get('Subject')
         csubject = re.sub(r'^\[PATCH]\s*', '', subject)
-        pline = '[PATCH%s %s/%s]' % (prefixes, 
str(counter).zfill(len(str(fullcount))), fullcount)
+        if fullcount > 1:
+            pline = '[PATCH%s %s/%s]' % (prefixes, 
str(counter).zfill(len(str(fullcount))), fullcount)
+        else:
+            pline = '[PATCH%s]' % prefixes
         msg.replace_header('Subject', f'{pline} {csubject}')
         inbodyhdrs = list()
         if mailfrom:
@@ -2996,6 +3068,16 @@
         sp = shlex.shlex(server, posix=True)
         sp.whitespace_split = True
         smtp = list(sp)
+        if '-i' not in smtp:
+            smtp.append('-i')
+        # Do we have the envelopesender defined?
+        env_sender = sconfig.get('envelopesender', '')
+        if env_sender:
+            envpair = email.utils.parseaddr(env_sender)
+        else:
+            envpair = email.utils.parseaddr(fromaddr)
+        if envpair[1]:
+            smtp += ['-f', envpair[1]]
         return smtp, fromaddr
 
     encryption = sconfig.get('smtpencryption')
@@ -3051,7 +3133,7 @@
     pwurl = config.get('pw-url')
     pwproj = config.get('pw-project')
     if not (pwkey and pwurl and pwproj):
-        logger.debug('Patchwork support not configured')
+        logger.debug('Patchwork support requires pw-key, pw-url and pw-project 
settings')
         return False
     pses, url = get_patchwork_session(pwkey, pwurl)
     patches_url = '/'.join((url, 'patches'))
@@ -3197,7 +3279,8 @@
         logger.info('Sending via "%s"', ' '.join(smtp))
         for destaddrs, bdata, lsubject in tosend:
             logger.info('  %s', lsubject.full_subject)
-            ecode, out, err = _run_command(smtp, stdin=bdata)
+            cmdargs = list(smtp) + list(destaddrs)
+            ecode, out, err = _run_command(cmdargs, stdin=bdata)
             if ecode > 0:
                 raise RuntimeError('Error running %s: %s' % (' '.join(smtp), 
err.decode()))
             sent += 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/b4-0.10.0/b4/ez.py new/b4-0.10.1/b4/ez.py
--- old/b4-0.10.0/b4/ez.py      2022-09-16 19:38:30.000000000 +0200
+++ new/b4-0.10.1/b4/ez.py      2022-09-26 19:17:19.000000000 +0200
@@ -437,7 +437,9 @@
                  'will be used by the project maintainer to make a decision 
whether your',
                  'patches should be reviewed, and in what priority order. 
Please be very',
                  'detailed and link to any relevant discussions or sites that 
the maintainer',
-                 'can review to better understand your proposed changes.',
+                 'can review to better understand your proposed changes. If 
you only have a',
+                 'single patch in your series, the contents of the cover 
letter will be',
+                 'appended to the "under-the-cut" portion of the patch.',
                  '',
                  '# You can add trailers to the cover letter. Any email 
addresses found in',
                  '# these trailers will be added to the addresses 
specified/generated during',
@@ -906,7 +908,9 @@
 
 
 def get_sent_tag_as_patches(tagname: str, revision: Optional[str] = None,
-                            prefixes: Optional[List[str]] = None) -> 
List[Tuple[str, email.message.Message]]:
+                            prefixes: Optional[List[str]] = None,
+                            hide_cover_to_cc: bool = False
+                            ) -> Tuple[List, List, List[Tuple[str, 
email.message.Message]]]:
     gitargs = ['cat-file', '-p', tagname]
     ecode, tagmsg = b4.git_run_command(None, gitargs)
     if ecode > 0:
@@ -931,13 +935,19 @@
     # First line is the subject
     csubject, cbody = cover.split('\n', maxsplit=1)
     cbody = cbody.strip() + '\n-- \n' + b4.get_email_signature()
+    if hide_cover_to_cc:
+        tos, ccs, body = remove_to_cc_trailers(cbody)
+    else:
+        tos = list()
+        ccs = list()
 
     cmsg = email.message.EmailMessage()
     cmsg.add_header('Subject', csubject)
     cmsg.set_payload(cbody.lstrip(), charset='utf-8')
     if prefixes is None:
         prefixes = list()
-    prefixes.append(f'v{revision}')
+    if revision != 1:
+        prefixes.append(f'v{revision}')
     seriests = int(time.time())
     msgid_tpt = make_msgid_tpt(change_id, revision)
     usercfg = b4.get_user_config()
@@ -949,7 +959,7 @@
                                       seriests=seriests,
                                       thread=True,
                                       mailfrom=mailfrom)
-    return patches
+    return tos, ccs, patches
 
 
 def make_msgid_tpt(change_id: str, revision: str, domain: Optional[str] = 
None) -> str:
@@ -971,9 +981,25 @@
     return msgid_tpt
 
 
+def remove_to_cc_trailers(body: str) -> Tuple[List, List, str]:
+    htrs, cmsg, mtrs, basement, sig = b4.LoreMessage.get_body_parts(body)
+    tos = list()
+    ccs = list()
+    for mtr in list(mtrs):
+        if mtr.lname == 'to':
+            tos.append(mtr.addr)
+            mtrs.remove(mtr)
+        elif mtr.lname == 'cc':
+            ccs.append(mtr.addr)
+            mtrs.remove(mtr)
+    body = b4.LoreMessage.rebuild_message(htrs, cmsg, mtrs, basement, sig)
+    return tos, ccs, body
+
+
 def get_prep_branch_as_patches(prefixes: Optional[List[str]] = None,
-                               movefrom: bool = True,
-                               thread: bool = True) -> List[Tuple[str, 
email.message.Message]]:
+                               movefrom: bool = True, thread: bool = True,
+                               hide_cover_to_cc: bool = False
+                               ) -> Tuple[List, List, List[Tuple[str, 
email.message.Message]]]:
     cover, tracking = load_cover(strip_comments=True)
     config = b4.get_main_config()
     cover_template = DEFAULT_COVER_TEMPLATE
@@ -988,6 +1014,7 @@
 
     # Put together the cover letter
     csubject, cbody = cover.split('\n', maxsplit=1)
+
     start_commit = get_series_start()
     base_commit, shortlog, diffstat = 
get_series_details(start_commit=start_commit)
     change_id = tracking['series'].get('change-id')
@@ -1002,6 +1029,12 @@
         'signature': b4.get_email_signature(),
     }
     body = Template(cover_template.lstrip()).safe_substitute(tptvals)
+    if hide_cover_to_cc:
+        tos, ccs, body = remove_to_cc_trailers(body)
+    else:
+        tos = list()
+        ccs = list()
+
     cmsg = email.message.EmailMessage()
     cmsg.add_header('Subject', csubject)
     cmsg.set_payload(body, charset='utf-8')
@@ -1012,8 +1045,9 @@
     cmsg.add_header('X-b4-tracking', ' 
'.join(textwrap.wrap(b64tracking.decode(), width=78)))
     if prefixes is None:
         prefixes = list()
+    if revision != 1:
+        prefixes.append(f'v{revision}')
 
-    prefixes.append(f'v{revision}')
     seriests = int(time.time())
     msgid_tpt = make_msgid_tpt(change_id, revision)
     if movefrom:
@@ -1036,12 +1070,12 @@
                                       thread=thread,
                                       mailfrom=mailfrom,
                                       ignore_commits=ignore_commits)
-    return patches
+    return tos, ccs, patches
 
 
 def format_patch(output_dir: str) -> None:
     try:
-        patches = get_prep_branch_as_patches(thread=False, movefrom=False)
+        tos, ccs, patches = get_prep_branch_as_patches(thread=False, 
movefrom=False)
     except RuntimeError as ex:
         logger.critical('CRITICAL: Failed to convert range to patches: %s', ex)
         sys.exit(1)
@@ -1075,6 +1109,10 @@
     if cmdargs.prefixes is None:
         prefixes = list()
 
+    config = b4.get_main_config()
+    if not cmdargs.hide_cover_to_cc and config.get('send-hide-cover-to-cc', 
'').lower() in {'yes', 'true', '1'}:
+        cmdargs.hide_cover_to_cc = True
+
     if cmdargs.resend:
         # We accept both a full tag name and just a vN short form
         matches = re.search(r'^v(\d+)$', cmdargs.resend)
@@ -1090,11 +1128,14 @@
 
         prefixes.append('RESEND')
         try:
-            patches = get_sent_tag_as_patches(tagname, revision=revision, 
prefixes=prefixes)
+            todests, ccdests, patches = get_sent_tag_as_patches(tagname, 
revision=revision, prefixes=prefixes,
+                                                                
hide_cover_to_cc=cmdargs.hide_cover_to_cc)
         except RuntimeError as ex:
             logger.critical('CRITICAL: Failed to convert tag to patches: %s', 
ex)
             sys.exit(1)
 
+        logger.info('Converted the tag to %s messages', len(patches))
+
     else:
         # Check if the cover letter has 'EDITME' in it
         cover, tracking = load_cover(strip_comments=True)
@@ -1106,66 +1147,70 @@
             sys.exit(1)
 
         try:
-            patches = get_prep_branch_as_patches(prefixes=prefixes)
+            todests, ccdests, patches = 
get_prep_branch_as_patches(prefixes=prefixes,
+                                                                   
hide_cover_to_cc=cmdargs.hide_cover_to_cc)
         except RuntimeError as ex:
             logger.critical('CRITICAL: Failed to convert range to patches: 
%s', ex)
             sys.exit(1)
-        logger.info('Converted the branch to %s patches', len(patches)-1)
+        logger.info('Converted the branch to %s messages', len(patches))
 
-    config = b4.get_main_config()
     usercfg = b4.get_user_config()
     myemail = usercfg.get('email')
 
     seen = set()
-    todests = list()
-    ccdests = list()
-    trailers = set()
     excludes = set()
-    # These override config values
-    if cmdargs.to:
-        todests = [('', x) for x in cmdargs.to]
-        seen.update(set(cmdargs.to))
-    elif config.get('send-series-to'):
-        for pair in utils.getaddresses([config.get('send-series-to')]):
-            if pair[1] in seen:
-                continue
-            seen.add(pair[1])
-            logger.debug('added %s to seen', pair[1])
-            todests.append(pair)
-    if cmdargs.cc:
-        ccdests = [('', x) for x in cmdargs.cc]
-        seen.update(set(cmdargs.cc))
-    elif config.get('send-series-cc'):
-        for pair in utils.getaddresses([config.get('send-series-cc')]):
-            if pair[1] in seen:
-                continue
-            seen.add(pair[1])
-            logger.debug('added %s to seen', pair[1])
-            ccdests.append(pair)
 
-    if not cmdargs.no_trailer_to_cc:
+    if cmdargs.no_trailer_to_cc:
+        todests = list()
+        ccdests = list()
+    else:
+        seen.update(todests)
+        seen.update(ccdests)
         logger.info('Populating To/Cc addresses')
         # Go through the messages to make to/cc headers
         for commit, msg in patches:
             if not msg:
                 continue
             body = msg.get_payload()
-            parts = b4.LoreMessage.get_body_parts(body)
-            trailers.update(parts[2])
-
-        # add addresses seen in trailers
-        for ltr in trailers:
-            if ltr.addr and ltr.addr[1] not in seen:
-                seen.add(ltr.addr[1])
-                if ltr.lname == 'to':
-                    todests.append(ltr.addr)
-                else:
-                    ccdests.append(ltr.addr)
+            btrs, junk = b4.LoreMessage.find_trailers(body)
+            for btr in btrs:
+                if btr.type != 'person':
+                    continue
+                if btr.addr[1] in seen:
+                    continue
+                seen.add(btr.addr[1])
+                if btr.lname == 'to':
+                    todests.append(btr.addr)
+                    continue
+                ccdests.append(btr.addr)
 
         excludes = b4.get_excluded_addrs()
         if cmdargs.not_me_too:
             excludes.add(myemail)
 
+    tos = set()
+    if cmdargs.to:
+        tos.update(cmdargs.to)
+    if config.get('send-series-to'):
+        tos.add(config.get('send-series-to'))
+    if tos:
+        for pair in utils.getaddresses(list(tos)):
+            if pair[1] in seen:
+                continue
+            seen.add(pair[1])
+            todests.append(pair)
+    ccs = set()
+    if cmdargs.cc:
+        ccs.update(cmdargs.cc)
+    if config.get('send-series-cc'):
+        ccs.add(config.get('send-series-cc'))
+    if ccs:
+        for pair in utils.getaddresses(list(ccs)):
+            if pair[1] in seen:
+                continue
+            seen.add(pair[1])
+            ccdests.append(pair)
+
     allto = list()
     allcc = list()
     alldests = set()
@@ -1222,11 +1267,6 @@
             continue
         if cover_msg is None:
             cover_msg = copy.deepcopy(msg)
-            if cmdargs.hide_cover_to_cc or config.get('send-hide-cover-to-cc', 
'').lower() in {'yes', 'true', '1'}:
-                logger.debug('Hiding To: and Cc: trailers from the cover 
letter')
-                lcm = b4.LoreMessage(msg)
-                lcm.fix_trailers(omit_trailers=['to', 'cc'])
-                msg.set_payload(lcm.body, charset='utf-8')
 
         msg.add_header('To', b4.format_addrs(allto))
         if allcc:
@@ -1469,7 +1509,7 @@
             logger.debug('added %s to seen', ltr.addr[1])
             extras.append(ltr)
 
-    patches = get_prep_branch_as_patches()
+    tos, ccs, patches = get_prep_branch_as_patches()
     logger.info('Collecting To/Cc addresses')
     # Go through the messages to make to/cc headers
     for commit, msg in patches:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/b4-0.10.0/b4/ty.py new/b4-0.10.1/b4/ty.py
--- old/b4-0.10.0/b4/ty.py      2022-09-16 19:38:30.000000000 +0200
+++ new/b4-0.10.1/b4/ty.py      2022-09-26 19:17:19.000000000 +0200
@@ -466,7 +466,6 @@
             logger.info('Sent %s thank-you letters', outgoing)
             if pwstate:
                 b4.patchwork_set_state(msgids, pwstate)
-        smtp.quit()
     else:
         if pwstate:
             b4.patchwork_set_state(msgids, pwstate)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/b4-0.10.0/docs/config.rst 
new/b4-0.10.1/docs/config.rst
--- old/b4-0.10.0/docs/config.rst       2022-09-16 19:38:30.000000000 +0200
+++ new/b4-0.10.1/docs/config.rst       2022-09-26 19:17:19.000000000 +0200
@@ -266,43 +266,44 @@
 If your project uses a patchwork server, these settings allow you to
 integrate your b4 workflow with patchwork.
 
-``b4.pw-url`` (v0.9+)
+``b4.pw-url`` (v0.10+)
   The URL of your patchwork server. Note, that this should point at the
   toplevel of your patchwork installation and NOT at the project patch
   listing. E.g.: ``https://patchwork.kernel.org/``.
 
   Default: ``None``
 
-``b4.pw-key`` (v0.9+)
+``b4.pw-key`` (v0.10+)
   You should be able to obtain an API key from your patchwork user
   profile. This API key will be used to perform actions on your behalf.
 
   Default: ``None``
 
-``b4.pw-project`` (v0.9+)
+``b4.pw-project`` (v0.10+)
   This should contain the name of your patchwork project, as seen in the
   URL subpath to it (e.g. ``linux-usb``).
 
   Default: ``None``
 
-``b4.pw-review-state`` (v0.9+)
+``b4.pw-review-state`` (v0.10+)
   When patchwork integration is enabled, every time you run ``b4 am`` or
-  ``b4 shazam``, b4 will mark those patches as with this state (e.g.
-  "under review").
+  ``b4 shazam``, b4 will mark those patches as with this state. E.g.:
+  ``under-review``).
 
-  Default: ``under-review``
+  Default: ``None``
 
-``b4.pw-accept-state`` (v0.9+)
+``b4.pw-accept-state`` (v0.10+)
   After you run ``b4 ty`` to thank the contributor, b4 will move the
-  matching patches into this state.
+  matching patches into this state. E.g.: ``accepted``.
 
-  Default: ``accepted``
+  Default: ``None``
 
-``b4.pw-discard-state`` (v0.9+)
+``b4.pw-discard-state`` (v0.10+)
   If you run ``b4 ty -d`` to delete the tracking information for a patch
   series, it will also be set on the patchwork server with this state.
+  E.g.: ``deferred`` (or ``rejected``).
 
-  Default: ``deferred``
+  Default: ``None``
 
 .. _contributor_settings:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/b4-0.10.0/docs/contributor/prep.rst 
new/b4-0.10.1/docs/contributor/prep.rst
--- old/b4-0.10.0/docs/contributor/prep.rst     2022-09-16 19:38:30.000000000 
+0200
+++ new/b4-0.10.1/docs/contributor/prep.rst     2022-09-26 19:17:19.000000000 
+0200
@@ -170,12 +170,12 @@
 
 What if I only have a single patch?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Even if you only have a single commit, you should still treat it as a
-single-patch series and send it along with a cover letter. It is very
-likely that you will be asked to make some changes to your patch or
-split it into several patches. Having a cover letter will help retain
-the change-id of the series across revisions, and will provide a
-convenient place to keep the changelog of revisions.
+When you only have a single patch, the contents of the cover letter will
+be mixed into the "under-the-cut" portion of the patch. You can just use
+the cover letter for extra To/Cc trailers and changelog entries as your
+patch goes through revisions. If you add more commits in the future
+version, you can fill in the cover letter content with additional
+information about the intent of your entire series.
 
 .. _prep_recipients:
 

Reply via email to