Skip to content

fix(deps): update dependency gitpython to v3.1.59 (main) - #21125

Closed
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/main-gitpython-3.x
Closed

fix(deps): update dependency gitpython to v3.1.59 (main)#21125
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/main-gitpython-3.x

Conversation

@renovate

@renovate renovate Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
GitPython ==3.1.58==3.1.59 age confidence

Release Notes

gitpython-developers/GitPython (GitPython)

v3.1.59: - Security

Compare Source

What's Changed

Full Changelog: gitpython-developers/GitPython@3.1.58...3.1.59


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added the dependencies PR: Third-party library dependencies. label Aug 10, 2026
@renovate
renovate Bot enabled auto-merge (squash) August 10, 2026 12:23
@renovate
renovate Bot force-pushed the renovate/main-gitpython-3.x branch from 1199f04 to 86b1c13 Compare August 10, 2026 12:52
@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

❌ 21 Tests Failed:

Tests completed Failed Passed Skipped
10383 21 10362 893
View the top 3 failed test(s) by shortest run time
weblate.vcs.tests.test_vcs.VCSBitbucketServerTest::test_configure_remote
Stack Traces | 0.184s run time
self = <weblate.vcs.tests.test_vcs.VCSBitbucketServerTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.vcs.tests.test_vcs.VCSGitHubTest::test_configure_remote
Stack Traces | 0.194s run time
self = <weblate.vcs.tests.test_vcs.VCSGitHubTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.vcs.tests.test_vcs.VCSBitbucketCloudTest::test_configure_remote
Stack Traces | 0.203s run time
self = <weblate.vcs.tests.test_vcs.VCSBitbucketCloudTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.vcs.tests.test_vcs.VCSGitLabTest::test_configure_remote
Stack Traces | 0.246s run time
self = <weblate.vcs.tests.test_vcs.VCSGitLabTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.vcs.tests.test_vcs.VCSGitForcePushTest::test_configure_remote
Stack Traces | 0.279s run time
self = <weblate.vcs.tests.test_vcs.VCSGitForcePushTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.vcs.tests.test_vcs.VCSPagureTest::test_configure_remote
Stack Traces | 0.281s run time
self = <weblate.vcs.tests.test_vcs.VCSPagureTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.vcs.tests.test_vcs.VCSGitTest::test_configure_remote
Stack Traces | 0.283s run time
self = <weblate.vcs.tests.test_vcs.VCSGitTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.vcs.tests.test_vcs.VCSGiteaTest::test_configure_remote
Stack Traces | 0.294s run time
self = <weblate.vcs.tests.test_vcs.VCSGiteaTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.vcs.tests.test_vcs.VCSGitUpstreamTest::test_configure_remote
Stack Traces | 0.357s run time
self = <weblate.vcs.tests.test_vcs.VCSGitUpstreamTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.vcs.tests.test_vcs.VCSGerritTest::test_push_branch_targets_gerrit_review_branch_with_options
Stack Traces | 0.361s run time
self = <weblate.vcs.tests.test_vcs.VCSGerritTest testMethod=test_push_branch_targets_gerrit_review_branch_with_options>

    def test_push_branch_targets_gerrit_review_branch_with_options(self) -> None:
        with (
            self.repo.lock,
            patch.object(self.repo, "needs_push", return_value=True) as needs_push,
            patch.object(self.repo, "execute") as execute,
        ):
            self.repo.push("review-branch%topic=l10n,hashtag=translations")
    
        needs_push.assert_called_once_with(
            "review-branch%topic=l10n,hashtag=translations"
        )
        execute.assert_called_once_with(
            [
                "review",
                "--remote",
                "gerrit",
                "--yes",
                "review-branch%topic=l10n,hashtag=translations",
            ],
            remote_op="push",
        )
>       self.assertEqual(
            self.repo.get_config("remote.gerrit.fetch"),
            "+refs/heads/review-branch:.../remotes/gerrit/review-branch",
        )
E       AssertionError: '"+refs/heads/review-branch:.../remotes/gerrit/review-branch"' != '+refs/heads/review-branch:.../remotes/gerrit/review-branch'
E       - "+refs/heads/review-branch:.../remotes/gerrit/review-branch"
E       ? -                                                           -
E       + +refs/heads/review-branch:.../remotes/gerrit/review-branch

