[Concept,6/6] patman: Clean up review worktrees on series rm and archive

Message ID 20260506153006.529909-7-sjg@u-boot.org
State New
Headers
Series patman: Concurrent DB access and per-series review worktrees |

Commit Message

Simon Glass May 6, 2026, 3:29 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

A worktree created by 'patman review' lives on disk until something
removes it. With nothing to trigger that today, abandoned reviews
accumulate under .git/patman/worktrees and the user has no obvious
way to reclaim the space.

Hook the worktree removal into the two paths that already invalidate
the underlying branch:

- 'series rm' deletes the database record. The worktree has no value
  without it, so drop it after the commit succeeds.
- 'series archive' deletes each version's branch. A checked-out
  branch cannot be deleted, so the worktree must go first; otherwise
  pygit2's branches.delete() fails.

Use gitutil.remove_worktree() with the path from
cser_helper.review_worktree_path(); both are no-ops when the worktree
is not registered, so this is safe for non-review series whose
branches were never reviewed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/patman/cseries.py | 10 ++++++++++
 1 file changed, 10 insertions(+)
  

Patch

diff --git a/tools/patman/cseries.py b/tools/patman/cseries.py
index fb3f5a6c49a..1149eef44e1 100644
--- a/tools/patman/cseries.py
+++ b/tools/patman/cseries.py
@@ -830,6 +830,11 @@  class Cseries(cser_helper.CseriesHelper):
         self.db.ser_ver_remove(ser.idnum, None)
         if not dry_run:
             self.commit()
+            # The review worktree (if any) has no value once the db row
+            # is gone; v1 review series share their branch name with the
+            # series name, so review_worktree_path() resolves it directly
+            gitutil.remove_worktree(self.topdir,
+                cser_helper.review_worktree_path(self.topdir, name))
         else:
             self.rollback()
 
@@ -1252,6 +1257,11 @@  class Cseries(cser_helper.CseriesHelper):
 
         # Delete the branches
         for idnum, name, tag_name in tag_info.values():
+            # Drop any review worktree first; a checked-out branch
+            # cannot be deleted
+            gitutil.remove_worktree(self.topdir,
+                cser_helper.review_worktree_path(self.topdir, name))
+
             # Detach HEAD from the branch if pointing to this branch
             commit = repo.revparse_single(name)
             if repo.head.target == commit.oid: