Skip to content

Commit 9bebaca

Browse files
authored
Merge pull request #446 from guyzmo/updating_remote_url_handling
Adding support for git remote set-url/get-url API to Remote
2 parents d22c40b + 3f4b410 commit 9bebaca

File tree

2 files changed

+95
-2
lines changed

2 files changed

+95
-2
lines changed

Diff for: git/remote.py

+48
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,54 @@ def iter_items(cls, repo):
451451
yield Remote(repo, section[lbound + 1:rbound])
452452
# END for each configuration section
453453

454+
def set_url(self, new_url, old_url=None, **kwargs):
455+
"""Configure URLs on current remote (cf command git remote set_url)
456+
457+
This command manages URLs on the remote.
458+
459+
:param new_url: string being the URL to add as an extra remote URL
460+
:param old_url: when set, replaces this URL with new_url for the remote
461+
:return: self
462+
"""
463+
scmd = 'set-url'
464+
kwargs['insert_kwargs_after'] = scmd
465+
if old_url:
466+
self.repo.git.remote(scmd, self.name, old_url, new_url, **kwargs)
467+
else:
468+
self.repo.git.remote(scmd, self.name, new_url, **kwargs)
469+
return self
470+
471+
def add_url(self, url, **kwargs):
472+
"""Adds a new url on current remote (special case of git remote set_url)
473+
474+
This command adds new URLs to a given remote, making it possible to have
475+
multiple URLs for a single remote.
476+
477+
:param url: string being the URL to add as an extra remote URL
478+
:return: self
479+
"""
480+
return self.set_url(url, add=True)
481+
482+
def delete_url(self, url, **kwargs):
483+
"""Deletes a new url on current remote (special case of git remote set_url)
484+
485+
This command deletes new URLs to a given remote, making it possible to have
486+
multiple URLs for a single remote.
487+
488+
:param url: string being the URL to delete from the remote
489+
:return: self
490+
"""
491+
return self.set_url(url, delete=True)
492+
493+
@property
494+
def urls(self):
495+
""":return: Iterator yielding all configured URL targets on a remote
496+
as strings"""
497+
remote_details = self.repo.git.remote("show", self.name)
498+
for line in remote_details.split('\n'):
499+
if ' Push URL:' in line:
500+
yield line.split(': ')[-1]
501+
454502
@property
455503
def refs(self):
456504
"""

Diff for: git/test/test_remote.py

+47-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
with_rw_repo,
1010
with_rw_and_rw_remote_repo,
1111
fixture,
12-
GIT_DAEMON_PORT
12+
GIT_DAEMON_PORT,
13+
assert_raises
1314
)
1415
from git import (
1516
RemoteProgress,
@@ -62,7 +63,7 @@ def update(self, op_code, cur_count, max_count=None, message=''):
6263
# check each stage only comes once
6364
op_id = op_code & self.OP_MASK
6465
assert op_id in (self.COUNTING, self.COMPRESSING, self.WRITING)
65-
66+
6667
if op_code & self.WRITING > 0:
6768
if op_code & self.BEGIN > 0:
6869
assert not message, 'should not have message when remote begins writing'
@@ -568,3 +569,47 @@ def test_uncommon_branch_names(self):
568569
assert res[0].remote_ref_path == 'refs/pull/1/head'
569570
assert res[0].ref.path == 'refs/heads/pull/1/head'
570571
assert isinstance(res[0].ref, Head)
572+
573+
@with_rw_repo('HEAD', bare=False)
574+
def test_multiple_urls(self, rw_repo):
575+
# test addresses
576+
test1 = 'https://github.com/gitpython-developers/GitPython'
577+
test2 = 'https://github.com/gitpython-developers/gitdb'
578+
test3 = 'https://github.com/gitpython-developers/smmap'
579+
580+
remote = rw_repo.remotes[0]
581+
# Testing setting a single URL
582+
remote.set_url(test1)
583+
assert list(remote.urls) == [test1]
584+
585+
# Testing replacing that single URL
586+
remote.set_url(test1)
587+
assert list(remote.urls) == [test1]
588+
# Testing adding new URLs
589+
remote.set_url(test2, add=True)
590+
assert list(remote.urls) == [test1, test2]
591+
remote.set_url(test3, add=True)
592+
assert list(remote.urls) == [test1, test2, test3]
593+
# Testing removing an URL
594+
remote.set_url(test2, delete=True)
595+
assert list(remote.urls) == [test1, test3]
596+
# Testing changing an URL
597+
remote.set_url(test3, test2)
598+
assert list(remote.urls) == [test1, test2]
599+
600+
# will raise: fatal: --add --delete doesn't make sense
601+
assert_raises(GitCommandError, remote.set_url, test2, add=True, delete=True)
602+
603+
# Testing on another remote, with the add/delete URL
604+
remote = rw_repo.create_remote('another', url=test1)
605+
remote.add_url(test2)
606+
assert list(remote.urls) == [test1, test2]
607+
remote.add_url(test3)
608+
assert list(remote.urls) == [test1, test2, test3]
609+
# Testing removing all the URLs
610+
remote.delete_url(test2)
611+
assert list(remote.urls) == [test1, test3]
612+
remote.delete_url(test1)
613+
assert list(remote.urls) == [test3]
614+
# will raise fatal: Will not delete all non-push URLs
615+
assert_raises(GitCommandError, remote.delete_url, test3)

0 commit comments

Comments
 (0)