diff --git a/examples/network/clone.c b/examples/network/clone.c index 8d598de41..9b323ff73 100644 --- a/examples/network/clone.c +++ b/examples/network/clone.c @@ -7,6 +7,16 @@ #include #include +/* Shamelessly borrowed from http://stackoverflow.com/questions/3417837/ */ +#ifdef UNUSED +#elif defined(__GNUC__) +# define UNUSED(x) UNUSED_ ## x __attribute__((unused)) +#elif defined(__LCLINT__) +# define UNUSED(x) /*@unused@*/ x +#else +# define UNUSED(x) x +#endif + typedef struct progress_data { git_transfer_progress fetch_progress; size_t completed_steps; @@ -47,7 +57,10 @@ static void checkout_progress(const char *path, size_t cur, size_t tot, void *pa print_progress(pd); } -static int cred_acquire(git_cred **out, const char *url, unsigned int allowed_types, void *payload) +static int cred_acquire(git_cred **out, + const char * UNUSED(url), + unsigned int UNUSED(allowed_types), + void * UNUSED(payload)) { char username[128] = {0}; char password[128] = {0}; @@ -64,9 +77,8 @@ static int cred_acquire(git_cred **out, const char *url, unsigned int allowed_ty int do_clone(git_repository *repo, int argc, char **argv) { - progress_data pd; + progress_data pd = {{0}}; git_repository *cloned_repo = NULL; - git_remote *origin; git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT; git_checkout_opts checkout_opts = GIT_CHECKOUT_OPTS_INIT; const char *url = argv[1]; @@ -84,25 +96,14 @@ int do_clone(git_repository *repo, int argc, char **argv) // Set up options checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; checkout_opts.progress_cb = checkout_progress; - memset(&pd, 0, sizeof(pd)); checkout_opts.progress_payload = &pd; - - // Create the origin remote, and set up for auth - error = git_remote_new(&origin, NULL, "origin", url, GIT_REMOTE_DEFAULT_FETCH); - if (error != 0) { - const git_error *err = giterr_last(); - if (err) printf("ERROR %d: %s\n", err->klass, err->message); - else printf("ERROR %d: no detailed info\n", error); - return error; - } - git_remote_set_cred_acquire_cb(origin, cred_acquire, NULL); - - // Do the clone - clone_opts.checkout_opts = &checkout_opts; + clone_opts.checkout_opts = checkout_opts; clone_opts.fetch_progress_cb = &fetch_progress; clone_opts.fetch_progress_payload = &pd; - error = git_clone(&cloned_repo, origin, path, &clone_opts); - git_remote_free(origin); + clone_opts.cred_acquire_cb = cred_acquire; + + // Do the clone + error = git_clone(&cloned_repo, url, path, &clone_opts); printf("\n"); if (error != 0) { const git_error *err = giterr_last(); diff --git a/examples/network/fetch.c b/examples/network/fetch.c index 8048fd67a..437b137d3 100644 --- a/examples/network/fetch.c +++ b/examples/network/fetch.c @@ -76,7 +76,7 @@ int fetch(git_repository *repo, int argc, char **argv) // Figure out whether it's a named remote or a URL printf("Fetching %s for repo %p\n", argv[1], repo); if (git_remote_load(&remote, repo, argv[1]) < 0) { - if (git_remote_new(&remote, repo, NULL, argv[1], NULL) < 0) + if (git_remote_create_inmemory(&remote, repo, NULL, argv[1]) < 0) return -1; } diff --git a/examples/network/ls-remote.c b/examples/network/ls-remote.c index 62131d4ba..737eeacd3 100644 --- a/examples/network/ls-remote.c +++ b/examples/network/ls-remote.c @@ -21,7 +21,7 @@ static int use_unnamed(git_repository *repo, const char *url) // Create an instance of a remote from the URL. The transport to use // is detected from the URL - error = git_remote_new(&remote, repo, NULL, url, NULL); + error = git_remote_create_inmemory(&remote, repo, NULL, url); if (error < 0) goto cleanup; diff --git a/include/git2/clone.h b/include/git2/clone.h index 2b5381e4d..c6ab8032b 100644 --- a/include/git2/clone.h +++ b/include/git2/clone.h @@ -11,6 +11,7 @@ #include "types.h" #include "indexer.h" #include "checkout.h" +#include "remote.h" /** @@ -30,27 +31,55 @@ GIT_BEGIN_DECL * * git_clone_options opts = GIT_CLONE_OPTIONS_INIT; * + * - `checkout_opts` is options for the checkout step. To disable checkout, + * set the `checkout_strategy` to GIT_CHECKOUT_DEFAULT. * - `bare` should be set to zero to create a standard repo, non-zero for * a bare repo * - `fetch_progress_cb` is optional callback for fetch progress. Be aware that * this is called inline with network and indexing operations, so performance * may be affected. * - `fetch_progress_payload` is payload for fetch_progress_cb - * - `checkout_opts` is options for the checkout step. If NULL, no checkout - * is performed + * + * ** "origin" remote options: ** + * - `remote_name` is the name given to the "origin" remote. The default is + * "origin". + * - `pushurl` is a URL to be used for pushing. NULL means use the fetch url. + * - `fetch_spec` is the fetch specification to be used for fetching. NULL + * results in the same behavior as GIT_REMOTE_DEFAULT_FETCH. + * - `push_spec` is the fetch specification to be used for pushing. NULL means + * use the same spec as for fetching. + * - `cred_acquire_cb` is a callback to be used if credentials are required + * during the initial fetch. + * - `cred_acquire_payload` is the payload for the above callback. + * - `transport` is a custom transport to be used for the initial fetch. NULL + * means use the transport autodetected from the URL. + * - `remote_callbacks` may be used to specify custom progress callbacks for + * the origin remote before the fetch is initiated. + * - `remote_autotag` may be used to specify the autotag setting before the + * initial fetch. */ typedef struct git_clone_options { unsigned int version; + git_checkout_opts checkout_opts; int bare; git_transfer_progress_callback fetch_progress_cb; void *fetch_progress_payload; - git_checkout_opts *checkout_opts; + + const char *remote_name; + const char *pushurl; + const char *fetch_spec; + const char *push_spec; + git_cred_acquire_cb cred_acquire_cb; + void *cred_acquire_payload; + git_transport *transport; + git_remote_callbacks *remote_callbacks; + git_remote_autotag_option_t remote_autotag; } git_clone_options; #define GIT_CLONE_OPTIONS_VERSION 1 -#define GIT_CLONE_OPTIONS_INIT {GIT_CLONE_OPTIONS_VERSION} +#define GIT_CLONE_OPTIONS_INIT {GIT_CLONE_OPTIONS_VERSION, {GIT_CHECKOUT_OPTS_VERSION, GIT_CHECKOUT_SAFE}} /** * Clone a remote repository, and checkout the branch pointed to by the remote @@ -66,7 +95,7 @@ typedef struct git_clone_options { */ GIT_EXTERN(int) git_clone( git_repository **out, - git_remote *origin, + const char *url, const char *local_path, const git_clone_options *options); diff --git a/include/git2/remote.h b/include/git2/remote.h index f3b0a9443..5f6a78097 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -24,14 +24,6 @@ */ GIT_BEGIN_DECL -/** - * Use this when creating a remote with git_remote_new to get the default fetch - * behavior produced by git_remote_add. It corresponds to this fetchspec (note - * the spaces between '/' and '*' to avoid C compiler errors): - * "+refs/heads/ *:refs/remotes// *" - */ -#define GIT_REMOTE_DEFAULT_FETCH "" - typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload); /* * TODO: This functions still need to be implemented: @@ -41,23 +33,43 @@ typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, voi * - _del (needs support from config) */ +/** + * Add a remote with the default fetch refspec to the repository's configuration. This + * calls git_remote_save before returning. + * + * @param out the resulting remote + * @param repo the repository in which to create the remote + * @param name the remote's name + * @param url the remote's url + * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code + */ +GIT_EXTERN(int) git_remote_create( + git_remote **out, + git_repository *repo, + const char *name, + const char *url); + /** * Create a remote in memory * - * Create a remote with the default refspecs in memory. You can use - * this when you have a URL instead of a remote's name. + * Create a remote with the given refspec in memory. You can use + * this when you have a URL instead of a remote's name. Note that in-memory + * remotes cannot be converted to persisted remotes. * * The name, when provided, will be checked for validity. * See `git_tag_create()` for rules about valid names. * * @param out pointer to the new remote object * @param repo the associated repository. May be NULL for a "dangling" remote. - * @param name the optional remote's name. May be NULL. - * @param url the remote repository's URL * @param fetch the fetch refspec to use for this remote. May be NULL for defaults. - * @return 0, GIT_EINVALIDSPEC or an error code + * @param url the remote repository's URL + * @return 0 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_create_inmemory( + git_remote **out, + git_repository *repo, + const char *fetch, + const char *url); /** * Sets the owning repository for the remote. This is only allowed on @@ -85,7 +97,7 @@ GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const ch /** * Save a remote to its repository's configuration * - * One can't save a nameless inmemory remote. Doing so will + * One can't save a in-memory remote. Doing so will * result in a GIT_EINVALIDSPEC being returned. * * @param remote the remote to save to config @@ -97,7 +109,7 @@ GIT_EXTERN(int) git_remote_save(const git_remote *remote); * Get the remote's name * * @param remote the remote - * @return a pointer to the name + * @return a pointer to the name or NULL for in-memory remotes */ GIT_EXTERN(const char *) git_remote_name(const git_remote *remote); @@ -300,17 +312,6 @@ GIT_EXTERN(int) git_remote_supported_url(const char* url); */ GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo); -/** - * Add a remote with the default fetch refspec to the repository's configuration - * - * @param out the resulting remote - * @param repo the repository in which to create the remote - * @param name the remote's name - * @param url the remote's url - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url); - /** * Choose whether to check the server's certificate (applies to HTTPS only) * @@ -427,12 +428,14 @@ GIT_EXTERN(void) git_remote_set_autotag( * The new name will be checked for validity. * See `git_tag_create()` for rules about valid names. * + * A temporary in-memory remote cannot be given a name with this method. + * * @param remote the remote to rename * @param new_name the new name the remote should bear * @param callback Optional callback to notify the consumer of fetch refspecs * that haven't been automatically updated and need potential manual tweaking. * @param payload Additional data to pass to the callback - * @return 0, GIT_EINVALIDSPEC or an error code + * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code */ GIT_EXTERN(int) git_remote_rename( git_remote *remote, diff --git a/src/clone.c b/src/clone.c index 865521bce..39c0ba26c 100644 --- a/src/clone.c +++ b/src/clone.c @@ -258,27 +258,71 @@ cleanup: * submodules? */ +static int create_and_configure_origin( + git_remote **out, + git_repository *repo, + const char *url, + const git_clone_options *options) +{ + int error; + git_remote *origin = NULL; + + if ((error = git_remote_create(&origin, repo, options->remote_name, url)) < 0) + goto on_error; + + git_remote_set_cred_acquire_cb(origin, options->cred_acquire_cb, + options->cred_acquire_payload); + git_remote_set_autotag(origin, options->remote_autotag); + /* + * Don't write FETCH_HEAD, we'll check out the remote tracking + * branch ourselves based on the server's default. + */ + git_remote_set_update_fetchhead(origin, 0); + + if (options->remote_callbacks && + (error = git_remote_set_callbacks(origin, options->remote_callbacks)) < 0) + goto on_error; + + if (options->fetch_spec && + (error = git_remote_set_fetchspec(origin, options->fetch_spec)) < 0) + goto on_error; + + if (options->push_spec && + (error = git_remote_set_pushspec(origin, options->push_spec)) < 0) + goto on_error; + + if (options->pushurl && + (error = git_remote_set_pushurl(origin, options->pushurl)) < 0) + goto on_error; + + if ((error = git_remote_save(origin)) < 0) + goto on_error; + + *out = origin; + return 0; + +on_error: + git_remote_free(origin); + return error; +} static int setup_remotes_and_fetch( git_repository *repo, - git_remote *origin, - git_transfer_progress_callback progress_cb, - void *progress_payload) + const char *url, + const git_clone_options *options) { int retcode = GIT_ERROR; + git_remote *origin; - /* Add the origin remote */ - if (!git_remote_set_repository(origin, repo) && !git_remote_save(origin)) { - /* - * Don't write FETCH_HEAD, we'll check out the remote tracking - * branch ourselves based on the server's default. - */ + /* Construct an origin remote */ + if (!create_and_configure_origin(&origin, repo, url, options)) { git_remote_set_update_fetchhead(origin, 0); /* Connect and download everything */ if (!git_remote_connect(origin, GIT_DIRECTION_FETCH)) { - if (!git_remote_download(origin, progress_cb, progress_payload)) { + if (!git_remote_download(origin, options->fetch_progress_cb, + options->fetch_progress_payload)) { /* Create "origin/foo" branches for all remote branches */ if (!git_remote_update_tips(origin)) { /* Point HEAD to the same ref as the remote's head */ @@ -318,62 +362,55 @@ static bool should_checkout( if (!opts) return false; + if (opts->checkout_strategy == GIT_CHECKOUT_DEFAULT) + return false; + return !git_repository_head_orphan(repo); } -static int clone_internal( +static void normalize_options(git_clone_options *dst, const git_clone_options *src) +{ + git_clone_options default_options = GIT_CLONE_OPTIONS_INIT; + if (!src) src = &default_options; + + *dst = *src; + + /* Provide defaults for null pointers */ + if (!dst->remote_name) dst->remote_name = "origin"; +} + +int git_clone( git_repository **out, - git_remote *origin_remote, - const char *path, - git_transfer_progress_callback fetch_progress_cb, - void *fetch_progress_payload, - git_checkout_opts *checkout_opts, - bool is_bare) + const char *url, + const char *local_path, + const git_clone_options *options) { int retcode = GIT_ERROR; git_repository *repo = NULL; + git_clone_options normOptions; - if (!path_is_okay(path)) { + assert(out && url && local_path); + + normalize_options(&normOptions, options); + GITERR_CHECK_VERSION(&normOptions, GIT_CLONE_OPTIONS_VERSION, "git_clone_options"); + + if (!path_is_okay(local_path)) { return GIT_ERROR; } - if (!(retcode = git_repository_init(&repo, path, is_bare))) { - if ((retcode = setup_remotes_and_fetch(repo, origin_remote, - fetch_progress_cb, fetch_progress_payload)) < 0) { + if (!(retcode = git_repository_init(&repo, local_path, normOptions.bare))) { + if ((retcode = setup_remotes_and_fetch(repo, url, &normOptions)) < 0) { /* Failed to fetch; clean up */ git_repository_free(repo); - git_futils_rmdir_r(path, NULL, GIT_RMDIR_REMOVE_FILES); + git_futils_rmdir_r(local_path, NULL, GIT_RMDIR_REMOVE_FILES); } else { *out = repo; retcode = 0; } } - if (!retcode && should_checkout(repo, is_bare, checkout_opts)) - retcode = git_checkout_head(*out, checkout_opts); + if (!retcode && should_checkout(repo, normOptions.bare, &normOptions.checkout_opts)) + retcode = git_checkout_head(*out, &normOptions.checkout_opts); return retcode; } - -int git_clone( - git_repository **out, - git_remote *origin, - const char *local_path, - const git_clone_options *options) -{ - git_clone_options dummy_options = GIT_CLONE_OPTIONS_INIT; - - assert(out && origin && local_path); - if (!options) options = &dummy_options; - - GITERR_CHECK_VERSION(options, GIT_CLONE_OPTIONS_VERSION, "git_clone_options"); - - return clone_internal( - out, - origin, - local_path, - options->fetch_progress_cb, - options->fetch_progress_payload, - options->checkout_opts, - options->bare ? 1 : 0); -} diff --git a/src/remote.c b/src/remote.c index 28ce88a93..29734cc1a 100644 --- a/src/remote.c +++ b/src/remote.c @@ -83,14 +83,14 @@ cleanup: return error; } -int git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch) +static int create_internal(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch) { git_remote *remote; git_buf fetchbuf = GIT_BUF_INIT; int error = -1; /* name is optional */ - assert(out && url); + assert(out && repo && url); remote = git__calloc(1, sizeof(git_remote)); GITERR_CHECK_ALLOC(remote); @@ -106,20 +106,8 @@ int git_remote_new(git_remote **out, git_repository *repo, const char *name, con GITERR_CHECK_ALLOC(remote->url); if (name != NULL) { - if ((error = ensure_remote_name_is_valid(name)) < 0) { - error = GIT_EINVALIDSPEC; - goto on_error; - } - remote->name = git__strdup(name); GITERR_CHECK_ALLOC(remote->name); - - /* An empty name indicates to use a sensible default for the fetchspec. */ - if (fetch && !(*fetch)) { - if (git_buf_printf(&fetchbuf, "+refs/heads/*:refs/remotes/%s/*", remote->name) < 0) - goto on_error; - fetch = git_buf_cstr(&fetchbuf); - } } if (fetch != NULL) { @@ -142,6 +130,71 @@ on_error: return error; } +static int ensure_remote_doesnot_exist(git_repository *repo, const char *name) +{ + int error; + git_remote *remote; + + error = git_remote_load(&remote, repo, name); + + if (error == GIT_ENOTFOUND) + return 0; + + if (error < 0) + return error; + + git_remote_free(remote); + + giterr_set( + GITERR_CONFIG, + "Remote '%s' already exists.", name); + + return GIT_EEXISTS; +} + + +int git_remote_create(git_remote **out, git_repository *repo, const char *name, const char *url) +{ + git_buf buf = GIT_BUF_INIT; + int error; + + if ((error = ensure_remote_name_is_valid(name)) < 0) + return error; + + if ((error = ensure_remote_doesnot_exist(repo, name)) < 0) + return error; + + if (git_buf_printf(&buf, "+refs/heads/*:refs/remotes/%s/*", name) < 0) + return -1; + + if (create_internal(out, repo, name, url, git_buf_cstr(&buf)) < 0) + goto on_error; + + git_buf_free(&buf); + + if (git_remote_save(*out) < 0) + goto on_error; + + return 0; + +on_error: + git_buf_free(&buf); + git_remote_free(*out); + return -1; +} + +int git_remote_create_inmemory(git_remote **out, git_repository *repo, const char *fetch, const char *url) +{ + int error; + git_remote *remote; + + if ((error = create_internal(&remote, repo, NULL, url, fetch)) < 0) + return error; + + *out = remote; + return 0; +} + int git_remote_set_repository(git_remote *remote, git_repository *repo) { assert(repo); @@ -312,9 +365,9 @@ int git_remote_save(const git_remote *remote) assert(remote); - if (!remote->repo) { - giterr_set(GITERR_INVALID, "Can't save a dangling remote."); - return GIT_ERROR; + if (!remote->name) { + giterr_set(GITERR_INVALID, "Can't save an in-memory remote."); + return GIT_EINVALIDSPEC; } if ((error = ensure_remote_name_is_valid(remote->name)) < 0) @@ -461,8 +514,7 @@ int git_remote_set_fetchspec(git_remote *remote, const char *spec) return -1; git_refspec__free(&remote->fetch); - remote->fetch.src = refspec.src; - remote->fetch.dst = refspec.dst; + memcpy(&remote->fetch, &refspec, sizeof(git_refspec)); return 0; } @@ -641,7 +693,7 @@ static int update_tips_callback(git_remote_head *head, void *payload) git_vector *refs = (git_vector *)payload; git_vector_insert(refs, head); - return 0; + return 0; } static int remote_head_for_fetchspec_src(git_remote_head **out, git_vector *update_heads, const char *fetchspec_src) @@ -652,11 +704,11 @@ static int remote_head_for_fetchspec_src(git_remote_head **out, git_vector *upda assert(update_heads && fetchspec_src); *out = NULL; - - git_vector_foreach(update_heads, i, remote_ref) { - if (strcmp(remote_ref->name, fetchspec_src) == 0) { - *out = remote_ref; - break; + + git_vector_foreach(update_heads, i, remote_ref) { + if (strcmp(remote_ref->name, fetchspec_src) == 0) { + *out = remote_ref; + break; } } @@ -727,7 +779,7 @@ static int git_remote_write_fetchhead(git_remote *remote, git_vector *update_hea } /* Create the FETCH_HEAD file */ - git_vector_foreach(update_heads, i, remote_ref) { + git_vector_foreach(update_heads, i, remote_ref) { int merge_this_fetchhead = (merge_remote_ref == remote_ref); if (!include_all_fetchheads && @@ -773,11 +825,6 @@ int git_remote_update_tips(git_remote *remote) assert(remote); - if (!remote->repo) { - giterr_set(GITERR_INVALID, "Can't update tips on a dangling remote."); - return GIT_ERROR; - } - spec = &remote->fetch; if (git_repository_odb__weakptr(&odb, remote->repo) < 0) @@ -788,7 +835,7 @@ int git_remote_update_tips(git_remote *remote) /* Make a copy of the transport's refs */ if (git_vector_init(&refs, 16, NULL) < 0 || - git_vector_init(&update_heads, 16, NULL) < 0) + git_vector_init(&update_heads, 16, NULL) < 0) return -1; if (git_remote_ls(remote, update_tips_callback, &refs) < 0) @@ -998,33 +1045,6 @@ int git_remote_list(git_strarray *remotes_list, git_repository *repo) return 0; } -int git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url) -{ - git_buf buf = GIT_BUF_INIT; - int error; - - if ((error = ensure_remote_name_is_valid(name)) < 0) - return error; - - if (git_buf_printf(&buf, "+refs/heads/*:refs/remotes/%s/*", name) < 0) - return -1; - - if (git_remote_new(out, repo, name, url, git_buf_cstr(&buf)) < 0) - goto on_error; - - git_buf_free(&buf); - - if (git_remote_save(*out) < 0) - goto on_error; - - return 0; - -on_error: - git_buf_free(&buf); - git_remote_free(*out); - return -1; -} - void git_remote_check_cert(git_remote *remote, int check) { assert(remote); @@ -1091,28 +1111,6 @@ void git_remote_set_autotag(git_remote *remote, git_remote_autotag_option_t valu remote->download_tags = value; } -static int ensure_remote_doesnot_exist(git_repository *repo, const char *name) -{ - int error; - git_remote *remote; - - error = git_remote_load(&remote, repo, name); - - if (error == GIT_ENOTFOUND) - return 0; - - if (error < 0) - return error; - - git_remote_free(remote); - - giterr_set( - GITERR_CONFIG, - "Remote '%s' already exists.", name); - - return GIT_EEXISTS; -} - static int rename_remote_config_section( git_repository *repo, const char *old_name, @@ -1326,6 +1324,11 @@ int git_remote_rename( assert(remote && new_name); + if (!remote->name) { + giterr_set(GITERR_INVALID, "Can't rename an in-memory remote."); + return GIT_EINVALIDSPEC; + } + if ((error = ensure_remote_name_is_valid(new_name)) < 0) return error; @@ -1343,6 +1346,7 @@ int git_remote_rename( remote->name = git__strdup(new_name); + if (!remote->name) return 0; return git_remote_save(remote); } diff --git a/src/repository.c b/src/repository.c index 10ed12b64..33aaee841 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1140,8 +1140,7 @@ static int repo_init_create_origin(git_repository *repo, const char *url) int error; git_remote *remote; - if (!(error = git_remote_add(&remote, repo, GIT_REMOTE_ORIGIN, url))) { - error = git_remote_save(remote); + if (!(error = git_remote_create(&remote, repo, GIT_REMOTE_ORIGIN, url))) { git_remote_free(remote); } diff --git a/tests-clar/clone/empty.c b/tests-clar/clone/empty.c index 8f2e6ff12..652363747 100644 --- a/tests-clar/clone/empty.c +++ b/tests-clar/clone/empty.c @@ -4,7 +4,6 @@ #include "repository.h" static git_clone_options g_options; -static git_remote *g_origin; static git_repository *g_repo; static git_repository *g_repo_cloned; @@ -17,13 +16,10 @@ void test_clone_empty__initialize(void) memset(&g_options, 0, sizeof(git_clone_options)); g_options.version = GIT_CLONE_OPTIONS_VERSION; - cl_git_pass(git_remote_new(&g_origin, NULL, "origin", cl_git_fixture_url("testrepo.git"), GIT_REMOTE_DEFAULT_FETCH)); } void test_clone_empty__cleanup(void) { - git_remote_free(g_origin); - g_origin = NULL; cl_git_sandbox_cleanup(); } @@ -39,23 +35,15 @@ void test_clone_empty__can_clone_an_empty_local_repo_barely(void) { cl_set_cleanup(&cleanup_repository, "./empty"); - git_remote_free(g_origin); - g_origin = NULL; - cl_git_pass(git_remote_new(&g_origin, NULL, "origin", "./empty_bare.git", GIT_REMOTE_DEFAULT_FETCH)); - g_options.bare = true; - cl_git_pass(git_clone(&g_repo_cloned, g_origin, "./empty", &g_options)); + cl_git_pass(git_clone(&g_repo_cloned, "./empty_bare.git", "./empty", &g_options)); } void test_clone_empty__can_clone_an_empty_local_repo(void) { cl_set_cleanup(&cleanup_repository, "./empty"); - git_remote_free(g_origin); - g_origin = NULL; - cl_git_pass(git_remote_new(&g_origin, NULL, "origin", "./empty_bare.git", GIT_REMOTE_DEFAULT_FETCH)); - - cl_git_pass(git_clone(&g_repo_cloned, g_origin, "./empty", &g_options)); + cl_git_pass(git_clone(&g_repo_cloned, "./empty_bare.git", "./empty", &g_options)); } void test_clone_empty__can_clone_an_empty_standard_repo(void) @@ -64,11 +52,7 @@ void test_clone_empty__can_clone_an_empty_standard_repo(void) g_repo = cl_git_sandbox_init("empty_standard_repo"); cl_git_remove_placeholders(git_repository_path(g_repo), "dummy-marker.txt"); - git_remote_free(g_origin); - g_origin = NULL; - cl_git_pass(git_remote_new(&g_origin, NULL, "origin", "./empty_standard_repo", GIT_REMOTE_DEFAULT_FETCH)); - cl_set_cleanup(&cleanup_repository, "./empty"); - cl_git_pass(git_clone(&g_repo_cloned, g_origin, "./empty", &g_options)); + cl_git_pass(git_clone(&g_repo_cloned, "./empty_standard_repo", "./empty", &g_options)); } diff --git a/tests-clar/clone/network.c b/tests-clar/clone/network.c index d3009660e..885098779 100644 --- a/tests-clar/clone/network.c +++ b/tests-clar/clone/network.c @@ -9,21 +9,18 @@ CL_IN_CATEGORY("network") #define LIVE_EMPTYREPO_URL "http://github.com/libgit2/TestEmptyRepository" static git_repository *g_repo; -static git_remote *g_origin; static git_clone_options g_options; void test_clone_network__initialize(void) { + git_checkout_opts dummy_opts = GIT_CHECKOUT_OPTS_INIT; + g_repo = NULL; memset(&g_options, 0, sizeof(git_clone_options)); g_options.version = GIT_CLONE_OPTIONS_VERSION; - cl_git_pass(git_remote_new(&g_origin, NULL, "origin", LIVE_REPO_URL, GIT_REMOTE_DEFAULT_FETCH)); -} - -void test_clone_network__cleanup(void) -{ - git_remote_free(g_origin); + g_options.checkout_opts = dummy_opts; + g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; } static void cleanup_repository(void *path) @@ -42,7 +39,7 @@ void test_clone_network__network_full(void) cl_set_cleanup(&cleanup_repository, "./foo"); - cl_git_pass(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_assert(!git_repository_is_bare(g_repo)); cl_git_pass(git_remote_load(&origin, g_repo, "origin")); @@ -57,7 +54,7 @@ void test_clone_network__network_bare(void) cl_set_cleanup(&cleanup_repository, "./foo"); g_options.bare = true; - cl_git_pass(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_assert(git_repository_is_bare(g_repo)); cl_git_pass(git_remote_load(&origin, g_repo, "origin")); @@ -69,7 +66,7 @@ void test_clone_network__cope_with_already_existing_directory(void) cl_set_cleanup(&cleanup_repository, "./foo"); p_mkdir("./foo", GIT_DIR_MODE); - cl_git_pass(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); } void test_clone_network__empty_repository(void) @@ -78,10 +75,7 @@ void test_clone_network__empty_repository(void) cl_set_cleanup(&cleanup_repository, "./foo"); - git_remote_free(g_origin); - cl_git_pass(git_remote_new(&g_origin, NULL, "origin", LIVE_EMPTYREPO_URL, GIT_REMOTE_DEFAULT_FETCH)); - - cl_git_pass(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_pass(git_clone(&g_repo, LIVE_EMPTYREPO_URL, "./foo", &g_options)); cl_assert_equal_i(true, git_repository_is_empty(g_repo)); cl_assert_equal_i(true, git_repository_head_orphan(g_repo)); @@ -98,7 +92,8 @@ void test_clone_network__can_prevent_the_checkout_of_a_standard_repo(void) git_buf path = GIT_BUF_INIT; cl_set_cleanup(&cleanup_repository, "./foo"); - cl_git_pass(git_clone(&g_repo, g_origin, "./foo", &g_options)); + g_options.checkout_opts.checkout_strategy = 0; + cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&path))); @@ -122,22 +117,20 @@ static void fetch_progress(const git_transfer_progress *stats, void *payload) void test_clone_network__can_checkout_a_cloned_repo(void) { - git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; git_buf path = GIT_BUF_INIT; git_reference *head; bool checkout_progress_cb_was_called = false, fetch_progress_cb_was_called = false; - opts.checkout_strategy = GIT_CHECKOUT_SAFE; - opts.progress_cb = &checkout_progress; - opts.progress_payload = &checkout_progress_cb_was_called; - g_options.checkout_opts = &opts; + g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; + g_options.checkout_opts.progress_cb = &checkout_progress; + g_options.checkout_opts.progress_payload = &checkout_progress_cb_was_called; g_options.fetch_progress_cb = &fetch_progress; g_options.fetch_progress_payload = &fetch_progress_cb_was_called; cl_set_cleanup(&cleanup_repository, "./foo"); - cl_git_pass(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&path))); @@ -152,3 +145,66 @@ void test_clone_network__can_checkout_a_cloned_repo(void) git_reference_free(head); git_buf_free(&path); } + +static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *payload) +{ + int *callcount = (int*)payload; + GIT_UNUSED(refname); GIT_UNUSED(a); GIT_UNUSED(b); + *callcount = *callcount + 1; + return 0; +} + +void test_clone_network__custom_remote_callbacks(void) +{ + git_remote_callbacks remote_callbacks = GIT_REMOTE_CALLBACKS_INIT; + int callcount = 0; + + cl_set_cleanup(&cleanup_repository, "./foo"); + + g_options.remote_callbacks = &remote_callbacks; + remote_callbacks.update_tips = update_tips; + remote_callbacks.payload = &callcount; + + cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); + cl_assert(callcount > 0); +} + +struct cred_user_pass { + const char *user; + const char *pass; +}; + +static int cred_acquire( + git_cred **cred, + const char *url, + unsigned int allowed_types, + void *payload) +{ + struct cred_user_pass *user_pass = (struct cred_user_pass*)payload; + + GIT_UNUSED(url); + if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 || + git_cred_userpass_plaintext_new(cred, user_pass->user, user_pass->pass) < 0) + return -1; + + return 0; +} + +void test_clone_network__credentials(void) +{ + /* Remote URL environment variable must be set. User and password are optional. */ + const char *remote_url = cl_getenv("GITTEST_REMOTE_URL"); + struct cred_user_pass user_pass = { + cl_getenv("GITTEST_REMOTE_USER"), + cl_getenv("GITTEST_REMOTE_PASS") + }; + + if (!remote_url) return; + + cl_set_cleanup(&cleanup_repository, "./foo"); + + g_options.cred_acquire_cb = cred_acquire; + g_options.cred_acquire_payload = &user_pass; + + cl_git_pass(git_clone(&g_repo, remote_url, "./foo", &g_options)); +} diff --git a/tests-clar/clone/nonetwork.c b/tests-clar/clone/nonetwork.c index 623a0683f..51fedabb3 100644 --- a/tests-clar/clone/nonetwork.c +++ b/tests-clar/clone/nonetwork.c @@ -6,21 +6,18 @@ #define LIVE_REPO_URL "git://github.com/libgit2/TestGitRepository" static git_clone_options g_options; -static git_remote *g_origin; static git_repository *g_repo; void test_clone_nonetwork__initialize(void) { + git_checkout_opts dummy_opts = GIT_CHECKOUT_OPTS_INIT; + g_repo = NULL; memset(&g_options, 0, sizeof(git_clone_options)); g_options.version = GIT_CLONE_OPTIONS_VERSION; - cl_git_pass(git_remote_new(&g_origin, NULL, "origin", cl_git_fixture_url("testrepo.git"), GIT_REMOTE_DEFAULT_FETCH)); -} - -void test_clone_nonetwork__cleanup(void) -{ - git_remote_free(g_origin); + g_options.checkout_opts = dummy_opts; + g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; } static void cleanup_repository(void *path) @@ -36,38 +33,34 @@ static void cleanup_repository(void *path) void test_clone_nonetwork__bad_url(void) { /* Clone should clean up the mess if the URL isn't a git repository */ - git_remote_free(g_origin); - cl_git_pass(git_remote_new(&g_origin, NULL, "origin", "not_a_repo", GIT_REMOTE_DEFAULT_FETCH)); - - cl_git_fail(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options)); cl_assert(!git_path_exists("./foo")); g_options.bare = true; - cl_git_fail(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options)); cl_assert(!git_path_exists("./foo")); } void test_clone_nonetwork__local(void) { cl_set_cleanup(&cleanup_repository, "./foo"); - cl_git_pass(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); } void test_clone_nonetwork__local_absolute_path(void) { - const char *local_src = cl_fixture("testrepo.git"); - git_remote_free(g_origin); - cl_git_pass(git_remote_new(&g_origin, NULL, "origin", local_src, GIT_REMOTE_DEFAULT_FETCH)); - + const char *local_src; cl_set_cleanup(&cleanup_repository, "./foo"); - cl_git_pass(git_clone(&g_repo, g_origin, "./foo", &g_options)); + local_src = cl_fixture("testrepo.git"); + cl_git_pass(git_clone(&g_repo, local_src, "./foo", &g_options)); } void test_clone_nonetwork__local_bare(void) { cl_set_cleanup(&cleanup_repository, "./foo"); + g_options.bare = true; - cl_git_pass(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); } void test_clone_nonetwork__fail_when_the_target_is_a_file(void) @@ -75,7 +68,7 @@ void test_clone_nonetwork__fail_when_the_target_is_a_file(void) cl_set_cleanup(&cleanup_repository, "./foo"); cl_git_mkfile("./foo", "Bar!"); - cl_git_fail(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); } void test_clone_nonetwork__fail_with_already_existing_but_non_empty_directory(void) @@ -84,5 +77,86 @@ void test_clone_nonetwork__fail_with_already_existing_but_non_empty_directory(vo p_mkdir("./foo", GIT_DIR_MODE); cl_git_mkfile("./foo/bar", "Baz!"); - cl_git_fail(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); } + +void test_clone_nonetwork__custom_origin_name(void) +{ + git_remote *remote; + + cl_set_cleanup(&cleanup_repository, "./foo"); + g_options.remote_name = "my_origin"; + cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); + + cl_git_pass(git_remote_load(&remote, g_repo, "my_origin")); + + git_remote_free(remote); +} + +void test_clone_nonetwork__custom_push_url(void) +{ + git_remote *remote; + const char *url = "http://example.com"; + + cl_set_cleanup(&cleanup_repository, "./foo"); + g_options.pushurl = url; + cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); + + cl_git_pass(git_remote_load(&remote, g_repo, "origin")); + cl_assert_equal_s(url, git_remote_pushurl(remote)); + + git_remote_free(remote); +} + +void test_clone_nonetwork__custom_fetch_spec(void) +{ + git_remote *remote; + git_reference *master; + const git_refspec *actual_fs; + const char *spec = "+refs/heads/master:refs/heads/foo"; + + cl_set_cleanup(&cleanup_repository, "./foo"); + g_options.fetch_spec = spec; + cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); + + cl_git_pass(git_remote_load(&remote, g_repo, "origin")); + actual_fs = git_remote_fetchspec(remote); + cl_assert_equal_s("refs/heads/master", git_refspec_src(actual_fs)); + cl_assert_equal_s("refs/heads/foo", git_refspec_dst(actual_fs)); + + cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/foo")); + git_reference_free(master); + + git_remote_free(remote); +} + +void test_clone_nonetwork__custom_push_spec(void) +{ + git_remote *remote; + const git_refspec *actual_fs; + const char *spec = "+refs/heads/master:refs/heads/foo"; + + cl_set_cleanup(&cleanup_repository, "./foo"); + g_options.push_spec = spec; + cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); + + cl_git_pass(git_remote_load(&remote, g_repo, "origin")); + actual_fs = git_remote_pushspec(remote); + cl_assert_equal_s("refs/heads/master", git_refspec_src(actual_fs)); + cl_assert_equal_s("refs/heads/foo", git_refspec_dst(actual_fs)); + + git_remote_free(remote); +} + +void test_clone_nonetwork__custom_autotag(void) +{ + git_strarray tags = {0}; + + cl_set_cleanup(&cleanup_repository, "./foo"); + g_options.remote_autotag = GIT_REMOTE_DOWNLOAD_TAGS_NONE; + cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); + + cl_git_pass(git_tag_list(&tags, g_repo)); + cl_assert_equal_i(0, tags.count); +} + diff --git a/tests-clar/fetchhead/network.c b/tests-clar/fetchhead/network.c index dc223e2aa..412f356c3 100644 --- a/tests-clar/fetchhead/network.c +++ b/tests-clar/fetchhead/network.c @@ -10,7 +10,6 @@ CL_IN_CATEGORY("network") #define LIVE_REPO_URL "git://github.com/libgit2/TestGitRepository" static git_repository *g_repo; -static git_remote *g_origin; static git_clone_options g_options; void test_fetchhead_network__initialize(void) @@ -19,12 +18,6 @@ void test_fetchhead_network__initialize(void) memset(&g_options, 0, sizeof(git_clone_options)); g_options.version = GIT_CLONE_OPTIONS_VERSION; - cl_git_pass(git_remote_new(&g_origin, NULL, "origin", LIVE_REPO_URL, GIT_REMOTE_DEFAULT_FETCH)); -} - -void test_fetchhead_network__cleanup(void) -{ - git_remote_free(g_origin); } static void cleanup_repository(void *path) @@ -42,7 +35,7 @@ static void fetchhead_test_clone(void) { cl_set_cleanup(&cleanup_repository, "./foo"); - cl_git_pass(git_clone(&g_repo, g_origin, "./foo", &g_options)); + cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); } static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fetchhead) diff --git a/tests-clar/network/fetch.c b/tests-clar/network/fetch.c index 4cc23318d..cde4f0365 100644 --- a/tests-clar/network/fetch.c +++ b/tests-clar/network/fetch.c @@ -42,7 +42,7 @@ static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n) callbacks.update_tips = update_tips; counter = 0; - cl_git_pass(git_remote_add(&remote, _repo, "test", url)); + cl_git_pass(git_remote_create(&remote, _repo, "test", url)); git_remote_set_callbacks(remote, &callbacks); git_remote_set_autotag(remote, flag); cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); @@ -87,13 +87,12 @@ void test_network_fetch__doesnt_retrieve_a_pack_when_the_repository_is_up_to_dat { git_repository *_repository; bool invoked = false; - git_remote *remote, *origin; + git_remote *remote; git_clone_options opts = GIT_CLONE_OPTIONS_INIT; - opts.bare = true; - cl_git_pass(git_remote_new(&origin, NULL, "origin", "https://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DEFAULT_FETCH)); - cl_git_pass(git_clone(&_repository, origin, "./fetch/lg2", &opts)); + cl_git_pass(git_clone(&_repository, "https://github.com/libgit2/TestGitRepository.git", + "./fetch/lg2", &opts)); git_repository_free(_repository); cl_git_pass(git_repository_open(&_repository, "./fetch/lg2")); @@ -111,6 +110,5 @@ void test_network_fetch__doesnt_retrieve_a_pack_when_the_repository_is_up_to_dat git_remote_disconnect(remote); git_remote_free(remote); - git_remote_free(origin); git_repository_free(_repository); } diff --git a/tests-clar/network/fetchlocal.c b/tests-clar/network/fetchlocal.c index 018531c5c..24949243e 100644 --- a/tests-clar/network/fetchlocal.c +++ b/tests-clar/network/fetchlocal.c @@ -21,7 +21,7 @@ void test_network_fetchlocal__complete(void) const char *url = cl_git_fixture_url("testrepo.git"); cl_git_pass(git_repository_init(&repo, "foo", true)); - cl_git_pass(git_remote_add(&origin, repo, GIT_REMOTE_ORIGIN, url)); + cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH)); cl_git_pass(git_remote_download(origin, transfer_cb, &callcount)); cl_git_pass(git_remote_update_tips(origin)); @@ -47,7 +47,7 @@ void test_network_fetchlocal__partial(void) cl_assert_equal_i(1, (int)refnames.count); url = cl_git_fixture_url("testrepo.git"); - cl_git_pass(git_remote_add(&origin, repo, GIT_REMOTE_ORIGIN, url)); + cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH)); cl_git_pass(git_remote_download(origin, transfer_cb, &callcount)); cl_git_pass(git_remote_update_tips(origin)); diff --git a/tests-clar/network/push.c b/tests-clar/network/push.c index 788af5267..5f0a80cc4 100644 --- a/tests-clar/network/push.c +++ b/tests-clar/network/push.c @@ -166,7 +166,7 @@ void test_network_push__initialize(void) _remote = NULL; if (_remote_url) { - cl_git_pass(git_remote_add(&_remote, _repo, "test", _remote_url)); + cl_git_pass(git_remote_create(&_remote, _repo, "test", _remote_url)); git_remote_set_cred_acquire_cb(_remote, cred_acquire_cb, &cred_acquire_called); record_callbacks_data_clear(&_record_cbs_data); @@ -496,7 +496,7 @@ void test_network_push__bad_refspecs(void) git_push *push; if (_remote) { - cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH)); +// cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH)); cl_git_pass(git_push_new(&push, _remote)); /* Unexpanded branch names not supported */ diff --git a/tests-clar/network/remotelocal.c b/tests-clar/network/remotelocal.c index 8376b8bf1..5d6a16a2a 100644 --- a/tests-clar/network/remotelocal.c +++ b/tests-clar/network/remotelocal.c @@ -50,7 +50,7 @@ static void connect_to_local_repository(const char *local_repository) { git_buf_sets(&file_path_buf, cl_git_path_url(local_repository)); - cl_git_pass(git_remote_new(&remote, repo, NULL, git_buf_cstr(&file_path_buf), NULL)); + cl_git_pass(git_remote_create_inmemory(&remote, repo, NULL, git_buf_cstr(&file_path_buf))); cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); } diff --git a/tests-clar/network/remoterename.c b/tests-clar/network/remoterename.c index bd582314d..24cfadcc3 100644 --- a/tests-clar/network/remoterename.c +++ b/tests-clar/network/remoterename.c @@ -148,46 +148,6 @@ void test_network_remoterename__cannot_overwrite_an_existing_remote(void) cl_assert_equal_i(GIT_EEXISTS, git_remote_rename(_remote, "test_with_pushurl", dont_call_me_cb, NULL)); } -void test_network_remoterename__renaming_an_inmemory_remote_persists_it(void) -{ - git_remote *remote; - - assert_config_entry_existence(_repo, "remote.durable.url", false); - - cl_git_pass(git_remote_new(&remote, _repo, NULL, "git://github.com/libgit2/durable.git", NULL)); - - assert_config_entry_existence(_repo, "remote.durable.url", false); - - cl_git_pass(git_remote_rename(remote, "durable", dont_call_me_cb, NULL)); - - assert_config_entry_value(_repo, "remote.durable.url", "git://github.com/libgit2/durable.git"); - - git_remote_free(remote); -} - -void test_network_remoterename__renaming_an_inmemory_nameless_remote_notifies_the_inability_to_update_the_fetch_refspec(void) -{ - git_remote *remote; - - char *expected_refspecs[] = { - "+refs/heads/*:refs/remotes/volatile/*", - NULL - }; - - assert_config_entry_existence(_repo, "remote.volatile.url", false); - - cl_git_pass(git_remote_new( - &remote, - _repo, - NULL, - "git://github.com/libgit2/volatile.git", - "+refs/heads/*:refs/remotes/volatile/*")); - - cl_git_pass(git_remote_rename(remote, "durable", ensure_refspecs, &expected_refspecs)); - - git_remote_free(remote); -} - void test_network_remoterename__renaming_a_remote_moves_the_underlying_reference(void) { git_reference *underlying; @@ -202,3 +162,13 @@ void test_network_remoterename__renaming_a_remote_moves_the_underlying_reference cl_git_pass(git_reference_lookup(&underlying, _repo, "refs/remotes/just/renamed/master")); git_reference_free(underlying); } + +void test_network_remoterename__cannot_rename_an_inmemory_remote(void) +{ + git_remote *remote; + + cl_git_pass(git_remote_create_inmemory(&remote, _repo, NULL, "file:///blah")); + cl_git_fail(git_remote_rename(remote, "newname", NULL, NULL)); + + git_remote_free(remote); +} diff --git a/tests-clar/network/remotes.c b/tests-clar/network/remotes.c index 651cbefec..e947ffe93 100644 --- a/tests-clar/network/remotes.c +++ b/tests-clar/network/remotes.c @@ -108,7 +108,7 @@ void test_network_remotes__save(void) _remote = NULL; /* Set up the remote and save it to config */ - cl_git_pass(git_remote_new(&_remote, _repo, "upstream", "git://github.com/libgit2/libgit2", NULL)); + cl_git_pass(git_remote_create(&_remote, _repo, "upstream", "git://github.com/libgit2/libgit2")); cl_git_pass(git_remote_set_fetchspec(_remote, "refs/heads/*:refs/remotes/upstream/*")); cl_git_pass(git_remote_set_pushspec(_remote, "refs/heads/*:refs/heads/*")); cl_git_pass(git_remote_set_pushurl(_remote, "git://github.com/libgit2/libgit2_push")); @@ -123,7 +123,7 @@ void test_network_remotes__save(void) cl_assert(_refspec != NULL); cl_assert_equal_s(git_refspec_src(_refspec), "refs/heads/*"); cl_assert_equal_s(git_refspec_dst(_refspec), "refs/remotes/upstream/*"); - cl_assert(git_refspec_force(_refspec) == 0); + cl_assert_equal_i(0, git_refspec_force(_refspec)); _refspec = git_remote_pushspec(_remote); cl_assert(_refspec != NULL); @@ -229,7 +229,7 @@ void test_network_remotes__add(void) git_remote_free(_remote); _remote = NULL; - cl_git_pass(git_remote_add(&_remote, _repo, "addtest", "http://github.com/libgit2/libgit2")); + cl_git_pass(git_remote_create(&_remote, _repo, "addtest", "http://github.com/libgit2/libgit2")); git_remote_free(_remote); _remote = NULL; @@ -248,16 +248,18 @@ void test_network_remotes__cannot_add_a_nameless_remote(void) cl_assert_equal_i( GIT_EINVALIDSPEC, - git_remote_add(&remote, _repo, NULL, "git://github.com/libgit2/libgit2")); + git_remote_create(&remote, _repo, NULL, "git://github.com/libgit2/libgit2")); } -void test_network_remotes__cannot_save_a_nameless_remote(void) +void test_network_remotes__cannot_save_an_inmemory_remote(void) { git_remote *remote; - cl_git_pass(git_remote_new(&remote, _repo, NULL, "git://github.com/libgit2/libgit2", NULL)); + cl_git_pass(git_remote_create_inmemory(&remote, _repo, NULL, "git://github.com/libgit2/libgit2")); - cl_assert_equal_i(GIT_EINVALIDSPEC, git_remote_save(remote)); + cl_assert_equal_p(NULL, git_remote_name(remote)); + + cl_git_fail(git_remote_save(remote)); git_remote_free(remote); } @@ -267,27 +269,12 @@ void test_network_remotes__cannot_add_a_remote_with_an_invalid_name(void) cl_assert_equal_i( GIT_EINVALIDSPEC, - git_remote_add(&remote, _repo, "Inv@{id", "git://github.com/libgit2/libgit2")); + git_remote_create(&remote, _repo, "Inv@{id", "git://github.com/libgit2/libgit2")); cl_assert_equal_p(remote, NULL); cl_assert_equal_i( GIT_EINVALIDSPEC, - git_remote_add(&remote, _repo, "", "git://github.com/libgit2/libgit2")); - cl_assert_equal_p(remote, NULL); -} - -void test_network_remotes__cannot_initialize_a_remote_with_an_invalid_name(void) -{ - git_remote *remote = NULL; - - cl_assert_equal_i( - GIT_EINVALIDSPEC, - git_remote_new(&remote, _repo, "Inv@{id", "git://github.com/libgit2/libgit2", NULL)); - cl_assert_equal_p(remote, NULL); - - cl_assert_equal_i( - GIT_EINVALIDSPEC, - git_remote_new(&remote, _repo, "", "git://github.com/libgit2/libgit2", NULL)); + git_remote_create(&remote, _repo, "", "git://github.com/libgit2/libgit2")); cl_assert_equal_p(remote, NULL); } @@ -331,7 +318,7 @@ void test_network_remotes__check_structure_version(void) git_remote_free(_remote); _remote = NULL; - cl_git_pass(git_remote_new(&_remote, _repo, NULL, "test-protocol://localhost", NULL)); + cl_git_pass(git_remote_create_inmemory(&_remote, _repo, NULL, "test-protocol://localhost")); transport.version = 0; cl_git_fail(git_remote_set_transport(_remote, &transport)); @@ -345,19 +332,13 @@ void test_network_remotes__check_structure_version(void) cl_assert_equal_i(GITERR_INVALID, err->klass); } -void test_network_remotes__dangling(void) +void test_network_remotes__cannot_create_a_remote_which_name_conflicts_with_an_existing_remote(void) { - git_remote_free(_remote); - _remote = NULL; + git_remote *remote = NULL; - cl_git_pass(git_remote_new(&_remote, NULL, "upstream", "git://github.com/libgit2/libgit2", NULL)); + cl_assert_equal_i( + GIT_EEXISTS, + git_remote_create(&remote, _repo, "test", "git://github.com/libgit2/libgit2")); - cl_git_pass(git_remote_rename(_remote, "newname", NULL, NULL)); - cl_assert_equal_s(git_remote_name(_remote), "newname"); - - cl_git_fail(git_remote_save(_remote)); - cl_git_fail(git_remote_update_tips(_remote)); - - cl_git_pass(git_remote_set_repository(_remote, _repo)); - cl_git_pass(git_remote_save(_remote)); + cl_assert_equal_p(remote, NULL); }