Message ID | 20240328-avoid-overwritting-cover-letter-v1-1-161d30ee533c@bootlin.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [b4] ez: Prevent overwriting an unrelated cover letter | expand |
On Thu, Mar 28, 2024 at 10:25:43AM +0100, Louis Chauvet wrote: > When editing a cover-letter, b4 expectedly selects as base the > cover-letter of the currently checked-out Git branch. When > saving/closing the editor, b4 also saves the changes as the > new cover-letter for the currently checked-out Git branch. > > While simplistic and apparently totally fine, it does not play well > when working on multiple branches. Said otherwise, the following > sequence of events will write the wrong file, possibly smashing a > valuable cover-letter: Makes sense, good catch! > def edit_cover() -> None: > + # To avoid losing the cover letter, ensure that we are still on the same branch as when the cover-letter was originally opened. > + read_branch = b4.git_get_current_branch() > cover, tracking = load_cover() > bcover = cover.encode() > new_bcover = b4.edit_in_editor(bcover, filehint='COMMIT_EDITMSG') I suggest we implement this check in b4.edit_in_editor(), so it applies to all situations, not just for cover editing: - get and remember the current branch name - open file in editor - re-check the current branch name - save the contents as temporary file - complain via logger.critical - throw RuntimeError Does that make sense? > @@ -768,8 +772,15 @@ def edit_cover() -> None: > if not len(new_cover): > logger.info('New cover letter blank, leaving current one unchanged.') > return > - > - store_cover(new_cover, tracking) > + write_branch = b4.git_get_current_branch() > + if write_branch != read_branch: > + with NamedTemporaryFile(mode="w", prefix=f"cover-{read_branch}".replace("/", "-"), delete=False) as save_file: > + save_file.write(new_cover) > + logger.critical(f'The cover letter was read on the branch {read_branch} but the current branch is now {write_branch}.') > + logger.critical(f'To avoid overwriting an unrelated cover letter, the operation is canceled and your new ' > + f'cover letter stored at {save_file.name}') Best practice is to use %s expansion for logger calls, because this way the substitution doesn't even happen if we're in a logging level above the one specified. Thanks! -K
diff --git a/src/b4/ez.py b/src/b4/ez.py index 1d360410d771..c322953564a0 100644 --- a/src/b4/ez.py +++ b/src/b4/ez.py @@ -8,6 +8,8 @@ __author__ = 'Konstantin Ryabitsev <konstantin@linuxfoundation.org>' import email.message import os import sys +from tempfile import NamedTemporaryFile + import b4 import re import argparse @@ -758,6 +760,8 @@ class FRCommitMessageEditor: def edit_cover() -> None: + # To avoid losing the cover letter, ensure that we are still on the same branch as when the cover-letter was originally opened. + read_branch = b4.git_get_current_branch() cover, tracking = load_cover() bcover = cover.encode() new_bcover = b4.edit_in_editor(bcover, filehint='COMMIT_EDITMSG') @@ -768,8 +772,15 @@ def edit_cover() -> None: if not len(new_cover): logger.info('New cover letter blank, leaving current one unchanged.') return - - store_cover(new_cover, tracking) + write_branch = b4.git_get_current_branch() + if write_branch != read_branch: + with NamedTemporaryFile(mode="w", prefix=f"cover-{read_branch}".replace("/", "-"), delete=False) as save_file: + save_file.write(new_cover) + logger.critical(f'The cover letter was read on the branch {read_branch} but the current branch is now {write_branch}.') + logger.critical(f'To avoid overwriting an unrelated cover letter, the operation is canceled and your new ' + f'cover letter stored at {save_file.name}') + else: + store_cover(new_cover, tracking) logger.info('Cover letter updated.')
When editing a cover-letter, b4 expectedly selects as base the cover-letter of the currently checked-out Git branch. When saving/closing the editor, b4 also saves the changes as the new cover-letter for the currently checked-out Git branch. While simplistic and apparently totally fine, it does not play well when working on multiple branches. Said otherwise, the following sequence of events will write the wrong file, possibly smashing a valuable cover-letter: $ b4 prep --edit-cover <make some changes> $ git checkout another-branch <oh, I forgot to save and close the cover letter editor!> *crunch* Add a simple check to only overwrite the cover-letter if it corresponds to the one that was originally opened, otherwise warn the user and save it in a temporary spot. Cc: tools@kernel.org Cc: miquel.raynal@bootlin.com Cc: thomas.petazzoni@bootlin.com Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com> --- src/b4/ez.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) --- base-commit: 23970c613f40356cc88716d07c2d427ca024e489 change-id: 20240328-avoid-overwritting-cover-letter-554bcd29b240 Best regards,