mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-06 23:26:39 +00:00
Merge pull request #2452 from libgit2/cmn/clone-custom-repo
Provide a callback to customize the repository on clone
This commit is contained in:
commit
b0ca1b18e2
@ -25,3 +25,10 @@ v0.21 + 1
|
|||||||
|
|
||||||
The remote_callbacks member has been preserved for convenience, although it
|
The remote_callbacks member has been preserved for convenience, although it
|
||||||
is not used when a remote creation callback is supplied.
|
is not used when a remote creation callback is supplied.
|
||||||
|
|
||||||
|
* The git_clone_options struct now provides repository_cb and
|
||||||
|
repository_cb_payload to allow the user to create a repository with
|
||||||
|
custom options.
|
||||||
|
|
||||||
|
* git_clone_into and git_clone_local_into have been removed from the
|
||||||
|
public API in favour of git_clone callbacks
|
||||||
|
@ -73,6 +73,26 @@ typedef int (*git_remote_create_cb)(
|
|||||||
const char *url,
|
const char *url,
|
||||||
void *payload);
|
void *payload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signature of a function matchin git_repository_init, with an
|
||||||
|
* aditional void * as callback payload.
|
||||||
|
*
|
||||||
|
* Callers of git_clone my provide a function matching this signature
|
||||||
|
* to override the repository creation and customization process
|
||||||
|
* during a clone operation.
|
||||||
|
*
|
||||||
|
* @param out the resulting repository
|
||||||
|
* @param path path in which to create the repository
|
||||||
|
* @param bare whether the repository is bare. This is the value from the clone options
|
||||||
|
* @param payload payload specified by the options
|
||||||
|
* @return 0, or a negative value to indicate error
|
||||||
|
*/
|
||||||
|
typedef int (*git_repository_create_cb)(
|
||||||
|
git_repository **out,
|
||||||
|
const char *path,
|
||||||
|
int bare,
|
||||||
|
void *payload);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clone options structure
|
* Clone options structure
|
||||||
*
|
*
|
||||||
@ -125,6 +145,19 @@ typedef struct git_clone_options {
|
|||||||
*/
|
*/
|
||||||
git_signature *signature;
|
git_signature *signature;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A callback used to create the new repository into which to
|
||||||
|
* clone. If NULL, the 'bare' field will be used to determine
|
||||||
|
* whether to create a bare repository.
|
||||||
|
*/
|
||||||
|
git_repository_create_cb repository_cb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An opaque payload to pass to the git_repository creation callback.
|
||||||
|
* This parameter is ignored unless repository_cb is non-NULL.
|
||||||
|
*/
|
||||||
|
void *repository_cb_payload;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback used to create the git_remote, prior to its being
|
* A callback used to create the git_remote, prior to its being
|
||||||
* used to perform the clone operation. See the documentation for
|
* used to perform the clone operation. See the documentation for
|
||||||
@ -158,9 +191,9 @@ GIT_EXTERN(int) git_clone_init_options(
|
|||||||
/**
|
/**
|
||||||
* Clone a remote repository.
|
* Clone a remote repository.
|
||||||
*
|
*
|
||||||
* This version handles the simple case. If you'd like to create the
|
* By default this creates its repository and initial remote to match
|
||||||
* repository or remote with non-default settings, you can create and
|
* git's defaults. You can use the options in the callback to
|
||||||
* configure them and then use `git_clone_into()`.
|
* customize how these are created.
|
||||||
*
|
*
|
||||||
* @param out pointer that will receive the resulting repository object
|
* @param out pointer that will receive the resulting repository object
|
||||||
* @param url the remote repository to clone
|
* @param url the remote repository to clone
|
||||||
@ -177,59 +210,6 @@ GIT_EXTERN(int) git_clone(
|
|||||||
const char *local_path,
|
const char *local_path,
|
||||||
const git_clone_options *options);
|
const git_clone_options *options);
|
||||||
|
|
||||||
/**
|
|
||||||
* Clone into a repository
|
|
||||||
*
|
|
||||||
* After creating the repository and remote and configuring them for
|
|
||||||
* paths and callbacks respectively, you can call this function to
|
|
||||||
* perform the clone operation and optionally checkout files.
|
|
||||||
*
|
|
||||||
* @param repo the repository to use
|
|
||||||
* @param remote the remote repository to clone from
|
|
||||||
* @param co_opts options to use during checkout
|
|
||||||
* @param branch the branch to checkout after the clone, pass NULL for the
|
|
||||||
* remote's default branch
|
|
||||||
* @param signature The identity used when updating the reflog.
|
|
||||||
* @return 0 on success, any non-zero return value from a callback
|
|
||||||
* function, or a negative value to indicate an error (use
|
|
||||||
* `giterr_last` for a detailed error message)
|
|
||||||
*/
|
|
||||||
GIT_EXTERN(int) git_clone_into(
|
|
||||||
git_repository *repo,
|
|
||||||
git_remote *remote,
|
|
||||||
const git_checkout_options *co_opts,
|
|
||||||
const char *branch,
|
|
||||||
const git_signature *signature);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a local clone into a repository
|
|
||||||
*
|
|
||||||
* A "local clone" bypasses any git-aware protocols and simply copies
|
|
||||||
* over the object database from the source repository. It is often
|
|
||||||
* faster than a git-aware clone, but no verification of the data is
|
|
||||||
* performed, and can copy over too much data.
|
|
||||||
*
|
|
||||||
* @param repo the repository to use
|
|
||||||
* @param remote the remote repository to clone from
|
|
||||||
* @param co_opts options to use during checkout
|
|
||||||
* @param branch the branch to checkout after the clone, pass NULL for the
|
|
||||||
* remote's default branch
|
|
||||||
* @param link wether to use hardlinks instead of copying
|
|
||||||
* objects. This is only possible if both repositories are on the same
|
|
||||||
* filesystem.
|
|
||||||
* @param signature the identity used when updating the reflog
|
|
||||||
* @return 0 on success, any non-zero return value from a callback
|
|
||||||
* function, or a negative value to indicate an error (use
|
|
||||||
* `giterr_last` for a detailed error message)
|
|
||||||
*/
|
|
||||||
GIT_EXTERN(int) git_clone_local_into(
|
|
||||||
git_repository *repo,
|
|
||||||
git_remote *remote,
|
|
||||||
const git_checkout_options *co_opts,
|
|
||||||
const char *branch,
|
|
||||||
int link,
|
|
||||||
const git_signature *signature);
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
GIT_END_DECL
|
GIT_END_DECL
|
||||||
#endif
|
#endif
|
||||||
|
25
src/clone.c
25
src/clone.c
@ -24,6 +24,8 @@
|
|||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
#include "odb.h"
|
#include "odb.h"
|
||||||
|
|
||||||
|
static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature);
|
||||||
|
|
||||||
static int create_branch(
|
static int create_branch(
|
||||||
git_reference **branch,
|
git_reference **branch,
|
||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
@ -229,6 +231,13 @@ cleanup:
|
|||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int default_repository_create(git_repository **out, const char *path, int bare, void *payload)
|
||||||
|
{
|
||||||
|
GIT_UNUSED(payload);
|
||||||
|
|
||||||
|
return git_repository_init(out, path, bare);
|
||||||
|
}
|
||||||
|
|
||||||
static int default_remote_create(
|
static int default_remote_create(
|
||||||
git_remote **out,
|
git_remote **out,
|
||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
@ -322,7 +331,7 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature)
|
static int clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
git_buf reflog_message = GIT_BUF_INIT;
|
git_buf reflog_message = GIT_BUF_INIT;
|
||||||
@ -396,6 +405,7 @@ int git_clone(
|
|||||||
git_remote *origin;
|
git_remote *origin;
|
||||||
git_clone_options options = GIT_CLONE_OPTIONS_INIT;
|
git_clone_options options = GIT_CLONE_OPTIONS_INIT;
|
||||||
uint32_t rmdir_flags = GIT_RMDIR_REMOVE_FILES;
|
uint32_t rmdir_flags = GIT_RMDIR_REMOVE_FILES;
|
||||||
|
git_repository_create_cb repository_cb;
|
||||||
|
|
||||||
assert(out && url && local_path);
|
assert(out && url && local_path);
|
||||||
|
|
||||||
@ -415,17 +425,22 @@ int git_clone(
|
|||||||
if (git_path_exists(local_path))
|
if (git_path_exists(local_path))
|
||||||
rmdir_flags |= GIT_RMDIR_SKIP_ROOT;
|
rmdir_flags |= GIT_RMDIR_SKIP_ROOT;
|
||||||
|
|
||||||
if ((error = git_repository_init(&repo, local_path, options.bare)) < 0)
|
if (options.repository_cb)
|
||||||
|
repository_cb = options.repository_cb;
|
||||||
|
else
|
||||||
|
repository_cb = default_repository_create;
|
||||||
|
|
||||||
|
if ((error = repository_cb(&repo, local_path, options.bare, options.repository_cb_payload)) < 0)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if (!(error = create_and_configure_origin(&origin, repo, url, &options))) {
|
if (!(error = create_and_configure_origin(&origin, repo, url, &options))) {
|
||||||
if (git_clone__should_clone_local(url, options.local)) {
|
if (git_clone__should_clone_local(url, options.local)) {
|
||||||
int link = options.local != GIT_CLONE_LOCAL_NO_LINKS;
|
int link = options.local != GIT_CLONE_LOCAL_NO_LINKS;
|
||||||
error = git_clone_local_into(
|
error = clone_local_into(
|
||||||
repo, origin, &options.checkout_opts,
|
repo, origin, &options.checkout_opts,
|
||||||
options.checkout_branch, link, options.signature);
|
options.checkout_branch, link, options.signature);
|
||||||
} else {
|
} else {
|
||||||
error = git_clone_into(
|
error = clone_into(
|
||||||
repo, origin, &options.checkout_opts,
|
repo, origin, &options.checkout_opts,
|
||||||
options.checkout_branch, options.signature);
|
options.checkout_branch, options.signature);
|
||||||
}
|
}
|
||||||
@ -485,7 +500,7 @@ static bool can_link(const char *src, const char *dst, int link)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature)
|
static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature)
|
||||||
{
|
{
|
||||||
int error, flags;
|
int error, flags;
|
||||||
git_repository *src;
|
git_repository *src;
|
||||||
|
@ -31,31 +31,24 @@ void test_clone_local__should_clone_local(void)
|
|||||||
void test_clone_local__hardlinks(void)
|
void test_clone_local__hardlinks(void)
|
||||||
{
|
{
|
||||||
git_repository *repo;
|
git_repository *repo;
|
||||||
git_remote *remote;
|
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
|
||||||
git_signature *sig;
|
|
||||||
git_buf buf = GIT_BUF_INIT;
|
git_buf buf = GIT_BUF_INIT;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In this first clone, we just copy over, since the temp dir
|
* In this first clone, we just copy over, since the temp dir
|
||||||
* will often be in a different filesystem, so we cannot
|
* will often be in a different filesystem, so we cannot
|
||||||
* link. It also allows us to control the number of links
|
* link. It also allows us to control the number of links
|
||||||
*/
|
*/
|
||||||
cl_git_pass(git_repository_init(&repo, "./clone.git", true));
|
opts.bare = true;
|
||||||
cl_git_pass(git_remote_create(&remote, repo, "origin", cl_fixture("testrepo.git")));
|
opts.local = GIT_CLONE_LOCAL_NO_LINKS;
|
||||||
cl_git_pass(git_signature_now(&sig, "foo", "bar"));
|
cl_git_pass(git_clone(&repo, cl_fixture("testrepo.git"), "./clone.git", &opts));
|
||||||
cl_git_pass(git_clone_local_into(repo, remote, NULL, NULL, false, sig));
|
|
||||||
|
|
||||||
git_remote_free(remote);
|
|
||||||
git_repository_free(repo);
|
git_repository_free(repo);
|
||||||
|
|
||||||
/* This second clone is in the same filesystem, so we can hardlink */
|
/* This second clone is in the same filesystem, so we can hardlink */
|
||||||
|
|
||||||
cl_git_pass(git_repository_init(&repo, "./clone2.git", true));
|
opts.local = GIT_CLONE_LOCAL;
|
||||||
cl_git_pass(git_buf_puts(&buf, cl_git_path_url("clone.git")));
|
cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone2.git", &opts));
|
||||||
cl_git_pass(git_remote_create(&remote, repo, "origin", buf.ptr));
|
|
||||||
cl_git_pass(git_clone_local_into(repo, remote, NULL, NULL, true, sig));
|
|
||||||
|
|
||||||
#ifndef GIT_WIN32
|
#ifndef GIT_WIN32
|
||||||
git_buf_clear(&buf);
|
git_buf_clear(&buf);
|
||||||
@ -65,14 +58,11 @@ void test_clone_local__hardlinks(void)
|
|||||||
cl_assert_equal_i(2, st.st_nlink);
|
cl_assert_equal_i(2, st.st_nlink);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
git_remote_free(remote);
|
|
||||||
git_repository_free(repo);
|
git_repository_free(repo);
|
||||||
git_buf_clear(&buf);
|
git_buf_clear(&buf);
|
||||||
|
|
||||||
cl_git_pass(git_repository_init(&repo, "./clone3.git", true));
|
opts.local = GIT_CLONE_LOCAL_NO_LINKS;
|
||||||
cl_git_pass(git_buf_puts(&buf, cl_git_path_url("clone.git")));
|
cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone3.git", &opts));
|
||||||
cl_git_pass(git_remote_create(&remote, repo, "origin", buf.ptr));
|
|
||||||
cl_git_pass(git_clone_local_into(repo, remote, NULL, NULL, false, sig));
|
|
||||||
|
|
||||||
git_buf_clear(&buf);
|
git_buf_clear(&buf);
|
||||||
cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
|
cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
|
||||||
@ -80,7 +70,6 @@ void test_clone_local__hardlinks(void)
|
|||||||
cl_git_pass(p_stat(buf.ptr, &st));
|
cl_git_pass(p_stat(buf.ptr, &st));
|
||||||
cl_assert_equal_i(1, st.st_nlink);
|
cl_assert_equal_i(1, st.st_nlink);
|
||||||
|
|
||||||
git_remote_free(remote);
|
|
||||||
git_repository_free(repo);
|
git_repository_free(repo);
|
||||||
|
|
||||||
/* this one should automatically use links */
|
/* this one should automatically use links */
|
||||||
@ -95,7 +84,6 @@ void test_clone_local__hardlinks(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
git_buf_free(&buf);
|
git_buf_free(&buf);
|
||||||
git_signature_free(sig);
|
|
||||||
git_repository_free(repo);
|
git_repository_free(repo);
|
||||||
|
|
||||||
cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
|
cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
|
||||||
|
@ -279,23 +279,6 @@ void test_clone_nonetwork__clone_updates_reflog_properly(void)
|
|||||||
assert_correct_reflog("refs/heads/master");
|
assert_correct_reflog("refs/heads/master");
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_clone_nonetwork__clone_into_updates_reflog_properly(void)
|
|
||||||
{
|
|
||||||
git_remote *remote;
|
|
||||||
git_signature *sig;
|
|
||||||
cl_git_pass(git_signature_now(&sig, "Me", "foo@example.com"));
|
|
||||||
|
|
||||||
cl_git_pass(git_repository_init(&g_repo, "./foo", false));
|
|
||||||
cl_git_pass(git_remote_create(&remote, g_repo, "origin", cl_git_fixture_url("testrepo.git")));
|
|
||||||
cl_git_pass(git_clone_into(g_repo, remote, NULL, NULL, sig));
|
|
||||||
|
|
||||||
assert_correct_reflog("HEAD");
|
|
||||||
assert_correct_reflog("refs/heads/master");
|
|
||||||
|
|
||||||
git_remote_free(remote);
|
|
||||||
git_signature_free(sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cleanup_repository(void *path)
|
static void cleanup_repository(void *path)
|
||||||
{
|
{
|
||||||
if (g_repo) {
|
if (g_repo) {
|
||||||
|
@ -87,28 +87,43 @@ void test_network_fetchlocal__partial(void)
|
|||||||
git_remote_free(origin);
|
git_remote_free(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_network_fetchlocal__clone_into_mirror(void)
|
static int remote_mirror_cb(git_remote **out, git_repository *repo,
|
||||||
|
const char *name, const char *url, void *payload)
|
||||||
{
|
{
|
||||||
git_buf path = GIT_BUF_INIT;
|
int error;
|
||||||
git_repository *repo;
|
|
||||||
git_remote *remote;
|
git_remote *remote;
|
||||||
git_reference *head;
|
|
||||||
|
|
||||||
cl_git_pass(git_repository_init(&repo, "./foo.git", true));
|
GIT_UNUSED(payload);
|
||||||
cl_git_pass(git_remote_create(&remote, repo, "origin", cl_git_fixture_url("testrepo.git")));
|
|
||||||
|
if ((error = git_remote_create(&remote, repo, name, url)) < 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
git_remote_clear_refspecs(remote);
|
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));
|
if ((error = git_remote_add_fetch(remote, "+refs/*:refs/*")) < 0) {
|
||||||
|
git_remote_free(remote);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = remote;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_network_fetchlocal__clone_into_mirror(void)
|
||||||
|
{
|
||||||
|
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
|
||||||
|
git_repository *repo;
|
||||||
|
git_reference *head;
|
||||||
|
|
||||||
|
opts.bare = true;
|
||||||
|
opts.remote_cb = remote_mirror_cb;
|
||||||
|
cl_git_pass(git_clone(&repo, cl_git_fixture_url("testrepo.git"), "./foo.git", &opts));
|
||||||
|
|
||||||
cl_git_pass(git_reference_lookup(&head, repo, "HEAD"));
|
cl_git_pass(git_reference_lookup(&head, repo, "HEAD"));
|
||||||
cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(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_s("refs/heads/master", git_reference_symbolic_target(head));
|
||||||
|
|
||||||
git_remote_free(remote);
|
|
||||||
git_reference_free(head);
|
git_reference_free(head);
|
||||||
git_repository_free(repo);
|
git_repository_free(repo);
|
||||||
git_buf_free(&path);
|
|
||||||
cl_fixture_cleanup("./foo.git");
|
cl_fixture_cleanup("./foo.git");
|
||||||
}
|
}
|
||||||
|
@ -124,65 +124,49 @@ void test_online_clone__can_checkout_a_cloned_repo(void)
|
|||||||
git_buf_free(&path);
|
git_buf_free(&path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_online_clone__clone_into(void)
|
static int remote_mirror_cb(git_remote **out, git_repository *repo,
|
||||||
|
const char *name, const char *url, void *payload)
|
||||||
{
|
{
|
||||||
git_buf path = GIT_BUF_INIT;
|
int error;
|
||||||
git_remote *remote;
|
git_remote *remote;
|
||||||
git_reference *head;
|
git_remote_callbacks *callbacks = (git_remote_callbacks *) payload;
|
||||||
git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
|
|
||||||
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
|
|
||||||
|
|
||||||
bool checkout_progress_cb_was_called = false,
|
|
||||||
fetch_progress_cb_was_called = false;
|
|
||||||
|
|
||||||
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
|
if ((error = git_remote_create(&remote, repo, name, url)) < 0)
|
||||||
checkout_opts.progress_cb = &checkout_progress;
|
return error;
|
||||||
checkout_opts.progress_payload = &checkout_progress_cb_was_called;
|
|
||||||
|
|
||||||
cl_git_pass(git_repository_init(&g_repo, "./foo", false));
|
if ((error = git_remote_set_callbacks(remote, callbacks)) < 0) {
|
||||||
cl_git_pass(git_remote_create(&remote, g_repo, "origin", LIVE_REPO_URL));
|
git_remote_free(remote);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
callbacks.transfer_progress = &fetch_progress;
|
git_remote_clear_refspecs(remote);
|
||||||
callbacks.payload = &fetch_progress_cb_was_called;
|
|
||||||
git_remote_set_callbacks(remote, &callbacks);
|
|
||||||
|
|
||||||
cl_git_pass(git_clone_into(g_repo, remote, &checkout_opts, NULL, NULL));
|
if ((error = git_remote_add_fetch(remote, "+refs/*:refs/*")) < 0) {
|
||||||
|
git_remote_free(remote);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt"));
|
*out = remote;
|
||||||
cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&path)));
|
return 0;
|
||||||
|
|
||||||
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, checkout_progress_cb_was_called);
|
|
||||||
cl_assert_equal_i(true, fetch_progress_cb_was_called);
|
|
||||||
|
|
||||||
git_remote_free(remote);
|
|
||||||
git_reference_free(head);
|
|
||||||
git_buf_free(&path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_online_clone__clone_mirror(void)
|
void test_online_clone__clone_mirror(void)
|
||||||
{
|
{
|
||||||
git_buf path = GIT_BUF_INIT;
|
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
|
||||||
git_remote *remote;
|
|
||||||
git_reference *head;
|
git_reference *head;
|
||||||
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
|
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
|
||||||
|
|
||||||
bool fetch_progress_cb_was_called = false;
|
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.transfer_progress = &fetch_progress;
|
||||||
callbacks.payload = &fetch_progress_cb_was_called;
|
callbacks.payload = &fetch_progress_cb_was_called;
|
||||||
git_remote_set_callbacks(remote, &callbacks);
|
|
||||||
|
|
||||||
git_remote_clear_refspecs(remote);
|
opts.bare = true;
|
||||||
cl_git_pass(git_remote_add_fetch(remote, "+refs/*:refs/*"));
|
opts.remote_cb = remote_mirror_cb;
|
||||||
|
opts.remote_cb_payload = &callbacks;
|
||||||
|
|
||||||
cl_git_pass(git_clone_into(g_repo, remote, NULL, NULL, NULL));
|
cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo.git", &opts));
|
||||||
|
|
||||||
cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
|
cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
|
||||||
cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
|
cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
|
||||||
@ -190,9 +174,7 @@ void test_online_clone__clone_mirror(void)
|
|||||||
|
|
||||||
cl_assert_equal_i(true, fetch_progress_cb_was_called);
|
cl_assert_equal_i(true, fetch_progress_cb_was_called);
|
||||||
|
|
||||||
git_remote_free(remote);
|
|
||||||
git_reference_free(head);
|
git_reference_free(head);
|
||||||
git_buf_free(&path);
|
|
||||||
git_repository_free(g_repo);
|
git_repository_free(g_repo);
|
||||||
g_repo = NULL;
|
g_repo = NULL;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user