Commit a71c27cc by Ben Straub

Allow creation of dangling remotes

parent 6cacd44b
...@@ -43,10 +43,10 @@ typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, voi ...@@ -43,10 +43,10 @@ typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, voi
* See `git_tag_create()` for rules about valid names. * See `git_tag_create()` for rules about valid names.
* *
* @param out pointer to the new remote object * @param out pointer to the new remote object
* @param repo the associated repository * @param repo the associated repository. May be NULL for a "dangling" remote.
* @param name the optional remote's name * @param name the optional remote's name. May be NULL.
* @param url the remote repository's URL * @param url the remote repository's URL
* @param fetch the fetch refspec to use for this remote * @param fetch the fetch refspec to use for this remote. May be NULL for defaults.
* @return 0, GIT_EINVALIDSPEC or an error code * @return 0, GIT_EINVALIDSPEC or an error code
*/ */
GIT_EXTERN(int) git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch); GIT_EXTERN(int) git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch);
......
...@@ -88,7 +88,7 @@ int git_remote_new(git_remote **out, git_repository *repo, const char *name, con ...@@ -88,7 +88,7 @@ int git_remote_new(git_remote **out, git_repository *repo, const char *name, con
git_remote *remote; git_remote *remote;
/* name is optional */ /* name is optional */
assert(out && repo && url); assert(out && url);
remote = git__calloc(1, sizeof(git_remote)); remote = git__calloc(1, sizeof(git_remote));
GITERR_CHECK_ALLOC(remote); GITERR_CHECK_ALLOC(remote);
...@@ -289,6 +289,11 @@ int git_remote_save(const git_remote *remote) ...@@ -289,6 +289,11 @@ int git_remote_save(const git_remote *remote)
assert(remote); assert(remote);
if (!remote->repo) {
giterr_set(GITERR_INVALID, "Can't save a dangling remote.");
return GIT_ERROR;
}
if ((error = ensure_remote_name_is_valid(remote->name)) < 0) if ((error = ensure_remote_name_is_valid(remote->name)) < 0)
return error; return error;
...@@ -543,7 +548,7 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur ...@@ -543,7 +548,7 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur
assert(remote); assert(remote);
if (!proxy_url) if (!proxy_url || !remote->repo)
return -1; return -1;
*proxy_url = NULL; *proxy_url = NULL;
...@@ -745,6 +750,11 @@ int git_remote_update_tips(git_remote *remote) ...@@ -745,6 +750,11 @@ int git_remote_update_tips(git_remote *remote)
assert(remote); assert(remote);
if (!remote->repo) {
giterr_set(GITERR_INVALID, "Can't update tips on a dangling remote.");
return GIT_ERROR;
}
spec = &remote->fetch; spec = &remote->fetch;
if (git_repository_odb__weakptr(&odb, remote->repo) < 0) if (git_repository_odb__weakptr(&odb, remote->repo) < 0)
...@@ -1293,49 +1303,51 @@ int git_remote_rename( ...@@ -1293,49 +1303,51 @@ int git_remote_rename(
assert(remote && new_name); assert(remote && new_name);
if ((error = ensure_remote_doesnot_exist(remote->repo, new_name)) < 0)
return error;
if ((error = ensure_remote_name_is_valid(new_name)) < 0) if ((error = ensure_remote_name_is_valid(new_name)) < 0)
return error; return error;
if (!remote->name) { if (remote->repo) {
if ((error = rename_fetch_refspecs( if ((error = ensure_remote_doesnot_exist(remote->repo, new_name)) < 0)
remote,
new_name,
callback,
payload)) < 0)
return error; return error;
remote->name = git__strdup(new_name); if (!remote->name) {
if ((error = rename_fetch_refspecs(
remote,
new_name,
callback,
payload)) < 0)
return error;
return git_remote_save(remote); remote->name = git__strdup(new_name);
}
if ((error = rename_remote_config_section( return git_remote_save(remote);
remote->repo, }
remote->name,
new_name)) < 0)
return error;
if ((error = update_branch_remote_config_entry( if ((error = rename_remote_config_section(
remote->repo, remote->repo,
remote->name, remote->name,
new_name)) < 0) new_name)) < 0)
return error; return error;
if ((error = rename_remote_references( if ((error = update_branch_remote_config_entry(
remote->repo, remote->repo,
remote->name, remote->name,
new_name)) < 0) new_name)) < 0)
return error; return error;
if ((error = rename_fetch_refspecs( if ((error = rename_remote_references(
remote, remote->repo,
new_name, remote->name,
callback, new_name)) < 0)
payload)) < 0) return error;
return error;
if ((error = rename_fetch_refspecs(
remote,
new_name,
callback,
payload)) < 0)
return error;
}
git__free(remote->name); git__free(remote->name);
remote->name = git__strdup(new_name); remote->name = git__strdup(new_name);
......
...@@ -326,3 +326,13 @@ void test_network_remotes__check_structure_version(void) ...@@ -326,3 +326,13 @@ void test_network_remotes__check_structure_version(void)
err = giterr_last(); err = giterr_last();
cl_assert_equal_i(GITERR_INVALID, err->klass); cl_assert_equal_i(GITERR_INVALID, err->klass);
} }
void test_network_remotes__dangling(void)
{
cl_git_pass(git_remote_new(&_remote, NULL, "upstream", "git://github.com/libgit2/libgit2", NULL));
cl_git_fail(git_remote_save(_remote));
cl_git_fail(git_remote_update_tips(_remote));
cl_git_pass(git_remote_rename(_remote, "newname", NULL, NULL));
cl_assert_equal_s(git_remote_name(_remote), "newname");
}
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