All of lore.kernel.org
 help / color / mirror / Atom feed
From: Breno Leitao <leitao@debian.org>
To: "Kernel.org Tools" <tools@kernel.org>
Cc: Konstantin Ryabitsev <konstantin@linuxfoundation.org>,
	 kernel-team@meta.com, Breno Leitao <leitao@debian.org>
Subject: [PATCH b4] prep: add --cleanup-older-than option to clean up stale branches
Date: Mon, 23 Mar 2026 04:58:26 -0700	[thread overview]
Message-ID: <20260323-cleanup-v1-1-cbf209f3de43@debian.org> (raw)

B4 is so useful that I have too many branches now, create a way to
easily remove old branches.

Add a new --cleanup-older-than DAYS option that archives and removes
prep-tracked branches whose latest commit is older than the specified
number of days. Each matching branch goes through the normal per-branch
confirmation prompt.

Signed-off-by: Breno Leitao <leitao@debian.org>
---
 src/b4/command.py |  2 ++
 src/b4/ez.py      | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/src/b4/command.py b/src/b4/command.py
index ca7f238..2d263de 100644
--- a/src/b4/command.py
+++ b/src/b4/command.py
@@ -401,6 +401,8 @@ def setup_parser() -> argparse.ArgumentParser:
                        help='Show series info in a format that can be passed to other commands.')
     spp_g.add_argument('--cleanup', metavar='BRANCHNAME', nargs='*',
                        help='Archive and remove prep-tracked branches and all associated sent/ tags')
+    sp_prep.add_argument('--cleanup-older-than', metavar='DAYS', type=int, default=None,
+                         help='Archive prep-tracked branches older than DAYS days')
 
     ag_prepn = sp_prep.add_argument_group('Create new branch', 'Create a new branch for working on patch series')
     ag_prepn.add_argument('-n', '--new', dest='new_series_name',
diff --git a/src/b4/ez.py b/src/b4/ez.py
index b7afab5..70b9f97 100644
--- a/src/b4/ez.py
+++ b/src/b4/ez.py
@@ -2681,6 +2681,47 @@ def _cleanup_branch(branch: str) -> None:
     logger.info('Wrote: %s', tarpath)
 
 
+def _get_branch_latest_commit_age_days(branch: str) -> Optional[int]:
+    """Return the age in days of the latest commit on *branch*, or None on error."""
+    lines = b4.git_get_command_lines(None, ['log', '-1', '--format=%ct', branch])
+    if not lines:
+        return None
+    try:
+        commit_ts = int(lines[0])
+    except ValueError:
+        return None
+    age_days = (time.time() - commit_ts) / 86400
+    return int(age_days)
+
+
+def cleanup_older_than(older_than_days: int) -> None:
+    """Find prep-tracked branches whose latest commit exceeds *older_than_days* and clean them up.
+
+    The currently checked-out branch is always skipped.  Each matching
+    branch is passed to ``_cleanup_branch``, which prompts the user for
+    confirmation before archiving and deleting it.
+    """
+    mybranches = get_prep_managed_branches(None)
+    if not mybranches:
+        logger.info('No b4-tracked branches found')
+        sys.exit(0)
+
+    curbranch = b4.git_get_current_branch()
+    old_branches = []
+    for branch in mybranches:
+        if branch == curbranch:
+            logger.debug('Skipping currently checked out branch: %s', branch)
+            continue
+        age = _get_branch_latest_commit_age_days(branch)
+        if age is not None and age > older_than_days:
+            old_branches.append(branch)
+    if not old_branches:
+        logger.info('No branches older than %d days found', older_than_days)
+        return
+    for branch in old_branches:
+        _cleanup_branch(branch)
+
+
 def cleanup(branches: List[str]) -> None:
     if not branches:
         # Show all b4-tracked branches
@@ -3089,6 +3130,9 @@ def cmd_prep(cmdargs: argparse.Namespace) -> None:
     if cmdargs.show_info:
         return show_info(cmdargs.show_info)
 
+    if cmdargs.cleanup_older_than is not None:
+        return cleanup_older_than(cmdargs.cleanup_older_than)
+
     if cmdargs.cleanup is not None:
         return cleanup(cmdargs.cleanup)
 

---
base-commit: bc4c73c5333d7d88428e4ce970facd48d6b8b107
change-id: 20260323-cleanup-4dea45140971

Best regards,
--  
Breno Leitao <leitao@debian.org>


                 reply	other threads:[~2026-03-23 12:01 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260323-cleanup-v1-1-cbf209f3de43@debian.org \
    --to=leitao@debian.org \
    --cc=kernel-team@meta.com \
    --cc=konstantin@linuxfoundation.org \
    --cc=tools@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.