Commit c9ffa84b by nulltoken

remote: Relax the parsing logic even more

In order to be loaded, a remote needs to be configured with at least a `url` or a `pushurl`.

ENOTFOUND will be returned when trying to git_remote_load() a remote with neither of these entries defined.
parent ece24ef7
...@@ -233,7 +233,8 @@ static int refspec_cb(const git_config_entry *entry, void *payload) ...@@ -233,7 +233,8 @@ static int refspec_cb(const git_config_entry *entry, void *payload)
} }
static int get_optional_config( static int get_optional_config(
git_config *config, git_buf *buf, git_config_foreach_cb cb, void *payload) bool *found, git_config *config, git_buf *buf,
git_config_foreach_cb cb, void *payload)
{ {
int error = 0; int error = 0;
const char *key = git_buf_cstr(buf); const char *key = git_buf_cstr(buf);
...@@ -246,6 +247,9 @@ static int get_optional_config( ...@@ -246,6 +247,9 @@ static int get_optional_config(
else else
error = git_config_get_string(payload, config, key); error = git_config_get_string(payload, config, key);
if (found)
*found = !error;
if (error == GIT_ENOTFOUND) { if (error == GIT_ENOTFOUND) {
giterr_clear(); giterr_clear();
error = 0; error = 0;
...@@ -265,6 +269,7 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name) ...@@ -265,6 +269,7 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
int error = 0; int error = 0;
git_config *config; git_config *config;
struct refspec_cb_data data; struct refspec_cb_data data;
bool optional_setting_found = false, found;
assert(out && repo && name); assert(out && repo && name);
...@@ -294,21 +299,33 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name) ...@@ -294,21 +299,33 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
goto cleanup; goto cleanup;
} }
if ((error = git_config_get_string(&val, config, git_buf_cstr(&buf))) < 0) if ((error = get_optional_config(&found, config, &buf, NULL, (void *)&val)) < 0)
goto cleanup; goto cleanup;
optional_setting_found |= found;
remote->repo = repo; remote->repo = repo;
if (found && strlen(val) > 0) {
remote->url = git__strdup(val); remote->url = git__strdup(val);
GITERR_CHECK_ALLOC(remote->url); GITERR_CHECK_ALLOC(remote->url);
}
val = NULL; val = NULL;
git_buf_clear(&buf); git_buf_clear(&buf);
git_buf_printf(&buf, "remote.%s.pushurl", name); git_buf_printf(&buf, "remote.%s.pushurl", name);
if ((error = get_optional_config(config, &buf, NULL, (void *)&val)) < 0) if ((error = get_optional_config(&found, config, &buf, NULL, (void *)&val)) < 0)
goto cleanup; goto cleanup;
if (val && strlen(val) > 0) { optional_setting_found |= found;
if (!optional_setting_found) {
error = GIT_ENOTFOUND;
goto cleanup;
}
if (found && strlen(val) > 0) {
remote->pushurl = git__strdup(val); remote->pushurl = git__strdup(val);
GITERR_CHECK_ALLOC(remote->pushurl); GITERR_CHECK_ALLOC(remote->pushurl);
} }
...@@ -318,14 +335,14 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name) ...@@ -318,14 +335,14 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
git_buf_clear(&buf); git_buf_clear(&buf);
git_buf_printf(&buf, "remote.%s.fetch", name); git_buf_printf(&buf, "remote.%s.fetch", name);
if ((error = get_optional_config(config, &buf, refspec_cb, &data)) < 0) if ((error = get_optional_config(NULL, config, &buf, refspec_cb, &data)) < 0)
goto cleanup; goto cleanup;
data.fetch = false; data.fetch = false;
git_buf_clear(&buf); git_buf_clear(&buf);
git_buf_printf(&buf, "remote.%s.push", name); git_buf_printf(&buf, "remote.%s.push", name);
if ((error = get_optional_config(config, &buf, refspec_cb, &data)) < 0) if ((error = get_optional_config(NULL, config, &buf, refspec_cb, &data)) < 0)
goto cleanup; goto cleanup;
if (download_tags_value(remote, config) < 0) if (download_tags_value(remote, config) < 0)
......
...@@ -378,6 +378,28 @@ void test_network_remote_remotes__can_load_with_an_empty_url(void) ...@@ -378,6 +378,28 @@ void test_network_remote_remotes__can_load_with_an_empty_url(void)
git_remote_free(remote); git_remote_free(remote);
} }
void test_network_remote_remotes__can_load_with_only_an_empty_pushurl(void)
{
git_remote *remote = NULL;
cl_git_pass(git_remote_load(&remote, _repo, "empty-remote-pushurl"));
cl_assert(remote->url == NULL);
cl_assert(remote->pushurl == NULL);
cl_git_fail(git_remote_connect(remote, GIT_DIRECTION_FETCH));
git_remote_free(remote);
}
void test_network_remote_remotes__returns_ENOTFOUND_when_neither_url_nor_pushurl(void)
{
git_remote *remote = NULL;
cl_git_fail_with(
git_remote_load(&remote, _repo, "no-remote-url"), GIT_ENOTFOUND);
}
void test_network_remote_remotes__check_structure_version(void) void test_network_remote_remotes__check_structure_version(void)
{ {
git_transport transport = GIT_TRANSPORT_INIT; git_transport transport = GIT_TRANSPORT_INIT;
......
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
[remote "empty-remote-url"] [remote "empty-remote-url"]
url = url =
pushurl = pushurl =
[remote "empty-remote-pushurl"]
pushurl =
[remote "no-remote-url"]
fetch =
[remote "test_with_pushurl"] [remote "test_with_pushurl"]
url = git://github.com/libgit2/fetchlibgit2 url = git://github.com/libgit2/fetchlibgit2
pushurl = git://github.com/libgit2/pushlibgit2 pushurl = git://github.com/libgit2/pushlibgit2
......
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