Skip to content

Commit d7b67e4

Browse files
committed
Allow bypassing automatic connection in Remote.ls_remotes()
Remote.ls_remotes() used to force a new connection to the remote. This can be harmful if a connection was already set up for other purposes, e.g. when calling ls_remotes from RemoteCallbacks.push_negotiation. This new argument `ls_remotes(..., connect)` lets you bypass the automatic connection.
1 parent 80f815e commit d7b67e4

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

pygit2/remotes.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,10 @@ def fetch(
224224
return TransferProgress(C.git_remote_stats(self._remote))
225225

226226
def ls_remotes(
227-
self, callbacks: RemoteCallbacks | None = None, proxy: str | None | bool = None
227+
self,
228+
callbacks: RemoteCallbacks | None = None,
229+
proxy: str | None | bool = None,
230+
connect: bool = True,
228231
) -> list[LsRemotesDict]:
229232
"""
230233
Return a list of dicts that maps to `git_remote_head` from a
@@ -235,9 +238,14 @@ def ls_remotes(
235238
callbacks : Passed to connect()
236239
237240
proxy : Passed to connect()
241+
242+
connect : Whether to connect to the remote first. You can pass False
243+
if the remote has already connected. The list remains available after
244+
disconnecting as long as a new connection is not initiated.
238245
"""
239246

240-
self.connect(callbacks=callbacks, proxy=proxy)
247+
if connect:
248+
self.connect(callbacks=callbacks, proxy=proxy)
241249

242250
refs = ffi.new('git_remote_head ***')
243251
refs_len = ffi.new('size_t *')

test/test_remote.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,22 @@ def test_ls_remotes(testrepo: Repository) -> None:
204204
assert next(iter(r for r in refs if r['name'] == 'refs/tags/v0.28.2'))
205205

206206

207+
@utils.requires_network
208+
def test_ls_remotes_without_implicit_connect(testrepo: Repository) -> None:
209+
assert 1 == len(testrepo.remotes)
210+
remote = testrepo.remotes[0]
211+
212+
with pytest.raises(pygit2.GitError, match='this remote has never connected'):
213+
remote.ls_remotes(connect=False)
214+
215+
remote.connect()
216+
refs = remote.ls_remotes(connect=False)
217+
assert refs
218+
219+
# Check that a known ref is returned.
220+
assert next(iter(r for r in refs if r['name'] == 'refs/tags/v0.28.2'))
221+
222+
207223
def test_remote_collection(testrepo: Repository) -> None:
208224
remote = testrepo.remotes['origin']
209225
assert REMOTE_NAME == remote.name

0 commit comments

Comments
 (0)