diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2015-05-13 10:47:13 +0200 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-05-13 10:47:13 +0200 |
commit | c5c5cdb106d012d132475d9156923857f8d302fc (patch) | |
tree | 5ae893bcb3220ccdab9284c271a966b20946a1a5 | |
parent | f85a9c2767b43f35904bf39858488a4b7bc304e8 (diff) | |
parent | 3251972e1fbab379d9ec5a94e455431d005446d1 (diff) | |
download | libgit2-c5c5cdb106d012d132475d9156923857f8d302fc.tar.gz |
Merge pull request #3066 from libgit2/cmn/remote-less-state
Remove the configuration state we keep in the remote
40 files changed, 905 insertions, 1017 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index d8bea9e15..80d7b41f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,12 @@ support for HTTPS connections insead of OpenSSL. * Checkout can now accept an index for the baseline computations via the `baseline_index` member. +* The configuration for fetching is no longer stored inside the + `git_remote` struct but has been moved to a `git_fetch_options`. The + remote functions now take these options or the callbacks instead of + setting them beforehand. + + ### API additions * The `git_merge_options` gained a `file_flags` member. @@ -64,7 +70,15 @@ support for HTTPS connections insead of OpenSSL. put into the reflog as the source/target. * `git_index_add_frombuffer()` can now create a blob from memory - buffer and add it to the index which is attached to a repository. + buffer and add it to the index which is attached to a repository. + +* The structure `git_fetch_options` has been added to determine the + runtime configuration for fetching, such as callbacks, pruning and + autotag behaviour. It has the runtime initializer + `git_fetch_init_options()`. + +* The enum `git_fetch_prune_t` has been added, letting you specify the + pruning behaviour for a fetch. * `git_stash_apply()` can now apply a stashed state from the stash list, placing the data into the working directory and index. @@ -74,6 +88,15 @@ support for HTTPS connections insead of OpenSSL. ### API removals +* `git_remote_save()` and `git_remote_clear_refspecs()` has been + removed. Remote's configuration is changed via the configuration + directly or through a convenience function which performs changes to + the configuration directly. + +* `git_remote_set_callbacks()`, `git_remote_get_callbacks()` and + `git_remote_set_transport()` have been removed a the remote no + longer stores this configuration. + ### Breaking API changes * `git_smart_subtransport_cb` now has a `param` parameter. @@ -130,6 +153,39 @@ support for HTTPS connections insead of OpenSSL. `git_rebase_open` functions take a `git_rebase_options`, where they will persist the options to subsequent `git_rebase` calls. +* The `git_clone_options` struct now has fetch options in a + `fetch_opts` field instead of remote callbacks in + `remote_callbacks`. + +* The following functions now longer act on a remote instance but + change the repository's configuration. Their signatures have changed + accordingly: + + * `git_remote_set_url()`, `git_remote_seturl()` + * `git_remote_add_fetch()`, `git_remote_add_push()` and + * `git_remote_set_autotag()` + +* `git_remote_connect()` and `git_remote_prune()` now take a pointer + to the callbacks. + +* `git_remote_fetch()` and `git_remote_download()` now take a poitner + to fetch options which determine the runtime configuration. + +* The `git_remote_autotag_option_t` values have been changed. It has + gained a `_FALLBACK` default value to specify no override for the + configured setting. + +* `git_remote_update_tips()` now takes a pointer to the callbacks as + well as a boolean whether to write `FETCH_HEAD` and the autotag + setting. + +* The `git_submodule_update_options` struct now has fetch options in + the `fetch_opts` field instead of callbacks in the + `remote_callbacks` field. + +* The `push` function in the `git_transport` interface now takes a + pointer to the remote callbacks. + v0.22 ------ diff --git a/examples/network/clone.c b/examples/network/clone.c index 270bb68be..37e373d5a 100644 --- a/examples/network/clone.c +++ b/examples/network/clone.c @@ -86,9 +86,9 @@ int do_clone(git_repository *repo, int argc, char **argv) checkout_opts.progress_cb = checkout_progress; checkout_opts.progress_payload = &pd; clone_opts.checkout_opts = checkout_opts; - clone_opts.remote_callbacks.transfer_progress = &fetch_progress; - clone_opts.remote_callbacks.credentials = cred_acquire_cb; - clone_opts.remote_callbacks.payload = &pd; + clone_opts.fetch_opts.callbacks.transfer_progress = &fetch_progress; + clone_opts.fetch_opts.callbacks.credentials = cred_acquire_cb; + clone_opts.fetch_opts.callbacks.payload = &pd; // Do the clone error = git_clone(&cloned_repo, url, path, &clone_opts); diff --git a/examples/network/fetch.c b/examples/network/fetch.c index a4bec032e..e47f5be4f 100644 --- a/examples/network/fetch.c +++ b/examples/network/fetch.c @@ -10,6 +10,7 @@ struct dl_data { git_remote *remote; + git_fetch_options *fetch_opts; int ret; int finished; }; @@ -28,7 +29,7 @@ static void *download(void *ptr) // Connect to the remote end specifying that we want to fetch // information from it. - if (git_remote_connect(data->remote, GIT_DIRECTION_FETCH) < 0) { + if (git_remote_connect(data->remote, GIT_DIRECTION_FETCH, &data->fetch_opts->callbacks) < 0) { data->ret = -1; goto exit; } @@ -36,7 +37,7 @@ static void *download(void *ptr) // Download the packfile and index it. This function updates the // amount of received data and the indexer stats which lets you // inform the user about progress. - if (git_remote_download(data->remote, NULL) < 0) { + if (git_remote_download(data->remote, NULL, data->fetch_opts) < 0) { data->ret = -1; goto exit; } @@ -78,7 +79,7 @@ int fetch(git_repository *repo, int argc, char **argv) git_remote *remote = NULL; const git_transfer_progress *stats; struct dl_data data; - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; #ifndef _WIN32 pthread_t worker; #endif @@ -96,13 +97,13 @@ int fetch(git_repository *repo, int argc, char **argv) } // Set up the callbacks (only update_tips for now) - callbacks.update_tips = &update_cb; - callbacks.sideband_progress = &progress_cb; - callbacks.credentials = cred_acquire_cb; - git_remote_set_callbacks(remote, &callbacks); + fetch_opts.callbacks.update_tips = &update_cb; + fetch_opts.callbacks.sideband_progress = &progress_cb; + fetch_opts.callbacks.credentials = cred_acquire_cb; // Set up the information for the background worker thread data.remote = remote; + data.fetch_opts = &fetch_opts; data.ret = 0; data.finished = 0; @@ -156,7 +157,7 @@ int fetch(git_repository *repo, int argc, char **argv) // right commits. This may be needed even if there was no packfile // to download, which can happen e.g. when the branches have been // changed but all the needed objects are available locally. - if (git_remote_update_tips(remote, NULL) < 0) + if (git_remote_update_tips(remote, &fetch_opts.callbacks, 1, fetch_opts.download_tags, NULL) < 0) return -1; git_remote_free(remote); diff --git a/examples/network/ls-remote.c b/examples/network/ls-remote.c index 5e3ade94f..a26092265 100644 --- a/examples/network/ls-remote.c +++ b/examples/network/ls-remote.c @@ -25,9 +25,8 @@ static int use_remote(git_repository *repo, char *name) * each of the remote references. */ callbacks.credentials = cred_acquire_cb; - git_remote_set_callbacks(remote, &callbacks); - error = git_remote_connect(remote, GIT_DIRECTION_FETCH); + error = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks); if (error < 0) goto cleanup; diff --git a/examples/remote.c b/examples/remote.c index b756b5642..e0d5a1406 100644 --- a/examples/remote.c +++ b/examples/remote.c @@ -151,7 +151,6 @@ static int cmd_seturl(git_repository *repo, struct opts *o) { int i, retval, push = 0; char *name = NULL, *url = NULL; - git_remote *remote; for (i = 0; i < o->argc; i++) { char *arg = o->argv[i]; @@ -170,19 +169,12 @@ static int cmd_seturl(git_repository *repo, struct opts *o) if (name == NULL || url == NULL) usage("you need to specify remote and the new URL", NULL); - check_lg2(git_remote_lookup(&remote, repo, name), - "could not look up remote", name); - if (push) - retval = git_remote_set_pushurl(remote, url); + retval = git_remote_set_pushurl(repo, name, url); else - retval = git_remote_set_url(remote, url); - check_lg2(retval, "could not set URL", url); + retval = git_remote_set_url(repo, name, url); - check_lg2(git_remote_save(remote), - "could not save remote", NULL); - - git_remote_free(remote); + check_lg2(retval, "could not set URL", url); return 0; } diff --git a/include/git2.h b/include/git2.h index cf6b5cb89..a1e78376f 100644 --- a/include/git2.h +++ b/include/git2.h @@ -40,7 +40,6 @@ #include "git2/pack.h" #include "git2/patch.h" #include "git2/pathspec.h" -#include "git2/push.h" #include "git2/rebase.h" #include "git2/refdb.h" #include "git2/reflog.h" diff --git a/include/git2/clone.h b/include/git2/clone.h index d3bd42485..9e23aaccb 100644 --- a/include/git2/clone.h +++ b/include/git2/clone.h @@ -111,13 +111,12 @@ typedef struct git_clone_options { git_checkout_options checkout_opts; /** - * Callbacks to use for reporting fetch progress, and for acquiring - * credentials in the event they are needed. This parameter is ignored if - * the remote_cb parameter is set; if you provide a remote creation - * callback, then you have the opportunity to configure remote callbacks in - * provided function. + * Options which control the fetch, including callbacks. + * + * The callbacks are used for reporting fetch progress, and for acquiring + * credentials in the event they are needed. */ - git_remote_callbacks remote_callbacks; + git_fetch_options fetch_opts; /** * Set to zero (false) to create a standard repo, or non-zero @@ -167,7 +166,7 @@ typedef struct git_clone_options { #define GIT_CLONE_OPTIONS_VERSION 1 #define GIT_CLONE_OPTIONS_INIT { GIT_CLONE_OPTIONS_VERSION, \ { GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE }, \ - GIT_REMOTE_CALLBACKS_INIT } + GIT_FETCH_OPTIONS_INIT } /** * Initializes a `git_clone_options` with default values. Equivalent to diff --git a/include/git2/push.h b/include/git2/push.h deleted file mode 100644 index 3f850453d..000000000 --- a/include/git2/push.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_push_h__ -#define INCLUDE_git_push_h__ - -#include "common.h" -#include "pack.h" - -/** - * @file git2/push.h - * @brief Git push management functions - * @defgroup git_push push management functions - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Controls the behavior of a git_push object. - */ -typedef struct { - unsigned int version; - - /** - * If the transport being used to push to the remote requires the creation - * of a pack file, this controls the number of worker threads used by - * the packbuilder when creating that pack file to be sent to the remote. - * - * If set to 0, the packbuilder will auto-detect the number of threads - * to create. The default value is 1. - */ - unsigned int pb_parallelism; -} git_push_options; - -#define GIT_PUSH_OPTIONS_VERSION 1 -#define GIT_PUSH_OPTIONS_INIT { GIT_PUSH_OPTIONS_VERSION } - -/** - * Initializes a `git_push_options` with default values. Equivalent to - * creating an instance with GIT_PUSH_OPTIONS_INIT. - * - * @param opts the `git_push_options` instance to initialize. - * @param version the version of the struct; you should pass - * `GIT_PUSH_OPTIONS_VERSION` here. - * @return Zero on success; -1 on failure. - */ -GIT_EXTERN(int) git_push_init_options( - git_push_options *opts, - unsigned int version); - -/** Push network progress notification function */ -typedef int (*git_push_transfer_progress)( - unsigned int current, - unsigned int total, - size_t bytes, - void* payload); - -/** - * Represents an update which will be performed on the remote during push - */ -typedef struct { - /** - * The source name of the reference - */ - char *src_refname; - /** - * The name of the reference to update on the server - */ - char *dst_refname; - /** - * The current target of the reference - */ - git_oid src; - /** - * The new target for the reference - */ - git_oid dst; -} git_push_update; - -/** - * @param updates an array containing the updates which will be sent - * as commands to the destination. - * @param len number of elements in `updates` - * @param payload Payload provided by the caller - */ -typedef int (*git_push_negotiation)(const git_push_update **updates, size_t len, void *payload); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/remote.h b/include/git2/remote.h index 6e88a4680..ab14ad4dc 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -14,7 +14,7 @@ #include "indexer.h" #include "strarray.h" #include "transport.h" -#include "push.h" +#include "pack.h" /** * @file git2/remote.h @@ -28,8 +28,7 @@ GIT_BEGIN_DECL typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload); /** - * Add a remote with the default fetch refspec to the repository's configuration. This - * calls git_remote_save before returning. + * 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 @@ -45,8 +44,7 @@ GIT_EXTERN(int) git_remote_create( /** * Add a remote with the provided fetch refspec (or default if NULL) to the repository's - * configuration. This - * calls git_remote_save before returning. + * configuration. * * @param out the resulting remote * @param repo the repository in which to create the remote @@ -98,17 +96,6 @@ GIT_EXTERN(int) git_remote_create_anonymous( GIT_EXTERN(int) git_remote_lookup(git_remote **out, git_repository *repo, const char *name); /** - * Save a remote to its repository's configuration - * - * 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 - * @return 0, GIT_EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_remote_save(const git_remote *remote); - -/** * Create a copy of an existing remote. All internal strings are also * duplicated. Callbacks are not duplicated. * @@ -153,38 +140,43 @@ GIT_EXTERN(const char *) git_remote_url(const git_remote *remote); GIT_EXTERN(const char *) git_remote_pushurl(const git_remote *remote); /** - * Set the remote's url + * Set the remote's url in the configuration * - * Existing connections will not be updated. + * Remote objects already in memory will not be affected. This assumes + * the common case of a single-url remote and will otherwise return an error. * - * @param remote the remote + * @param repo the repository in which to perform the change + * @param remote the remote's name * @param url the url to set * @return 0 or an error value */ -GIT_EXTERN(int) git_remote_set_url(git_remote *remote, const char* url); +GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, const char* url); /** - * Set the remote's url for pushing + * Set the remote's url for pushing in the configuration. * - * Existing connections will not be updated. + * Remote objects already in memory will not be affected. This assumes + * the common case of a single-url remote and will otherwise return an error. * - * @param remote the remote - * @param url the url to set or NULL to clear the pushurl - * @return 0 or an error value + * + * @param repo the repository in which to perform the change + * @param remote the remote's name + * @param url the url to set */ -GIT_EXTERN(int) git_remote_set_pushurl(git_remote *remote, const char* url); +GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url); /** - * Add a fetch refspec to the remote + * Add a fetch refspec to the remote's configuration * - * Convenience function for adding a single fetch refspec to the - * current list in the remote. + * Add the given refspec to the fetch list in the configuration. No + * loaded remote instances will be affected. * - * @param remote the remote + * @param repo the repository in which to change the configuration + * @param remote the name of the remote to change * @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); +GIT_EXTERN(int) git_remote_add_fetch(git_repository *repo, const char *remote, const char *refspec); /** * Get the remote's list of fetch refspecs @@ -208,16 +200,17 @@ GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, const git_rem GIT_EXTERN(int) git_remote_set_fetch_refspecs(git_remote *remote, git_strarray *array); /** - * Add a push refspec to the remote + * Add a push refspec to the remote's configuration * - * Convenience function for adding a single push refspec to the - * current list in the remote. + * Add the given refspec to the push list in the configuration. No + * loaded remote instances will be affected. * - * @param remote the remote + * @param repo the repository in which to change the configuration + * @param remote the name of the remote to change * @param refspec the new push refspec * @return 0 or an error value */ -GIT_EXTERN(int) git_remote_add_push(git_remote *remote, const char *refspec); +GIT_EXTERN(int) git_remote_add_push(git_repository *repo, const char *remote, const char *refspec); /** * Get the remote's list of push refspecs @@ -241,15 +234,6 @@ GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, const git_remo 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. - * - * @param remote the remote - */ -GIT_EXTERN(void) git_remote_clear_refspecs(git_remote *remote); - -/** * Get the number of refspecs for a remote * * @param remote the remote @@ -276,9 +260,10 @@ GIT_EXTERN(const git_refspec *)git_remote_get_refspec(const git_remote *remote, * @param remote the remote to connect to * @param direction GIT_DIRECTION_FETCH if you want to fetch or * GIT_DIRECTION_PUSH if you want to push + * @param callbacks the callbacks to use for this connection * @return 0 or an error code */ -GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction); +GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks); /** * Get the remote repository's reference advertisement list @@ -303,36 +288,6 @@ GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction); GIT_EXTERN(int) git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote); /** - * Download and index the packfile - * - * Connect to the remote if it hasn't been done yet, negotiate with - * the remote git which objects are missing, download and index the - * packfile. - * - * The .idx file will be created and both it and the packfile with be - * renamed to their final name. - * - * @param remote the remote - * @param refspecs the refspecs to use for this negotiation and - * download. Use NULL or an empty array to use the base refspecs - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_download(git_remote *remote, const git_strarray *refspecs); - -/** - * Create a packfile and send it to the server - * - * Connect to the remote if it hasn't been done yet, negotiate with - * the remote git which objects are missing, create a packfile with the missing objects and send it. - * - * @param remote the remote - * @param refspecs the refspecs to use for this negotiation and - * upload. Use NULL or an empty array to use the base refspecs - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_upload(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts); - -/** * Check whether the remote is connected * * Check whether the remote's underlying transport is connected to the @@ -373,60 +328,6 @@ GIT_EXTERN(void) git_remote_disconnect(git_remote *remote); GIT_EXTERN(void) git_remote_free(git_remote *remote); /** - * Update the tips to the new state - * - * @param remote the remote to update - * @param reflog_message The message to insert into the reflogs. If - * NULL and fetching, the default is "fetch <name>", where <name> is - * the name of the remote (or its url, for in-memory remotes). This - * parameter is ignored when pushing. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_update_tips( - git_remote *remote, - const char *reflog_message); - -/** - * Prune tracking refs that are no longer present on remote - * - * @param remote the remote to prune - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_prune(git_remote *remote); - -/** - * Download new data and update tips - * - * Convenience function to connect to a remote, download the data, - * disconnect and update the remote-tracking branches. - * - * @param remote the remote to fetch from - * @param refspecs the refspecs to use for this fetch. Pass NULL or an - * empty array to use the base refspecs. - * @param reflog_message The message to insert into the reflogs. If NULL, the - * default is "fetch" - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_fetch( - git_remote *remote, - const git_strarray *refspecs, - const char *reflog_message); - -/** - * Perform a push - * - * Peform all the steps from a push. - * - * @param remote the remote to push to - * @param refspecs the refspecs to use for pushing. If none are - * passed, the configured refspecs will be used - * @param opts the options - */ -GIT_EXTERN(int) git_remote_push(git_remote *remote, - const git_strarray *refspecs, - const git_push_options *opts); - -/** * Get a list of the configured remotes for a repo * * The string array must be freed by the user. @@ -447,6 +348,42 @@ typedef enum git_remote_completion_type { GIT_REMOTE_COMPLETION_ERROR, } git_remote_completion_type; +/** Push network progress notification function */ +typedef int (*git_push_transfer_progress)( + unsigned int current, + unsigned int total, + size_t bytes, + void* payload); +/** + * Represents an update which will be performed on the remote during push + */ +typedef struct { + /** + * The source name of the reference + */ + char *src_refname; + /** + * The name of the reference to update on the server + */ + char *dst_refname; + /** + * The current target of the reference + */ + git_oid src; + /** + * The new target for the reference + */ + git_oid dst; +} git_push_update; + +/** + * @param updates an array containing the updates which will be sent + * as commands to the destination. + * @param len number of elements in `updates` + * @param payload Payload provided by the caller + */ +typedef int (*git_push_negotiation)(const git_push_update **updates, size_t len, void *payload); + /** * The callback settings structure * @@ -527,6 +464,12 @@ struct git_remote_callbacks { git_push_negotiation push_negotiation; /** + * Create the transport to use for this operation. Leave NULL + * to auto-detect. + */ + git_transport_cb transport; + + /** * This will be passed to each of the callbacks in this struct * as the last parameter. */ @@ -548,44 +491,230 @@ GIT_EXTERN(int) git_remote_init_callbacks( git_remote_callbacks *opts, unsigned int version); +typedef enum { + /** + * Use the setting from the configuration + */ + GIT_FETCH_PRUNE_FALLBACK, + /** + * Force pruning on + */ + GIT_FETCH_PRUNE, + /** + * Force pruning off + */ + GIT_FETCH_NO_PRUNE, +} git_fetch_prune_t; + +/** + * Automatic tag following option + * + * Lets us select the --tags option to use. + */ +typedef enum { + /** + * Use the setting from the configuration. + */ + GIT_REMOTE_DOWNLOAD_TAGS_FALLBACK = 0, + /** + * Ask the server for tags pointing to objects we're already + * downloading. + */ + GIT_REMOTE_DOWNLOAD_TAGS_AUTO, + /** + * Don't ask for any tags beyond the refspecs. + */ + GIT_REMOTE_DOWNLOAD_TAGS_NONE, + /** + * Ask for the all the tags. + */ + GIT_REMOTE_DOWNLOAD_TAGS_ALL, +} git_remote_autotag_option_t; + +typedef struct { + int version; + + /** + * Callbacks to use for this fetch operation + */ + git_remote_callbacks callbacks; + + /** + * Whether to perform a prune after the fetch + */ + git_fetch_prune_t prune; + + /** + * Whether to write the results to FETCH_HEAD. Defaults to + * on. Leave this default in order to behave like git. + */ + int update_fetchhead; + + /** + * Determines how to behave regarding tags on the remote, such + * as auto-downloading tags for objects we're downloading or + * downloading all of them. + * + * The default is to auto-follow tags. + */ + git_remote_autotag_option_t download_tags; +} git_fetch_options; + +#define GIT_FETCH_OPTIONS_VERSION 1 +#define GIT_FETCH_OPTIONS_INIT { GIT_FETCH_OPTIONS_VERSION, GIT_REMOTE_CALLBACKS_INIT, 0, 1 } + +/** + * Initializes a `git_fetch_options` with default values. Equivalent to + * creating an instance with GIT_FETCH_OPTIONS_INIT. + * + * @param opts the `git_push_options` instance to initialize. + * @param version the version of the struct; you should pass + * `GIT_FETCH_OPTIONS_VERSION` here. + * @return Zero on success; -1 on failure. + */ +GIT_EXTERN(int) git_fetch_init_options( + git_fetch_options *opts, + unsigned int version); + + /** - * Set the callbacks for a remote + * Controls the behavior of a git_push object. + */ +typedef struct { + unsigned int version; + + /** + * If the transport being used to push to the remote requires the creation + * of a pack file, this controls the number of worker threads used by + * the packbuilder when creating that pack file to be sent to the remote. + * + * If set to 0, the packbuilder will auto-detect the number of threads + * to create. The default value is 1. + */ + unsigned int pb_parallelism; + + /** + * Callbacks to use for this push operation + */ + git_remote_callbacks callbacks; +} git_push_options; + +#define GIT_PUSH_OPTIONS_VERSION 1 +#define GIT_PUSH_OPTIONS_INIT { GIT_PUSH_OPTIONS_VERSION, 0, GIT_REMOTE_CALLBACKS_INIT } + +/** + * Initializes a `git_push_options` with default values. Equivalent to + * creating an instance with GIT_PUSH_OPTIONS_INIT. * - * Note that the remote keeps its own copy of the data and you need to - * call this function again if you want to change the callbacks. + * @param opts the `git_push_options` instance to initialize. + * @param version the version of the struct; you should pass + * `GIT_PUSH_OPTIONS_VERSION` here. + * @return Zero on success; -1 on failure. + */ +GIT_EXTERN(int) git_push_init_options( + git_push_options *opts, + unsigned int version); + +/** + * Download and index the packfile + * + * Connect to the remote if it hasn't been done yet, negotiate with + * the remote git which objects are missing, download and index the + * packfile. * - * @param remote the remote to configure - * @param callbacks a pointer to the user's callback settings + * The .idx file will be created and both it and the packfile with be + * renamed to their final name. + * + * @param remote the remote + * @param refspecs the refspecs to use for this negotiation and + * download. Use NULL or an empty array to use the base refspecs + * @param opts the options to use for this fetch * @return 0 or an error code */ -GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *callbacks); + GIT_EXTERN(int) git_remote_download(git_remote *remote, const git_strarray *refspecs, const git_fetch_options *opts); /** - * Retrieve the current callback structure + * Create a packfile and send it to the server * - * This provides read access to the callbacks structure as the remote - * sees it. + * Connect to the remote if it hasn't been done yet, negotiate with + * the remote git which objects are missing, create a packfile with the missing objects and send it. * - * @param remote the remote to query - * @return a pointer to the callbacks structure + * @param remote the remote + * @param refspecs the refspecs to use for this negotiation and + * upload. Use NULL or an empty array to use the base refspecs + * @param opts the options to use for this push + * @return 0 or an error code */ -GIT_EXTERN(const git_remote_callbacks *) git_remote_get_callbacks(git_remote *remote); +GIT_EXTERN(int) git_remote_upload(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts); /** - * Get the statistics structure that is filled in by the fetch operation. + * Update the tips to the new state + * + * @param remote the remote to update + * @param reflog_message The message to insert into the reflogs. If + * NULL and fetching, the default is "fetch <name>", where <name> is + * the name of the remote (or its url, for in-memory remotes). This + * parameter is ignored when pushing. + * @param callbacks pointer to the callback structure to use + * @param update_fetchhead whether to write to FETCH_HEAD. Pass 1 to behave like git. + * @param download_tags what the behaviour for downloading tags is for this fetch. This is + * ignored for push. This must be the same value passed to `git_remote_download()`. + * @return 0 or an error code */ -GIT_EXTERN(const git_transfer_progress *) git_remote_stats(git_remote *remote); +GIT_EXTERN(int) git_remote_update_tips( + git_remote *remote, + const git_remote_callbacks *callbacks, + int update_fetchhead, + git_remote_autotag_option_t download_tags, + const char *reflog_message); /** - * Automatic tag following option + * Download new data and update tips * - * Lets us select the --tags option to use. + * Convenience function to connect to a remote, download the data, + * disconnect and update the remote-tracking branches. + * + * @param remote the remote to fetch from + * @param refspecs the refspecs to use for this fetch. Pass NULL or an + * empty array to use the base refspecs. + * @param opts options to use for this fetch + * @param reflog_message The message to insert into the reflogs. If NULL, the + * default is "fetch" + * @return 0 or an error code */ -typedef enum { - GIT_REMOTE_DOWNLOAD_TAGS_AUTO = 0, - GIT_REMOTE_DOWNLOAD_TAGS_NONE = 1, - GIT_REMOTE_DOWNLOAD_TAGS_ALL = 2 -} git_remote_autotag_option_t; +GIT_EXTERN(int) git_remote_fetch( + git_remote *remote, + const git_strarray *refspecs, + const git_fetch_options *opts, + const char *reflog_message); + +/** + * Prune tracking refs that are no longer present on remote + * + * @param remote the remote to prune + * @param callbacks callbacks to use for this prune + * @return 0 or an error code + */ +GIT_EXTERN(int) git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks); + +/** + * Perform a push + * + * Peform all the steps from a push. + * + * @param remote the remote to push to + * @param refspecs the refspecs to use for pushing. If none are + * passed, the configured refspecs will be used + * @param opts options to use for this push + */ +GIT_EXTERN(int) git_remote_push(git_remote *remote, + const git_strarray *refspecs, + const git_push_options *opts); + +/** + * Get the statistics structure that is filled in by the fetch operation. + */ +GIT_EXTERN(const git_transfer_progress *) git_remote_stats(git_remote *remote); /** * Retrieve the tag auto-follow setting @@ -596,15 +725,16 @@ typedef enum { GIT_EXTERN(git_remote_autotag_option_t) git_remote_autotag(const git_remote *remote); /** - * Set the tag auto-follow setting + * Set the remote's tag following setting. + * + * The change will be made in the configuration. No loaded remotes + * will be affected. * - * @param remote the remote to configure - * @param value a GIT_REMOTE_DOWNLOAD_TAGS value + * @param repo the repository in which to make the change + * @param remote the name of the remote + * @param value the new value to take. */ -GIT_EXTERN(void) git_remote_set_autotag( - git_remote *remote, - git_remote_autotag_option_t value); - +GIT_EXTERN(int) git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_autotag_option_t value); /** * Retrieve the ref-prune setting * @@ -640,23 +770,6 @@ GIT_EXTERN(int) git_remote_rename( const char *new_name); /** - * Retrieve the update FETCH_HEAD setting. - * - * @param remote the remote to query - * @return the update FETCH_HEAD setting - */ -GIT_EXTERN(int) git_remote_update_fetchhead(git_remote *remote); - -/** - * Sets the update FETCH_HEAD setting. By default, FETCH_HEAD will be - * updated on every fetch. Set to 0 to disable. - * - * @param remote the remote to configure - * @param value 0 to disable updating FETCH_HEAD - */ -GIT_EXTERN(void) git_remote_set_update_fetchhead(git_remote *remote, int value); - -/** * Ensure the remote name is well-formed. * * @param remote_name name to be checked. diff --git a/include/git2/submodule.h b/include/git2/submodule.h index 86f5fef22..48faf8a49 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -130,10 +130,12 @@ typedef struct git_submodule_update_options { git_checkout_options checkout_opts; /** - * Callbacks to use for reporting fetch progress, and for acquiring + * Options which control the fetch, including callbacks. + * + * The callbacks to use for reporting fetch progress, and for acquiring * credentials in the event they are needed. */ - git_remote_callbacks remote_callbacks; + git_fetch_options fetch_opts; /** * The checkout strategy to use when the sub repository needs to @@ -147,7 +149,7 @@ typedef struct git_submodule_update_options { #define GIT_SUBMODULE_UPDATE_OPTIONS_INIT \ { GIT_CHECKOUT_OPTIONS_VERSION, \ { GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE }, \ - GIT_REMOTE_CALLBACKS_INIT, GIT_CHECKOUT_SAFE } + GIT_FETCH_OPTIONS_INIT, GIT_CHECKOUT_SAFE } /** * Initializes a `git_submodule_update_options` with default values. diff --git a/include/git2/sys/transport.h b/include/git2/sys/transport.h index 2cb1a97eb..867fbcbce 100644 --- a/include/git2/sys/transport.h +++ b/include/git2/sys/transport.h @@ -30,8 +30,6 @@ typedef enum { GIT_TRANSPORTFLAGS_NONE = 0, } git_transport_flags_t; -typedef struct git_transport git_transport; - struct git_transport { unsigned int version; /* Set progress and error callbacks */ @@ -61,7 +59,7 @@ struct git_transport { git_transport *transport); /* Executes the push whose context is in the git_push object. */ - int (*push)(git_transport *transport, git_push *push); + int (*push)(git_transport *transport, git_push *push, const git_remote_callbacks *callbacks); /* This function may be called after a successful call to connect(), when * the direction is FETCH. The function performs a negotiation to calculate @@ -142,9 +140,6 @@ GIT_EXTERN(int) git_transport_new(git_transport **out, git_remote *owner, const */ GIT_EXTERN(int) git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *payload); -/* Signature of a function which creates a transport */ -typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param); - /** * Add a custom transport definition, to be used in addition to the built-in * set of transports that come with libgit2. @@ -353,21 +348,6 @@ GIT_EXTERN(int) git_smart_subtransport_ssh( git_transport* owner, void *param); -/** - * Sets a custom transport factory for the remote. The caller can use this - * function to override the transport used for this remote when performing - * network operations. - * - * @param remote the remote to configure - * @param transport_cb the function to use to create a transport - * @param payload opaque parameter passed to transport_cb - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_set_transport( - git_remote *remote, - git_transport_cb transport_cb, - void *payload); - /** @} */ GIT_END_DECL #endif diff --git a/include/git2/transport.h b/include/git2/transport.h index c10907f5f..99fd09a1b 100644 --- a/include/git2/transport.h +++ b/include/git2/transport.h @@ -20,6 +20,9 @@ */ GIT_BEGIN_DECL +/** Signature of a function which creates a transport */ +typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param); + /** * Type of SSH host fingerprint */ diff --git a/include/git2/types.h b/include/git2/types.h index fdb5f2b09..d1e7cd92c 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -224,6 +224,12 @@ typedef struct git_refspec git_refspec; typedef struct git_remote git_remote; /** + * Interface which represents a transport to communicate with a + * remote. + */ +typedef struct git_transport git_transport; + +/** * Preparation for a push operation. Can be used to configure what to * push and the level of parallelism of the packfile builder. */ diff --git a/src/clone.c b/src/clone.c index 7e5d3302e..8b42ce706 100644 --- a/src/clone.c +++ b/src/clone.c @@ -24,7 +24,7 @@ #include "repository.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); +static int clone_local_into(git_repository *repo, git_remote *remote, const git_fetch_options *fetch_opts, const git_checkout_options *co_opts, const char *branch, int link); static int create_branch( git_reference **branch, @@ -242,13 +242,9 @@ static int default_remote_create( const char *url, void *payload) { - int error; - git_remote_callbacks *callbacks = payload; - - if ((error = git_remote_create(out, repo, name, url)) < 0) - return error; + GIT_UNUSED(payload); - return git_remote_set_callbacks(*out, callbacks); + return git_remote_create(out, repo, name, url); } /* @@ -277,15 +273,12 @@ static int create_and_configure_origin( if (!remote_create) { remote_create = default_remote_create; - payload = (void *)&options->remote_callbacks; + payload = NULL; } if ((error = remote_create(&origin, repo, "origin", url, payload)) < 0) goto on_error; - if ((error = git_remote_save(origin)) < 0) - goto on_error; - *out = origin; return 0; @@ -328,12 +321,12 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c return error; } -static int clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch) +static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch_options *opts, const git_checkout_options *co_opts, const char *branch) { int error; git_buf reflog_message = GIT_BUF_INIT; + git_fetch_options fetch_opts; git_remote *remote; - const git_remote_callbacks *callbacks; assert(repo && _remote); @@ -345,18 +338,12 @@ static int clone_into(git_repository *repo, git_remote *_remote, const git_check 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, callbacks)) < 0) - goto cleanup; - - if ((error = git_remote_add_fetch(remote, "refs/tags/*:refs/tags/*")) < 0) - goto cleanup; - - git_remote_set_update_fetchhead(remote, 0); + memcpy(&fetch_opts, opts, sizeof(git_fetch_options)); + fetch_opts.update_fetchhead = 0; + fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL; git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote)); - if ((error = git_remote_fetch(remote, NULL, git_buf_cstr(&reflog_message))) != 0) + if ((error = git_remote_fetch(remote, NULL, &fetch_opts, git_buf_cstr(&reflog_message))) != 0) goto cleanup; error = checkout_branch(repo, remote, co_opts, branch, git_buf_cstr(&reflog_message)); @@ -439,11 +426,11 @@ int git_clone( if (clone_local == 1) error = clone_local_into( - repo, origin, &options.checkout_opts, + repo, origin, &options.fetch_opts, &options.checkout_opts, options.checkout_branch, link); else if (clone_local == 0) error = clone_into( - repo, origin, &options.checkout_opts, + repo, origin, &options.fetch_opts, &options.checkout_opts, options.checkout_branch); else error = -1; @@ -506,7 +493,7 @@ static bool can_link(const char *src, const char *dst, int link) #endif } -static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link) +static int clone_local_into(git_repository *repo, git_remote *remote, const git_fetch_options *fetch_opts, const git_checkout_options *co_opts, const char *branch, int link) { int error, flags; git_repository *src; @@ -551,7 +538,7 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_ git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote)); - if ((error = git_remote_fetch(remote, NULL, git_buf_cstr(&reflog_message))) != 0) + if ((error = git_remote_fetch(remote, NULL, fetch_opts, git_buf_cstr(&reflog_message))) != 0) goto cleanup; error = checkout_branch(repo, remote, co_opts, branch, git_buf_cstr(&reflog_message)); diff --git a/src/fetch.c b/src/fetch.c index f61685619..82d86bbce 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -19,14 +19,14 @@ #include "repository.h" #include "refs.h" -static int maybe_want(git_remote *remote, git_remote_head *head, git_odb *odb, git_refspec *tagspec) +static int maybe_want(git_remote *remote, git_remote_head *head, git_odb *odb, git_refspec *tagspec, git_remote_autotag_option_t tagopt) { int match = 0; if (!git_reference_is_valid_name(head->name)) return 0; - if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL) { + if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_ALL) { /* * If tagopt is --tags, always request tags * in addition to the remote's refspecs @@ -51,13 +51,17 @@ static int maybe_want(git_remote *remote, git_remote_head *head, git_odb *odb, g return git_vector_insert(&remote->refs, head); } -static int filter_wants(git_remote *remote) +static int filter_wants(git_remote *remote, const git_fetch_options *opts) { git_remote_head **heads; git_refspec tagspec, head; int error = 0; git_odb *odb; size_t i, heads_len; + git_remote_autotag_option_t tagopt = remote->download_tags; + + if (opts && opts->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_FALLBACK) + tagopt = opts->download_tags; git_vector_clear(&remote->refs); if ((error = git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true)) < 0) @@ -87,7 +91,7 @@ static int filter_wants(git_remote *remote) goto cleanup; for (i = 0; i < heads_len; i++) { - if ((error = maybe_want(remote, heads[i], odb, &tagspec)) < 0) + if ((error = maybe_want(remote, heads[i], odb, &tagspec, tagopt)) < 0) break; } @@ -102,13 +106,13 @@ cleanup: * them out. When we get an ACK we hide that commit and continue * traversing until we're done */ -int git_fetch_negotiate(git_remote *remote) +int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) { git_transport *t = remote->transport; - remote->need_pack = 0; + remote->need_pack = 0; - if (filter_wants(remote) < 0) { + if (filter_wants(remote, opts) < 0) { giterr_set(GITERR_NET, "Failed to filter the reference list for wants"); return -1; } @@ -127,13 +131,26 @@ int git_fetch_negotiate(git_remote *remote) remote->refs.length); } -int git_fetch_download_pack(git_remote *remote) +int git_fetch_download_pack(git_remote *remote, const git_remote_callbacks *callbacks) { git_transport *t = remote->transport; + git_transfer_progress_cb progress = NULL; + void *payload = NULL; if (!remote->need_pack) return 0; - return t->download_pack(t, remote->repo, &remote->stats, - remote->callbacks.transfer_progress, remote->callbacks.payload); + if (callbacks) { + progress = callbacks->transfer_progress; + payload = callbacks->payload; + } + + return t->download_pack(t, remote->repo, &remote->stats, progress, payload); +} + +int git_fetch_init_options(git_fetch_options *opts, unsigned int version) +{ + GIT_INIT_STRUCTURE_FROM_TEMPLATE( + opts, version, git_fetch_options, GIT_FETCH_OPTIONS_INIT); + return 0; } diff --git a/src/fetch.h b/src/fetch.h index f66e44663..aa2a87715 100644 --- a/src/fetch.h +++ b/src/fetch.h @@ -9,9 +9,9 @@ #include "netops.h" -int git_fetch_negotiate(git_remote *remote); +int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts); -int git_fetch_download_pack(git_remote *remote); +int git_fetch_download_pack(git_remote *remote, const git_remote_callbacks *callbacks); int git_fetch__download_pack( git_transport *t, diff --git a/src/push.c b/src/push.c index 3ac6fbf63..abe90b76d 100644 --- a/src/push.c +++ b/src/push.c @@ -77,30 +77,6 @@ int git_push_set_options(git_push *push, const git_push_options *opts) return 0; } -int git_push_set_callbacks( - git_push *push, - git_packbuilder_progress pack_progress_cb, - void *pack_progress_cb_payload, - git_push_transfer_progress transfer_progress_cb, - void *transfer_progress_cb_payload, - git_push_negotiation negotiation_cb, - void *negotiation_cb_payload) -{ - if (!push) - return -1; - - push->pack_progress_cb = pack_progress_cb; - push->pack_progress_cb_payload = pack_progress_cb_payload; - - push->transfer_progress_cb = transfer_progress_cb; - push->transfer_progress_cb_payload = transfer_progress_cb_payload; - - push->negotiation_cb = negotiation_cb; - push->negotiation_cb_payload = negotiation_cb_payload; - - return 0; -} - static void free_refspec(push_spec *spec) { if (spec == NULL) @@ -179,7 +155,7 @@ int git_push_add_refspec(git_push *push, const char *refspec) return 0; } -int git_push_update_tips(git_push *push) +int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks) { git_buf remote_ref_name = GIT_BUF_INIT; size_t i, j; @@ -236,9 +212,9 @@ int git_push_update_tips(git_push *push) fire_callback = 0; } - if (fire_callback && push->remote->callbacks.update_tips) { - error = push->remote->callbacks.update_tips(git_buf_cstr(&remote_ref_name), - &push_spec->roid, &push_spec->loid, push->remote->callbacks.payload); + if (fire_callback && callbacks && callbacks->update_tips) { + error = callbacks->update_tips(git_buf_cstr(&remote_ref_name), + &push_spec->roid, &push_spec->loid, callbacks->payload); if (error < 0) goto on_error; @@ -595,7 +571,7 @@ static int calculate_work(git_push *push) return 0; } -static int do_push(git_push *push) +static int do_push(git_push *push, const git_remote_callbacks *callbacks) { int error = 0; git_transport *transport = push->remote->transport; @@ -617,21 +593,20 @@ static int do_push(git_push *push) git_packbuilder_set_threads(push->pb, push->pb_parallelism); - if (push->pack_progress_cb) - if ((error = git_packbuilder_set_callbacks(push->pb, push->pack_progress_cb, push->pack_progress_cb_payload)) < 0) + if (callbacks && callbacks->pack_progress) + if ((error = git_packbuilder_set_callbacks(push->pb, callbacks->pack_progress, callbacks->payload)) < 0) goto on_error; if ((error = calculate_work(push)) < 0) goto on_error; - if (push->negotiation_cb && - (error = push->negotiation_cb((const git_push_update **) push->updates.contents, - push->updates.length, - push->negotiation_cb_payload))) + if (callbacks && callbacks->push_negotiation && + (error = callbacks->push_negotiation((const git_push_update **) push->updates.contents, + push->updates.length, callbacks->payload)) < 0) goto on_error; if ((error = queue_objects(push)) < 0 || - (error = transport->push(transport, push)) < 0) + (error = transport->push(transport, push, callbacks)) < 0) goto on_error; on_error: @@ -657,16 +632,16 @@ static int filter_refs(git_remote *remote) return 0; } -int git_push_finish(git_push *push) +int git_push_finish(git_push *push, const git_remote_callbacks *callbacks) { int error; if (!git_remote_connected(push->remote) && - (error = git_remote_connect(push->remote, GIT_DIRECTION_PUSH)) < 0) + (error = git_remote_connect(push->remote, GIT_DIRECTION_PUSH, callbacks)) < 0) return error; if ((error = filter_refs(push->remote)) < 0 || - (error = do_push(push)) < 0) + (error = do_push(push, callbacks)) < 0) return error; if (!push->unpack_ok) { @@ -707,6 +682,7 @@ void git_push_free(git_push *push) { push_spec *spec; push_status *status; + git_push_update *update; unsigned int i; if (push == NULL) @@ -722,6 +698,13 @@ void git_push_free(git_push *push) } git_vector_free(&push->status); + git_vector_foreach(&push->updates, i, update) { + git__free(update->src_refname); + git__free(update->dst_refname); + git__free(update); + } + git_vector_free(&push->updates); + git__free(push); } diff --git a/src/push.h b/src/push.h index fb5f01480..094f96ca9 100644 --- a/src/push.h +++ b/src/push.h @@ -38,13 +38,6 @@ struct git_push { /* options */ unsigned pb_parallelism; - - git_packbuilder_progress pack_progress_cb; - void *pack_progress_cb_payload; - git_push_transfer_progress transfer_progress_cb; - void *transfer_progress_cb_payload; - git_push_negotiation negotiation_cb; - void *negotiation_cb_payload; }; /** @@ -77,31 +70,6 @@ int git_push_set_options( const git_push_options *opts); /** - * Set the callbacks for a push - * - * @param push The push object - * @param pack_progress_cb Function to call with progress information during - * pack building. Be aware that this is called inline with pack building - * operations, so performance may be affected. - * @param pack_progress_cb_payload Payload for the pack progress callback. - * @param transfer_progress_cb Function to call with progress information during - * the upload portion of a push. Be aware that this is called inline with - * pack building operations, so performance may be affected. - * @param transfer_progress_cb_payload Payload for the network progress callback. - * @param push_negotiation_cb Function to call before sending the commands to the remote. - * @param push_negotiation_cb_payload Payload for the negotiation callback - * @return 0 or an error code - */ -int git_push_set_callbacks( - git_push *push, - git_packbuilder_progress pack_progress_cb, - void *pack_progress_cb_payload, - git_push_transfer_progress transfer_progress_cb, - void *transfer_progress_cb_payload, - git_push_negotiation negotiation_cb, - void *negotiation_cb_payload); - -/** * Add a refspec to be pushed * * @param push The push object @@ -119,7 +87,7 @@ int git_push_add_refspec(git_push *push, const char *refspec); * * @return 0 or an error code */ -int git_push_update_tips(git_push *push); +int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks); /** * Perform the push @@ -135,7 +103,7 @@ int git_push_update_tips(git_push *push); * * @return 0 or an error code */ -int git_push_finish(git_push *push); +int git_push_finish(git_push *push, const git_remote_callbacks *callbacks); /** * Invoke callback `cb' on each status entry diff --git a/src/remote.c b/src/remote.c index 5257e85f3..44885bd17 100644 --- a/src/remote.c +++ b/src/remote.c @@ -20,6 +20,12 @@ #include "fetchhead.h" #include "push.h" +#define CONFIG_URL_FMT "remote.%s.url" +#define CONFIG_PUSHURL_FMT "remote.%s.pushurl" +#define CONFIG_FETCH_FMT "remote.%s.fetch" +#define CONFIG_PUSH_FMT "remote.%s.push" +#define CONFIG_TAGOPT_FMT "remote.%s.tagopt" + static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs); static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name); @@ -56,7 +62,6 @@ static int download_tags_value(git_remote *remote, git_config *cfg) git_buf buf = GIT_BUF_INIT; int error; - /* The 0 value is the default (auto), let's see if we need to change it */ if (git_buf_printf(&buf, "remote.%s.tagopt", remote->name) < 0) return -1; @@ -88,6 +93,38 @@ static int ensure_remote_name_is_valid(const char *name) return error; } +static int write_add_refspec(git_repository *repo, const char *name, const char *refspec, bool fetch) +{ + git_config *cfg; + git_buf var = GIT_BUF_INIT; + const char *fmt; + int error; + + if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) + return error; + + fmt = fetch ? CONFIG_FETCH_FMT : CONFIG_PUSH_FMT; + + if ((error = ensure_remote_name_is_valid(name)) < 0) + return error; + + if ((error = git_buf_printf(&var, fmt, name)) < 0) + return error; + + /* + * "$^" is a unmatcheable regexp: it will not match anything at all, so + * all values will be considered new and we will not replace any + * present value. + */ + if ((error = git_config_set_multivar(cfg, var.ptr, "$^", refspec)) < 0) { + goto cleanup; + } + +cleanup: + git_buf_free(&var); + return 0; +} + #if 0 /* We could export this as a helper */ static int get_check_cert(int *out, git_repository *repo) @@ -141,17 +178,20 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n { git_remote *remote; git_config *config = NULL; - git_buf canonical_url = GIT_BUF_INIT, fetchbuf = GIT_BUF_INIT; + git_buf canonical_url = GIT_BUF_INIT; + git_buf var = GIT_BUF_INIT; int error = -1; /* name is optional */ assert(out && repo && url); + if ((error = git_repository_config__weakptr(&config, repo)) < 0) + return error; + remote = git__calloc(1, sizeof(git_remote)); GITERR_CHECK_ALLOC(remote); remote->repo = repo; - remote->update_fetchhead = 1; if (git_vector_init(&remote->refs, 32, NULL) < 0 || canonicalize_url(&canonical_url, url) < 0) @@ -162,10 +202,20 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n if (name != NULL) { remote->name = git__strdup(name); GITERR_CHECK_ALLOC(remote->name); + + if ((error = git_buf_printf(&var, CONFIG_URL_FMT, name)) < 0) + goto on_error; + + if ((error = git_config_set_string(config, var.ptr, remote->url)) < 0) + goto on_error; } if (fetch != NULL) { - if (add_refspec(remote, fetch, true) < 0) + if ((error = add_refspec(remote, fetch, true)) < 0) + goto on_error; + + /* only write for non-anonymous remotes */ + if (name && (error = write_add_refspec(repo, name, fetch, true)) < 0) goto on_error; if ((error = git_repository_config_snapshot(&config, repo)) < 0) @@ -179,9 +229,14 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n goto on_error; } + /* A remote without a name doesn't download tags */ if (!name) - /* A remote without a name doesn't download tags */ remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE; + else + remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO; + + + git_buf_free(&var); *out = remote; error = 0; @@ -191,8 +246,8 @@ on_error: git_remote_free(remote); git_config_free(config); - git_buf_free(&fetchbuf); git_buf_free(&canonical_url); + git_buf_free(&var); return error; } @@ -247,9 +302,6 @@ int git_remote_create_with_fetchspec(git_remote **out, git_repository *repo, con if (create_internal(&remote, repo, name, url, fetch) < 0) goto on_error; - if (git_remote_save(remote) < 0) - goto on_error; - *out = remote; return 0; @@ -261,14 +313,7 @@ on_error: int git_remote_create_anonymous(git_remote **out, git_repository *repo, const char *url, const char *fetch) { - int error; - git_remote *remote; - - if ((error = create_internal(&remote, repo, NULL, url, fetch)) < 0) - return error; - - *out = remote; - return 0; + return create_internal(out, repo, NULL, url, fetch); } int git_remote_dup(git_remote **dest, git_remote *source) @@ -293,11 +338,8 @@ int git_remote_dup(git_remote **dest, git_remote *source) GITERR_CHECK_ALLOC(remote->pushurl); } - remote->transport_cb = source->transport_cb; - remote->transport_cb_payload = source->transport_cb_payload; remote->repo = source->repo; remote->download_tags = source->download_tags; - remote->update_fetchhead = source->update_fetchhead; remote->prune_refs = source->prune_refs; if (git_vector_init(&remote->refs, 32, NULL) < 0 || @@ -387,7 +429,6 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) remote = git__calloc(1, sizeof(git_remote)); GITERR_CHECK_ALLOC(remote); - remote->update_fetchhead = 1; remote->name = git__strdup(name); GITERR_CHECK_ALLOC(remote->name); @@ -408,6 +449,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) optional_setting_found |= found; remote->repo = repo; + remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO; if (found && strlen(val) > 0) { remote->url = git__strdup(val); @@ -543,87 +585,6 @@ cleanup: return error; } -int git_remote_save(const git_remote *remote) -{ - int error; - git_config *cfg; - const char *tagopt = NULL; - git_buf buf = GIT_BUF_INIT; - git_config_entry *existing = NULL; - - assert(remote); - - if (!remote->name) { - giterr_set(GITERR_INVALID, "Can't save an anonymous remote."); - return GIT_EINVALIDSPEC; - } - - if ((error = ensure_remote_name_is_valid(remote->name)) < 0) - return error; - - if ((error = git_repository_config__weakptr(&cfg, remote->repo)) < 0) - return error; - - if ((error = git_buf_printf(&buf, "remote.%s.url", remote->name)) < 0) - return error; - - /* after this point, buffer is allocated so end with cleanup */ - - if ((error = git_config_set_string( - cfg, git_buf_cstr(&buf), remote->url)) < 0) - goto cleanup; - - git_buf_clear(&buf); - if ((error = git_buf_printf(&buf, "remote.%s.pushurl", remote->name)) < 0) - goto cleanup; - - if ((error = git_config__update_entry( - cfg, git_buf_cstr(&buf), remote->pushurl, true, false)) < 0) - goto cleanup; - - if ((error = update_config_refspec(remote, cfg, GIT_DIRECTION_FETCH)) < 0) - goto cleanup; - - if ((error = update_config_refspec(remote, cfg, GIT_DIRECTION_PUSH)) < 0) - goto cleanup; - - /* - * What action to take depends on the old and new values. This - * is describes by the table below. tagopt means whether the - * is already a value set in the config - * - * AUTO ALL or NONE - * +-----------------------+ - * tagopt | remove | set | - * +---------+-------------| - * !tagopt | nothing | set | - * +---------+-------------+ - */ - - git_buf_clear(&buf); - if ((error = git_buf_printf(&buf, "remote.%s.tagopt", remote->name)) < 0) - goto cleanup; - - if ((error = git_config__lookup_entry( - &existing, cfg, git_buf_cstr(&buf), false)) < 0) - goto cleanup; - - if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL) - tagopt = "--tags"; - else if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_NONE) - tagopt = "--no-tags"; - else if (existing != NULL) - tagopt = NULL; - - error = git_config__update_entry( - cfg, git_buf_cstr(&buf), tagopt, true, false); - -cleanup: - git_config_entry_free(existing); - git_buf_free(&buf); - return error; -} - const char *git_remote_name(const git_remote *remote) { assert(remote); @@ -642,16 +603,42 @@ const char *git_remote_url(const git_remote *remote) return remote->url; } -int git_remote_set_url(git_remote *remote, const char* url) +static int set_url(git_repository *repo, const char *remote, const char *pattern, const char *url) { - assert(remote); - assert(url); + git_config *cfg; + git_buf buf = GIT_BUF_INIT, canonical_url = GIT_BUF_INIT; + int error; - git__free(remote->url); - remote->url = git__strdup(url); - GITERR_CHECK_ALLOC(remote->url); + assert(repo && remote); - return 0; + if ((error = ensure_remote_name_is_valid(remote)) < 0) + return error; + + if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) + return error; + + if ((error = git_buf_printf(&buf, pattern, remote)) < 0) + return error; + + if (url) { + if ((error = canonicalize_url(&canonical_url, url)) < 0) + goto cleanup; + + error = git_config_set_string(cfg, buf.ptr, url); + } else { + error = git_config_delete_entry(cfg, buf.ptr); + } + +cleanup: + git_buf_free(&canonical_url); + git_buf_free(&buf); + + return error; +} + +int git_remote_set_url(git_repository *repo, const char *remote, const char *url) +{ + return set_url(repo, remote, CONFIG_URL_FMT, url); } const char *git_remote_pushurl(const git_remote *remote) @@ -660,18 +647,9 @@ const char *git_remote_pushurl(const git_remote *remote) return remote->pushurl; } -int git_remote_set_pushurl(git_remote *remote, const char* url) +int git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url) { - assert(remote); - - git__free(remote->pushurl); - if (url) { - remote->pushurl = git__strdup(url); - GITERR_CHECK_ALLOC(remote->pushurl); - } else { - remote->pushurl = NULL; - } - return 0; + return set_url(repo, remote, CONFIG_PUSHURL_FMT, url); } const char* git_remote__urlfordirection(git_remote *remote, int direction) @@ -691,15 +669,34 @@ const char* git_remote__urlfordirection(git_remote *remote, int direction) return NULL; } -int git_remote_connect(git_remote *remote, git_direction direction) +int set_transport_callbacks(git_transport *t, const git_remote_callbacks *cbs) +{ + if (!t->set_callbacks || !cbs) + return 0; + + return t->set_callbacks(t, cbs->sideband_progress, NULL, + cbs->certificate_check, cbs->payload); +} + +int git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks) { git_transport *t; const char *url; int flags = GIT_TRANSPORTFLAGS_NONE; int error; + void *payload = NULL; + git_cred_acquire_cb credentials = NULL; + git_transport_cb transport = NULL; assert(remote); + if (callbacks) { + GITERR_CHECK_VERSION(callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); + credentials = callbacks->credentials; + transport = callbacks->transport; + payload = callbacks->payload; + } + t = remote->transport; url = git_remote__urlfordirection(remote, direction); @@ -711,8 +708,8 @@ int git_remote_connect(git_remote *remote, git_direction direction) /* If we don't have a transport object yet, and the caller specified a * custom transport factory, use that */ - if (!t && remote->transport_cb && - (error = remote->transport_cb(&t, remote, remote->transport_cb_payload)) < 0) + if (!t && transport && + (error = transport(&t, remote, payload)) < 0) return error; /* If we still don't have a transport, then use the global @@ -720,11 +717,8 @@ int git_remote_connect(git_remote *remote, git_direction direction) if (!t && (error = git_transport_new(&t, remote, url)) < 0) return error; - if (t->set_callbacks && - (error = t->set_callbacks(t, remote->callbacks.sideband_progress, NULL, remote->callbacks.certificate_check, remote->callbacks.payload)) < 0) - goto on_error; - - if ((error = t->connect(t, url, remote->callbacks.credentials, remote->callbacks.payload, direction, flags)) != 0) + if ((error = set_transport_callbacks(t, callbacks)) < 0 || + (error = t->connect(t, url, credentials, payload, direction, flags)) != 0) goto on_error; remote->transport = t; @@ -866,14 +860,24 @@ static int ls_to_vector(git_vector *out, git_remote *remote) return 0; } -int git_remote_download(git_remote *remote, const git_strarray *refspecs) +int git_remote_download(git_remote *remote, const git_strarray *refspecs, const git_fetch_options *opts) { int error = -1; size_t i; git_vector refs, specs, *to_active; + const git_remote_callbacks *cbs = NULL; assert(remote); + if (opts) { + GITERR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); + cbs = &opts->callbacks; + } + + if (!git_remote_connected(remote) && + (error = git_remote_connect(remote, GIT_DIRECTION_FETCH, cbs)) < 0) + goto on_error; + if (ls_to_vector(&refs, remote) < 0) return -1; @@ -912,10 +916,10 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs) remote->push = NULL; } - if ((error = git_fetch_negotiate(remote)) < 0) + if ((error = git_fetch_negotiate(remote, opts)) < 0) return error; - return git_fetch_download_pack(remote); + return git_fetch_download_pack(remote, cbs); on_error: git_vector_free(&refs); @@ -927,16 +931,27 @@ on_error: int git_remote_fetch( git_remote *remote, const git_strarray *refspecs, + const git_fetch_options *opts, const char *reflog_message) { - int error; + int error, update_fetchhead = 1; + git_remote_autotag_option_t tagopt = remote->download_tags; + bool prune = false; git_buf reflog_msg_buf = GIT_BUF_INIT; + const git_remote_callbacks *cbs = NULL; + + if (opts) { + GITERR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); + cbs = &opts->callbacks; + update_fetchhead = opts->update_fetchhead; + tagopt = opts->download_tags; + } /* Connect and download everything */ - if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH)) != 0) + if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH, cbs)) != 0) return error; - error = git_remote_download(remote, refspecs); + error = git_remote_download(remote, refspecs, opts); /* We don't need to be connected anymore */ git_remote_disconnect(remote); @@ -954,13 +969,22 @@ int git_remote_fetch( } /* Create "remote/foo" branches for all remote branches */ - error = git_remote_update_tips(remote, git_buf_cstr(&reflog_msg_buf)); + error = git_remote_update_tips(remote, cbs, update_fetchhead, tagopt, git_buf_cstr(&reflog_msg_buf)); git_buf_free(&reflog_msg_buf); if (error < 0) return error; - if (remote->prune_refs) - error = git_remote_prune(remote); + if (opts && opts->prune == GIT_FETCH_PRUNE) + prune = true; + else if (opts && opts->prune == GIT_FETCH_PRUNE_FALLBACK && remote->prune_refs) + prune = true; + else if (opts && opts->prune == GIT_FETCH_NO_PRUNE) + prune = false; + else + prune = remote->prune_refs; + + if (prune) + error = git_remote_prune(remote, cbs); return error; } @@ -1156,7 +1180,7 @@ static int find_head(const void *_a, const void *_b) return strcmp(a->name, b->name); } -int git_remote_prune(git_remote *remote) +int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks) { size_t i, j; git_vector remote_refs = GIT_VECTOR_INIT; @@ -1166,6 +1190,9 @@ int git_remote_prune(git_remote *remote) int error; git_oid zero_id = {{ 0 }}; + if (callbacks) + GITERR_CHECK_VERSION(callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); + if ((error = ls_to_vector(&remote_refs, remote)) < 0) goto cleanup; @@ -1242,8 +1269,8 @@ int git_remote_prune(git_remote *remote) if (error < 0) goto cleanup; - if (remote->callbacks.update_tips) - error = remote->callbacks.update_tips(refname, &id, &zero_id, remote->callbacks.payload); + if (callbacks && callbacks->update_tips) + error = callbacks->update_tips(refname, &id, &zero_id, callbacks->payload); if (error < 0) goto cleanup; @@ -1257,6 +1284,9 @@ cleanup: static int update_tips_for_spec( git_remote *remote, + const git_remote_callbacks *callbacks, + int update_fetchhead, + git_remote_autotag_option_t tagopt, git_refspec *spec, git_vector *refs, const char *log_message) @@ -1292,9 +1322,9 @@ static int update_tips_for_spec( continue; if (git_refspec_src_matches(&tagspec, head->name)) { - if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_NONE) { + if (tagopt != GIT_REMOTE_DOWNLOAD_TAGS_NONE) { - if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_AUTO) + if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_AUTO) autotag = 1; git_buf_clear(&refname); @@ -1339,13 +1369,13 @@ static int update_tips_for_spec( git_reference_free(ref); - if (remote->callbacks.update_tips != NULL) { - if (remote->callbacks.update_tips(refname.ptr, &old, &head->oid, remote->callbacks.payload) < 0) + if (callbacks && callbacks->update_tips != NULL) { + if (callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload) < 0) goto on_error; } } - if (git_remote_update_fetchhead(remote) && + if (update_fetchhead && (error = git_remote_write_fetchhead(remote, spec, &update_heads)) < 0) goto on_error; @@ -1455,16 +1485,20 @@ static int opportunistic_updates(const git_remote *remote, git_vector *refs, con int git_remote_update_tips( git_remote *remote, + const git_remote_callbacks *callbacks, + int update_fetchhead, + git_remote_autotag_option_t download_tags, const char *reflog_message) { git_refspec *spec, tagspec; git_vector refs = GIT_VECTOR_INIT; + git_remote_autotag_option_t tagopt; int error; size_t i; /* push has its own logic hidden away in the push object */ if (remote->push) { - return git_push_update_tips(remote->push); + return git_push_update_tips(remote->push, callbacks); } if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0) @@ -1474,8 +1508,13 @@ int git_remote_update_tips( if ((error = ls_to_vector(&refs, remote)) < 0) goto out; - if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL) { - if ((error = update_tips_for_spec(remote, &tagspec, &refs, reflog_message)) < 0) + if (download_tags == GIT_REMOTE_DOWNLOAD_TAGS_FALLBACK) + tagopt = remote->download_tags; + else + tagopt = download_tags; + + if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_ALL) { + if ((error = update_tips_for_spec(remote, callbacks, update_fetchhead, tagopt, &tagspec, &refs, reflog_message)) < 0) goto out; } @@ -1483,7 +1522,7 @@ int git_remote_update_tips( if (spec->push) continue; - if ((error = update_tips_for_spec(remote, spec, &refs, reflog_message)) < 0) + if ((error = update_tips_for_spec(remote, callbacks, update_fetchhead, tagopt, spec, &refs, reflog_message)) < 0) goto out; } @@ -1600,48 +1639,6 @@ int git_remote_list(git_strarray *remotes_list, git_repository *repo) return 0; } -int git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *callbacks) -{ - assert(remote && callbacks); - - GITERR_CHECK_VERSION(callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); - - memcpy(&remote->callbacks, callbacks, sizeof(git_remote_callbacks)); - - if (remote->transport && remote->transport->set_callbacks) - return remote->transport->set_callbacks(remote->transport, - remote->callbacks.sideband_progress, - NULL, - remote->callbacks.certificate_check, - remote->callbacks.payload); - - return 0; -} - -const git_remote_callbacks *git_remote_get_callbacks(git_remote *remote) -{ - assert(remote); - - return &remote->callbacks; -} - -int git_remote_set_transport( - git_remote *remote, - git_transport_cb transport_cb, - void *payload) -{ - assert(remote); - - if (remote->transport) { - giterr_set(GITERR_NET, "A transport is already bound to this remote"); - return -1; - } - - remote->transport_cb = transport_cb; - remote->transport_cb_payload = payload; - return 0; -} - const git_transfer_progress* git_remote_stats(git_remote *remote) { assert(remote); @@ -1653,9 +1650,42 @@ git_remote_autotag_option_t git_remote_autotag(const git_remote *remote) return remote->download_tags; } -void git_remote_set_autotag(git_remote *remote, git_remote_autotag_option_t value) +int git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_autotag_option_t value) { - remote->download_tags = value; + git_buf var = GIT_BUF_INIT; + git_config *config; + int error; + + assert(repo && remote); + + if ((error = ensure_remote_name_is_valid(remote)) < 0) + return error; + + if ((error = git_repository_config__weakptr(&config, repo)) < 0) + return error; + + if ((error = git_buf_printf(&var, CONFIG_TAGOPT_FMT, remote))) + return error; + + switch (value) { + case GIT_REMOTE_DOWNLOAD_TAGS_NONE: + error = git_config_set_string(config, var.ptr, "--no-tags"); + break; + case GIT_REMOTE_DOWNLOAD_TAGS_ALL: + error = git_config_set_string(config, var.ptr, "--tags"); + break; + case GIT_REMOTE_DOWNLOAD_TAGS_AUTO: + error = git_config_delete_entry(config, var.ptr); + if (error == GIT_ENOTFOUND) + error = 0; + break; + default: + giterr_set(GITERR_INVALID, "Invalid value for the tagopt setting"); + error = -1; + } + + git_buf_free(&var); + return error; } int git_remote_prune_refs(const git_remote *remote) @@ -1926,16 +1956,6 @@ cleanup: return error; } -int git_remote_update_fetchhead(git_remote *remote) -{ - return (remote->update_fetchhead != 0); -} - -void git_remote_set_update_fetchhead(git_remote *remote, int value) -{ - remote->update_fetchhead = (value != 0); -} - int git_remote_is_valid_name( const char *remote_name) { @@ -1988,26 +2008,14 @@ git_refspec *git_remote__matching_dst_refspec(git_remote *remote, const char *re return NULL; } -void git_remote_clear_refspecs(git_remote *remote) +int git_remote_add_fetch(git_repository *repo, const char *remote, const char *refspec) { - git_refspec *spec; - size_t i; - - git_vector_foreach(&remote->refspecs, i, spec) { - git_refspec__free(spec); - git__free(spec); - } - git_vector_clear(&remote->refspecs); -} - -int git_remote_add_fetch(git_remote *remote, const char *refspec) -{ - return add_refspec(remote, refspec, true); + return write_add_refspec(repo, remote, refspec, true); } -int git_remote_add_push(git_remote *remote, const char *refspec) +int git_remote_add_push(git_repository *repo, const char *remote, const char *refspec) { - return add_refspec(remote, refspec, false); + return write_add_refspec(repo, remote, refspec, false); } static int set_refspecs(git_remote *remote, git_strarray *array, int push) @@ -2321,12 +2329,15 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi int error; git_push *push; git_refspec *spec; - git_remote_callbacks *cbs; + const git_remote_callbacks *cbs = NULL; assert(remote); + if (opts) + cbs = &opts->callbacks; + if (!git_remote_connected(remote) && - (error = git_remote_connect(remote, GIT_DIRECTION_PUSH)) < 0) + (error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs)) < 0) goto cleanup; free_refspecs(&remote->active_refspecs); @@ -2360,17 +2371,10 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi } } - cbs = &remote->callbacks; - if ((error = git_push_set_callbacks(push, - cbs->pack_progress, cbs->payload, - cbs->push_transfer_progress, cbs->payload, - cbs->push_negotiation, cbs->payload)) < 0) - goto cleanup; - - if ((error = git_push_finish(push)) < 0) + if ((error = git_push_finish(push, cbs)) < 0) goto cleanup; - if (cbs->push_update_reference && + if (cbs && cbs->push_update_reference && (error = git_push_status_foreach(push, cbs->push_update_reference, cbs->payload)) < 0) goto cleanup; @@ -2381,16 +2385,22 @@ cleanup: int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts) { int error; + const git_remote_callbacks *cbs = NULL; + + if (opts) { + GITERR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); + cbs = &opts->callbacks; + } assert(remote && refspecs); - if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH)) < 0) + if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs)) < 0) return error; if ((error = git_remote_upload(remote, refspecs, opts)) < 0) return error; - error = git_remote_update_tips(remote, NULL); + error = git_remote_update_tips(remote, cbs, 0, 0, NULL); git_remote_disconnect(remote); return error; diff --git a/src/remote.h b/src/remote.h index a28b565ce..e696997f4 100644 --- a/src/remote.h +++ b/src/remote.h @@ -24,16 +24,12 @@ struct git_remote { git_vector refspecs; git_vector active_refspecs; git_vector passive_refspecs; - git_transport_cb transport_cb; - void *transport_cb_payload; git_transport *transport; git_repository *repo; git_push *push; - git_remote_callbacks callbacks; git_transfer_progress stats; unsigned int need_pack; git_remote_autotag_option_t download_tags; - int update_fetchhead; int prune_refs; int passed_refspecs; }; diff --git a/src/submodule.c b/src/submodule.c index d24a7773a..1139df973 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -950,7 +950,7 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio GITERR_CHECK_VERSION(&update_options, GIT_SUBMODULE_UPDATE_OPTIONS_VERSION, "git_submodule_update_options"); /* Copy over the remote callbacks */ - clone_options.remote_callbacks = update_options.remote_callbacks; + memcpy(&clone_options.fetch_opts, &update_options.fetch_opts, sizeof(git_fetch_options)); /* Get the status of the submodule to determine if it is already initialized */ if ((error = git_submodule_status(&submodule_status, sm)) < 0) diff --git a/src/transports/local.c b/src/transports/local.c index def8ac037..305c71bf0 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -16,7 +16,6 @@ #include "git2/pack.h" #include "git2/commit.h" #include "git2/revparse.h" -#include "git2/push.h" #include "pack-objects.h" #include "refs.h" #include "posix.h" @@ -366,7 +365,8 @@ static int local_push_update_remote_ref( static int local_push( git_transport *transport, - git_push *push) + git_push *push, + const git_remote_callbacks *cbs) { transport_local *t = (transport_local *)transport; git_odb *remote_odb = NULL; @@ -380,6 +380,8 @@ static int local_push( unsigned int i; size_t j; + GIT_UNUSED(cbs); + /* 'push->remote->url' may be a url or path; convert to a path */ if ((error = git_path_from_url_or_path(&buf, push->remote->url)) < 0) { git_buf_free(&buf); @@ -471,7 +473,7 @@ static int local_push( if (!url || t->parent.close(&t->parent) < 0 || t->parent.connect(&t->parent, url, - push->remote->callbacks.credentials, NULL, GIT_DIRECTION_PUSH, flags)) + NULL, NULL, GIT_DIRECTION_PUSH, flags)) goto on_error; } diff --git a/src/transports/smart.h b/src/transports/smart.h index 44e241adc..4c728c7cc 100644 --- a/src/transports/smart.h +++ b/src/transports/smart.h @@ -158,7 +158,7 @@ typedef struct { /* smart_protocol.c */ int git_smart__store_refs(transport_smart *t, int flushes); int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vector *symrefs); -int git_smart__push(git_transport *transport, git_push *push); +int git_smart__push(git_transport *transport, git_push *push, const git_remote_callbacks *cbs); int git_smart__negotiate_fetch( git_transport *transport, diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index f023db4df..7f6b74ca7 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -946,7 +946,7 @@ static int stream_thunk(void *buf, size_t size, void *data) return error; } -int git_smart__push(git_transport *transport, git_push *push) +int git_smart__push(git_transport *transport, git_push *push, const git_remote_callbacks *cbs) { transport_smart *t = (transport_smart *)transport; struct push_packbuilder_payload packbuilder_payload = {0}; @@ -957,9 +957,9 @@ int git_smart__push(git_transport *transport, git_push *push) packbuilder_payload.pb = push->pb; - if (push->transfer_progress_cb) { - packbuilder_payload.cb = push->transfer_progress_cb; - packbuilder_payload.cb_payload = push->transfer_progress_cb_payload; + if (cbs && cbs->transfer_progress) { + packbuilder_payload.cb = cbs->push_transfer_progress; + packbuilder_payload.cb_payload = cbs->payload; } #ifdef PUSH_DEBUG @@ -1010,12 +1010,12 @@ int git_smart__push(git_transport *transport, git_push *push) goto done; /* If progress is being reported write the final report */ - if (push->transfer_progress_cb) { - error = push->transfer_progress_cb( + if (cbs && cbs->push_transfer_progress) { + error = cbs->push_transfer_progress( push->pb->nr_written, push->pb->nr_objects, packbuilder_payload.last_bytes, - push->transfer_progress_cb_payload); + cbs->payload); if (error < 0) goto done; diff --git a/tests/checkout/index.c b/tests/checkout/index.c index b759db206..de0770dba 100644 --- a/tests/checkout/index.c +++ b/tests/checkout/index.c @@ -154,9 +154,7 @@ void test_checkout_index__honor_coresymlinks_default(void) cl_git_pass(git_repository_set_workdir(repo, "symlink", 1)); 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, NULL)); - cl_git_pass(git_remote_update_tips(origin, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, NULL, NULL)); git_remote_free(origin); cl_git_pass(git_revparse_single(&target, repo, "remotes/origin/master")); diff --git a/tests/clone/empty.c b/tests/clone/empty.c index 8f6071096..2a6217580 100644 --- a/tests/clone/empty.c +++ b/tests/clone/empty.c @@ -10,14 +10,14 @@ static git_repository *g_repo_cloned; void test_clone_empty__initialize(void) { git_repository *sandbox = cl_git_sandbox_init("empty_bare.git"); - git_remote_callbacks dummy_callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options dummy_options = GIT_FETCH_OPTIONS_INIT; cl_git_remove_placeholders(git_repository_path(sandbox), "dummy-marker.txt"); g_repo = NULL; memset(&g_options, 0, sizeof(git_clone_options)); g_options.version = GIT_CLONE_OPTIONS_VERSION; - g_options.remote_callbacks = dummy_callbacks; + g_options.fetch_opts = dummy_options; } void test_clone_empty__cleanup(void) diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c index e4794fc14..fec6aff2e 100644 --- a/tests/clone/nonetwork.c +++ b/tests/clone/nonetwork.c @@ -15,7 +15,7 @@ static git_remote* g_remote; void test_clone_nonetwork__initialize(void) { git_checkout_options dummy_opts = GIT_CHECKOUT_OPTIONS_INIT; - git_remote_callbacks dummy_callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options dummy_fetch = GIT_FETCH_OPTIONS_INIT; g_repo = NULL; @@ -23,7 +23,7 @@ void test_clone_nonetwork__initialize(void) g_options.version = GIT_CLONE_OPTIONS_VERSION; g_options.checkout_opts = dummy_opts; g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; - g_options.remote_callbacks = dummy_callbacks; + g_options.fetch_opts = dummy_fetch; } void test_clone_nonetwork__cleanup(void) @@ -179,7 +179,7 @@ void test_clone_nonetwork__can_cancel_clone_in_fetch(void) { g_options.checkout_branch = "test"; - g_options.remote_callbacks.transfer_progress = + g_options.fetch_opts.callbacks.transfer_progress = clone_cancel_fetch_transfer_progress_cb; cl_git_fail_with(git_clone( diff --git a/tests/clone/transport.c b/tests/clone/transport.c index 46c16a241..cccaae219 100644 --- a/tests/clone/transport.c +++ b/tests/clone/transport.c @@ -24,10 +24,9 @@ static int custom_transport_remote_create( { int error; - if ((error = git_remote_create(out, repo, name, url)) < 0) - return error; + GIT_UNUSED(payload); - if ((error = git_remote_set_transport(*out, custom_transport, payload)) < 0) + if ((error = git_remote_create(out, repo, name, url)) < 0) return error; return 0; @@ -40,7 +39,8 @@ void test_clone_transport__custom_transport(void) int custom_transport_used = 0; clone_opts.remote_cb = custom_transport_remote_create; - clone_opts.remote_cb_payload = &custom_transport_used; + clone_opts.fetch_opts.callbacks.transport = custom_transport; + clone_opts.fetch_opts.callbacks.payload = &custom_transport_used; cl_git_pass(git_clone(&repo, cl_fixture("testrepo.git"), "./custom_transport.git", &clone_opts)); git_repository_free(repo); diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c index 2d6d53eb6..24e87a618 100644 --- a/tests/fetchhead/nonetwork.c +++ b/tests/fetchhead/nonetwork.c @@ -331,11 +331,10 @@ void test_fetchhead_nonetwork__unborn_with_upstream(void) cl_git_pass(git_clone(&repo, "./test1", "./repowithunborn", NULL)); /* Simulate someone pushing to it by changing to one that has stuff */ + cl_git_pass(git_remote_set_url(repo, "origin", cl_fixture("testrepo.git"))); cl_git_pass(git_remote_lookup(&remote, repo, "origin")); - cl_git_pass(git_remote_set_url(remote, cl_fixture("testrepo.git"))); - cl_git_pass(git_remote_save(remote)); - cl_git_pass(git_remote_fetch(remote, NULL, NULL)); + cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL)); git_remote_free(remote); cl_git_pass(git_repository_fetchhead_foreach(repo, assert_master_for_merge, NULL)); diff --git a/tests/network/fetchlocal.c b/tests/network/fetchlocal.c index 13b3cf07c..06ee3dd36 100644 --- a/tests/network/fetchlocal.c +++ b/tests/network/fetchlocal.c @@ -34,19 +34,16 @@ void test_network_fetchlocal__complete(void) git_strarray refnames = {0}; const char *url = cl_git_fixture_url("testrepo.git"); - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; - callbacks.transfer_progress = transfer_cb; - callbacks.payload = &callcount; + options.callbacks.transfer_progress = transfer_cb; + options.callbacks.payload = &callcount; cl_set_cleanup(&cleanup_local_repo, "foo"); cl_git_pass(git_repository_init(&repo, "foo", true)); cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH)); - cl_git_pass(git_remote_download(origin, NULL)); - cl_git_pass(git_remote_update_tips(origin, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(19, (int)refnames.count); @@ -66,17 +63,16 @@ void test_network_fetchlocal__prune(void) git_reference *ref; git_repository *remote_repo = cl_git_sandbox_init("testrepo.git"); const char *url = cl_git_path_url(git_repository_path(remote_repo)); - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; - callbacks.transfer_progress = transfer_cb; - callbacks.payload = &callcount; + options.callbacks.transfer_progress = transfer_cb; + options.callbacks.payload = &callcount; cl_set_cleanup(&cleanup_local_repo, "foo"); cl_git_pass(git_repository_init(&repo, "foo", true)); cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_fetch(origin, NULL, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(19, (int)refnames.count); @@ -89,11 +85,8 @@ void test_network_fetchlocal__prune(void) git_reference_free(ref); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH)); - cl_git_pass(git_remote_download(origin, NULL)); - cl_git_pass(git_remote_prune(origin)); - cl_git_pass(git_remote_update_tips(origin, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); + cl_git_pass(git_remote_prune(origin, &options.callbacks)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(18, (int)refnames.count); @@ -105,11 +98,8 @@ void test_network_fetchlocal__prune(void) git_reference_free(ref); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH)); - cl_git_pass(git_remote_download(origin, NULL)); - cl_git_pass(git_remote_prune(origin)); - cl_git_pass(git_remote_update_tips(origin, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); + cl_git_pass(git_remote_prune(origin, &options.callbacks)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(17, (int)refnames.count); @@ -151,9 +141,9 @@ void test_network_fetchlocal__prune_overlapping(void) git_repository *remote_repo = cl_git_sandbox_init("testrepo.git"); const char *url = cl_git_path_url(git_repository_path(remote_repo)); - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; - callbacks.transfer_progress = transfer_cb; - callbacks.payload = &callcount; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; + options.callbacks.transfer_progress = transfer_cb; + options.callbacks.payload = &callcount; cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/master")); git_oid_cpy(&target, git_reference_target(ref)); @@ -165,7 +155,6 @@ void test_network_fetchlocal__prune_overlapping(void) cl_git_pass(git_repository_init(&repo, "foo", true)); cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); - git_remote_set_callbacks(origin, &callbacks); cl_git_pass(git_repository_config(&config, repo)); cl_git_pass(git_config_set_bool(config, "remote.origin.prune", true)); @@ -173,8 +162,7 @@ void test_network_fetchlocal__prune_overlapping(void) git_remote_free(origin); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_fetch(origin, NULL, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); assert_ref_exists(repo, "refs/remotes/origin/master"); assert_ref_exists(repo, "refs/remotes/origin/pr/42"); @@ -188,9 +176,8 @@ void test_network_fetchlocal__prune_overlapping(void) git_remote_free(origin); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); - callbacks.update_tips = update_tips_fail_on_call; - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_fetch(origin, NULL, NULL)); + options.callbacks.update_tips = update_tips_fail_on_call; + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); assert_ref_exists(repo, "refs/remotes/origin/master"); assert_ref_exists(repo, "refs/remotes/origin/pr/42"); @@ -204,9 +191,8 @@ void test_network_fetchlocal__prune_overlapping(void) git_remote_free(origin); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); - callbacks.update_tips = update_tips_fail_on_call; - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_fetch(origin, NULL, NULL)); + options.callbacks.update_tips = update_tips_fail_on_call; + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); git_config_free(config); git_strarray_free(&refnames); @@ -224,17 +210,16 @@ void test_network_fetchlocal__fetchprune(void) git_config *config; git_repository *remote_repo = cl_git_sandbox_init("testrepo.git"); const char *url = cl_git_path_url(git_repository_path(remote_repo)); - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; - callbacks.transfer_progress = transfer_cb; - callbacks.payload = &callcount; + options.callbacks.transfer_progress = transfer_cb; + options.callbacks.payload = &callcount; cl_set_cleanup(&cleanup_local_repo, "foo"); cl_git_pass(git_repository_init(&repo, "foo", true)); cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_fetch(origin, NULL, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(19, (int)refnames.count); @@ -247,9 +232,8 @@ void test_network_fetchlocal__fetchprune(void) git_reference_free(ref); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_fetch(origin, NULL, NULL)); - cl_git_pass(git_remote_prune(origin)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); + cl_git_pass(git_remote_prune(origin, &options.callbacks)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(18, (int)refnames.count); @@ -265,8 +249,7 @@ void test_network_fetchlocal__fetchprune(void) git_config_free(config); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); cl_assert_equal_i(1, git_remote_prune_refs(origin)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_fetch(origin, NULL, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(17, (int)refnames.count); @@ -289,17 +272,16 @@ void test_network_fetchlocal__prune_tag(void) git_repository *remote_repo = cl_git_sandbox_init("testrepo.git"); const char *url = cl_git_path_url(git_repository_path(remote_repo)); - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; - callbacks.transfer_progress = transfer_cb; - callbacks.payload = &callcount; + options.callbacks.transfer_progress = transfer_cb; + options.callbacks.payload = &callcount; cl_set_cleanup(&cleanup_local_repo, "foo"); cl_git_pass(git_repository_init(&repo, "foo", true)); cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_fetch(origin, NULL, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); git_remote_free(origin); cl_git_pass(git_revparse_single(&obj, repo, "origin/master")); @@ -321,8 +303,7 @@ void test_network_fetchlocal__prune_tag(void) git_config_free(config); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); cl_assert_equal_i(1, git_remote_prune_refs(origin)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_fetch(origin, NULL, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); assert_ref_exists(repo, "refs/tags/some-tag"); cl_git_fail_with(GIT_ENOTFOUND, git_reference_lookup(&ref, repo, "refs/remotes/origin/fake-remote")); @@ -346,10 +327,10 @@ void test_network_fetchlocal__partial(void) int callcount = 0; git_strarray refnames = {0}; const char *url; - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; - callbacks.transfer_progress = transfer_cb; - callbacks.payload = &callcount; + options.callbacks.transfer_progress = transfer_cb; + options.callbacks.payload = &callcount; cl_set_cleanup(&cleanup_sandbox, NULL); cl_git_pass(git_reference_list(&refnames, repo)); @@ -357,10 +338,7 @@ void test_network_fetchlocal__partial(void) url = cl_git_fixture_url("testrepo.git"); cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); - git_remote_set_callbacks(origin, &callbacks); - cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH)); - cl_git_pass(git_remote_download(origin, NULL)); - cl_git_pass(git_remote_update_tips(origin, NULL)); + cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); git_strarray_free(&refnames); @@ -380,16 +358,9 @@ static int remote_mirror_cb(git_remote **out, git_repository *repo, GIT_UNUSED(payload); - if ((error = git_remote_create(&remote, repo, name, url)) < 0) + if ((error = git_remote_create_with_fetchspec(&remote, repo, name, url, "+refs/*:refs/*")) < 0) return error; - git_remote_clear_refspecs(remote); - - if ((error = git_remote_add_fetch(remote, "+refs/*:refs/*")) < 0) { - git_remote_free(remote); - return error; - } - *out = remote; return 0; } @@ -418,27 +389,21 @@ void test_network_fetchlocal__multi_remotes(void) git_repository *repo = cl_git_sandbox_init("testrepo.git"); git_remote *test, *test2; git_strarray refnames = {0}; - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; cl_set_cleanup(&cleanup_sandbox, NULL); - callbacks.transfer_progress = transfer_cb; + options.callbacks.transfer_progress = transfer_cb; + cl_git_pass(git_remote_set_url(repo, "test", cl_git_fixture_url("testrepo.git"))); cl_git_pass(git_remote_lookup(&test, repo, "test")); - cl_git_pass(git_remote_set_url(test, cl_git_fixture_url("testrepo.git"))); - git_remote_set_callbacks(test, &callbacks); - cl_git_pass(git_remote_connect(test, GIT_DIRECTION_FETCH)); - cl_git_pass(git_remote_download(test, NULL)); - cl_git_pass(git_remote_update_tips(test, NULL)); + cl_git_pass(git_remote_fetch(test, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(32, (int)refnames.count); git_strarray_free(&refnames); + cl_git_pass(git_remote_set_url(repo, "test_with_pushurl", cl_git_fixture_url("testrepo.git"))); cl_git_pass(git_remote_lookup(&test2, repo, "test_with_pushurl")); - cl_git_pass(git_remote_set_url(test2, cl_git_fixture_url("testrepo.git"))); - git_remote_set_callbacks(test2, &callbacks); - cl_git_pass(git_remote_connect(test2, GIT_DIRECTION_FETCH)); - cl_git_pass(git_remote_download(test2, NULL)); - cl_git_pass(git_remote_update_tips(test2, NULL)); + cl_git_pass(git_remote_fetch(test2, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(44, (int)refnames.count); @@ -463,7 +428,7 @@ void test_network_fetchlocal__call_progress(void) { git_repository *repo; git_remote *remote; - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; int callcount = 0; cl_git_pass(git_repository_init(&repo, "foo.git", true)); @@ -471,11 +436,10 @@ void test_network_fetchlocal__call_progress(void) cl_git_pass(git_remote_create_with_fetchspec(&remote, repo, "origin", cl_git_fixture_url("testrepo.git"), "+refs/heads/*:refs/heads/*")); - callbacks.sideband_progress = sideband_cb; - callbacks.payload = &callcount; - cl_git_pass(git_remote_set_callbacks(remote, &callbacks)); + options.callbacks.sideband_progress = sideband_cb; + options.callbacks.payload = &callcount; - cl_git_pass(git_remote_fetch(remote, NULL, NULL)); + cl_git_pass(git_remote_fetch(remote, NULL, &options, NULL)); cl_assert(callcount != 0); git_remote_free(remote); diff --git a/tests/network/remote/defaultbranch.c b/tests/network/remote/defaultbranch.c index c83d5c8b0..e83755ef6 100644 --- a/tests/network/remote/defaultbranch.c +++ b/tests/network/remote/defaultbranch.c @@ -26,7 +26,7 @@ static void assert_default_branch(const char *should) { git_buf name = GIT_BUF_INIT; - cl_git_pass(git_remote_connect(g_remote, GIT_DIRECTION_FETCH)); + cl_git_pass(git_remote_connect(g_remote, GIT_DIRECTION_FETCH, NULL)); cl_git_pass(git_remote_default_branch(&name, g_remote)); cl_assert_equal_s(should, name.ptr); git_buf_free(&name); @@ -57,7 +57,7 @@ void test_network_remote_defaultbranch__no_default_branch(void) git_buf buf = GIT_BUF_INIT; cl_git_pass(git_remote_create(&remote_b, g_repo_b, "self", git_repository_path(g_repo_b))); - cl_git_pass(git_remote_connect(remote_b, GIT_DIRECTION_FETCH)); + cl_git_pass(git_remote_connect(remote_b, GIT_DIRECTION_FETCH, NULL)); cl_git_pass(git_remote_ls(&heads, &len, remote_b)); cl_assert_equal_i(0, len); @@ -80,7 +80,7 @@ void test_network_remote_defaultbranch__detached_sharing_nonbranch_id(void) cl_git_pass(git_reference_create(&ref, g_repo_a, "refs/foo/bar", &id, 1, NULL)); git_reference_free(ref); - cl_git_pass(git_remote_connect(g_remote, GIT_DIRECTION_FETCH)); + cl_git_pass(git_remote_connect(g_remote, GIT_DIRECTION_FETCH, NULL)); cl_git_fail_with(GIT_ENOTFOUND, git_remote_default_branch(&buf, g_remote)); cl_git_pass(git_clone(&cloned_repo, git_repository_path(g_repo_a), "./local-detached", NULL)); diff --git a/tests/network/remote/local.c b/tests/network/remote/local.c index ba54de6af..21cb93c57 100644 --- a/tests/network/remote/local.c +++ b/tests/network/remote/local.c @@ -40,7 +40,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_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf), NULL)); - cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); + cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL)); } void test_network_remote_local__connected(void) @@ -138,8 +138,7 @@ void test_network_remote_local__shorthand_fetch_refspec0(void) connect_to_local_repository(cl_fixture("testrepo.git")); - cl_git_pass(git_remote_download(remote, &array)); - cl_git_pass(git_remote_update_tips(remote, NULL)); + cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL)); cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/sloppy/master")); git_reference_free(ref); @@ -162,31 +161,29 @@ void test_network_remote_local__shorthand_fetch_refspec1(void) git_reference *ref; connect_to_local_repository(cl_fixture("testrepo.git")); - git_remote_clear_refspecs(remote); - cl_git_pass(git_remote_download(remote, &array)); - cl_git_pass(git_remote_update_tips(remote, NULL)); - - cl_git_fail(git_reference_lookup(&ref, repo, "refs/remotes/master")); + cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL)); + cl_git_fail(git_reference_lookup(&ref, repo, "refs/remotes/origin/master")); cl_git_fail(git_reference_lookup(&ref, repo, "refs/tags/hard_tag")); } void test_network_remote_local__tagopt(void) { git_reference *ref; + git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; cl_git_pass(git_remote_create(&remote, repo, "tagopt", cl_git_path_url(cl_fixture("testrepo.git")))); - git_remote_set_autotag(remote, GIT_REMOTE_DOWNLOAD_TAGS_ALL); - cl_git_pass(git_remote_fetch(remote, NULL, NULL)); + fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL; + cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL)); cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/tagopt/master")); git_reference_free(ref); cl_git_pass(git_reference_lookup(&ref, repo, "refs/tags/hard_tag")); git_reference_free(ref); - git_remote_set_autotag(remote, GIT_REMOTE_DOWNLOAD_TAGS_AUTO); - cl_git_pass(git_remote_fetch(remote, NULL, NULL)); + fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO; + cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL)); cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/tagopt/master")); git_reference_free(ref); } @@ -206,9 +203,7 @@ void test_network_remote_local__push_to_bare_remote(void) /* Get some commits */ connect_to_local_repository(cl_fixture("testrepo.git")); - cl_git_pass(git_remote_download(remote, &array)); - cl_git_pass(git_remote_update_tips(remote, NULL)); - git_remote_disconnect(remote); + cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL)); /* Set up an empty bare repo to push into */ { @@ -219,7 +214,7 @@ void test_network_remote_local__push_to_bare_remote(void) /* Connect to the bare repo */ cl_git_pass(git_remote_create_anonymous(&localremote, repo, "./localbare.git", NULL)); - cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH)); + cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL)); /* Try to push */ cl_git_pass(git_remote_upload(remote, &push_array, NULL)); @@ -244,9 +239,7 @@ void test_network_remote_local__push_to_bare_remote_with_file_url(void) /* Get some commits */ connect_to_local_repository(cl_fixture("testrepo.git")); - cl_git_pass(git_remote_download(remote, &array)); - cl_git_pass(git_remote_update_tips(remote, NULL)); - git_remote_disconnect(remote); + cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL)); /* Set up an empty bare repo to push into */ { @@ -260,7 +253,7 @@ void test_network_remote_local__push_to_bare_remote_with_file_url(void) /* Connect to the bare repo */ cl_git_pass(git_remote_create_anonymous(&localremote, repo, url, NULL)); - cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH)); + cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL)); /* Try to push */ cl_git_pass(git_remote_upload(remote, &push_array, NULL)); @@ -282,12 +275,11 @@ void test_network_remote_local__push_to_non_bare_remote(void) }; /* Shouldn't be able to push to a non-bare remote */ git_remote *localremote; + git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; /* Get some commits */ connect_to_local_repository(cl_fixture("testrepo.git")); - cl_git_pass(git_remote_download(remote, &array)); - cl_git_pass(git_remote_update_tips(remote, NULL)); - git_remote_disconnect(remote); + cl_git_pass(git_remote_fetch(remote, &array, &fetch_opts, NULL)); /* Set up an empty non-bare repo to push into */ { @@ -298,7 +290,7 @@ void test_network_remote_local__push_to_non_bare_remote(void) /* Connect to the bare repo */ cl_git_pass(git_remote_create_anonymous(&localremote, repo, "./localnonbare", NULL)); - cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH)); + cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL)); /* Try to push */ cl_git_fail_with(GIT_EBAREREPO, git_remote_upload(localremote, &push_array, NULL)); @@ -324,7 +316,7 @@ void test_network_remote_local__fetch(void) connect_to_local_repository(cl_fixture("testrepo.git")); - cl_git_pass(git_remote_fetch(remote, &array, "UPDAAAAAATE!!")); + cl_git_pass(git_remote_fetch(remote, &array, NULL, "UPDAAAAAATE!!")); cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/sloppy/master")); git_reference_free(ref); @@ -353,8 +345,7 @@ void test_network_remote_local__reflog(void) connect_to_local_repository(cl_fixture("testrepo.git")); - cl_git_pass(git_remote_download(remote, &array)); - cl_git_pass(git_remote_update_tips(remote, "UPDAAAAAATE!!")); + cl_git_pass(git_remote_fetch(remote, &array, NULL, "UPDAAAAAATE!!")); cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master")); cl_assert_equal_i(1, git_reflog_entrycount(log)); @@ -381,7 +372,7 @@ void test_network_remote_local__fetch_default_reflog_message(void) connect_to_local_repository(cl_fixture("testrepo.git")); - cl_git_pass(git_remote_fetch(remote, &array, NULL)); + cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL)); cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master")); cl_assert_equal_i(1, git_reflog_entrycount(log)); @@ -408,7 +399,7 @@ void test_network_remote_local__opportunistic_update(void) /* this remote has a passive refspec of "refs/heads/<star>:refs/remotes/origin/<star>" */ cl_git_pass(git_remote_create(&remote, repo, "origin", cl_git_fixture_url("testrepo.git"))); /* and we pass the active refspec "master" */ - cl_git_pass(git_remote_fetch(remote, &array, NULL)); + cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL)); /* and we expect that to update our copy of origin's master */ cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/origin/master")); @@ -430,11 +421,8 @@ void test_network_remote_local__update_tips_for_new_remote(void) { /* Push to bare repo */ cl_git_pass(git_remote_create(&new_remote, src_repo, "bare", "./localbare.git")); - cl_git_pass(git_remote_connect(new_remote, GIT_DIRECTION_PUSH)); - cl_git_pass(git_remote_upload(new_remote, &push_array, NULL)); - - /* Update tips and make sure remote branch has been created */ - cl_git_pass(git_remote_update_tips(new_remote, NULL)); + cl_git_pass(git_remote_push(new_remote, &push_array, NULL)); + /* Make sure remote branch has been created */ cl_git_pass(git_branch_lookup(&branch, src_repo, "bare/master", GIT_BRANCH_REMOTE)); git_reference_free(branch); diff --git a/tests/network/remote/remotes.c b/tests/network/remote/remotes.c index 3e6e438cc..f81c1ccc0 100644 --- a/tests/network/remote/remotes.c +++ b/tests/network/remote/remotes.c @@ -54,11 +54,18 @@ void test_network_remote_remotes__parsing(void) void test_network_remote_remotes__pushurl(void) { - cl_git_pass(git_remote_set_pushurl(_remote, "git://github.com/libgit2/notlibgit2")); - cl_assert_equal_s(git_remote_pushurl(_remote), "git://github.com/libgit2/notlibgit2"); + const char *name = git_remote_name(_remote); + git_remote *mod; - cl_git_pass(git_remote_set_pushurl(_remote, NULL)); - cl_assert(git_remote_pushurl(_remote) == NULL); + cl_git_pass(git_remote_set_pushurl(_repo, name, "git://github.com/libgit2/notlibgit2")); + cl_git_pass(git_remote_lookup(&mod, _repo, name)); + cl_assert_equal_s(git_remote_pushurl(mod), "git://github.com/libgit2/notlibgit2"); + git_remote_free(mod); + + cl_git_pass(git_remote_set_pushurl(_repo, name, NULL)); + cl_git_pass(git_remote_lookup(&mod, _repo, name)); + cl_assert(git_remote_pushurl(mod) == NULL); + git_remote_free(mod); } void test_network_remote_remotes__error_when_not_found(void) @@ -73,6 +80,7 @@ void test_network_remote_remotes__error_when_not_found(void) void test_network_remote_remotes__error_when_no_push_available(void) { git_remote *r; + git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; char *specs = { "refs/heads/master", }; @@ -84,9 +92,8 @@ void test_network_remote_remotes__error_when_no_push_available(void) cl_git_pass(git_remote_create_anonymous(&r, _repo, cl_fixture("testrepo.git"), NULL)); - cl_git_pass(git_remote_set_transport(r, git_transport_local, NULL)); - - cl_git_pass(git_remote_connect(r, GIT_DIRECTION_PUSH)); + callbacks.transport = git_transport_local; + cl_git_pass(git_remote_connect(r, GIT_DIRECTION_PUSH, &callbacks)); /* Make sure that push is really not available */ r->transport->push = NULL; @@ -108,9 +115,12 @@ void test_network_remote_remotes__add_fetchspec(void) size = git_remote_refspec_count(_remote); - cl_git_pass(git_remote_add_fetch(_remote, "refs/*:refs/*")); - + cl_git_pass(git_remote_add_fetch(_repo, "test", "refs/*:refs/*")); size++; + + git_remote_free(_remote); + cl_git_pass(git_remote_lookup(&_remote, _repo, "test")); + cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote)); _refspec = git_remote_get_refspec(_remote, size - 1); @@ -149,8 +159,12 @@ void test_network_remote_remotes__add_pushspec(void) size = git_remote_refspec_count(_remote); - cl_git_pass(git_remote_add_push(_remote, "refs/*:refs/*")); + cl_git_pass(git_remote_add_push(_repo, "test", "refs/*:refs/*")); size++; + + git_remote_free(_remote); + cl_git_pass(git_remote_lookup(&_remote, _repo, "test")); + cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote)); _refspec = git_remote_get_refspec(_remote, size - 1); @@ -161,58 +175,6 @@ void test_network_remote_remotes__add_pushspec(void) cl_assert_equal_b(_refspec->push, true); } -void test_network_remote_remotes__save(void) -{ - git_strarray array; - const char *fetch_refspec1 = "refs/heads/ns1/*:refs/remotes/upstream/ns1/*"; - const char *fetch_refspec2 = "refs/heads/ns2/*:refs/remotes/upstream/ns2/*"; - const char *push_refspec1 = "refs/heads/ns1/*:refs/heads/ns1/*"; - const char *push_refspec2 = "refs/heads/ns2/*:refs/heads/ns2/*"; - - git_remote_free(_remote); - _remote = NULL; - - /* Set up the remote and save it to config */ - cl_git_pass(git_remote_create(&_remote, _repo, "upstream", "git://github.com/libgit2/libgit2")); - git_remote_clear_refspecs(_remote); - - cl_git_pass(git_remote_add_fetch(_remote, fetch_refspec1)); - cl_git_pass(git_remote_add_fetch(_remote, fetch_refspec2)); - cl_git_pass(git_remote_add_push(_remote, push_refspec1)); - cl_git_pass(git_remote_add_push(_remote, push_refspec2)); - cl_git_pass(git_remote_set_pushurl(_remote, "git://github.com/libgit2/libgit2_push")); - cl_git_pass(git_remote_save(_remote)); - git_remote_free(_remote); - _remote = NULL; - - /* Load it from config and make sure everything matches */ - cl_git_pass(git_remote_lookup(&_remote, _repo, "upstream")); - - cl_git_pass(git_remote_get_fetch_refspecs(&array, _remote)); - cl_assert_equal_i(2, (int)array.count); - cl_assert_equal_s(fetch_refspec1, array.strings[0]); - cl_assert_equal_s(fetch_refspec2, array.strings[1]); - git_strarray_free(&array); - - cl_git_pass(git_remote_get_push_refspecs(&array, _remote)); - cl_assert_equal_i(2, (int)array.count); - cl_assert_equal_s(push_refspec1, array.strings[0]); - cl_assert_equal_s(push_refspec2, array.strings[1]); - git_strarray_free(&array); - - cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2"); - cl_assert_equal_s(git_remote_pushurl(_remote), "git://github.com/libgit2/libgit2_push"); - - /* remove the pushurl again and see if we can save that too */ - cl_git_pass(git_remote_set_pushurl(_remote, NULL)); - cl_git_pass(git_remote_save(_remote)); - git_remote_free(_remote); - _remote = NULL; - - cl_git_pass(git_remote_lookup(&_remote, _repo, "upstream")); - cl_assert(git_remote_pushurl(_remote) == NULL); -} - void test_network_remote_remotes__fnmatch(void) { cl_assert(git_refspec_src_matches(_refspec, "refs/heads/master")); @@ -273,7 +235,7 @@ void test_network_remote_remotes__nonmatch_upstream_refspec(void) cl_git_pass(git_config_set_string(config, "branch.master.remote", "taggy")); cl_git_pass(git_config_set_string(config, "branch.master.merge", "refs/heads/foo")); - cl_git_pass(git_remote_fetch(remote, &specs, NULL)); + cl_git_pass(git_remote_fetch(remote, &specs, NULL, NULL)); git_remote_free(remote); } @@ -357,18 +319,6 @@ void test_network_remote_remotes__cannot_add_a_nameless_remote(void) git_remote_create(&remote, _repo, NULL, "git://github.com/libgit2/libgit2")); } -void test_network_remote_remotes__cannot_save_an_inmemory_remote(void) -{ - git_remote *remote; - - cl_git_pass(git_remote_create_anonymous(&remote, _repo, "git://github.com/libgit2/libgit2", NULL)); - - cl_assert_equal_p(NULL, git_remote_name(remote)); - - cl_git_fail(git_remote_save(remote)); - git_remote_free(remote); -} - void test_network_remote_remotes__cannot_add_a_remote_with_an_invalid_name(void) { git_remote *remote = NULL; @@ -386,16 +336,15 @@ void test_network_remote_remotes__cannot_add_a_remote_with_an_invalid_name(void) void test_network_remote_remotes__tagopt(void) { - git_remote_set_autotag(_remote, GIT_REMOTE_DOWNLOAD_TAGS_ALL); - cl_git_pass(git_remote_save(_remote)); + const char *name = git_remote_name(_remote); + + git_remote_set_autotag(_repo, name, GIT_REMOTE_DOWNLOAD_TAGS_ALL); assert_config_entry_value(_repo, "remote.test.tagopt", "--tags"); - git_remote_set_autotag(_remote, GIT_REMOTE_DOWNLOAD_TAGS_NONE); - cl_git_pass(git_remote_save(_remote)); + git_remote_set_autotag(_repo, name, GIT_REMOTE_DOWNLOAD_TAGS_NONE); assert_config_entry_value(_repo, "remote.test.tagopt", "--no-tags"); - git_remote_set_autotag(_remote, GIT_REMOTE_DOWNLOAD_TAGS_AUTO); - cl_git_pass(git_remote_save(_remote)); + git_remote_set_autotag(_repo, name, GIT_REMOTE_DOWNLOAD_TAGS_AUTO); assert_config_entry_existence(_repo, "remote.test.tagopt", false); } @@ -408,7 +357,7 @@ void test_network_remote_remotes__can_load_with_an_empty_url(void) cl_assert(remote->url == NULL); cl_assert(remote->pushurl == NULL); - cl_git_fail(git_remote_connect(remote, GIT_DIRECTION_FETCH)); + cl_git_fail(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL)); cl_assert(giterr_last() != NULL); cl_assert(giterr_last()->klass == GITERR_INVALID); @@ -425,7 +374,7 @@ void test_network_remote_remotes__can_load_with_only_an_empty_pushurl(void) cl_assert(remote->url == NULL); cl_assert(remote->pushurl == NULL); - cl_git_fail(git_remote_connect(remote, GIT_DIRECTION_FETCH)); + cl_git_fail(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL)); git_remote_free(remote); } @@ -491,13 +440,16 @@ void test_network_remote_remotes__query_refspecs(void) git_strarray array; int i; - cl_git_pass(git_remote_create_anonymous(&remote, _repo, "git://github.com/libgit2/libgit2", NULL)); + cl_git_pass(git_remote_create_with_fetchspec(&remote, _repo, "query", "git://github.com/libgit2/libgit2", NULL)); + git_remote_free(remote); for (i = 0; i < 3; i++) { - cl_git_pass(git_remote_add_fetch(remote, fetch_refspecs[i])); - cl_git_pass(git_remote_add_push(remote, push_refspecs[i])); + cl_git_pass(git_remote_add_fetch(_repo, "query", fetch_refspecs[i])); + cl_git_pass(git_remote_add_push(_repo, "query", push_refspecs[i])); } + cl_git_pass(git_remote_lookup(&remote, _repo, "query")); + cl_git_pass(git_remote_get_fetch_refspecs(&array, remote)); for (i = 0; i < 3; i++) { cl_assert_equal_s(fetch_refspecs[i], array.strings[i]); @@ -511,6 +463,7 @@ void test_network_remote_remotes__query_refspecs(void) git_strarray_free(&array); git_remote_free(remote); + git_remote_delete(_repo, "test"); } void test_network_remote_remotes__fetch_from_anonymous(void) @@ -519,6 +472,6 @@ void test_network_remote_remotes__fetch_from_anonymous(void) cl_git_pass(git_remote_create_anonymous(&remote, _repo, cl_fixture("testrepo.git"), "refs/heads/*:refs/other/*")); - cl_git_pass(git_remote_fetch(remote, NULL, NULL)); + cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL)); git_remote_free(remote); } diff --git a/tests/online/clone.c b/tests/online/clone.c index 4fdeee1d2..1930a8ba3 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -20,7 +20,7 @@ static git_clone_options g_options; void test_online_clone__initialize(void) { git_checkout_options dummy_opts = GIT_CHECKOUT_OPTIONS_INIT; - git_remote_callbacks dummy_callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options dummy_fetch = GIT_FETCH_OPTIONS_INIT; g_repo = NULL; @@ -28,7 +28,7 @@ void test_online_clone__initialize(void) g_options.version = GIT_CLONE_OPTIONS_VERSION; g_options.checkout_opts = dummy_opts; g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; - g_options.remote_callbacks = dummy_callbacks; + g_options.fetch_opts = dummy_fetch; } void test_online_clone__cleanup(void) @@ -107,8 +107,8 @@ void test_online_clone__can_checkout_a_cloned_repo(void) 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.remote_callbacks.transfer_progress = &fetch_progress; - g_options.remote_callbacks.payload = &fetch_progress_cb_was_called; + g_options.fetch_opts.callbacks.transfer_progress = &fetch_progress; + g_options.fetch_opts.callbacks.payload = &fetch_progress_cb_was_called; cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); @@ -131,23 +131,11 @@ static int remote_mirror_cb(git_remote **out, git_repository *repo, { int error; git_remote *remote; - git_remote_callbacks *callbacks = (git_remote_callbacks *) payload; + GIT_UNUSED(payload); - if ((error = git_remote_create(&remote, repo, name, url)) < 0) - return error; - - if ((error = git_remote_set_callbacks(remote, callbacks)) < 0) { - git_remote_free(remote); + if ((error = git_remote_create_with_fetchspec(&remote, repo, name, url, "+refs/*:refs/*")) < 0) return error; - } - - git_remote_clear_refspecs(remote); - - if ((error = git_remote_add_fetch(remote, "+refs/*:refs/*")) < 0) { - git_remote_free(remote); - return error; - } *out = remote; return 0; @@ -157,16 +145,14 @@ void test_online_clone__clone_mirror(void) { git_clone_options opts = GIT_CLONE_OPTIONS_INIT; git_reference *head; - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; bool fetch_progress_cb_was_called = false; - callbacks.transfer_progress = &fetch_progress; - callbacks.payload = &fetch_progress_cb_was_called; + opts.fetch_opts.callbacks.transfer_progress = &fetch_progress; + opts.fetch_opts.callbacks.payload = &fetch_progress_cb_was_called; opts.bare = true; opts.remote_cb = remote_mirror_cb; - opts.remote_cb_payload = &callbacks; cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo.git", &opts)); @@ -195,8 +181,8 @@ void test_online_clone__custom_remote_callbacks(void) { int callcount = 0; - g_options.remote_callbacks.update_tips = update_tips; - g_options.remote_callbacks.payload = &callcount; + g_options.fetch_opts.callbacks.update_tips = update_tips; + g_options.fetch_opts.callbacks.payload = &callcount; cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_assert(callcount > 0); @@ -222,7 +208,7 @@ void test_online_clone__cred_callback_failure_return_code_is_tunnelled(void) if (!remote_url || !remote_user) clar__skip(); - g_options.remote_callbacks.credentials = cred_failure_cb; + g_options.fetch_opts.callbacks.credentials = cred_failure_cb; cl_git_fail_with(-172, git_clone(&g_repo, remote_url, "./foo", &g_options)); } @@ -254,8 +240,8 @@ void test_online_clone__cred_callback_called_again_on_auth_failure(void) if (!remote_url || !remote_user) clar__skip(); - g_options.remote_callbacks.credentials = cred_count_calls_cb; - g_options.remote_callbacks.payload = &counter; + g_options.fetch_opts.callbacks.credentials = cred_count_calls_cb; + g_options.fetch_opts.callbacks.payload = &counter; cl_git_fail_with(GIT_EUSER, git_clone(&g_repo, remote_url, "./foo", &g_options)); cl_assert_equal_i(3, counter); @@ -292,10 +278,10 @@ void test_online_clone__credentials(void) if (!remote_url) return; if (cl_getenv("GITTEST_REMOTE_DEFAULT")) { - g_options.remote_callbacks.credentials = cred_default; + g_options.fetch_opts.callbacks.credentials = cred_default; } else { - g_options.remote_callbacks.credentials = git_cred_userpass; - g_options.remote_callbacks.payload = &user_pass; + g_options.fetch_opts.callbacks.credentials = git_cred_userpass; + g_options.fetch_opts.callbacks.payload = &user_pass; } cl_git_pass(git_clone(&g_repo, remote_url, "./foo", &g_options)); @@ -309,8 +295,8 @@ void test_online_clone__bitbucket_style(void) "libgit2", "libgit2" }; - g_options.remote_callbacks.credentials = git_cred_userpass; - g_options.remote_callbacks.payload = &user_pass; + g_options.fetch_opts.callbacks.credentials = git_cred_userpass; + g_options.fetch_opts.callbacks.payload = &user_pass; cl_git_pass(git_clone(&g_repo, BB_REPO_URL, "./foo", &g_options)); git_repository_free(g_repo); g_repo = NULL; @@ -340,7 +326,7 @@ static int cancel_at_half(const git_transfer_progress *stats, void *payload) void test_online_clone__can_cancel(void) { - g_options.remote_callbacks.transfer_progress = cancel_at_half; + g_options.fetch_opts.callbacks.transfer_progress = cancel_at_half; cl_git_fail_with( git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options), 4321); @@ -387,8 +373,8 @@ void test_online_clone__ssh_auth_methods(void) #ifndef GIT_SSH clar__skip(); #endif - g_options.remote_callbacks.credentials = check_ssh_auth_methods; - g_options.remote_callbacks.payload = &with_user; + g_options.fetch_opts.callbacks.credentials = check_ssh_auth_methods; + g_options.fetch_opts.callbacks.payload = &with_user; with_user = 0; cl_git_fail_with(GIT_EUSER, @@ -407,17 +393,12 @@ static int custom_remote_ssh_with_paths( void *payload) { int error; - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; - if ((error = git_remote_create(out, repo, name, url)) < 0) - return error; + GIT_UNUSED(payload); - if ((error = git_remote_set_transport(*out, git_transport_ssh_with_paths, payload)) < 0) + if ((error = git_remote_create(out, repo, name, url)) < 0) return error; - callbacks.credentials = cred_cb; - git_remote_set_callbacks(*out, &callbacks); - return 0; } @@ -446,7 +427,8 @@ void test_online_clone__ssh_with_paths(void) clar__skip(); g_options.remote_cb = custom_remote_ssh_with_paths; - g_options.remote_cb_payload = &arr; + g_options.fetch_opts.callbacks.transport = git_transport_ssh_with_paths; + g_options.fetch_opts.callbacks.payload = &arr; cl_git_fail(git_clone(&g_repo, remote_url, "./foo", &g_options)); @@ -468,7 +450,7 @@ void test_online_clone__ssh_cannot_change_username(void) #ifndef GIT_SSH clar__skip(); #endif - g_options.remote_callbacks.credentials = cred_foo_bar; + g_options.fetch_opts.callbacks.credentials = cred_foo_bar; cl_git_fail(git_clone(&g_repo, "ssh://git@github.com/libgit2/TestGitRepository", "./foo", &g_options)); } @@ -511,7 +493,7 @@ int ssh_certificate_check(git_cert *cert, int valid, const char *host, void *pay void test_online_clone__ssh_cert(void) { - g_options.remote_callbacks.certificate_check = ssh_certificate_check; + g_options.fetch_opts.callbacks.certificate_check = ssh_certificate_check; if (!cl_getenv("GITTEST_REMOTE_SSH_FINGERPRINT")) cl_skip(); @@ -537,7 +519,7 @@ static int fail_certificate_check(git_cert *cert, int valid, const char *host, v void test_online_clone__certificate_invalid(void) { - g_options.remote_callbacks.certificate_check = fail_certificate_check; + g_options.fetch_opts.callbacks.certificate_check = fail_certificate_check; cl_git_fail_with(git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options), GIT_ECERTIFICATE); @@ -561,14 +543,14 @@ static int succeed_certificate_check(git_cert *cert, int valid, const char *host void test_online_clone__certificate_valid(void) { - g_options.remote_callbacks.certificate_check = succeed_certificate_check; + g_options.fetch_opts.callbacks.certificate_check = succeed_certificate_check; cl_git_pass(git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options)); } void test_online_clone__start_with_http(void) { - g_options.remote_callbacks.certificate_check = succeed_certificate_check; + g_options.fetch_opts.callbacks.certificate_check = succeed_certificate_check; cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); } diff --git a/tests/online/fetch.c b/tests/online/fetch.c index 22f32ba1a..72e7c24e3 100644 --- a/tests/online/fetch.c +++ b/tests/online/fetch.c @@ -35,21 +35,17 @@ static int progress(const git_transfer_progress *stats, void *payload) static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n) { git_remote *remote; - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; size_t bytes_received = 0; - callbacks.transfer_progress = progress; - callbacks.update_tips = update_tips; - callbacks.payload = &bytes_received; + options.callbacks.transfer_progress = progress; + options.callbacks.update_tips = update_tips; + options.callbacks.payload = &bytes_received; + options.download_tags = flag; counter = 0; 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)); - cl_git_pass(git_remote_download(remote, NULL)); - cl_git_pass(git_remote_update_tips(remote, NULL)); - git_remote_disconnect(remote); + cl_git_pass(git_remote_fetch(remote, NULL, &options, NULL)); cl_assert_equal_i(counter, n); cl_assert(bytes_received > 0); @@ -85,12 +81,12 @@ void test_online_fetch__fetch_twice(void) { git_remote *remote; cl_git_pass(git_remote_create(&remote, _repo, "test", "git://github.com/libgit2/TestGitRepository.git")); - cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); - cl_git_pass(git_remote_download(remote, NULL)); + cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL)); + cl_git_pass(git_remote_download(remote, NULL, NULL)); git_remote_disconnect(remote); - git_remote_connect(remote, GIT_DIRECTION_FETCH); - cl_git_pass(git_remote_download(remote, NULL)); + git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL); + cl_git_pass(git_remote_download(remote, NULL, NULL)); git_remote_disconnect(remote); git_remote_free(remote); @@ -110,7 +106,7 @@ void test_online_fetch__doesnt_retrieve_a_pack_when_the_repository_is_up_to_date git_repository *_repository; bool invoked = false; git_remote *remote; - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; git_clone_options opts = GIT_CLONE_OPTIONS_INIT; opts.bare = true; @@ -121,18 +117,17 @@ void test_online_fetch__doesnt_retrieve_a_pack_when_the_repository_is_up_to_date cl_git_pass(git_repository_open(&_repository, "./fetch/lg2")); cl_git_pass(git_remote_lookup(&remote, _repository, "origin")); - cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); + cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL)); cl_assert_equal_i(false, invoked); - callbacks.transfer_progress = &transferProgressCallback; - callbacks.payload = &invoked; - git_remote_set_callbacks(remote, &callbacks); - cl_git_pass(git_remote_download(remote, NULL)); + options.callbacks.transfer_progress = &transferProgressCallback; + options.callbacks.payload = &invoked; + cl_git_pass(git_remote_download(remote, NULL, &options)); cl_assert_equal_i(false, invoked); - cl_git_pass(git_remote_update_tips(remote, NULL)); + cl_git_pass(git_remote_update_tips(remote, &options.callbacks, 1, options.download_tags, NULL)); git_remote_disconnect(remote); git_remote_free(remote); @@ -152,17 +147,16 @@ void test_online_fetch__can_cancel(void) { git_remote *remote; size_t bytes_received = 0; - git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; cl_git_pass(git_remote_create(&remote, _repo, "test", "http://github.com/libgit2/TestGitRepository.git")); - callbacks.transfer_progress = cancel_at_half; - callbacks.payload = &bytes_received; - git_remote_set_callbacks(remote, &callbacks); + options.callbacks.transfer_progress = cancel_at_half; + options.callbacks.payload = &bytes_received; - cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); - cl_git_fail_with(git_remote_download(remote, NULL), -4321); + cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL)); + cl_git_fail_with(git_remote_download(remote, NULL, &options), -4321); git_remote_disconnect(remote); git_remote_free(remote); } @@ -175,7 +169,7 @@ void test_online_fetch__ls_disconnected(void) cl_git_pass(git_remote_create(&remote, _repo, "test", "http://github.com/libgit2/TestGitRepository.git")); - cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); + cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL)); cl_git_pass(git_remote_ls(&refs, &refs_len_before, remote)); git_remote_disconnect(remote); cl_git_pass(git_remote_ls(&refs, &refs_len_after, remote)); @@ -193,7 +187,7 @@ void test_online_fetch__remote_symrefs(void) cl_git_pass(git_remote_create(&remote, _repo, "test", "http://github.com/libgit2/TestGitRepository.git")); - cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); + cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL)); git_remote_disconnect(remote); cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); @@ -208,8 +202,8 @@ void test_online_fetch__twice(void) git_remote *remote; cl_git_pass(git_remote_create(&remote, _repo, "test", "http://github.com/libgit2/TestGitRepository.git")); - cl_git_pass(git_remote_fetch(remote, NULL, NULL)); - cl_git_pass(git_remote_fetch(remote, NULL, NULL)); + cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL)); + cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL)); git_remote_free(remote); } diff --git a/tests/online/fetchhead.c b/tests/online/fetchhead.c index 9a97abef3..200edacfd 100644 --- a/tests/online/fetchhead.c +++ b/tests/online/fetchhead.c @@ -12,12 +12,12 @@ static git_clone_options g_options; void test_online_fetchhead__initialize(void) { - git_remote_callbacks dummy_callbacks = GIT_REMOTE_CALLBACKS_INIT; + git_fetch_options dummy_fetch = GIT_FETCH_OPTIONS_INIT; g_repo = NULL; memset(&g_options, 0, sizeof(git_clone_options)); g_options.version = GIT_CLONE_OPTIONS_VERSION; - g_options.remote_callbacks = dummy_callbacks; + g_options.fetch_opts = dummy_fetch; } void test_online_fetchhead__cleanup(void) @@ -38,12 +38,13 @@ static void fetchhead_test_clone(void) static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fetchhead) { git_remote *remote; + git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; git_buf fetchhead_buf = GIT_BUF_INIT; int equals = 0; git_strarray array, *active_refs = NULL; cl_git_pass(git_remote_lookup(&remote, g_repo, "origin")); - git_remote_set_autotag(remote, GIT_REMOTE_DOWNLOAD_TAGS_AUTO); + fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO; if(fetchspec != NULL) { array.count = 1; @@ -51,10 +52,7 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet active_refs = &array; } - cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); - cl_git_pass(git_remote_download(remote, active_refs)); - cl_git_pass(git_remote_update_tips(remote, NULL)); - git_remote_disconnect(remote); + cl_git_pass(git_remote_fetch(remote, active_refs, &fetch_opts, NULL)); git_remote_free(remote); cl_git_pass(git_futils_readbuffer(&fetchhead_buf, "./foo/.git/FETCH_HEAD")); diff --git a/tests/online/push.c b/tests/online/push.c index 9b98bc77a..04ad7a2ed 100644 --- a/tests/online/push.c +++ b/tests/online/push.c @@ -369,9 +369,8 @@ void test_online_push__initialize(void) cl_git_pass(git_remote_create(&_remote, _repo, "test", _remote_url)); record_callbacks_data_clear(&_record_cbs_data); - git_remote_set_callbacks(_remote, &_record_cbs); - cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH)); + cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH, NULL)); /* Clean up previously pushed branches. Fails if receive.denyDeletes is * set on the remote. Also, on Git 1.7.0 and newer, you must run @@ -394,10 +393,7 @@ void test_online_push__initialize(void) git_vector_free(&delete_specs); /* Now that we've deleted everything, fetch from the remote */ - cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_FETCH)); - cl_git_pass(git_remote_download(_remote, NULL)); - cl_git_pass(git_remote_update_tips(_remote, NULL)); - git_remote_disconnect(_remote); + cl_git_pass(git_remote_fetch(_remote, NULL, NULL, NULL)); } void test_online_push__cleanup(void) @@ -459,20 +455,18 @@ static void do_push( size_t i; int error; git_strarray specs = {0}; - git_remote_callbacks callbacks; record_callbacks_data *data; if (_remote) { /* Auto-detect the number of threads to use */ opts.pb_parallelism = 0; - memcpy(&callbacks, git_remote_get_callbacks(_remote), sizeof(callbacks)); - data = callbacks.payload; + memcpy(&opts.callbacks, &_record_cbs, sizeof(git_remote_callbacks)); + data = opts.callbacks.payload; - callbacks.pack_progress = push_pack_progress_cb; - callbacks.push_transfer_progress = push_transfer_progress_cb; - callbacks.push_update_reference = record_push_status_cb; - cl_git_pass(git_remote_set_callbacks(_remote, &callbacks)); + opts.callbacks.pack_progress = push_pack_progress_cb; + opts.callbacks.push_transfer_progress = push_transfer_progress_cb; + opts.callbacks.push_update_reference = record_push_status_cb; if (refspecs_len) { specs.count = refspecs_len; @@ -867,6 +861,7 @@ void test_online_push__configured(void) { git_oid note_oid, *target_oid, expected_oid; git_signature *signature; + git_remote *old_remote; const char *specs[] = { "refs/notes/commits:refs/notes/commits" }; push_status exp_stats[] = { { "refs/notes/commits", 1 } }; expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } }; @@ -876,7 +871,10 @@ void test_online_push__configured(void) target_oid = &_oid_b6; - cl_git_pass(git_remote_add_push(_remote, specs[0])); + cl_git_pass(git_remote_add_push(_repo, git_remote_name(_remote), specs[0])); + old_remote = _remote; + cl_git_pass(git_remote_lookup(&_remote, _repo, git_remote_name(_remote))); + git_remote_free(old_remote); /* Create note to push */ cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */ diff --git a/tests/online/push_util.h b/tests/online/push_util.h index 83d46b506..822341bd2 100644 --- a/tests/online/push_util.h +++ b/tests/online/push_util.h @@ -12,7 +12,7 @@ extern const git_oid OID_ZERO; * @param data pointer to a record_callbacks_data instance */ #define RECORD_CALLBACKS_INIT(data) \ - { GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, data } + { GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, NULL, data } typedef struct { char *name; diff --git a/tests/refs/branches/remote.c b/tests/refs/branches/remote.c index bac088454..47526717f 100644 --- a/tests/refs/branches/remote.c +++ b/tests/refs/branches/remote.c @@ -57,12 +57,7 @@ void test_refs_branches_remote__ambiguous_remote_returns_error(void) git_buf buf; /* Create the remote */ - cl_git_pass(git_remote_create(&remote, g_repo, "addtest", "http://github.com/libgit2/libgit2")); - - /* Update the remote fetch spec */ - git_remote_clear_refspecs(remote); - cl_git_pass(git_remote_add_fetch(remote, "refs/heads/*:refs/remotes/test/*")); - cl_git_pass(git_remote_save(remote)); + cl_git_pass(git_remote_create_with_fetchspec(&remote, g_repo, "addtest", "http://github.com/libgit2/libgit2", "refs/heads/*:refs/remotes/test/*")); git_remote_free(remote); diff --git a/tests/submodule/update.c b/tests/submodule/update.c index 533e64efc..e7f1b76b8 100644 --- a/tests/submodule/update.c +++ b/tests/submodule/update.c @@ -96,8 +96,8 @@ void test_submodule_update__update_submodule(void) update_options.checkout_opts.progress_cb = checkout_progress_cb; update_options.checkout_opts.progress_payload = &update_payload; - update_options.remote_callbacks.update_tips = update_tips; - update_options.remote_callbacks.payload = &update_payload; + update_options.fetch_opts.callbacks.update_tips = update_tips; + update_options.fetch_opts.callbacks.payload = &update_payload; /* get the submodule */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); |