.../vcs/tests/test_vcs.py:4787: AssertionError
weblate.vcs.tests.test_vcs.VCSAzureDevOpsTest::test_configure_remote
Stack Traces | 0.388s run time
self = <weblate.vcs.tests.test_vcs.VCSAzureDevOpsTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.vcs.tests.test_vcs.VCSGerritTest::test_push_branch_targets_gerrit_review_branch
Stack Traces | 0.397s run time
self = <weblate.vcs.tests.test_vcs.VCSGerritTest testMethod=test_push_branch_targets_gerrit_review_branch>

    def test_push_branch_targets_gerrit_review_branch(self) -> None:
        with (
            self.repo.lock,
            patch.object(self.repo, "needs_push", return_value=True) as needs_push,
            patch.object(self.repo, "execute") as execute,
        ):
            self.repo.push("review-branch")
    
        needs_push.assert_called_once_with("review-branch")
        execute.assert_called_once_with(
            ["review", "--remote", "gerrit", "--yes", "review-branch"],
            remote_op="push",
        )
>       self.assertEqual(
            self.repo.get_config("remote.gerrit.fetch"),
            "+refs/heads/review-branch:.../remotes/gerrit/review-branch",
        )
E       AssertionError: '"+refs/heads/review-branch:.../remotes/gerrit/review-branch"' != '+refs/heads/review-branch:.../remotes/gerrit/review-branch'
E       - "+refs/heads/review-branch:.../remotes/gerrit/review-branch"
E       ? -                                                           -
E       + +refs/heads/review-branch:.../remotes/gerrit/review-branch

