From 7cfc65177af7f2fee3af08881b0f42473db799a8 Mon Sep 17 00:00:00 2001 From: nrybowski Date: Mon, 4 Aug 2025 16:54:54 +0200 Subject: [PATCH] Instrument git_submodule_set_url. This commit adds a setter for the url property of the Submodule class. The new setter leverages 'git_submodule_set_url' from libgit2. --- pygit2/decl/submodule.h | 2 ++ pygit2/submodules.py | 8 ++++++++ test/test_submodule.py | 11 +++++++++++ 3 files changed, 21 insertions(+) diff --git a/pygit2/decl/submodule.h b/pygit2/decl/submodule.h index fda915a5..b16f4b03 100644 --- a/pygit2/decl/submodule.h +++ b/pygit2/decl/submodule.h @@ -41,3 +41,5 @@ const char * git_submodule_branch(git_submodule *submodule); const git_oid * git_submodule_head_id(git_submodule *submodule); int git_submodule_status(unsigned int *status, git_repository *repo, const char *name, git_submodule_ignore_t ignore); + +int git_submodule_set_url(git_repository *repo, const char *name, const char *url); diff --git a/pygit2/submodules.py b/pygit2/submodules.py index 46227e77..4cd036a8 100644 --- a/pygit2/submodules.py +++ b/pygit2/submodules.py @@ -152,6 +152,14 @@ def url(self) -> Union[str, None]: url = C.git_submodule_url(self._subm) return maybe_string(url) + @url.setter + def url(self, url: str) -> None: + crepo = self._repo._repo + cname = ffi.new('char[]', to_bytes(self.name)) + curl = ffi.new('char[]', to_bytes(url)) + err = C.git_submodule_set_url(crepo, cname, curl) + check_error(err) + @property def branch(self): """Branch that is to be tracked by the submodule.""" diff --git a/test/test_submodule.py b/test/test_submodule.py index 52c55b2b..453a5abf 100644 --- a/test/test_submodule.py +++ b/test/test_submodule.py @@ -124,6 +124,17 @@ def test_url(repo: Repository) -> None: assert SUBM_URL == s.url +def test_set_url(repo: Repository) -> None: + new_url = 'ssh://git@127.0.0.1:2222/my_repo' + s = repo.submodules[SUBM_PATH] + s.url = new_url + assert new_url == repo.submodules[SUBM_PATH].url + # Ensure .gitmodules has been correctly altered + with open(Path(repo.workdir, '.gitmodules'), 'r') as fd: + modules = fd.read() + assert new_url in modules + + def test_missing_url(repo: Repository) -> None: # Remove "url" from .gitmodules with open(Path(repo.workdir, '.gitmodules'), 'wt') as f: