diff --git a/include/git2/remote.h b/include/git2/remote.h index e81e25f98..856da3b6b 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -218,6 +218,16 @@ GIT_EXTERN(int) git_remote_supported_url(const char* url); */ GIT_EXTERN(int) git_remote_list(git_strarray *remotes_list, git_repository *repo); +/** + * Add a remote with the default fetch refspec to the repository's configuration + * + * @param out the resulting remote + * @param repo the repository in which to create the remote + * @param name the remote's name + * @param url the remote's url + */ +GIT_EXTERN(int) git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url); + /** @} */ GIT_END_DECL #endif diff --git a/src/remote.c b/src/remote.c index 6a1390dba..3678d3475 100644 --- a/src/remote.c +++ b/src/remote.c @@ -476,3 +476,28 @@ int git_remote_list(git_strarray *remotes_list, git_repository *repo) return 0; } + +int git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url) +{ + git_buf buf = GIT_BUF_INIT; + if (git_remote_new(out, repo, url, name) < 0) + return -1; + + if (git_buf_printf(&buf, "refs/heads/*:refs/remotes/%s/*", name) < 0) + goto on_error; + + if (git_remote_set_fetchspec(*out, git_buf_cstr(&buf)) < 0) + goto on_error; + + git_buf_free(&buf); + + if (git_remote_save(*out) < 0) + return -1; + + return 0; + +on_error: + git_buf_free(&buf); + git_remote_free(*out); + return -1; +} diff --git a/tests-clar/network/remotes.c b/tests-clar/network/remotes.c index f03d983c3..608f09a27 100644 --- a/tests-clar/network/remotes.c +++ b/tests-clar/network/remotes.c @@ -158,3 +158,15 @@ void test_network_remotes__loading_a_missing_remote_returns_ENOTFOUND(void) { cl_assert_equal_i(GIT_ENOTFOUND, git_remote_load(&_remote, _repo, "just-left-few-minutes-ago")); } + +void test_network_remotes__add(void) +{ + git_remote_free(_remote); + cl_git_pass(git_remote_add(&_remote, _repo, "addtest", "http://github.com/libgit2/libgit2")); + git_remote_free(_remote); + + cl_git_pass(git_remote_load(&_remote, _repo, "addtest")); + _refspec = git_remote_fetchspec(_remote); + cl_assert(!strcmp(git_refspec_src(_refspec), "refs/heads/*")); + cl_assert(!strcmp(git_refspec_dst(_refspec), "refs/remotes/addtest/*")); +}