.../vcs/tests/test_vcs.py:4761: AssertionError
weblate.vcs.tests.test_vcs.VCSGerritTest::test_configure_remote_sets_gerrit_fetch
Stack Traces | 0.44s run time
self = <weblate.vcs.tests.test_vcs.VCSGerritTest testMethod=test_configure_remote_sets_gerrit_fetch>

    def test_configure_remote_sets_gerrit_fetch(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote(
                "pullurl", "ssh://sshuser@domain.com:29418/repo.git", "branch"
            )
>           self.assertEqual(
                self.repo.get_config("remote.gerrit.fetch"),
                "+refs/heads/branch:.../remotes/gerrit/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/gerrit/branch"' != '+refs/heads/branch:.../remotes/gerrit/branch'
E           - "+refs/heads/branch:.../remotes/gerrit/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/gerrit/branch

.../vcs/tests/test_vcs.py:4729: AssertionError
weblate.vcs.tests.test_vcs.VCSGerritTest::test_branch_targets_gerrit_review_branch_with_options
Stack Traces | 0.552s run time
self = <weblate.vcs.tests.test_vcs.VCSGerritTest testMethod=test_branch_targets_gerrit_review_branch_with_options>

    def test_branch_targets_gerrit_review_branch_with_options(self) -> None:
        self.repo.branch = "review-branch%topic=l10n,hashtag=translations"
    
        with (
            self.repo.lock,
            patch.object(self.repo, "needs_push", return_value=True) as needs_push,
            patch.object(self.repo, "execute") as execute,
        ):
            self.repo.push("")
    
        needs_push.assert_called_once_with("")
        execute.assert_called_once_with(
            [
                "review",
                "--remote",
                "gerrit",
                "--yes",
                "review-branch%topic=l10n,hashtag=translations",
            ],
            remote_op="push",
        )
>       self.assertEqual(
            self.repo.get_config("remote.gerrit.fetch"),
            "+refs/heads/review-branch:.../remotes/gerrit/review-branch",
        )
E       AssertionError: '"+refs/heads/review-branch:.../remotes/gerrit/review-branch"' != '+refs/heads/review-branch:.../remotes/gerrit/review-branch'
E       - "+refs/heads/review-branch:.../remotes/gerrit/review-branch"
E       ? -                                                           -
E       + +refs/heads/review-branch:.../remotes/gerrit/review-branch

.../vcs/tests/test_vcs.py:4813: AssertionError
weblate.vcs.tests.test_vcs.VCSGerritTest::test_configure_remote
Stack Traces | 0.555s run time
self = <weblate.vcs.tests.test_vcs.VCSGerritTest testMethod=test_configure_remote>

    def test_configure_remote(self) -> None:
        with self.repo.lock:
            self.repo.configure_remote("pullurl", "pushurl", "branch")
            self.assertEqual(self.repo.get_config("remote.origin.url"), "pullurl")
            if self._sets_push:
                self.assertEqual(
                    self.repo.get_config("remote.origin.pushURL"), "pushurl"
                )
            # Test that we handle not set fetching
            self.repo.execute(
                ["config", "--unset", "remote.origin.fetch"],
                remote_op="none",
            )
            self.repo.configure_remote("pullurl", "pushurl", "branch")
>           self.assertEqual(
                self.repo.get_config("remote.origin.fetch"),
                "+refs/heads/branch:.../remotes/origin/branch",
            )
E           AssertionError: '"+refs/heads/branch:.../remotes/origin/branch"' != '+refs/heads/branch:.../remotes/origin/branch'
E           - "+refs/heads/branch:.../remotes/origin/branch"
E           ? -                                             -
E           + +refs/heads/branch:.../remotes/origin/branch

.../vcs/tests/test_vcs.py:2777: AssertionError
weblate.trans.tests.test_manage.RenameTest::test_rename_project
Stack Traces | 1.23s run time
self = <weblate.trans.tests.test_manage.RenameTest testMethod=test_rename_project>

    def test_rename_project(self) -> None:
        # Remove stale dir from previous tests
        target = os.path.join(data_dir("vcs"), "xxxx")
        if os.path.exists(target):
            remove_tree(target)
        self.make_manager()
        self.assertContains(
            self.client.get(self.project.get_absolute_url()), "#organize"
        )
        response = self.client.post(
            reverse("rename", kwargs={"path": self.project.get_url_path()}),
            {"slug": "xxxx", "name": self.project.name},
        )
        self.assertRedirects(response, "/projects/xxxx/")
        project = Project.objects.get(pk=self.project.pk)
        self.assertEqual(project.slug, "xxxx")
        self.assertEqual(
            project.change_set.get(action=ActionEvents.RENAME_PROJECT).user, self.user
        )
        for component in project.component_set.iterator():
>           self.assertIsNotNone(component.repository.last_remote_revision)
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.../trans/tests/test_manage.py:672: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.14.../django/utils/functional.py:47: in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
weblate/vcs/base.py:1097: in last_remote_revision
    return self.execute(
weblate/vcs/base.py:1048: in execute
    self.last_output = self._popen(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = <class 'weblate.vcs.git.GitRepository'>
args = ['log', '-n', '1', '--format=format:%H', '@{upstream}', '--']
cwd = '.../vcs/xxxx/test'
merge_err = False, fullcmd = False, raw = False, local = False, stdin = None
environment = None, retry = True

    @classmethod
    def _popen(
        cls,
        args: list[str],
        *,
        cwd: str | None = None,
        merge_err: bool = True,
        fullcmd: bool = False,
        raw: bool = False,
        local: bool = False,
        stdin: str | None = None,
        environment: dict[str, str] | None = None,
        retry: bool = True,
    ):
        """Execute the command using popen."""
        if args is None:
            raise RepositoryError(0, "Not supported functionality")
        cmd = args if fullcmd else [cls._cmd, *args]
        text_cmd = " ".join(cmd)
        # These are mutually exclusive, gevent actually checks
        # for their presence, not a value.
        kwargs: SubprocessArgs = {}
        if stdin is None:
            kwargs["stdin"] = subprocess.PIPE
        else:
            kwargs["input"] = stdin
    
        try:
            process = subprocess.run(
                args=cmd,
                cwd=cwd,
                env=environment or {} if local else cls._getenv(environment, cwd=cwd),
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT if merge_err else subprocess.PIPE,
                text=not raw,
                check=False,
                # Excessively long timeout to catch misbehaving processes
                timeout=3600,
                **kwargs,
            )
        except OSError as error:
            if cwd is None or error.filename != cwd:
                raise
            raise RepositoryCommandError(
                error.errno or 1, cls.sanitize_error_message(str(error))
            ) from error
        except subprocess.TimeoutExpired as error:
            stdout = (
                error.stdout.decode()
                if isinstance(error.stdout, bytes)
                else error.stdout
            )
            stderr = (
                error.stderr.decode()
                if isinstance(error.stderr, bytes)
                else error.stderr
            )
            raise RepositoryCommandError(
                0,
                f"Subprocess didn't complete before {error.timeout} seconds\n{stdout}{stderr or ''}",
            ) from error
        cls.add_breadcrumb(
            text_cmd,
            retcode=process.returncode,
            output=process.stdout,
            stderr=process.stderr,
            cwd=cwd,
        )
        if process.returncode:
            errormessage: str = cls.sanitize_error_message(
                process.stdout + (process.stderr or "")
            )
            if retry and cls.should_retry_popen(errormessage):
                return cls._popen(
                    args,
                    cwd=cwd,
                    merge_err=merge_err,
                    fullcmd=fullcmd,
                    raw=raw,
                    local=local,
                    stdin=stdin,
                    environment=environment,
                    retry=False,
                )
    
>           raise RepositoryCommandError(process.returncode, errormessage)
E           weblate.vcs.base.RepositoryCommandError: fatal: upstream branch '"refs/heads/main"' not stored as a remote-tracking branch
E            (128)

weblate/vcs/base.py:980: RepositoryCommandError
weblate.vcs.tests.test_vcs.VCSGerritTest::test_push_commit
Stack Traces | 1.39s run time
self = <weblate.vcs.tests.test_vcs.VCSGerritTest testMethod=test_push_commit>

    def test_push_commit(self) -> None:
        self.test_commit()
>       self.test_push()

.../vcs/tests/test_vcs.py:2349: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../vcs/tests/test_vcs.py:2310: in test_push
    self.repo.push(branch)
weblate/vcs/git.py:1740: in push
    self.execute(
weblate/vcs/base.py:1048: in execute
    self.last_output = self._popen(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = <class 'weblate.vcs.git.GitWithGerritRepository'>
args = ['review', '--remote', 'gerrit', '--yes', 'main']
cwd = '.../djsxfhc17x95674wsm_g8s980000gn/T/tmpcbp7evjjweblate'
merge_err = True, fullcmd = False, raw = False, local = False, stdin = None
environment = None, retry = True

    @classmethod
    def _popen(
        cls,
        args: list[str],
        *,
        cwd: str | None = None,
        merge_err: bool = True,
        fullcmd: bool = False,
        raw: bool = False,
        local: bool = False,
        stdin: str | None = None,
        environment: dict[str, str] | None = None,
        retry: bool = True,
    ):
        """Execute the command using popen."""
        if args is None:
            raise RepositoryError(0, "Not supported functionality")
        cmd = args if fullcmd else [cls._cmd, *args]
        text_cmd = " ".join(cmd)
        # These are mutually exclusive, gevent actually checks
        # for their presence, not a value.
        kwargs: SubprocessArgs = {}
        if stdin is None:
            kwargs["stdin"] = subprocess.PIPE
        else:
            kwargs["input"] = stdin
    
        try:
            process = subprocess.run(
                args=cmd,
                cwd=cwd,
                env=environment or {} if local else cls._getenv(environment, cwd=cwd),
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT if merge_err else subprocess.PIPE,
                text=not raw,
                check=False,
                # Excessively long timeout to catch misbehaving processes
                timeout=3600,
                **kwargs,
            )
        except OSError as error:
            if cwd is None or error.filename != cwd:
                raise
            raise RepositoryCommandError(
                error.errno or 1, cls.sanitize_error_message(str(error))
            ) from error
        except subprocess.TimeoutExpired as error:
            stdout = (
                error.stdout.decode()
                if isinstance(error.stdout, bytes)
                else error.stdout
            )
            stderr = (
                error.stderr.decode()
                if isinstance(error.stderr, bytes)
                else error.stderr
            )
            raise RepositoryCommandError(
                0,
                f"Subprocess didn't complete before {error.timeout} seconds\n{stdout}{stderr or ''}",
            ) from error
        cls.add_breadcrumb(
            text_cmd,
            retcode=process.returncode,
            output=process.stdout,
            stderr=process.stderr,
            cwd=cwd,
        )
        if process.returncode:
            errormessage: str = cls.sanitize_error_message(
                process.stdout + (process.stderr or "")
            )
            if retry and cls.should_retry_popen(errormessage):
                return cls._popen(
                    args,
                    cwd=cwd,
                    merge_err=merge_err,
                    fullcmd=fullcmd,
                    raw=raw,
                    local=local,
                    stdin=stdin,
                    environment=environment,
                    retry=False,
                )
    
>           raise RepositoryCommandError(process.returncode, errormessage)
E           weblate.vcs.base.RepositoryCommandError: Problem running 'git remote update gerrit'
E           Fetching gerrit
E           fatal: couldn't find remote ref "+refs/heads/main
E           error: could not fetch gerrit
E           Problem running 'git remote update gerrit'
E           Fetching gerrit
E           fatal: couldn't find remote ref "+refs/heads/main
E           error: could not fetch gerrit
E           Errors running git rebase --abort
E           fatal: no rebase in progress
E            (1)

weblate/vcs/base.py:980: RepositoryCommandError
weblate.vcs.tests.test_vcs.VCSGerritTest::test_push_branch
Stack Traces | 1.4s run time
self = <weblate.vcs.tests.test_vcs.VCSGerritTest testMethod=test_push_branch>

    def test_push_branch(self) -> None:
        self.test_commit()
>       self.test_push("translations")

.../vcs/tests/test_vcs.py:4838: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../vcs/tests/test_vcs.py:2310: in test_push
    self.repo.push(branch)
weblate/vcs/git.py:1740: in push
    self.execute(
weblate/vcs/base.py:1048: in execute
    self.last_output = self._popen(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = <class 'weblate.vcs.git.GitWithGerritRepository'>
args = ['review', '--remote', 'gerrit', '--yes', 'translations']
cwd = '.../djsxfhc17x95674wsm_g8s980000gn/T/tmplzulhdgnweblate'
merge_err = True, fullcmd = False, raw = False, local = False, stdin = None
environment = None, retry = True

    @classmethod
    def _popen(
        cls,
        args: list[str],
        *,
        cwd: str | None = None,
        merge_err: bool = True,
        fullcmd: bool = False,
        raw: bool = False,
        local: bool = False,
        stdin: str | None = None,
        environment: dict[str, str] | None = None,
        retry: bool = True,
    ):
        """Execute the command using popen."""
        if args is None:
            raise RepositoryError(0, "Not supported functionality")
        cmd = args if fullcmd else [cls._cmd, *args]
        text_cmd = " ".join(cmd)
        # These are mutually exclusive, gevent actually checks
        # for their presence, not a value.
        kwargs: SubprocessArgs = {}
        if stdin is None:
            kwargs["stdin"] = subprocess.PIPE
        else:
            kwargs["input"] = stdin
    
        try:
            process = subprocess.run(
                args=cmd,
                cwd=cwd,
                env=environment or {} if local else cls._getenv(environment, cwd=cwd),
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT if merge_err else subprocess.PIPE,
                text=not raw,
                check=False,
                # Excessively long timeout to catch misbehaving processes
                timeout=3600,
                **kwargs,
            )
        except OSError as error:
            if cwd is None or error.filename != cwd:
                raise
            raise RepositoryCommandError(
                error.errno or 1, cls.sanitize_error_message(str(error))
            ) from error
        except subprocess.TimeoutExpired as error:
            stdout = (
                error.stdout.decode()
                if isinstance(error.stdout, bytes)
                else error.stdout
            )
            stderr = (
                error.stderr.decode()
                if isinstance(error.stderr, bytes)
                else error.stderr
            )
            raise RepositoryCommandError(
                0,
                f"Subprocess didn't complete before {error.timeout} seconds\n{stdout}{stderr or ''}",
            ) from error
        cls.add_breadcrumb(
            text_cmd,
            retcode=process.returncode,
            output=process.stdout,
            stderr=process.stderr,
            cwd=cwd,
        )
        if process.returncode:
            errormessage: str = cls.sanitize_error_message(
                process.stdout + (process.stderr or "")
            )
            if retry and cls.should_retry_popen(errormessage):
                return cls._popen(
                    args,
                    cwd=cwd,
                    merge_err=merge_err,
                    fullcmd=fullcmd,
                    raw=raw,
                    local=local,
                    stdin=stdin,
                    environment=environment,
                    retry=False,
                )
    
>           raise RepositoryCommandError(process.returncode, errormessage)
E           weblate.vcs.base.RepositoryCommandError: Problem running 'git remote update gerrit'
E           Fetching gerrit
E           fatal: couldn't find remote ref "+refs/heads/translations
E           error: could not fetch gerrit
E           Problem running 'git remote update gerrit'
E           Fetching gerrit
E           fatal: couldn't find remote ref "+refs/heads/translations
E           error: could not fetch gerrit
E           Errors running git rebase --abort
E           fatal: no rebase in progress
E            (1)

weblate/vcs/base.py:980: RepositoryCommandError
weblate.trans.tests.test_manage.RenameTest::test_rename_component
Stack Traces | 1.4s run time
self = <weblate.trans.tests.test_manage.RenameTest testMethod=test_rename_component>

    def test_rename_component(self) -> None:
        self.make_manager()
        original_url = self.component.get_absolute_url()
        self.assertContains(self.client.get(original_url), "#organize")
        response = self.client.post(
            reverse("rename", kwargs=self.kw_component),
            {"project": self.project.pk, "slug": "xxxx", "name": self.component.name},
        )
        self.assertRedirects(response, ".../projects/test/xxxx/")
        component = Component.objects.get(pk=self.component.pk)
        self.assertEqual(component.slug, "xxxx")
        self.assertEqual(
            component.change_set.get(action=ActionEvents.RENAME_COMPONENT).user,
            self.user,
        )
>       self.assertIsNotNone(component.repository.last_remote_revision)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.../trans/tests/test_manage.py:270: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.14.../django/utils/functional.py:47: in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
weblate/vcs/base.py:1097: in last_remote_revision
    return self.execute(
weblate/vcs/base.py:1048: in execute
    self.last_output = self._popen(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = <class 'weblate.vcs.git.GitRepository'>
args = ['log', '-n', '1', '--format=format:%H', '@{upstream}', '--']
cwd = '.../vcs/test/xxxx'
merge_err = False, fullcmd = False, raw = False, local = False, stdin = None
environment = None, retry = True

    @classmethod
    def _popen(
        cls,
        args: list[str],
        *,
        cwd: str | None = None,
        merge_err: bool = True,
        fullcmd: bool = False,
        raw: bool = False,
        local: bool = False,
        stdin: str | None = None,
        environment: dict[str, str] | None = None,
        retry: bool = True,
    ):
        """Execute the command using popen."""
        if args is None:
            raise RepositoryError(0, "Not supported functionality")
        cmd = args if fullcmd else [cls._cmd, *args]
        text_cmd = " ".join(cmd)
        # These are mutually exclusive, gevent actually checks
        # for their presence, not a value.
        kwargs: SubprocessArgs = {}
        if stdin is None:
            kwargs["stdin"] = subprocess.PIPE
        else:
            kwargs["input"] = stdin
    
        try:
            process = subprocess.run(
                args=cmd,
                cwd=cwd,
                env=environment or {} if local else cls._getenv(environment, cwd=cwd),
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT if merge_err else subprocess.PIPE,
                text=not raw,
                check=False,
                # Excessively long timeout to catch misbehaving processes
                timeout=3600,
                **kwargs,
            )
        except OSError as error:
            if cwd is None or error.filename != cwd:
                raise
            raise RepositoryCommandError(
                error.errno or 1, cls.sanitize_error_message(str(error))
            ) from error
        except subprocess.TimeoutExpired as error:
            stdout = (
                error.stdout.decode()
                if isinstance(error.stdout, bytes)
                else error.stdout
            )
            stderr = (
                error.stderr.decode()
                if isinstance(error.stderr, bytes)
                else error.stderr
            )
            raise RepositoryCommandError(
                0,
                f"Subprocess didn't complete before {error.timeout} seconds\n{stdout}{stderr or ''}",
            ) from error
        cls.add_breadcrumb(
            text_cmd,
            retcode=process.returncode,
            output=process.stdout,
            stderr=process.stderr,
            cwd=cwd,
        )
        if process.returncode:
            errormessage: str = cls.sanitize_error_message(
                process.stdout + (process.stderr or "")
            )
            if retry and cls.should_retry_popen(errormessage):
                return cls._popen(
                    args,
                    cwd=cwd,
                    merge_err=merge_err,
                    fullcmd=fullcmd,
                    raw=raw,
                    local=local,
                    stdin=stdin,
                    environment=environment,
                    retry=False,
                )
    
>           raise RepositoryCommandError(process.returncode, errormessage)
E           weblate.vcs.base.RepositoryCommandError: fatal: upstream branch '"refs/heads/main"' not stored as a remote-tracking branch
E            (128)

weblate/vcs/base.py:980: RepositoryCommandError
weblate.trans.tests.test_manage.RenameTest::test_move_component
Stack Traces | 1.49s run time
self = <weblate.trans.tests.test_manage.RenameTest testMethod=test_move_component>

    def test_move_component(self) -> None:
        self.make_manager()
        other = Project.objects.create(name="Other project", slug="other")
        # Other project should be visible as target for moving
        self.assertContains(
            self.client.get(self.component.get_absolute_url()),
            "Other project",
        )
        response = self.client.post(
            reverse("rename", kwargs=self.kw_component),
            {
                "project": other.pk,
                "slug": self.component.slug,
                "name": self.component.name,
            },
        )
        self.assertRedirects(response, ".../projects/other/test/")
        component = Component.objects.get(pk=self.component.pk)
        self.assertEqual(component.project.slug, "other")
>       self.assertIsNotNone(component.repository.last_remote_revision)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.../trans/tests/test_manage.py:237: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.14.../django/utils/functional.py:47: in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
weblate/vcs/base.py:1097: in last_remote_revision
    return self.execute(
weblate/vcs/base.py:1048: in execute
    self.last_output = self._popen(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = <class 'weblate.vcs.git.GitRepository'>
args = ['log', '-n', '1', '--format=format:%H', '@{upstream}', '--']
cwd = '.../vcs/other/test'
merge_err = False, fullcmd = False, raw = False, local = False, stdin = None
environment = None, retry = True

    @classmethod
    def _popen(
        cls,
        args: list[str],
        *,
        cwd: str | None = None,
        merge_err: bool = True,
        fullcmd: bool = False,
        raw: bool = False,
        local: bool = False,
        stdin: str | None = None,
        environment: dict[str, str] | None = None,
        retry: bool = True,
    ):
        """Execute the command using popen."""
        if args is None:
            raise RepositoryError(0, "Not supported functionality")
        cmd = args if fullcmd else [cls._cmd, *args]
        text_cmd = " ".join(cmd)
        # These are mutually exclusive, gevent actually checks
        # for their presence, not a value.
        kwargs: SubprocessArgs = {}
        if stdin is None:
            kwargs["stdin"] = subprocess.PIPE
        else:
            kwargs["input"] = stdin
    
        try:
            process = subprocess.run(
                args=cmd,
                cwd=cwd,
                env=environment or {} if local else cls._getenv(environment, cwd=cwd),
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT if merge_err else subprocess.PIPE,
                text=not raw,
                check=False,
                # Excessively long timeout to catch misbehaving processes
                timeout=3600,
                **kwargs,
            )
        except OSError as error:
            if cwd is None or error.filename != cwd:
                raise
            raise RepositoryCommandError(
                error.errno or 1, cls.sanitize_error_message(str(error))
            ) from error
        except subprocess.TimeoutExpired as error:
            stdout = (
                error.stdout.decode()
                if isinstance(error.stdout, bytes)
                else error.stdout
            )
            stderr = (
                error.stderr.decode()
                if isinstance(error.stderr, bytes)
                else error.stderr
            )
            raise RepositoryCommandError(
                0,
                f"Subprocess didn't complete before {error.timeout} seconds\n{stdout}{stderr or ''}",
            ) from error
        cls.add_breadcrumb(
            text_cmd,
            retcode=process.returncode,
            output=process.stdout,
            stderr=process.stderr,
            cwd=cwd,
        )
        if process.returncode:
            errormessage: str = cls.sanitize_error_message(
                process.stdout + (process.stderr or "")
            )
            if retry and cls.should_retry_popen(errormessage):
                return cls._popen(
                    args,
                    cwd=cwd,
                    merge_err=merge_err,
                    fullcmd=fullcmd,
                    raw=raw,
                    local=local,
                    stdin=stdin,
                    environment=environment,
                    retry=False,
                )
    
>           raise RepositoryCommandError(process.returncode, errormessage)
E           weblate.vcs.base.RepositoryCommandError: fatal: upstream branch '"refs/heads/main"' not stored as a remote-tracking branch
E            (128)

weblate/vcs/base.py:980: RepositoryCommandError
weblate.trans.tests.test_backups.BackupsTest::test_restore_skips_unsafe_vcs_files
Stack Traces | 3.58s run time
self = <weblate.trans.tests.test_backups.BackupsTest testMethod=test_restore_skips_unsafe_vcs_files>

    def test_restore_skips_unsafe_vcs_files(self) -> None:
        backup = ProjectBackup()
        backup.backup_project(self.project)
        marker = Path(settings.DATA_DIR) / "PWNED_COMMONDIR"
        marker.unlink(missing_ok=True)
        self.addCleanup(marker.unlink, missing_ok=True)
        unsafe_paths = {
            ".git/commondir": b"evil\n",
            ".git/evil/config": (
                b'[filter "pwn"]\n'
                + f"clean = touch {marker.as_posix()}\n".encode()
                + b"required = true\n"
            ),
            "..../evil/info/attributes": b"* filter=pwn\n",
            ".git/hooks/post-checkout": b"unsafe",
            ".git/info/attributes": b"unsafe",
            "..../modules/submodule/config": b"unsafe",
            "..../objects/info/alternates": b"evil/objects\n",
            "..../worktrees/evil/config": b"unsafe",
            ".hg/hgrc": b"unsafe",
            ".hg/sharedpath": b"unsafe",
            ".GIT/HOOKS/pre-commit": b"unsafe",
            ".GiT/CONFIG": b"unsafe",
        }
    
        with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as temp_handle:
            temp_name = temp_handle.name
    
        with remove_file_after(temp_name):
            with (
                ZipFile(backup.filename, "r") as source_zip,
                ZipFile(temp_name, "w") as target_zip,
            ):
                for item in source_zip.infolist():
                    data = source_zip.read(item.filename)
                    target_zip.writestr(item, data)
                    git_prefix = "vcs/test/.git/"
                    if (
                        item.filename.startswith(
                            (f"{git_prefix}objects/", f"{git_prefix}refs/")
                        )
                        or item.filename == f"{git_prefix}packed-refs"
                    ):
                        relative_path = item.filename.removeprefix(git_prefix)
                        target_zip.writestr(f"{git_prefix}evil/{relative_path}", data)
                for path, data in unsafe_paths.items():
                    target_zip.writestr(f"vcs/test/{path}", data)
    
            restore = ProjectBackup(temp_name)
            restore.validate()
            restored = restore.restore(
                project_name="Restored", project_slug="restored", user=self.user
            )
            component = restored.component_set.get(slug="test")
            repository = component.repository
            assert isinstance(repository, GitRepository)
            for path, payload in unsafe_paths.items():
                with self.subTest(path=path):
                    restored_path = os.path.join(component.full_path, path)
                    if os.path.exists(restored_path):
                        # On case-insensitive filesystems, a mixed-case path can
                        # resolve to the legitimate .git/config from the backup.
                        self.assertNotEqual(Path(restored_path).read_bytes(), payload)
            with repository.lock:
                common_dir = Path(
                    repository.execute(
                        ["rev-parse", "--git-common-dir"], remote_op="none"
                    ).strip()
                )
                if not common_dir.is_absolute():
                    common_dir = Path(component.full_path) / common_dir
                self.assertEqual(
                    common_dir.resolve(),
                    (Path(component.full_path) / ".git").resolve(),
                )
            self.assertEqual(repository.get_config("remote.origin.url"), component.repo)
            self.assertEqual(
                repository.get_config(f"branch.{component.branch}.remote"),
                "origin",
            )
>           self.assertEqual(
                repository.get_config(f"branch.{component.branch}.merge"),
                f"refs/heads/{component.branch}",
            )
E           AssertionError: '"refs/heads/main"' != 'refs/heads/main'
E           - "refs/heads/main"
E           ? -               -
E           + refs/heads/main

.../trans/tests/test_backups.py:1817: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@renovate
renovate Bot force-pushed the renovate/main-gitpython-3.x branch 3 times, most recently from d892347 to 1609db4 Compare August 10, 2026 22:29
@nijel

nijel commented Aug 11, 2026

Copy link
Copy Markdown
Member

We need to remove json.dumps here, but this cannot be done before gitpython-developers/GitPython#2214 is fixed.

@renovate
renovate Bot force-pushed the renovate/main-gitpython-3.x branch 19 times, most recently from 9aca6f6 to dd1f798 Compare August 14, 2026 13:41
@renovate
renovate Bot force-pushed the renovate/main-gitpython-3.x branch from dd1f798 to 4d5249b Compare August 14, 2026 14:52
@nijel nijel closed this Aug 14, 2026
auto-merge was automatically disabled August 14, 2026 14:52

Pull request was closed

@renovate

renovate Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Renovate Ignore Notification

Because you closed this PR without merging, Renovate will ignore this update (==3.1.59). You will get a PR once a newer version is released. To ignore this dependency forever, add it to the ignoreDeps array of your Renovate config.

If you accidentally closed this PR, or if you changed your mind: rename this PR to get a fresh replacement PR.

@renovate
renovate Bot deleted the renovate/main-gitpython-3.x branch August 14, 2026 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies PR: Third-party library dependencies.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant