From d587bf021386e2e366c722969133edc5bd0677a2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 08:16:39 +0000 Subject: [PATCH 01/19] Initial plan From cd72050b612b95e735736cf2f63c53ee8389a257 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 08:26:17 +0000 Subject: [PATCH 02/19] Fix GitLab merge request detection to prevent empty MRs Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/git.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index db2887897c3d..5eb6e5506b94 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -881,6 +881,19 @@ class GitMergeRequestBase(GitForcePushRepository): REQUIRED_CONFIG: ClassVar[set[str]] = {"username", "token"} OPTIONAL_CONFIG: ClassVar[set[str]] = {"scheme"} + def count_outgoing(self, branch: str | None = None): + """ + Count outgoing commits. + + For merge request workflows, we need to check against the origin remote, + not the fork remote, to determine if commits are already in the upstream + repository. This prevents creating duplicate merge requests when commits + have already been merged. + """ + # Use origin remote instead of fork when counting outgoing commits + remote_branch = f"origin/{self.branch if branch is None else branch}" + return len(self.log_revisions(self.ref_from_remote.format(remote_branch))) + def merge( self, abort: bool = False, message: str | None = None, no_ff: bool = False ) -> None: From 7abfcb5e88083e531322869b9688620f6fa415df Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 08:27:37 +0000 Subject: [PATCH 03/19] Add test for count_outgoing after merge detection Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/tests/test_vcs.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/weblate/vcs/tests/test_vcs.py b/weblate/vcs/tests/test_vcs.py index 9beaaf0f2652..7fd6819fab3e 100644 --- a/weblate/vcs/tests/test_vcs.py +++ b/weblate/vcs/tests/test_vcs.py @@ -1626,6 +1626,27 @@ def test_pull_request_exists(self, branch: str = "") -> None: super().test_push(branch) mock_push_to_fork.stop() + def test_count_outgoing_after_merge(self) -> None: + """Test that count_outgoing correctly detects no pending changes after merge.""" + self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" + + # Make a commit locally + self.test_commit() + + # Verify there are outgoing commits before merge + self.assertTrue(self.repo.count_outgoing() > 0) + + # Simulate the commit being merged to origin by updating the origin ref + # In a real scenario, after a merge request is merged and git fetch is done, + # origin/main would contain the local commits + self.repo.execute(["update-ref", "refs/remotes/origin/main", "HEAD"]) + + # Now count_outgoing should return 0 since origin has our commits + self.assertEqual(self.repo.count_outgoing(), 0) + + # Verify with explicit branch parameter + self.assertEqual(self.repo.count_outgoing(self.repo.branch), 0) + @override_settings( PAGURE_CREDENTIALS={"pagure.io": {"username": "test", "token": "token"}} From 8248223b97646a394dad5d5e024c348b6d652aec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 08:33:09 +0000 Subject: [PATCH 04/19] Address code review feedback on count_outgoing fix Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/git.py | 10 ++++++++-- weblate/vcs/tests/test_vcs.py | 15 ++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index 5eb6e5506b94..340e1a460030 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -889,9 +889,15 @@ def count_outgoing(self, branch: str | None = None): not the fork remote, to determine if commits are already in the upstream repository. This prevents creating duplicate merge requests when commits have already been merged. + + Unlike push operations which use the fork remote, counting outgoing commits + should always compare against the upstream origin to detect if changes have + been merged. """ - # Use origin remote instead of fork when counting outgoing commits - remote_branch = f"origin/{self.branch if branch is None else branch}" + # Always use origin remote (not fork) when counting outgoing commits + # to check if our changes are already in the upstream repository + target_branch = self.branch if branch is None else branch + remote_branch = f"origin/{target_branch}" return len(self.log_revisions(self.ref_from_remote.format(remote_branch))) def merge( diff --git a/weblate/vcs/tests/test_vcs.py b/weblate/vcs/tests/test_vcs.py index 7fd6819fab3e..84b19964a479 100644 --- a/weblate/vcs/tests/test_vcs.py +++ b/weblate/vcs/tests/test_vcs.py @@ -1629,21 +1629,22 @@ def test_pull_request_exists(self, branch: str = "") -> None: def test_count_outgoing_after_merge(self) -> None: """Test that count_outgoing correctly detects no pending changes after merge.""" self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" - + # Make a commit locally self.test_commit() - + # Verify there are outgoing commits before merge self.assertTrue(self.repo.count_outgoing() > 0) - + # Simulate the commit being merged to origin by updating the origin ref # In a real scenario, after a merge request is merged and git fetch is done, - # origin/main would contain the local commits - self.repo.execute(["update-ref", "refs/remotes/origin/main", "HEAD"]) - + # origin/{branch} would contain the local commits + origin_ref = f"refs/remotes/origin/{self.repo.branch}" + self.repo.execute(["update-ref", origin_ref, "HEAD"]) + # Now count_outgoing should return 0 since origin has our commits self.assertEqual(self.repo.count_outgoing(), 0) - + # Verify with explicit branch parameter self.assertEqual(self.repo.count_outgoing(self.repo.branch), 0) From 048d27d8c91b64769bb7a56d43b74150e611f2c3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 08:34:03 +0000 Subject: [PATCH 05/19] Add changelog entry for merge request fix Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- docs/changes.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changes.rst b/docs/changes.rst index ab128a496550..55469290900e 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -36,6 +36,7 @@ Weblate 5.15 * Avoid false positive checks upon committing pending changes. * Performance improvements for file upload. * Show glossary matches for the source language. +* Fixed merge request repositories creating duplicate empty merge requests when no translation changes exist. .. rubric:: Compatibility From b9b737ee7c3d91c2000d920a8cc08e2660b5e280 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 08:47:06 +0000 Subject: [PATCH 06/19] Check both origin and fork to prevent unnecessary pushes Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- docs/changes.rst | 2 +- weblate/vcs/git.py | 49 ++++++++++++++++++++++++++--------- weblate/vcs/tests/test_vcs.py | 20 +++++++++++--- 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index 55469290900e..5886edae8a0c 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -36,7 +36,7 @@ Weblate 5.15 * Avoid false positive checks upon committing pending changes. * Performance improvements for file upload. * Show glossary matches for the source language. -* Fixed merge request repositories creating duplicate empty merge requests when no translation changes exist. +* Fixed merge request repositories creating duplicate empty merge requests and unnecessary pushes when changes are already merged or pushed to fork. .. rubric:: Compatibility diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index 340e1a460030..ae62463e3932 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -885,20 +885,45 @@ def count_outgoing(self, branch: str | None = None): """ Count outgoing commits. - For merge request workflows, we need to check against the origin remote, - not the fork remote, to determine if commits are already in the upstream - repository. This prevents creating duplicate merge requests when commits - have already been merged. - - Unlike push operations which use the fork remote, counting outgoing commits - should always compare against the upstream origin to detect if changes have - been merged. + For merge request workflows, we need to check against both the origin + remote (to see if commits are already merged) and the fork remote (to see + if commits are already pushed but not merged). This prevents creating + duplicate merge requests when commits have already been merged, while also + avoiding unnecessary pushes when commits are already in the fork. """ - # Always use origin remote (not fork) when counting outgoing commits - # to check if our changes are already in the upstream repository target_branch = self.branch if branch is None else branch - remote_branch = f"origin/{target_branch}" - return len(self.log_revisions(self.ref_from_remote.format(remote_branch))) + origin_branch = f"origin/{target_branch}" + + # First check if commits are already in origin (merged) + origin_outgoing = len( + self.log_revisions(self.ref_from_remote.format(origin_branch)) + ) + if origin_outgoing == 0: + # All commits are in origin, nothing to push + return 0 + + # Check if commits are in the fork (already pushed) + # The fork branch has a different name (weblate-project-component) + # computed from component info + if self.component is not None: + credentials = self.get_credentials() + fork_remote = credentials["username"] + fork_branch_name = f"weblate-{self.component.project.slug}-{self.component.slug}" + fork_branch = f"{fork_remote}/{fork_branch_name}" + + try: + fork_outgoing = len( + self.log_revisions(self.ref_from_remote.format(fork_branch)) + ) + # If fork has all commits, don't need to push + if fork_outgoing == 0: + return 0 + except RepositoryError: + # Fork branch doesn't exist yet, fall through to return origin count + pass + + # Commits are not in origin or fork, need to push + return origin_outgoing def merge( self, abort: bool = False, message: str | None = None, no_ff: bool = False diff --git a/weblate/vcs/tests/test_vcs.py b/weblate/vcs/tests/test_vcs.py index 84b19964a479..37cff834ebf3 100644 --- a/weblate/vcs/tests/test_vcs.py +++ b/weblate/vcs/tests/test_vcs.py @@ -1633,16 +1633,28 @@ def test_count_outgoing_after_merge(self) -> None: # Make a commit locally self.test_commit() - # Verify there are outgoing commits before merge - self.assertTrue(self.repo.count_outgoing() > 0) + # Verify there are outgoing commits before any push/merge + initial_count = self.repo.count_outgoing() + self.assertTrue(initial_count > 0) + + # Scenario 1: Simulate the commit being pushed to fork + # The fork branch name is weblate-{project}-{component} + credentials = self.repo.get_credentials() + fork_branch_name = f"weblate-{self.repo.component.project.slug}-{self.repo.component.slug}" + fork_ref = f"refs/remotes/{credentials['username']}/{fork_branch_name}" + self.repo.execute(["update-ref", fork_ref, "HEAD"]) + + # count_outgoing should now be 0 since fork has our commits + # (even though origin doesn't yet - MR is pending) + self.assertEqual(self.repo.count_outgoing(), 0) - # Simulate the commit being merged to origin by updating the origin ref + # Scenario 2: Simulate the merge request being merged to origin # In a real scenario, after a merge request is merged and git fetch is done, # origin/{branch} would contain the local commits origin_ref = f"refs/remotes/origin/{self.repo.branch}" self.repo.execute(["update-ref", origin_ref, "HEAD"]) - # Now count_outgoing should return 0 since origin has our commits + # count_outgoing should still return 0 since origin has our commits self.assertEqual(self.repo.count_outgoing(), 0) # Verify with explicit branch parameter From 86ddf1cd1bd540d731d537fe2b0fa4a9dfdeb0d3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 08:52:22 +0000 Subject: [PATCH 07/19] Address code review feedback and improve error handling Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/git.py | 37 +++++++++++++++++++---------------- weblate/vcs/tests/test_vcs.py | 1 + 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index ae62463e3932..eebc30416008 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -893,7 +893,7 @@ def count_outgoing(self, branch: str | None = None): """ target_branch = self.branch if branch is None else branch origin_branch = f"origin/{target_branch}" - + # First check if commits are already in origin (merged) origin_outgoing = len( self.log_revisions(self.ref_from_remote.format(origin_branch)) @@ -901,27 +901,30 @@ def count_outgoing(self, branch: str | None = None): if origin_outgoing == 0: # All commits are in origin, nothing to push return 0 - + # Check if commits are in the fork (already pushed) # The fork branch has a different name (weblate-project-component) # computed from component info + credentials = self.get_credentials() + fork_remote = credentials["username"] if self.component is not None: - credentials = self.get_credentials() - fork_remote = credentials["username"] fork_branch_name = f"weblate-{self.component.project.slug}-{self.component.slug}" - fork_branch = f"{fork_remote}/{fork_branch_name}" - - try: - fork_outgoing = len( - self.log_revisions(self.ref_from_remote.format(fork_branch)) - ) - # If fork has all commits, don't need to push - if fork_outgoing == 0: - return 0 - except RepositoryError: - # Fork branch doesn't exist yet, fall through to return origin count - pass - + else: + fork_branch_name = f"weblate-{target_branch}" + fork_branch = f"{fork_remote}/{fork_branch_name}" + + try: + fork_outgoing = len( + self.log_revisions(self.ref_from_remote.format(fork_branch)) + ) + # If fork has all commits, don't need to push + if fork_outgoing == 0: + return 0 + except RepositoryError: + # Fork branch doesn't exist yet or is not accessible, + # indicating commits haven't been pushed to fork + pass + # Commits are not in origin or fork, need to push return origin_outgoing diff --git a/weblate/vcs/tests/test_vcs.py b/weblate/vcs/tests/test_vcs.py index 37cff834ebf3..c3bd1177a269 100644 --- a/weblate/vcs/tests/test_vcs.py +++ b/weblate/vcs/tests/test_vcs.py @@ -1639,6 +1639,7 @@ def test_count_outgoing_after_merge(self) -> None: # Scenario 1: Simulate the commit being pushed to fork # The fork branch name is weblate-{project}-{component} + # (matches the logic in push() method) credentials = self.repo.get_credentials() fork_branch_name = f"weblate-{self.repo.component.project.slug}-{self.repo.component.slug}" fork_ref = f"refs/remotes/{credentials['username']}/{fork_branch_name}" From 28176463660cb518ecf6067cbc2106fbfdcbff2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Wed, 7 Jan 2026 11:03:19 +0100 Subject: [PATCH 08/19] Update weblate/vcs/git.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- weblate/vcs/git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index eebc30416008..92b9773b0dbd 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -881,7 +881,7 @@ class GitMergeRequestBase(GitForcePushRepository): REQUIRED_CONFIG: ClassVar[set[str]] = {"username", "token"} OPTIONAL_CONFIG: ClassVar[set[str]] = {"scheme"} - def count_outgoing(self, branch: str | None = None): + def count_outgoing(self, branch: str | None = None) -> int: """ Count outgoing commits. From 3ca4e67b28ec8ae2fc38b0d49195d81dc904bf5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Wed, 7 Jan 2026 11:03:25 +0100 Subject: [PATCH 09/19] Update weblate/vcs/tests/test_vcs.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- weblate/vcs/tests/test_vcs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weblate/vcs/tests/test_vcs.py b/weblate/vcs/tests/test_vcs.py index c3bd1177a269..6c3d1f3874c2 100644 --- a/weblate/vcs/tests/test_vcs.py +++ b/weblate/vcs/tests/test_vcs.py @@ -1635,7 +1635,7 @@ def test_count_outgoing_after_merge(self) -> None: # Verify there are outgoing commits before any push/merge initial_count = self.repo.count_outgoing() - self.assertTrue(initial_count > 0) + self.assertGreater(initial_count, 0) # Scenario 1: Simulate the commit being pushed to fork # The fork branch name is weblate-{project}-{component} From 6a066ab46196208286b45e1ca11c39c4dacfb6f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Wed, 7 Jan 2026 11:04:42 +0100 Subject: [PATCH 10/19] Apply suggestion from @nijel --- docs/changes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changes.rst b/docs/changes.rst index 5886edae8a0c..6141c9ee8466 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -36,7 +36,7 @@ Weblate 5.15 * Avoid false positive checks upon committing pending changes. * Performance improvements for file upload. * Show glossary matches for the source language. -* Fixed merge request repositories creating duplicate empty merge requests and unnecessary pushes when changes are already merged or pushed to fork. +* Pull/merge requests are now only created when necessary. .. rubric:: Compatibility From 49abd18f82a66f04a13fcf28373ea5c0a3a37c23 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 12:04:34 +0000 Subject: [PATCH 11/19] Refactor to use helper method and super() implementation - Add get_fork_branch_name() helper to avoid code duplication - Use super().count_outgoing() for origin check (looks at pull branch) - Update push() to use the helper method - Update test to use helper method for consistency Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/git.py | 27 ++++++++++----------------- weblate/vcs/tests/test_vcs.py | 5 ++--- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index 92b9773b0dbd..025e9a32b6ff 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -881,6 +881,12 @@ class GitMergeRequestBase(GitForcePushRepository): REQUIRED_CONFIG: ClassVar[set[str]] = {"username", "token"} OPTIONAL_CONFIG: ClassVar[set[str]] = {"scheme"} + def get_fork_branch_name(self) -> str: + """Get the fork branch name used for pushing.""" + if self.component is not None: + return f"weblate-{self.component.project.slug}-{self.component.slug}" + return f"weblate-{self.branch}" + def count_outgoing(self, branch: str | None = None) -> int: """ Count outgoing commits. @@ -891,13 +897,8 @@ def count_outgoing(self, branch: str | None = None) -> int: duplicate merge requests when commits have already been merged, while also avoiding unnecessary pushes when commits are already in the fork. """ - target_branch = self.branch if branch is None else branch - origin_branch = f"origin/{target_branch}" - - # First check if commits are already in origin (merged) - origin_outgoing = len( - self.log_revisions(self.ref_from_remote.format(origin_branch)) - ) + # Omit branch to look at pull branch, not push branch + origin_outgoing = super().count_outgoing() if origin_outgoing == 0: # All commits are in origin, nothing to push return 0 @@ -907,10 +908,7 @@ def count_outgoing(self, branch: str | None = None) -> int: # computed from component info credentials = self.get_credentials() fork_remote = credentials["username"] - if self.component is not None: - fork_branch_name = f"weblate-{self.component.project.slug}-{self.component.slug}" - else: - fork_branch_name = f"weblate-{target_branch}" + fork_branch_name = self.get_fork_branch_name() fork_branch = f"{fork_remote}/{fork_branch_name}" try: @@ -1140,12 +1138,7 @@ def push(self, branch: str) -> None: else: fork_remote = credentials["username"] self.fork(credentials) - if self.component is not None: - fork_branch = ( - f"weblate-{self.component.project.slug}-{self.component.slug}" - ) - else: - fork_branch = f"weblate-{self.branch}" + fork_branch = self.get_fork_branch_name() self.push_to_fork(credentials, self.branch, fork_branch) self.create_pull_request(credentials, self.branch, fork_remote, fork_branch) diff --git a/weblate/vcs/tests/test_vcs.py b/weblate/vcs/tests/test_vcs.py index 6c3d1f3874c2..5e7236d26ffc 100644 --- a/weblate/vcs/tests/test_vcs.py +++ b/weblate/vcs/tests/test_vcs.py @@ -1638,10 +1638,9 @@ def test_count_outgoing_after_merge(self) -> None: self.assertGreater(initial_count, 0) # Scenario 1: Simulate the commit being pushed to fork - # The fork branch name is weblate-{project}-{component} - # (matches the logic in push() method) + # The fork branch name is from get_fork_branch_name() method credentials = self.repo.get_credentials() - fork_branch_name = f"weblate-{self.repo.component.project.slug}-{self.repo.component.slug}" + fork_branch_name = self.repo.get_fork_branch_name() fork_ref = f"refs/remotes/{credentials['username']}/{fork_branch_name}" self.repo.execute(["update-ref", fork_ref, "HEAD"]) From d54eea88e5860c27478befb7f4ebc40552bd67ba Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 12:07:57 +0000 Subject: [PATCH 12/19] Improve code comments for clarity Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/git.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index 025e9a32b6ff..e02f6dd2f958 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -897,15 +897,14 @@ def count_outgoing(self, branch: str | None = None) -> int: duplicate merge requests when commits have already been merged, while also avoiding unnecessary pushes when commits are already in the fork. """ - # Omit branch to look at pull branch, not push branch + # Check the pull branch using parent class implementation origin_outgoing = super().count_outgoing() if origin_outgoing == 0: # All commits are in origin, nothing to push return 0 # Check if commits are in the fork (already pushed) - # The fork branch has a different name (weblate-project-component) - # computed from component info + # The fork branch name is determined by get_fork_branch_name() credentials = self.get_credentials() fork_remote = credentials["username"] fork_branch_name = self.get_fork_branch_name() From 06f8254bebc2f0aca9e6da61fd3eaae57b3ae2b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 12:56:41 +0000 Subject: [PATCH 13/19] Fix count_outgoing to respect should_use_fork logic - Add check for should_use_fork(branch) before fork checking - Only check fork branch when fork is actually used for that branch - Add test for non-default branch behavior - Add comment explaining why branch parameter is omitted from super() call Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/git.py | 7 ++++++- weblate/vcs/tests/test_vcs.py | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index e02f6dd2f958..76c3a6657527 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -897,12 +897,17 @@ def count_outgoing(self, branch: str | None = None) -> int: duplicate merge requests when commits have already been merged, while also avoiding unnecessary pushes when commits are already in the fork. """ - # Check the pull branch using parent class implementation + # Omit branch to look at pull branch, not push branch origin_outgoing = super().count_outgoing() if origin_outgoing == 0: # All commits are in origin, nothing to push return 0 + # Only check fork if we're using fork for this branch + if not self.should_use_fork(branch): + # Not using fork for this branch, delegate to parent + return origin_outgoing + # Check if commits are in the fork (already pushed) # The fork branch name is determined by get_fork_branch_name() credentials = self.get_credentials() diff --git a/weblate/vcs/tests/test_vcs.py b/weblate/vcs/tests/test_vcs.py index 5e7236d26ffc..6853ff0932fa 100644 --- a/weblate/vcs/tests/test_vcs.py +++ b/weblate/vcs/tests/test_vcs.py @@ -1660,6 +1660,26 @@ def test_count_outgoing_after_merge(self) -> None: # Verify with explicit branch parameter self.assertEqual(self.repo.count_outgoing(self.repo.branch), 0) + def test_count_outgoing_non_default_branch(self) -> None: + """Test count_outgoing with non-default branch doesn't check fork.""" + self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" + + # Make a commit locally + self.test_commit() + + # When called with a different branch than self.branch, + # should_use_fork() returns False, so fork checking is skipped + # Create a different branch name + different_branch = "develop" if self.repo.branch != "develop" else "feature" + + # Update origin ref for the different branch + origin_ref = f"refs/remotes/origin/{different_branch}" + self.repo.execute(["update-ref", origin_ref, "HEAD"]) + + # count_outgoing with different branch should return 0 + # (commits are in origin for that branch, fork not checked) + self.assertEqual(self.repo.count_outgoing(different_branch), 0) + @override_settings( PAGURE_CREDENTIALS={"pagure.io": {"username": "test", "token": "token"}} From 6ad485b3ea170e358483a2fbd950278ee8e8d5d3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 17:05:46 +0000 Subject: [PATCH 14/19] Fix branch parameter handling in count_outgoing - Move should_use_fork check to beginning of method - Pass branch parameter to super() when not using fork - Only omit branch parameter when using fork (to check pull branch) - This ensures branch parameter is correctly respected Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/git.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index 76c3a6657527..9433fffe0f9b 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -897,17 +897,18 @@ def count_outgoing(self, branch: str | None = None) -> int: duplicate merge requests when commits have already been merged, while also avoiding unnecessary pushes when commits are already in the fork. """ - # Omit branch to look at pull branch, not push branch + # Only check fork if we're using fork for this branch + if not self.should_use_fork(branch): + # Not using fork for this branch, use parent implementation + return super().count_outgoing(branch) + + # For fork-based workflows, check the pull branch (not push branch) + # to see if commits have been merged to origin origin_outgoing = super().count_outgoing() if origin_outgoing == 0: # All commits are in origin, nothing to push return 0 - # Only check fork if we're using fork for this branch - if not self.should_use_fork(branch): - # Not using fork for this branch, delegate to parent - return origin_outgoing - # Check if commits are in the fork (already pushed) # The fork branch name is determined by get_fork_branch_name() credentials = self.get_credentials() From a7631bf63eb95b47955972ec7e0a6921b9288878 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 17:07:32 +0000 Subject: [PATCH 15/19] Improve comments for clarity in count_outgoing Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/git.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index 9433fffe0f9b..9412fddba27b 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -897,13 +897,13 @@ def count_outgoing(self, branch: str | None = None) -> int: duplicate merge requests when commits have already been merged, while also avoiding unnecessary pushes when commits are already in the fork. """ - # Only check fork if we're using fork for this branch + # Check if fork is used for this branch (default and matching branches use fork) if not self.should_use_fork(branch): - # Not using fork for this branch, use parent implementation + # Fork not used: check specified branch directly on origin return super().count_outgoing(branch) - # For fork-based workflows, check the pull branch (not push branch) - # to see if commits have been merged to origin + # Fork workflow: check if commits have been merged to origin's pull branch + # Omit branch parameter to check the repository's default pull branch origin_outgoing = super().count_outgoing() if origin_outgoing == 0: # All commits are in origin, nothing to push From 35e3c0e36395027e0d650a7e58934b92f4c5ef9f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:00:39 +0000 Subject: [PATCH 16/19] Fix KeyError when credentials are not configured - Wrap credentials access in try-except to catch KeyError - This handles cases where credentials are not configured for the repository - Prevents test failures when fork credentials are missing Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/git.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index 9412fddba27b..3e80ab34a63f 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -911,21 +911,21 @@ def count_outgoing(self, branch: str | None = None) -> int: # Check if commits are in the fork (already pushed) # The fork branch name is determined by get_fork_branch_name() - credentials = self.get_credentials() - fork_remote = credentials["username"] - fork_branch_name = self.get_fork_branch_name() - fork_branch = f"{fork_remote}/{fork_branch_name}" - try: + credentials = self.get_credentials() + fork_remote = credentials["username"] + fork_branch_name = self.get_fork_branch_name() + fork_branch = f"{fork_remote}/{fork_branch_name}" + fork_outgoing = len( self.log_revisions(self.ref_from_remote.format(fork_branch)) ) # If fork has all commits, don't need to push if fork_outgoing == 0: return 0 - except RepositoryError: - # Fork branch doesn't exist yet or is not accessible, - # indicating commits haven't been pushed to fork + except (RepositoryError, KeyError): + # Fork branch doesn't exist yet, credentials not configured, + # or branch is not accessible - indicating commits haven't been pushed to fork pass # Commits are not in origin or fork, need to push From b8049b20d1d79e6fe91a2532ebca93ab9dd6f0d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:16:29 +0000 Subject: [PATCH 17/19] Revert KeyError handling and configure credentials in test - Revert commit 35e3c0e that added KeyError handling - Add setUp method to VCSGitLabTest to set repo URL to gitlab.com - This ensures credentials are properly matched during tests - Credentials were already configured via @override_settings decorator Co-authored-by: nijel <212189+nijel@users.noreply.github.com> --- weblate/vcs/git.py | 16 ++++++++-------- weblate/vcs/tests/test_vcs.py | 5 +++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index 3e80ab34a63f..9412fddba27b 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -911,21 +911,21 @@ def count_outgoing(self, branch: str | None = None) -> int: # Check if commits are in the fork (already pushed) # The fork branch name is determined by get_fork_branch_name() - try: - credentials = self.get_credentials() - fork_remote = credentials["username"] - fork_branch_name = self.get_fork_branch_name() - fork_branch = f"{fork_remote}/{fork_branch_name}" + credentials = self.get_credentials() + fork_remote = credentials["username"] + fork_branch_name = self.get_fork_branch_name() + fork_branch = f"{fork_remote}/{fork_branch_name}" + try: fork_outgoing = len( self.log_revisions(self.ref_from_remote.format(fork_branch)) ) # If fork has all commits, don't need to push if fork_outgoing == 0: return 0 - except (RepositoryError, KeyError): - # Fork branch doesn't exist yet, credentials not configured, - # or branch is not accessible - indicating commits haven't been pushed to fork + except RepositoryError: + # Fork branch doesn't exist yet or is not accessible, + # indicating commits haven't been pushed to fork pass # Commits are not in origin or fork, need to push diff --git a/weblate/vcs/tests/test_vcs.py b/weblate/vcs/tests/test_vcs.py index 6853ff0932fa..85e9cbc882ec 100644 --- a/weblate/vcs/tests/test_vcs.py +++ b/weblate/vcs/tests/test_vcs.py @@ -1252,6 +1252,11 @@ class VCSGitLabTest(VCSGitUpstreamTest): _vcs = "git" _sets_push = False + def setUp(self) -> None: + super().setUp() + # Set repo URL to match configured credentials for GitLab tests + self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" + def mock_fork_responses(self, get_forks, repo_state=200) -> None: if repo_state == 409: # Response to mock existing of repo with duplicate name From 7450dcfd113aeede83260e9e4799310559afc628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Thu, 8 Jan 2026 19:53:07 +0100 Subject: [PATCH 18/19] tests: fix execution --- weblate/vcs/tests/test_vcs.py | 89 +++++++---------------------------- 1 file changed, 17 insertions(+), 72 deletions(-) diff --git a/weblate/vcs/tests/test_vcs.py b/weblate/vcs/tests/test_vcs.py index fb773168a369..93f875d23e6e 100644 --- a/weblate/vcs/tests/test_vcs.py +++ b/weblate/vcs/tests/test_vcs.py @@ -513,6 +513,13 @@ class VCSGitForcePushTest(VCSGitTest): class VCSGitUpstreamTest(VCSGitTest): + _repo_override: str + + def setUp(self) -> None: + super().setUp() + # Set repo URL to match configured credentials + self.repo.component.repo = self._repo_override + def add_remote_commit(self, conflict=False, rename=False) -> None: # Use Git to create changed upstream repo backup = self._class @@ -530,6 +537,7 @@ class VCSGiteaTest(VCSGitUpstreamTest): _class = GiteaFakeRepository _vcs = "git" _sets_push = False + _repo_override = "https://try.gitea.io/WeblateOrg/test.git" def mock_responses(self, pr_response, pr_status=200) -> None: """ @@ -623,8 +631,6 @@ def test_api_url_try_gitea(self) -> None: @responses.activate def test_push(self, branch: str = "") -> None: - self.repo.component.repo = "https://try.gitea.io/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -641,8 +647,6 @@ def test_push(self, branch: str = "") -> None: @responses.activate def test_pull_request_error(self, branch: str = "") -> None: - self.repo.component.repo = "https://try.gitea.io/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -660,8 +664,6 @@ def test_pull_request_error(self, branch: str = "") -> None: @responses.activate def test_pull_request_exists(self, branch: str = "") -> None: - self.repo.component.repo = "https://try.gitea.io/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -699,13 +701,10 @@ class VCSAzureDevOpsTest(VCSGitUpstreamTest): _vcs = "git" _sets_push = False _mock_push_to_fork = None + _repo_override = "https://dev.azure.com/organization/WeblateOrg/test.git" def setUp(self) -> None: super().setUp() - self.repo.component.repo = ( - "https://dev.azure.com/organization/WeblateOrg/test.git" - ) - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1059,6 +1058,7 @@ class VCSGitHubTest(VCSGitUpstreamTest): _class = GithubFakeRepository _vcs = "git" _sets_push = False + _repo_override = "https://github.com/WeblateOrg/test.git" def mock_responses(self, pr_response, pr_status=200) -> None: """ @@ -1166,8 +1166,6 @@ def test_api_url_ghes(self) -> None: @responses.activate def test_push(self, branch: str = "") -> None: - self.repo.component.repo = "https://github.com/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1184,8 +1182,6 @@ def test_push(self, branch: str = "") -> None: @responses.activate def test_pull_request_error(self, branch: str = "") -> None: - self.repo.component.repo = "https://github.com/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1203,8 +1199,6 @@ def test_pull_request_error(self, branch: str = "") -> None: @responses.activate def test_pull_request_exists(self, branch: str = "") -> None: - self.repo.component.repo = "https://github.com/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1245,11 +1239,7 @@ class VCSGitLabTest(VCSGitUpstreamTest): _class = GitLabFakeRepository _vcs = "git" _sets_push = False - - def setUp(self) -> None: - super().setUp() - # Set repo URL to match configured credentials for GitLab tests - self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" + _repo_override = "https://gitlab.com/WeblateOrg/test.git" def mock_fork_responses(self, get_forks, repo_state=200) -> None: if repo_state == 409: @@ -1474,8 +1464,6 @@ def test_api_url_self_hosted(self) -> None: @responses.activate def test_push(self, branch: str = "") -> None: - self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1495,8 +1483,6 @@ def test_push(self, branch: str = "") -> None: @responses.activate def test_push_with_existing_fork(self, branch: str = "") -> None: - self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1530,8 +1516,6 @@ def test_push_with_existing_fork(self, branch: str = "") -> None: @responses.activate def test_push_duplicate_repo_name(self, branch: str = "") -> None: - self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1559,8 +1543,6 @@ def test_push_duplicate_repo_name(self, branch: str = "") -> None: @responses.activate def test_push_rejected(self, branch: str = "") -> None: - self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1589,8 +1571,6 @@ def test_push_rejected(self, branch: str = "") -> None: @responses.activate def test_pull_request_error(self, branch: str = "") -> None: - self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1607,8 +1587,6 @@ def test_pull_request_error(self, branch: str = "") -> None: @responses.activate def test_pull_request_exists(self, branch: str = "") -> None: - self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1627,8 +1605,6 @@ def test_pull_request_exists(self, branch: str = "") -> None: def test_count_outgoing_after_merge(self) -> None: """Test that count_outgoing correctly detects no pending changes after merge.""" - self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" - # Make a commit locally self.test_commit() @@ -1641,7 +1617,7 @@ def test_count_outgoing_after_merge(self) -> None: credentials = self.repo.get_credentials() fork_branch_name = self.repo.get_fork_branch_name() fork_ref = f"refs/remotes/{credentials['username']}/{fork_branch_name}" - self.repo.execute(["update-ref", fork_ref, "HEAD"]) + self.repo.execute(["update-ref", fork_ref, "HEAD"], needs_lock=False) # count_outgoing should now be 0 since fork has our commits # (even though origin doesn't yet - MR is pending) @@ -1651,7 +1627,7 @@ def test_count_outgoing_after_merge(self) -> None: # In a real scenario, after a merge request is merged and git fetch is done, # origin/{branch} would contain the local commits origin_ref = f"refs/remotes/origin/{self.repo.branch}" - self.repo.execute(["update-ref", origin_ref, "HEAD"]) + self.repo.execute(["update-ref", origin_ref, "HEAD"], needs_lock=False) # count_outgoing should still return 0 since origin has our commits self.assertEqual(self.repo.count_outgoing(), 0) @@ -1661,8 +1637,6 @@ def test_count_outgoing_after_merge(self) -> None: def test_count_outgoing_non_default_branch(self) -> None: """Test count_outgoing with non-default branch doesn't check fork.""" - self.repo.component.repo = "https://gitlab.com/WeblateOrg/test.git" - # Make a commit locally self.test_commit() @@ -1673,7 +1647,7 @@ def test_count_outgoing_non_default_branch(self) -> None: # Update origin ref for the different branch origin_ref = f"refs/remotes/origin/{different_branch}" - self.repo.execute(["update-ref", origin_ref, "HEAD"]) + self.repo.execute(["update-ref", origin_ref, "HEAD"], needs_lock=False) # count_outgoing with different branch should return 0 # (commits are in origin for that branch, fork not checked) @@ -1687,6 +1661,7 @@ class VCSPagureTest(VCSGitUpstreamTest): _class = PagureFakeRepository _vcs = "git" _sets_push = False + _repo_override = "https://pagure.io/testrepo.git" def mock_responses(self, pr_response: dict, existing_response: dict) -> None: """Mock response helper function.""" @@ -1717,8 +1692,6 @@ def mock_responses(self, pr_response: dict, existing_response: dict) -> None: @responses.activate def test_push(self, branch: str = "") -> None: - self.repo.component.repo = "https://pagure.io/testrepo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1737,8 +1710,6 @@ def test_push(self, branch: str = "") -> None: @responses.activate def test_push_with_existing_fork(self, branch: str = "") -> None: - self.repo.component.repo = "https://pagure.io/testrepo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1766,8 +1737,6 @@ def test_push_with_existing_fork(self, branch: str = "") -> None: @responses.activate def test_push_with_existing_request(self, branch: str = "") -> None: - self.repo.component.repo = "https://pagure.io/testrepo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -1988,6 +1957,7 @@ class VCSBitbucketServerTest(VCSGitUpstreamTest): _sets_push = False _bbhost = "https://api.selfhosted.com" + _repo_override = f"{_bbhost}/bb_pk/bb_repo.git" _bb_api_error_stub: ClassVar[dict] = { "errors": [{"context": "", "message": ""}] } @@ -2158,8 +2128,6 @@ def test_get_headers(self) -> None: @responses.activate def test_default_reviewers_repo_error(self) -> None: - self.repo.component.repo = f"{self._bbhost}/bb_pk/bb_repo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -2180,8 +2148,6 @@ def test_default_reviewers_repo_error(self) -> None: @responses.activate def test_default_reviewers_error(self) -> None: - self.repo.component.repo = f"{self._bbhost}/bb_pk/bb_repo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -2204,8 +2170,6 @@ def test_default_reviewers_error(self) -> None: @responses.activate def test_push(self, branch: str = "") -> None: - self.repo.component.repo = f"{self._bbhost}/bb_pk/bb_repo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -2223,8 +2187,6 @@ def test_push(self, branch: str = "") -> None: @responses.activate def test_push_with_existing_pr(self, branch: str = "") -> None: - self.repo.component.repo = f"{self._bbhost}/bb_pk/bb_repo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -2242,8 +2204,6 @@ def test_push_with_existing_pr(self, branch: str = "") -> None: @responses.activate def test_push_pr_error_response(self, branch: str = "") -> None: - self.repo.component.repo = f"{self._bbhost}/bb_pk/bb_repo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -2262,8 +2222,6 @@ def test_push_pr_error_response(self, branch: str = "") -> None: @responses.activate def test_push_with_existing_fork(self, branch: str = "") -> None: - self.repo.component.repo = f"{self._bbhost}/bb_pk/bb_repo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -2282,8 +2240,6 @@ def test_push_with_existing_fork(self, branch: str = "") -> None: @responses.activate def test_create_fork_unexpected_fail(self, branch: str = "") -> None: - self.repo.component.repo = f"{self._bbhost}/bb_pk/bb_repo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -2299,8 +2255,6 @@ def test_create_fork_unexpected_fail(self, branch: str = "") -> None: @responses.activate def test_existing_fork_not_found(self, branch: str = "") -> None: - self.repo.component.repo = f"{self._bbhost}/bb_pk/bb_repo.git" - # Patch push_to_fork() function because we don't want to actually # make a git push request mock_push_to_fork_patcher = patch( @@ -2331,6 +2285,7 @@ class VCSBitbucketCloudTest(VCSGitUpstreamTest): _vcs = "git" _sets_push = False _apihost = "bitbucket.org" + _repo_override = "git@bitbucket.org:WeblateOrg/test.git" def mock_responses(self) -> None: """ @@ -2416,7 +2371,6 @@ def mock_responses(self) -> None: @responses.activate def test_push(self, branch: str = "") -> None: """Test push to bitbucket cloud.""" - self.repo.component.repo = "git@bitbucket.org:WeblateOrg/test.git" self.mock_responses() with patch("weblate.vcs.git.GitMergeRequestBase.push_to_fork", return_value=""): super().test_push(branch) @@ -2424,7 +2378,6 @@ def test_push(self, branch: str = "") -> None: @responses.activate def test_push_with_http(self, branch: str = "") -> None: """Test push to bitbucket cloud with HTTP repo link.""" - self.repo.component.repo = "https://bitbucket.org/WeblateOrg/test.git" self.mock_responses() with patch("weblate.vcs.git.GitMergeRequestBase.push_to_fork", return_value=""): super().test_push(branch) @@ -2432,8 +2385,6 @@ def test_push_with_http(self, branch: str = "") -> None: @responses.activate def test_push_with_missing_permission(self, branch: str = "") -> None: """Test push with missing permission for App Password.""" - self.repo.component.repo = "git@bitbucket.org:WeblateOrg/test.git" - self.mock_responses() responses.replace( responses.POST, @@ -2459,7 +2410,6 @@ def test_push_with_missing_permission(self, branch: str = "") -> None: @responses.activate def test_default_reviewers_error(self, branch: str = "") -> None: """Test default reviewers error, push expected to be successful.""" - self.repo.component.repo = "git@bitbucket.org:WeblateOrg/test.git" self.mock_responses() responses.replace( @@ -2483,7 +2433,6 @@ def test_default_reviewers_error(self, branch: str = "") -> None: @responses.activate def test_paginated_reviewers_list(self, branch: str = "") -> None: """Test the 'build_full_paginated_result' with default reviewers list.""" - self.repo.component.repo = "git@bitbucket.org:WeblateOrg/test.git" self.mock_responses() responses.replace( @@ -2534,7 +2483,6 @@ def test_paginated_reviewers_list(self, branch: str = "") -> None: @responses.activate def test_push_nothing_to_merge(self, branch: str = "") -> None: """Test push to bitbucket cloud with no changes to be merged.""" - self.repo.component.repo = "git@bitbucket.org:WeblateOrg/test.git" self.mock_responses() responses.replace( @@ -2553,7 +2501,6 @@ def test_push_nothing_to_merge(self, branch: str = "") -> None: @responses.activate def test_fork_already_exists(self, branch: str = "") -> None: """Test push to bitbucket cloud with HTTP repo link.""" - self.repo.component.repo = "git@bitbucket.org:WeblateOrg/test.git" self.mock_responses() responses.replace( @@ -2591,7 +2538,6 @@ def test_fork_already_exists(self, branch: str = "") -> None: @responses.activate def test_fork_name_already_taken(self, branch: str = "") -> None: """Test push to bitbucket cloud with HTTP repo link.""" - self.repo.component.repo = "git@bitbucket.org:WeblateOrg/test.git" responses.add( responses.POST, "https://api.bitbucket.org/2.0/repositories/WeblateOrg/test/forks", @@ -2613,7 +2559,6 @@ def test_fork_name_already_taken(self, branch: str = "") -> None: @responses.activate def test_fork_error(self, branch: str = "") -> None: """Test push to bitbucket cloud with HTTP repo link.""" - self.repo.component.repo = "git@bitbucket.org:WeblateOrg/test.git" self.mock_responses() responses.replace( responses.POST, From df6d1626df57c63e342986e7d8da6e9f7ff32f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Fri, 9 Jan 2026 07:56:01 +0100 Subject: [PATCH 19/19] tests: avoid setting override if not needed --- weblate/vcs/tests/test_vcs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/weblate/vcs/tests/test_vcs.py b/weblate/vcs/tests/test_vcs.py index 93f875d23e6e..e298369e1191 100644 --- a/weblate/vcs/tests/test_vcs.py +++ b/weblate/vcs/tests/test_vcs.py @@ -513,12 +513,13 @@ class VCSGitForcePushTest(VCSGitTest): class VCSGitUpstreamTest(VCSGitTest): - _repo_override: str + _repo_override: str = "" def setUp(self) -> None: super().setUp() # Set repo URL to match configured credentials - self.repo.component.repo = self._repo_override + if self._repo_override: + self.repo.component.repo = self._repo_override def add_remote_commit(self, conflict=False, rename=False) -> None: # Use Git to create changed upstream repo