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: