Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for git remote set-url/get-url API to Remote #446

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions git/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,54 @@ def iter_items(cls, repo):
yield Remote(repo, section[lbound + 1:rbound])
# END for each configuration section

def set_url(self, new_url, old_url=None, **kwargs):
"""Configure URLs on current remote (cf command git remote set_url)

This command manages URLs on the remote.

:param new_url: string being the URL to add as an extra remote URL
:param old_url: when set, replaces this URL with new_url for the remote
:return: self
"""
scmd = 'set-url'
kwargs['insert_kwargs_after'] = scmd
if old_url:
self.repo.git.remote(scmd, self.name, old_url, new_url, **kwargs)
else:
self.repo.git.remote(scmd, self.name, new_url, **kwargs)
return self

def add_url(self, url, **kwargs):
"""Adds a new url on current remote (special case of git remote set_url)

This command adds new URLs to a given remote, making it possible to have
multiple URLs for a single remote.

:param url: string being the URL to add as an extra remote URL
:return: self
"""
return self.set_url(url, add=True)

def delete_url(self, url, **kwargs):
"""Deletes a new url on current remote (special case of git remote set_url)

This command deletes new URLs to a given remote, making it possible to have
multiple URLs for a single remote.

:param url: string being the URL to delete from the remote
:return: self
"""
return self.set_url(url, delete=True)

@property
def urls(self):
""":return: Iterator yielding all configured URL targets on a remote
as strings"""
remote_details = self.repo.git.remote("show", self.name)
for line in remote_details.split('\n'):
if ' Push URL:' in line:
yield line.split(': ')[-1]

@property
def refs(self):
"""
Expand Down
49 changes: 47 additions & 2 deletions git/test/test_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
with_rw_repo,
with_rw_and_rw_remote_repo,
fixture,
GIT_DAEMON_PORT
GIT_DAEMON_PORT,
assert_raises
)
from git import (
RemoteProgress,
Expand Down Expand Up @@ -62,7 +63,7 @@ def update(self, op_code, cur_count, max_count=None, message=''):
# check each stage only comes once
op_id = op_code & self.OP_MASK
assert op_id in (self.COUNTING, self.COMPRESSING, self.WRITING)

if op_code & self.WRITING > 0:
if op_code & self.BEGIN > 0:
assert not message, 'should not have message when remote begins writing'
Expand Down Expand Up @@ -568,3 +569,47 @@ def test_uncommon_branch_names(self):
assert res[0].remote_ref_path == 'refs/pull/1/head'
assert res[0].ref.path == 'refs/heads/pull/1/head'
assert isinstance(res[0].ref, Head)

@with_rw_repo('HEAD', bare=False)
def test_multiple_urls(self, rw_repo):
# test addresses
test1 = 'https://github.com/gitpython-developers/GitPython'
test2 = 'https://github.com/gitpython-developers/gitdb'
test3 = 'https://github.com/gitpython-developers/smmap'

remote = rw_repo.remotes[0]
# Testing setting a single URL
remote.set_url(test1)
assert list(remote.urls) == [test1]

# Testing replacing that single URL
remote.set_url(test1)
assert list(remote.urls) == [test1]
# Testing adding new URLs
remote.set_url(test2, add=True)
assert list(remote.urls) == [test1, test2]
remote.set_url(test3, add=True)
assert list(remote.urls) == [test1, test2, test3]
# Testing removing an URL
remote.set_url(test2, delete=True)
assert list(remote.urls) == [test1, test3]
# Testing changing an URL
remote.set_url(test3, test2)
assert list(remote.urls) == [test1, test2]

# will raise: fatal: --add --delete doesn't make sense
assert_raises(GitCommandError, remote.set_url, test2, add=True, delete=True)

# Testing on another remote, with the add/delete URL
remote = rw_repo.create_remote('another', url=test1)
remote.add_url(test2)
assert list(remote.urls) == [test1, test2]
remote.add_url(test3)
assert list(remote.urls) == [test1, test2, test3]
# Testing removing all the URLs
remote.delete_url(test2)
assert list(remote.urls) == [test1, test3]
remote.delete_url(test1)
assert list(remote.urls) == [test3]
# will raise fatal: Will not delete all non-push URLs
assert_raises(GitCommandError, remote.delete_url, test3)