mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-28 14:02:57 +00:00
Merge pull request #2354 from libgit2/cmn/clone-into-mirror
Allow mirror-clone via `git_clone_into()`
This commit is contained in:
commit
124a45ead3
31
src/clone.c
31
src/clone.c
@ -171,6 +171,10 @@ static int update_head_to_new_branch(
|
||||
|
||||
git_reference_free(tracking_branch);
|
||||
|
||||
/* if it already existed, then the user's refspec created it for us, ignore it' */
|
||||
if (error == GIT_EEXISTS)
|
||||
error = 0;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -336,25 +340,30 @@ static bool should_checkout(
|
||||
return !git_repository_head_unborn(repo);
|
||||
}
|
||||
|
||||
int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature)
|
||||
int git_clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature)
|
||||
{
|
||||
int error = 0, old_fetchhead;
|
||||
git_strarray refspecs;
|
||||
git_buf reflog_message = GIT_BUF_INIT;
|
||||
git_remote *remote;
|
||||
const git_remote_callbacks *callbacks;
|
||||
|
||||
assert(repo && remote);
|
||||
assert(repo && _remote);
|
||||
|
||||
if (!git_repository_is_empty(repo)) {
|
||||
giterr_set(GITERR_INVALID, "the repository is not empty");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((error = git_remote_get_fetch_refspecs(&refspecs, remote)) < 0)
|
||||
if ((error = git_remote_dup(&remote, _remote)) < 0)
|
||||
return error;
|
||||
|
||||
callbacks = git_remote_get_callbacks(_remote);
|
||||
if (!giterr__check_version(callbacks, 1, "git_remote_callbacks") &&
|
||||
(error = git_remote_set_callbacks(remote, git_remote_get_callbacks(_remote))) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = git_remote_add_fetch(remote, "refs/tags/*:refs/tags/*")) < 0)
|
||||
return error;
|
||||
goto cleanup;
|
||||
|
||||
old_fetchhead = git_remote_update_fetchhead(remote);
|
||||
git_remote_set_update_fetchhead(remote, 0);
|
||||
@ -375,15 +384,7 @@ int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_
|
||||
|
||||
cleanup:
|
||||
git_remote_set_update_fetchhead(remote, old_fetchhead);
|
||||
|
||||
/* Go back to the original refspecs */
|
||||
{
|
||||
int error_alt = git_remote_set_fetch_refspecs(remote, &refspecs);
|
||||
if (!error)
|
||||
error = error_alt;
|
||||
}
|
||||
|
||||
git_strarray_free(&refspecs);
|
||||
git_remote_free(remote);
|
||||
git_buf_free(&reflog_message);
|
||||
|
||||
return error;
|
||||
|
@ -86,3 +86,29 @@ void test_network_fetchlocal__partial(void)
|
||||
git_strarray_free(&refnames);
|
||||
git_remote_free(origin);
|
||||
}
|
||||
|
||||
void test_network_fetchlocal__clone_into_mirror(void)
|
||||
{
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
git_repository *repo;
|
||||
git_remote *remote;
|
||||
git_reference *head;
|
||||
|
||||
cl_git_pass(git_repository_init(&repo, "./foo.git", true));
|
||||
cl_git_pass(git_remote_create(&remote, repo, "origin", cl_git_fixture_url("testrepo.git")));
|
||||
|
||||
git_remote_clear_refspecs(remote);
|
||||
cl_git_pass(git_remote_add_fetch(remote, "+refs/*:refs/*"));
|
||||
|
||||
cl_git_pass(git_clone_into(repo, remote, NULL, NULL, NULL));
|
||||
|
||||
cl_git_pass(git_reference_lookup(&head, repo, "HEAD"));
|
||||
cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
|
||||
cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
|
||||
|
||||
git_remote_free(remote);
|
||||
git_reference_free(head);
|
||||
git_repository_free(repo);
|
||||
git_buf_free(&path);
|
||||
cl_fixture_cleanup("./foo.git");
|
||||
}
|
||||
|
@ -164,6 +164,39 @@ void test_online_clone__clone_into(void)
|
||||
git_buf_free(&path);
|
||||
}
|
||||
|
||||
void test_online_clone__clone_mirror(void)
|
||||
{
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
git_remote *remote;
|
||||
git_reference *head;
|
||||
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
|
||||
|
||||
bool fetch_progress_cb_was_called = false;
|
||||
|
||||
cl_git_pass(git_repository_init(&g_repo, "./foo.git", true));
|
||||
cl_git_pass(git_remote_create(&remote, g_repo, "origin", LIVE_REPO_URL));
|
||||
|
||||
callbacks.transfer_progress = &fetch_progress;
|
||||
callbacks.payload = &fetch_progress_cb_was_called;
|
||||
git_remote_set_callbacks(remote, &callbacks);
|
||||
|
||||
git_remote_clear_refspecs(remote);
|
||||
cl_git_pass(git_remote_add_fetch(remote, "+refs/*:refs/*"));
|
||||
|
||||
cl_git_pass(git_clone_into(g_repo, remote, NULL, NULL, NULL));
|
||||
|
||||
cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
|
||||
cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
|
||||
cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
|
||||
|
||||
cl_assert_equal_i(true, fetch_progress_cb_was_called);
|
||||
|
||||
git_remote_free(remote);
|
||||
git_reference_free(head);
|
||||
git_buf_free(&path);
|
||||
cl_fixture_cleanup("./foo.git");
|
||||
}
|
||||
|
||||
static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *payload)
|
||||
{
|
||||
int *callcount = (int*)payload;
|
||||
|
Loading…
Reference in New Issue
Block a user