Commit 266af6d8 by Carlos Martín Nieto

remote: don't allow such direct access to the refspecs

Removing arbitrary refspecs makes things more complex to reason
about. Instead, let the user set the fetch and push refspec list to
whatever they want it to be.
parent af613ecd
......@@ -145,8 +145,11 @@ GIT_EXTERN(int) git_remote_set_pushurl(git_remote *remote, const char* url);
/**
* Add a fetch refspec to the remote
*
* Convenience function for adding a single fetch refspec to the
* current list in the remote.
*
* @param remote the remote
* @apram refspec the new fetch refspec
* @param refspec the new fetch refspec
* @return 0 or an error value
*/
GIT_EXTERN(int) git_remote_add_fetch(git_remote *remote, const char *refspec);
......@@ -163,8 +166,21 @@ GIT_EXTERN(int) git_remote_add_fetch(git_remote *remote, const char *refspec);
GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, git_remote *remote);
/**
* Set the remote's list of fetch refspecs
*
* The contents of the string array are copied.
*
* @param remote the remote to modify
* @param array the new list of fetch resfpecs
*/
GIT_EXTERN(int) git_remote_set_fetch_refspecs(git_remote *remote, git_strarray *array);
/**
* Add a push refspec to the remote
*
* Convenience function for adding a single push refspec to the
* current list in the remote.
*
* @param remote the remote
* @param refspec the new push refspec
* @return 0 or an error value
......@@ -183,6 +199,16 @@ GIT_EXTERN(int) git_remote_add_push(git_remote *remote, const char *refspec);
GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, git_remote *remote);
/**
* Set the remote's list of push refspecs
*
* The contents of the string array are copied.
*
* @param remote the remote to modify
* @param array the new list of push resfpecs
*/
GIT_EXTERN(int) git_remote_set_push_refspecs(git_remote *remote, git_strarray *array);
/**
* Clear the refspecs
*
* Remove all configured fetch and push refspecs from the remote.
......@@ -209,15 +235,6 @@ GIT_EXTERN(size_t) git_remote_refspec_count(git_remote *remote);
GIT_EXTERN(const git_refspec *)git_remote_get_refspec(git_remote *remote, size_t n);
/**
* Remove a refspec from the remote
*
* @param remote the remote to query
* @param n the refspec to remove
* @return 0 or GIT_ENOTFOUND
*/
GIT_EXTERN(int) git_remote_remove_refspec(git_remote *remote, size_t n);
/**
* Open a connection to a remote
*
* The transport is selected based on the URL. The direction argument
......
......@@ -349,7 +349,7 @@ static bool should_checkout(
int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_opts *co_opts, const char *branch)
{
int error = 0, old_fetchhead;
size_t nspecs;
git_strarray refspecs;
assert(repo && remote);
......@@ -358,6 +358,10 @@ int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_
return -1;
}
if ((error = git_remote_get_fetch_refspecs(&refspecs, remote)) < 0)
return error;
if ((error = git_remote_add_fetch(remote, "refs/tags/*:refs/tags/*")) < 0)
return error;
......@@ -378,9 +382,13 @@ int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_
cleanup:
git_remote_set_update_fetchhead(remote, old_fetchhead);
/* Remove the tags refspec */
nspecs = git_remote_refspec_count(remote);
git_remote_remove_refspec(remote, nspecs);
/* Go back to the original refspecs */
if (git_remote_set_fetch_refspecs(remote, &refspecs) < 0) {
git_strarray_free(&refspecs);
return -1;
}
git_strarray_free(&refspecs);
return error;
}
......
......@@ -1047,9 +1047,6 @@ void git_remote_disconnect(git_remote *remote)
void git_remote_free(git_remote *remote)
{
git_refspec *spec;
size_t i;
if (remote == NULL)
return;
......@@ -1515,14 +1512,68 @@ void git_remote_clear_refspecs(git_remote *remote)
git_vector_clear(&remote->refspecs);
}
static int add_and_dwim(git_remote *remote, const char *str, int push)
{
git_refspec *spec;
git_vector *vec;
if (add_refspec(remote, str, !push) < 0)
return -1;
vec = &remote->refspecs;
spec = git_vector_get(vec, vec->length - 1);
return git_refspec__dwim_one(&remote->active_refspecs, spec, &remote->refs);
}
int git_remote_add_fetch(git_remote *remote, const char *refspec)
{
return add_refspec(remote, refspec, true);
return add_and_dwim(remote, refspec, false);
}
int git_remote_add_push(git_remote *remote, const char *refspec)
{
return add_refspec(remote, refspec, false);
return add_and_dwim(remote, refspec, true);
}
static int set_refspecs(git_remote *remote, git_strarray *array, int push)
{
git_vector *vec = &remote->refspecs;
git_refspec *spec;
size_t i;
/* Start by removing any refspecs of the same type */
for (i = 0; i < vec->length; i++) {
spec = git_vector_get(vec, i);
if (spec->push != push)
continue;
git_refspec__free(spec);
git__free(spec);
git_vector_remove(vec, i);
i--;
}
/* And now we add the new ones */
for (i = 0; i < array->count; i++) {
if (add_refspec(remote, array->strings[i], !push) < 0)
return -1;
}
free_refspecs(&remote->active_refspecs);
git_vector_clear(&remote->active_refspecs);
return dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs);
}
int git_remote_set_fetch_refspecs(git_remote *remote, git_strarray *array)
{
return set_refspecs(remote, array, false);
}
int git_remote_set_push_refspecs(git_remote *remote, git_strarray *array)
{
return set_refspecs(remote, array, true);
}
static int copy_refspecs(git_strarray *array, git_remote *remote, unsigned int push)
......@@ -1580,18 +1631,3 @@ const git_refspec *git_remote_get_refspec(git_remote *remote, size_t n)
{
return git_vector_get(&remote->refspecs, n);
}
int git_remote_remove_refspec(git_remote *remote, size_t n)
{
git_refspec *spec;
assert(remote);
spec = git_vector_get(&remote->refspecs, n);
if (spec) {
git_refspec__free(spec);
git__free(spec);
}
return git_vector_remove(&remote->refspecs, n);
}
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