Commit 67240677 by Edward Thomson

remote: introduce set_instance_url

Users may want to override the URL on a particular instance of a remote,
instead of updating the configuration.  Previously, users could use a
callback to do this, but this is not particularly idiomatic.
parent 45489a11
......@@ -212,7 +212,8 @@ GIT_EXTERN(const char *) git_remote_name(const git_remote *remote);
* Get the remote's url
*
* If url.*.insteadOf has been configured for this URL, it will
* return the modified URL.
* return the modified URL. If `git_remote_set_instance_pushurl`
* has been called for this remote, then that URL will be returned.
*
* @param remote the remote
* @return a pointer to the url
......@@ -220,10 +221,11 @@ GIT_EXTERN(const char *) git_remote_name(const git_remote *remote);
GIT_EXTERN(const char *) git_remote_url(const git_remote *remote);
/**
* Get the remote's url for pushing
* Get the remote's url for pushing.
*
* If url.*.pushInsteadOf has been configured for this URL, it
* will return the modified URL.
* will return the modified URL. If `git_remote_set_instance_pushurl`
* has been called for this remote, then that URL will be returned.
*
* @param remote the remote
* @return a pointer to the url or NULL if no special url for pushing is set
......@@ -258,6 +260,26 @@ GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, con
GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url);
/**
* Set the url for this particular url instance. The URL in the
* configuration will be ignored, and will not be changed.
*
* @param remote the remote's name
* @param url the url to set
* @return 0 or an error value
*/
GIT_EXTERN(int) git_remote_set_instance_url(git_remote *remote, const char *url);
/**
* Set the push url for this particular url instance. The URL in the
* configuration will be ignored, and will not be changed.
*
* @param remote the remote's name
* @param url the url to set
* @return 0 or an error value
*/
GIT_EXTERN(int) git_remote_set_instance_pushurl(git_remote *remote, const char *url);
/**
* Add a fetch refspec to the remote's configuration
*
* Add the given refspec to the fetch list in the configuration. No
......
......@@ -600,6 +600,22 @@ const char *git_remote_url(const git_remote *remote)
return remote->url;
}
int git_remote_set_instance_url(git_remote *remote, const char *url)
{
char *tmp;
GIT_ASSERT_ARG(remote);
GIT_ASSERT_ARG(url);
if ((tmp = git__strdup(url)) == NULL)
return -1;
git__free(remote->url);
remote->url = tmp;
return 0;
}
static int set_url(git_repository *repo, const char *remote, const char *pattern, const char *url)
{
git_config *cfg;
......@@ -645,6 +661,22 @@ const char *git_remote_pushurl(const git_remote *remote)
return remote->pushurl;
}
int git_remote_set_instance_pushurl(git_remote *remote, const char *url)
{
char *tmp;
GIT_ASSERT_ARG(remote);
GIT_ASSERT_ARG(url);
if ((tmp = git__strdup(url)) == NULL)
return -1;
git__free(remote->pushurl);
remote->pushurl = tmp;
return 0;
}
int git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url)
{
return set_url(repo, remote, CONFIG_PUSHURL_FMT, url);
......
......@@ -121,6 +121,51 @@ void test_network_remote_remotes__urlresolve_passthrough(void)
git_buf_dispose(&url);
}
void test_network_remote_remotes__instance_url(void)
{
git_buf url = GIT_BUF_INIT;
const char *orig_url = "git://github.com/libgit2/libgit2";
cl_assert_equal_s(git_remote_name(_remote), "test");
cl_assert_equal_s(git_remote_url(_remote), orig_url);
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, NULL));
cl_assert_equal_s(url.ptr, orig_url);
git_buf_clear(&url);
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, NULL));
cl_assert_equal_s(url.ptr, orig_url);
git_buf_clear(&url);
/* Setting the instance url updates the fetch and push URLs */
git_remote_set_instance_url(_remote, "https://github.com/new/remote/url");
cl_assert_equal_s(git_remote_url(_remote), "https://github.com/new/remote/url");
cl_assert_equal_p(git_remote_pushurl(_remote), NULL);
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, NULL));
cl_assert_equal_s(url.ptr, "https://github.com/new/remote/url");
git_buf_clear(&url);
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, NULL));
cl_assert_equal_s(url.ptr, "https://github.com/new/remote/url");
git_buf_clear(&url);
/* Setting the instance push url updates only the push URL */
git_remote_set_instance_pushurl(_remote, "https://github.com/new/push/url");
cl_assert_equal_s(git_remote_url(_remote), "https://github.com/new/remote/url");
cl_assert_equal_s(git_remote_pushurl(_remote), "https://github.com/new/push/url");
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, NULL));
cl_assert_equal_s(url.ptr, "https://github.com/new/remote/url");
git_buf_clear(&url);
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, NULL));
cl_assert_equal_s(url.ptr, "https://github.com/new/push/url");
git_buf_clear(&url);
git_buf_dispose(&url);
}
void test_network_remote_remotes__pushurl(void)
{
const char *name = git_remote_name(_remote);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment