Skip to content

Commit bde58d9

Browse files
committed
Remote: make renaming take a method call
Renaming a remote in pygit2 has been done via Remote.name= up to now, but this is inherently unsafe, as it provides no way to pass up the refspecs that libgit2 was unable to remap. In fact, if there ever was such problem, we would have segfaulted. libgit2 now provides a much more direct way of getting back the results, so expose it as the return value of Remote.rename(). This also removes the hint that a rename might be something that happens only to the in-memory structure.
1 parent 130fff6 commit bde58d9

File tree

3 files changed

+25
-13
lines changed

3 files changed

+25
-13
lines changed

pygit2/decl.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,11 @@ int git_remote_create(
116116
const char *url);
117117

118118
const char * git_remote_name(const git_remote *remote);
119-
typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload);
120-
int git_remote_rename(git_remote *remote,
121-
const char *new_name,
122-
git_remote_rename_problem_cb callback,
123-
void *payload);
119+
120+
int git_remote_rename(
121+
git_strarray *problems,
122+
git_remote *remote,
123+
const char *new_name);
124124
const char * git_remote_url(const git_remote *remote);
125125
int git_remote_set_url(git_remote *remote, const char* url);
126126
const char * git_remote_pushurl(const git_remote *remote);

pygit2/remote.py

+15-4
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,25 @@ def name(self):
142142

143143
return maybe_string(C.git_remote_name(self._remote))
144144

145-
@name.setter
146-
def name(self, value):
147-
if not value:
145+
def rename(self, new_name):
146+
"""Rename this remote
147+
148+
Returns a list of fetch refspecs which were not in the standard format
149+
and thus could not be remapped
150+
"""
151+
152+
if not new_name:
148153
raise ValueError("New remote name must be a non-empty string")
149154

150-
err = C.git_remote_rename(self._remote, to_str(value), ffi.NULL, ffi.NULL)
155+
problems = ffi.new('git_strarray *')
156+
err = C.git_remote_rename(problems, self._remote, to_str(new_name))
151157
check_error(err)
152158

159+
ret = strarray_to_strings(problems)
160+
C.git_strarray_free(problems)
161+
162+
return ret
163+
153164
@property
154165
def url(self):
155166
"""Url of the remote"""

test/test_remote.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,12 @@ def test_remote_rename(self):
6161
remote = self.repo.remotes[0]
6262

6363
self.assertEqual(REMOTE_NAME, remote.name)
64-
remote.name = 'new'
64+
problems = remote.rename('new')
65+
self.assertEqual([], problems)
6566
self.assertEqual('new', remote.name)
6667

67-
self.assertRaisesAssign(ValueError, remote, 'name', '')
68-
self.assertRaisesAssign(ValueError, remote, 'name', None)
68+
self.assertRaises(ValueError, remote.rename, '')
69+
self.assertRaises(ValueError, remote.rename, None)
6970

7071

7172
def test_remote_set_url(self):
@@ -153,7 +154,7 @@ def test_remote_list(self):
153154
def test_remote_save(self):
154155
remote = self.repo.remotes[0]
155156

156-
remote.name = 'new-name'
157+
remote.rename('new-name')
157158
remote.url = 'http://example.com/test.git'
158159

159160
remote.save()

0 commit comments

Comments
 (0)