Linux maintainer tooling and workflows
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: "Kernel.org Tools" <tools@kernel.org>
Cc: "Christian Brauner (Amutable)" <brauner@kernel.org>,
	 Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Subject: [PATCH b4 v2 13/44] ty: check reachability in the repository the commit landed in
Date: Fri, 31 Jul 2026 23:58:54 +0200	[thread overview]
Message-ID: <20260731-work-b4-editor-branch-guard-v2-13-243fd19d322d@kernel.org> (raw)
In-Reply-To: <20260731-work-b4-editor-branch-guard-v2-0-243fd19d322d@kernel.org>

The local half of the publish check ran in the process cwd. "b4 review
cron" resolves a topdir per project and never chdirs, so a sweep
checks ancestry against the wrong repository and the thanks waits
forever. Take the repository as an argument and pass the topdir the
queue sweep already has. Pass it to ls-remote too, so repository-local
config applies.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
 src/b4/ty.py         | 32 +++++++++++++++++++++++---------
 src/tests/test_ty.py | 28 +++++++++++++++++++++-------
 2 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/src/b4/ty.py b/src/b4/ty.py
index 9fe5f40..5e225a7 100644
--- a/src/b4/ty.py
+++ b/src/b4/ty.py
@@ -1050,7 +1050,7 @@ def get_check_repo_for_branch(
 
 
 def commit_reachable_on_remote(
-    commit: str, repo_url: str, branch: str = ''
+    commit: str, repo_url: str, branch: str = '', gitdir: Optional[str] = None
 ) -> Optional[bool]:
     """Check if a commit is reachable from a branch advertised by repo_url.
 
@@ -1066,8 +1066,14 @@ def commit_reachable_on_remote(
     deleted), any advertised branch is accepted as before.
 
     Ancestry is computed locally against the advertised tips, so tips we
-    do not have objects for are ignored. Returns True/False, or None if
-    the state could not be determined (e.g. the remote is unreachable).
+    do not have objects for are ignored.  That happens in *gitdir* — the
+    repository the commit was applied in.  It defaults to the process
+    cwd, which is only right for callers that operate on it; a queue
+    sweep covering several projects must name the tree each message
+    belongs to.
+
+    Returns True/False, or None if the state could not be determined
+    (e.g. the remote is unreachable).
     """
     gitargs = [
         '-c',
@@ -1078,7 +1084,7 @@ def commit_reachable_on_remote(
         '--heads',
         repo_url,
     ]
-    ecode, out = b4.git_run_command(None, gitargs)
+    ecode, out = b4.git_run_command(gitdir, gitargs)
     if ecode > 0:
         logger.debug('ls-remote failed for %s (exit code %s)', repo_url, ecode)
         return None
@@ -1104,7 +1110,7 @@ def commit_reachable_on_remote(
     # for them, so treat them as not containing the commit
     stdin = ('\n'.join(sorted(tips)) + '\n').encode()
     _ecode, out = b4.git_run_command(
-        None, ['cat-file', '--batch-check=%(objectname) %(objecttype)'], stdin=stdin
+        gitdir, ['cat-file', '--batch-check=%(objectname) %(objecttype)'], stdin=stdin
     )
     known: List[str] = []
     for line in out.splitlines():
@@ -1116,7 +1122,7 @@ def commit_reachable_on_remote(
         return False
     # Empty output means every commit reachable from ours is also
     # reachable from one of the known tips, i.e. ours is published
-    ecode, out = b4.git_run_command(None, ['rev-list', '-1', commit, '--not', *known])
+    ecode, out = b4.git_run_command(gitdir, ['rev-list', '-1', commit, '--not', *known])
     if ecode > 0:
         logger.debug('rev-list failed for %s (exit code %s)', commit, ecode)
         return None
@@ -1124,7 +1130,11 @@ def commit_reachable_on_remote(
 
 
 def _check_published(
-    checkurl: str, checkcommit: str, checkrepo: str, checkbranch: str = ''
+    checkurl: str,
+    checkcommit: str,
+    checkrepo: str,
+    checkbranch: str = '',
+    gitdir: Optional[str] = None,
 ) -> Optional[bool]:
     """Tri-state publish check for a queued thanks message.
 
@@ -1140,7 +1150,9 @@ def _check_published(
     if checkurl and not checkrepo:
         checkrepo = _get_check_repo(checkurl) or ''
     if checkcommit and checkrepo:
-        return commit_reachable_on_remote(checkcommit, checkrepo, branch=checkbranch)
+        return commit_reachable_on_remote(
+            checkcommit, checkrepo, branch=checkbranch, gitdir=gitdir
+        )
     if not checkurl:
         return True
     try:
@@ -1453,7 +1465,9 @@ def _process_queue_locked(
 
         # Check if the commit is publicly visible
         if not dryrun and (checkurl or (checkcommit and checkrepo)):
-            published = _check_published(checkurl, checkcommit, checkrepo, checkbranch)
+            published = _check_published(
+                checkurl, checkcommit, checkrepo, checkbranch, gitdir=topdir
+            )
             if published is None:
                 still_pending += 1
                 if progress_cb:
diff --git a/src/tests/test_ty.py b/src/tests/test_ty.py
index 54fa6d4..610e5af 100644
--- a/src/tests/test_ty.py
+++ b/src/tests/test_ty.py
@@ -503,7 +503,9 @@ def test_process_queue_passes_branch(
 
     calls: List[Tuple[str, str, str]] = []
 
-    def fake_reachable(commit: str, repo_url: str, branch: str = '') -> Optional[bool]:
+    def fake_reachable(
+        commit: str, repo_url: str, branch: str = '', gitdir: Optional[str] = None
+    ) -> Optional[bool]:
         calls.append((commit, repo_url, branch))
         return False
 
@@ -530,7 +532,9 @@ def test_process_queue_holds_unpublished(
 
     calls: List[Tuple[str, str]] = []
 
-    def fake_reachable(commit: str, repo_url: str, branch: str = '') -> Optional[bool]:
+    def fake_reachable(
+        commit: str, repo_url: str, branch: str = '', gitdir: Optional[str] = None
+    ) -> Optional[bool]:
         calls.append((commit, repo_url))
         return False
 
@@ -580,7 +584,9 @@ def test_process_queue_lock_held(
     monkeypatch.chdir(repo)
     _queue_test_message()
     monkeypatch.setattr(
-        b4.ty, 'commit_reachable_on_remote', lambda commit, repo_url, branch='': False
+        b4.ty,
+        'commit_reachable_on_remote',
+        lambda commit, repo_url, branch='', gitdir=None: False,
     )
     with b4.lockfile_nb(b4.ty._get_queue_lock_path()):
         with pytest.raises(b4.LockHeldError):
@@ -599,7 +605,9 @@ def test_process_queue_check_only(
     monkeypatch.chdir(repo)
     _queue_test_message()
     monkeypatch.setattr(
-        b4.ty, 'commit_reachable_on_remote', lambda commit, repo_url, branch='': True
+        b4.ty,
+        'commit_reachable_on_remote',
+        lambda commit, repo_url, branch='', gitdir=None: True,
     )
 
     def _no_send(dryrun: bool = False) -> Tuple[None, str]:
@@ -627,7 +635,9 @@ def test_process_queue_explicit_topdir(
     monkeypatch.chdir(repo)
     _queue_test_message()
     monkeypatch.setattr(
-        b4.ty, 'commit_reachable_on_remote', lambda commit, repo_url, branch='': True
+        b4.ty,
+        'commit_reachable_on_remote',
+        lambda commit, repo_url, branch='', gitdir=None: True,
     )
     outside = tmp_path / 'elsewhere'
     outside.mkdir()
@@ -665,7 +675,9 @@ def test_process_queue_finalizes_thanked(
 
     _queue_test_message()
     monkeypatch.setattr(
-        b4.ty, 'commit_reachable_on_remote', lambda commit, repo_url, branch='': True
+        b4.ty,
+        'commit_reachable_on_remote',
+        lambda commit, repo_url, branch='', gitdir=None: True,
     )
     monkeypatch.setattr(b4, 'get_smtp', lambda dryrun=False: (None, 't@example.com'))
     monkeypatch.setattr(b4, 'send_mail', lambda *args, **kwargs: 1)
@@ -738,7 +750,9 @@ def _series_status(identifier: str, change_id: str = 'test-change-id') -> str:
 
 def _mock_delivery(monkeypatch: pytest.MonkeyPatch) -> None:
     monkeypatch.setattr(
-        b4.ty, 'commit_reachable_on_remote', lambda commit, repo_url, branch='': True
+        b4.ty,
+        'commit_reachable_on_remote',
+        lambda commit, repo_url, branch='', gitdir=None: True,
     )
     monkeypatch.setattr(b4, 'get_smtp', lambda dryrun=False: (None, 't@example.com'))
     monkeypatch.setattr(b4, 'send_mail', lambda *args, **kwargs: 1)

-- 
2.53.0


  parent reply	other threads:[~2026-07-31 21:59 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-31 21:58 [PATCH b4 v2 00/44] Stop the editor branch guard from eating review replies Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 01/44] review-tui: mark all outgoing mail as read, not just " Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 02/44] tests: cover the shared outgoing-seen helper Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 03/44] review: close the messages database when auto-marking fails Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 04/44] review: use the same busy timeout for both review databases Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 05/44] review: drop the unused return value from set_flags_bulk() Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 06/44] review: don't let archiving a series raise Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 07/44] tests: cover an unwritable series archive Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 08/44] review-tui: keep post-send bookkeeping out of the send error path Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 09/44] tests: cover the thank-you send's post-send bookkeeping Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 10/44] review-tui: say which way a take did not reach 'accepted' Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 11/44] tests: cover the take statuses in the thank-and-archive chain Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 12/44] review-tui: use the shared helper to delete a review branch Christian Brauner
2026-07-31 21:58 ` Christian Brauner [this message]
2026-07-31 21:58 ` [PATCH b4 v2 14/44] tests: cover the publish check using the repository it is given Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 15/44] edit_in_editor: make the branch guard opt-in Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 16/44] tests: cover the opt-in branch guard in edit_in_editor Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 17/44] edit_in_editor: work in the tree the caller names Christian Brauner
2026-07-31 21:58 ` [PATCH b4 v2 18/44] tests: cover edit_in_editor working in the caller's tree Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 19/44] ty: edit the thank-you review in the tree it was pointed at Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 20/44] tests: cover the ty review editing in the named tree Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 21/44] tui: route editor launches through one non-fatal helper Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 22/44] tests: cover an editor failure leaving the review TUI standing Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 23/44] review-tui: only put back a branch b4 checked out itself Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 24/44] tests: cover the review TUI's branch-restore guard Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 25/44] review-tui: put HEAD back where it was when it was not on a branch Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 26/44] tests: cover the restore from a detached HEAD Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 27/44] tests: pin the default branch in the queue-delivery fixture Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 28/44] ty: an unknown remote tip is undetermined, not unpublished Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 29/44] review-tui: keep post-send bookkeeping out of the review send error path Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 30/44] tests: cover the review send's post-send bookkeeping Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 31/44] review: close the tracking database when archiving fails Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 32/44] review: clean up a review branch that cannot be finished Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 33/44] tests: cover create_review_branch cleaning up a half-built branch Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 34/44] review-tui: put the branch back after a revision upgrade Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 35/44] tests: cover the revision upgrade's branch handling Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 36/44] review-tui: restore the original branch however the tracking loop ends Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 37/44] review-tui: do not let a failed tracking load skip the branch restore Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 38/44] tests: cover the tracking TUI restoring the branch on the way out Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 39/44] review-tui: close the tracking database when the status sync fails Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 40/44] tests: cover the status sync closing its database Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 41/44] review-tui: catch the exit a failed checkout reports itself with Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 42/44] tests: cover a failed checkout leaving the tracking list standing Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 43/44] review-tui: put the user back when the branch they are on is deleted Christian Brauner
2026-07-31 21:59 ` [PATCH b4 v2 44/44] tests: cover the branch delete leaving the worktree on a branch Christian Brauner
2026-08-03 14:59 ` [PATCH b4 v2 00/44] Stop the editor branch guard from eating review replies Konstantin Ryabitsev

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=20260731-work-b4-editor-branch-guard-v2-13-243fd19d322d@kernel.org \
    --to=brauner@kernel.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox