Repository: VirtusLab/git-machete
Pull request #1039 (2023-08-31 18:51:59)

Make `github retarget-pr` actually fail when no PR is opened for the branch


Patch:
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 08f3c2a..5cd1fbf 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -2,6 +2,7 @@
 
 ## New in git-machete 3.18.2
 
+- fixed: `git machete github retarget-pr`, when invoked without `--ignore-if-missing`, actually fails now if there is no PR for the branch
 - improved: GitHub tokens are automatically redacted from command outputs in `--debug` mode
 
 ## New in git-machete 3.18.1
diff --git a/git_machete/client.py b/git_machete/client.py
index 9f02a32..a64430a 100644
--- a/git_machete/client.py
+++ b/git_machete/client.py
@@ -2185,17 +2185,15 @@ class MacheteClient:
 
         debug(f'organization is {org_repo_remote.organization}, repository is {org_repo_remote.repository}')
 
-        try:
-            prs: List[GitHubPullRequest] = github_client.derive_pull_requests_by_head(head)
-        except MacheteException as err:
+        prs: List[GitHubPullRequest] = github_client.derive_pull_requests_by_head(head)
+        if not prs:
             if ignore_if_missing:
-                prs = []
+                warn(f"no PRs have `{head}` as its head")
+                return
             else:
-                raise MacheteException(err.msg)
-        if not prs:
-            return
+                raise MacheteException(f"No PRs have `{head}` as its head")
         if len(prs) > 1:
-            raise MacheteException(f"Multiple PRs have {head} as its head: " + ", ".join(f"#{_pr.number}" for _pr in prs))
+            raise MacheteException(f"Multiple PRs have `{head}` as its head: " + ", ".join(f"#{_pr.number}" for _pr in prs))
         pr = prs[0]
         debug(f'found {pr}')
 


Test patch:
diff --git a/tests/mockers_github.py b/tests/mockers_github.py
index 8331c64..b4afa13 100644
--- a/tests/mockers_github.py
+++ b/tests/mockers_github.py
@@ -119,9 +119,8 @@ def __mock_urlopen_impl(github_api_state: MockGitHubAPIState, request: Request)
             if full_head_name:
                 head: str = full_head_name.split(':')[1]
                 prs = github_api_state.get_pulls_by_head(head)
-                if prs:
-                    return MockGitHubAPIResponse(HTTPStatus.OK, prs)
-                raise error_404()
+                # If no matching PRs are found, the real GitHub returns 200 OK with an empty JSON array - not 404.
+                return MockGitHubAPIResponse(HTTPStatus.OK, prs)
             else:
                 pulls = github_api_state.get_open_pulls()
                 page_str = query_params.get('page')
diff --git a/tests/test_github_retarget_pr.py b/tests/test_github_retarget_pr.py
index 52831e9..e5d89dd 100644
--- a/tests/test_github_retarget_pr.py
+++ b/tests/test_github_retarget_pr.py
@@ -213,17 +213,13 @@ class TestGitHubRetargetPR(BaseTest):
             expected_result=expected_status_output
         )
 
-        expected_error_message = ('GET https://api.github.com/repos/user/repo/pulls?head=user:branch-without-pr request '
-                                  'ended up in 404 response from GitHub. A valid GitHub API token is required.\n'
-                                  'Provide a GitHub API token with repo access via one of the:\n'
-                                  '\t1. GITHUB_TOKEN environment variable\n'
-                                  '\t2. Content of the ~/.github-token file\n'
-                                  '\t3. Current auth token from the gh GitHub CLI\n'
-                                  '\t4. Current auth token from the hub GitHub CLI\n'
-                                  ' Visit https://github.com/settings/tokens to generate a new one.')
-        assert_failure(["github", "retarget-pr", "--branch", "branch-without-pr"], expected_error_message)
-
-        launch_command('github', 'retarget-pr', '--branch', 'branch-without-pr', '--ignore-if-missing')
+        assert_failure(
+            ["github", "retarget-pr", "--branch", "branch-without-pr"],
+            "No PRs have branch-without-pr as its head")
+
+        assert_success(
+            ['github', 'retarget-pr', '--branch', 'branch-without-pr', '--ignore-if-missing'],
+            "Warn: no PRs have branch-without-pr as its head\n")
 
     def test_github_retarget_pr_multiple_non_origin_remotes(self, mocker: MockerFixture) -> None:
         self.patch_symbol(mocker, 'git_machete.github.OrganizationAndRepository.from_url', mock_from_url)