]> git.proxmox.com Git - libgit2.git/blobdiff - include/git2/remote.h
New upstream version 1.4.3+dfsg.1
[libgit2.git] / include / git2 / remote.h
index 6e88a4680a74d9b40db0787ad1e3d8e772a1a6a7..8c9c26f3fd58b937e5cd1e7cd00ca6fdb500c2c7 100644 (file)
@@ -14,7 +14,8 @@
 #include "indexer.h"
 #include "strarray.h"
 #include "transport.h"
-#include "push.h"
+#include "pack.h"
+#include "proxy.h"
 
 /**
  * @file git2/remote.h
  */
 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
@@ -43,10 +41,107 @@ GIT_EXTERN(int) git_remote_create(
                const char *name,
                const char *url);
 
+/**
+ * Remote redirection settings; whether redirects to another host
+ * are permitted.  By default, git will follow a redirect on the
+ * initial request (`/info/refs`), but not subsequent requests.
+ */
+typedef enum {
+       /**
+        * Do not follow any off-site redirects at any stage of
+        * the fetch or push.
+        */
+       GIT_REMOTE_REDIRECT_NONE = (1 << 0),
+
+       /**
+        * Allow off-site redirects only upon the initial request.
+        * This is the default.
+        */
+       GIT_REMOTE_REDIRECT_INITIAL = (1 << 1),
+
+       /**
+        * Allow redirects at any stage in the fetch or push.
+        */
+       GIT_REMOTE_REDIRECT_ALL = (1 << 2)
+} git_remote_redirect_t;
+
+/**
+ * Remote creation options flags
+ */
+typedef enum {
+       /** Ignore the repository apply.insteadOf configuration */
+       GIT_REMOTE_CREATE_SKIP_INSTEADOF = (1 << 0),
+
+       /** Don't build a fetchspec from the name if none is set */
+       GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC = (1 << 1)
+} git_remote_create_flags;
+
+/**
+ * Remote creation options structure
+ *
+ * Initialize with `GIT_REMOTE_CREATE_OPTIONS_INIT`. Alternatively, you can
+ * use `git_remote_create_options_init`.
+ *
+ */
+typedef struct git_remote_create_options {
+       unsigned int version;
+
+       /**
+        * The repository that should own the remote.
+        * Setting this to NULL results in a detached remote.
+        */
+       git_repository *repository;
+
+       /**
+        * The remote's name.
+        * Setting this to NULL results in an in-memory/anonymous remote.
+        */
+       const char *name;
+
+       /** The fetchspec the remote should use. */
+       const char *fetchspec;
+
+       /** Additional flags for the remote. See git_remote_create_flags. */
+       unsigned int flags;
+} git_remote_create_options;
+
+#define GIT_REMOTE_CREATE_OPTIONS_VERSION 1
+#define GIT_REMOTE_CREATE_OPTIONS_INIT {GIT_REMOTE_CREATE_OPTIONS_VERSION}
+
+/**
+ * Initialize git_remote_create_options structure
+ *
+ * Initializes a `git_remote_create_options` with default values. Equivalent to
+ * creating an instance with `GIT_REMOTE_CREATE_OPTIONS_INIT`.
+ *
+ * @param opts The `git_remote_create_options` struct to initialize.
+ * @param version The struct version; pass `GIT_REMOTE_CREATE_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_remote_create_options_init(
+               git_remote_create_options *opts,
+               unsigned int version);
+
+/**
+ * Create a remote, with options.
+ *
+ * This function allows more fine-grained control over the remote creation.
+ *
+ * Passing NULL as the opts argument will result in a detached remote.
+ *
+ * @param out the resulting remote
+ * @param url the remote's url
+ * @param opts the remote creation options
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+GIT_EXTERN(int) git_remote_create_with_opts(
+               git_remote **out,
+               const char *url,
+               const git_remote_create_options *opts);
+
 /**
  * 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
@@ -65,24 +160,36 @@ GIT_EXTERN(int) git_remote_create_with_fetchspec(
 /**
  * Create an anonymous remote
  *
- * Create a remote with the given url and refspec in memory. You can use
- * this when you have a URL instead of a remote's name.  Note that anonymous
- * remotes cannot be converted to persisted remotes.
+ * Create a remote with the given url in-memory. You can use this when
+ * you have a URL instead of a remote's name.
  *
- * The name, when provided, will be checked for validity.
- * See `git_tag_create()` for rules about valid names.
- *
- * @param out pointer to the new remote object
+ * @param out pointer to the new remote objects
  * @param repo the associated repository
  * @param url the remote repository's URL
- * @param fetch the fetch refspec to use for this remote.
  * @return 0 or an error code
  */
 GIT_EXTERN(int) git_remote_create_anonymous(
                git_remote **out,
                git_repository *repo,
-               const char *url,
-               const char *fetch);
+               const char *url);
+
+/**
+ * Create a remote without a connected local repo
+ *
+ * Create a remote with the given url in-memory. You can use this when
+ * you have a URL instead of a remote's name.
+ *
+ * Contrasted with git_remote_create_anonymous, a detached remote
+ * will not consider any repo configuration values (such as insteadof url
+ * substitutions).
+ *
+ * @param out pointer to the new remote objects
+ * @param url the remote repository's URL
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_create_detached(
+               git_remote **out,
+               const char *url);
 
 /**
  * Get the information for a particular remote
@@ -97,17 +204,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.
@@ -139,13 +235,21 @@ GIT_EXTERN(const char *) git_remote_name(const git_remote *remote);
 /**
  * Get the remote's url
  *
+ * If url.*.insteadOf has been configured for this URL, it will
+ * return the modified URL.  If `git_remote_set_instance_pushurl`
+ * has been called for this remote, then that URL will be returned.
+ *
  * @param remote the remote
  * @return a pointer to the url
  */
 GIT_EXTERN(const char *) git_remote_url(const git_remote *remote);
 
 /**
- * Get the remote's url for pushing
+ * Get the remote's url for pushing.
+ *
+ * If url.*.pushInsteadOf has been configured for this URL, it
+ * will return the modified URL.  If `git_remote_set_instance_pushurl`
+ * has been called for this remote, then that URL will be returned.
  *
  * @param remote the remote
  * @return a pointer to the url or NULL if no special url for pushing is set
@@ -153,38 +257,64 @@ 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
+ *
+ * @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 code
+ */
+GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char *url);
+
+/**
+ * Set the url for this particular url instance.  The URL in the
+ * configuration will be ignored, and will not be changed.
+ *
+ * @param remote the remote's name
+ * @param url the url to set
  * @return 0 or an error value
  */
-GIT_EXTERN(int) git_remote_set_pushurl(git_remote *remote, const char* url);
+GIT_EXTERN(int) git_remote_set_instance_url(git_remote *remote, const char *url);
 
 /**
- * Add a fetch refspec to the remote
+ * Set the push url for this particular url instance.  The URL in the
+ * configuration will be ignored, and will not be changed.
  *
- * Convenience function for adding a single fetch refspec to the
- * current list in the remote.
+ * @param remote the remote's name
+ * @param url the url to set
+ * @return 0 or an error value
+ */
+GIT_EXTERN(int) git_remote_set_instance_pushurl(git_remote *remote, const char *url);
+
+/**
+ * Add a fetch refspec to the remote's configuration
  *
- * @param remote the remote
+ * Add the given refspec to the fetch list in the configuration. No
+ * loaded remote instances will be affected.
+ *
+ * @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
+ * @return 0, GIT_EINVALIDSPEC if refspec is invalid 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
@@ -194,30 +324,22 @@ GIT_EXTERN(int) git_remote_add_fetch(git_remote *remote, const char *refspec);
  *
  * @param array pointer to the array in which to store the strings
  * @param remote the remote to query
+ * @return 0 or an error code.
  */
 GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, const git_remote *remote);
 
 /**
- * Set the remote's list of fetch refspecs
- *
- * The contents of the string array are copied.
- *
- * @param remote the remote to modify
- * @param array the new list of fetch resfpecs
- */
-GIT_EXTERN(int) git_remote_set_fetch_refspecs(git_remote *remote, git_strarray *array);
-
-/**
- * Add a push refspec to the remote
+ * 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
+ * @return 0, GIT_EINVALIDSPEC if refspec is invalid 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
@@ -227,28 +349,10 @@ GIT_EXTERN(int) git_remote_add_push(git_remote *remote, const char *refspec);
  *
  * @param array pointer to the array in which to store the strings
  * @param remote the remote to query
+ * @return 0 or an error code.
  */
 GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, const git_remote *remote);
 
-/**
- * Set the remote's list of push refspecs
- *
- * The contents of the string array are copied.
- *
- * @param remote the remote to modify
- * @param array the new list of push resfpecs
- */
-GIT_EXTERN(int) git_remote_set_push_refspecs(git_remote *remote, git_strarray *array);
-
-/**
- * Clear the refspecs
- *
- * Remove all configured fetch and push refspecs from the remote.
- *
- * @param remote the remote
- */
-GIT_EXTERN(void) git_remote_clear_refspecs(git_remote *remote);
-
 /**
  * Get the number of refspecs for a remote
  *
@@ -266,20 +370,6 @@ GIT_EXTERN(size_t) git_remote_refspec_count(const git_remote *remote);
  */
 GIT_EXTERN(const git_refspec *)git_remote_get_refspec(const git_remote *remote, size_t n);
 
-/**
- * Open a connection to a remote
- *
- * The transport is selected based on the URL. The direction argument
- * is due to a limitation of the git protocol (over TCP or SSH) which
- * starts up a specific binary which can only do the one or the other.
- *
- * @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
- * @return 0 or an error code
- */
-GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction);
-
 /**
  * Get the remote repository's reference advertisement list
  *
@@ -302,36 +392,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
  *
@@ -350,8 +410,9 @@ GIT_EXTERN(int) git_remote_connected(const git_remote *remote);
  * the operation has been cancelled and if so stops the operation.
  *
  * @param remote the remote
+ * @return 0 on success, or an error code
  */
-GIT_EXTERN(void) git_remote_stop(git_remote *remote);
+GIT_EXTERN(int) git_remote_stop(git_remote *remote);
 
 /**
  * Disconnect from the remote
@@ -359,8 +420,9 @@ GIT_EXTERN(void) git_remote_stop(git_remote *remote);
  * Close the connection to the remote.
  *
  * @param remote the remote to disconnect from
+ * @return 0 on success, or an error code
  */
-GIT_EXTERN(void) git_remote_disconnect(git_remote *remote);
+GIT_EXTERN(int) git_remote_disconnect(git_remote *remote);
 
 /**
  * Free the memory associated with a remote
@@ -373,79 +435,107 @@ 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
+ * Get a list of the configured remotes for a repo
  *
- * @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.
+ * The string array must be freed by the user.
+ *
+ * @param out a string array which receives the names of the remotes
+ * @param repo the repository to query
  * @return 0 or an error code
  */
-GIT_EXTERN(int) git_remote_update_tips(
-               git_remote *remote,
-               const char *reflog_message);
+GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo);
 
 /**
- * Prune tracking refs that are no longer present on remote
- *
- * @param remote the remote to prune
- * @return 0 or an error code
+ * Argument to the completion callback which tells it which operation
+ * finished.
  */
-GIT_EXTERN(int) git_remote_prune(git_remote *remote);
+typedef enum git_remote_completion_t {
+       GIT_REMOTE_COMPLETION_DOWNLOAD,
+       GIT_REMOTE_COMPLETION_INDEXING,
+       GIT_REMOTE_COMPLETION_ERROR
+} git_remote_completion_t;
+
+/** Push network progress notification function */
+typedef int GIT_CALLBACK(git_push_transfer_progress_cb)(
+       unsigned int current,
+       unsigned int total,
+       size_t bytes,
+       void *payload);
 
 /**
- * Download new data and update tips
- *
- * Convenience function to connect to a remote, download the data,
- * disconnect and update the remote-tracking branches.
+ * 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;
+
+/**
+ * Callback used to inform of upcoming updates.
  *
- * @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
+ * @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
  */
-GIT_EXTERN(int) git_remote_fetch(
-               git_remote *remote,
-               const git_strarray *refspecs,
-               const char *reflog_message);
+typedef int GIT_CALLBACK(git_push_negotiation)(const git_push_update **updates, size_t len, void *payload);
 
 /**
- * Perform a push
+ * Callback used to inform of the update status from the remote.
  *
- * Peform all the steps from a push.
+ * Called for each updated reference on push. If `status` is
+ * not `NULL`, the update was rejected by the remote server
+ * and `status` contains the reason given.
  *
- * @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
+ * @param refname refname specifying to the remote ref
+ * @param status status message sent from the remote
+ * @param data data provided by the caller
+ * @return 0 on success, otherwise an error
  */
-GIT_EXTERN(int) git_remote_push(git_remote *remote,
-                               const git_strarray *refspecs,
-                               const git_push_options *opts);
+typedef int GIT_CALLBACK(git_push_update_reference_cb)(const char *refname, const char *status, void *data);
 
+#ifndef GIT_DEPRECATE_HARD
 /**
- * Get a list of the configured remotes for a repo
+ * Callback to resolve URLs before connecting to remote
  *
- * The string array must be freed by the user.
+ * If you return GIT_PASSTHROUGH, you don't need to write anything to
+ * url_resolved.
  *
- * @param out a string array which receives the names of the remotes
- * @param repo the repository to query
- * @return 0 or an error code
+ * @param url_resolved The buffer to write the resolved URL to
+ * @param url The URL to resolve
+ * @param direction GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH
+ * @param payload Payload provided by the caller
+ * @return 0 on success, GIT_PASSTHROUGH or an error
+ * @deprecated Use `git_remote_set_instance_url`
  */
-GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo);
+typedef int GIT_CALLBACK(git_url_resolve_cb)(git_buf *url_resolved, const char *url, int direction, void *payload);
+#endif
 
 /**
- * Argument to the completion callback which tells it which operation
- * finished.
+ * Callback invoked immediately before we attempt to connect to the
+ * given url.  Callers may change the URL before the connection by
+ * calling `git_remote_set_instance_url` in the callback.
+ *
+ * @param remote The remote to be connected
+ * @param direction GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH
+ * @param payload Payload provided by the caller
+ * @return 0 on success, or an error
  */
-typedef enum git_remote_completion_type {
-       GIT_REMOTE_COMPLETION_DOWNLOAD,
-       GIT_REMOTE_COMPLETION_INDEXING,
-       GIT_REMOTE_COMPLETION_ERROR,
-} git_remote_completion_type;
+typedef int GIT_CALLBACK(git_remote_ready_cb)(git_remote *remote, int direction, void *payload);
 
 /**
  * The callback settings structure
@@ -454,11 +544,12 @@ typedef enum git_remote_completion_type {
  * about the progress of the network operations.
  */
 struct git_remote_callbacks {
-       unsigned int version;
+       unsigned int version; /**< The version */
+
        /**
         * Textual progress from the remote. Text send over the
         * progress side-band will be passed to this function (this is
-        * the 'counting objects' output.
+        * the 'counting objects' output).
         */
        git_transport_message_cb sideband_progress;
 
@@ -466,7 +557,7 @@ struct git_remote_callbacks {
         * Completion is called when different parts of the download
         * process are done (currently unused).
         */
-       int (*completion)(git_remote_completion_type type, void *data);
+       int GIT_CALLBACK(completion)(git_remote_completion_t type, void *data);
 
        /**
         * This will be called if the remote host requires
@@ -475,28 +566,28 @@ struct git_remote_callbacks {
         * Returning GIT_PASSTHROUGH will make libgit2 behave as
         * though this field isn't set.
         */
-       git_cred_acquire_cb credentials;
+       git_credential_acquire_cb credentials;
 
        /**
         * If cert verification fails, this will be called to let the
         * user make the final decision of whether to allow the
-        * connection to proceed. Returns 1 to allow the connection, 0
-        * to disallow it or a negative value to indicate an error.
+        * connection to proceed. Returns 0 to allow the connection
+        * or a negative value to indicate an error.
         */
-        git_transport_certificate_check_cb certificate_check;
+       git_transport_certificate_check_cb certificate_check;
 
        /**
         * During the download of new data, this will be regularly
         * called with the current count of progress done by the
         * indexer.
         */
-       git_transfer_progress_cb transfer_progress;
+       git_indexer_progress_cb transfer_progress;
 
        /**
         * Each time a reference is updated locally, this function
         * will be called with information about it.
         */
-       int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data);
+       int GIT_CALLBACK(update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data);
 
        /**
         * Function to call with progress information during pack
@@ -511,14 +602,12 @@ struct git_remote_callbacks {
         * inline with pack building operations, so performance may be
         * affected.
         */
-       git_push_transfer_progress push_transfer_progress;
+       git_push_transfer_progress_cb push_transfer_progress;
 
        /**
-        * Called for each updated reference on push. If `status` is
-        * not `NULL`, the update was rejected by the remote server
-        * and `status` contains the reason given.
+        * See documentation of git_push_update_reference_cb
         */
-       int (*push_update_reference)(const char *refname, const char *status, void *data);
+       git_push_update_reference_cb push_update_reference;
 
        /**
         * Called once between the negotiation step and the upload. It
@@ -526,11 +615,35 @@ 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;
+
+       /**
+        * Callback when the remote is ready to connect.
+        */
+       git_remote_ready_cb remote_ready;
+
        /**
         * This will be passed to each of the callbacks in this struct
         * as the last parameter.
         */
        void *payload;
+
+#ifdef GIT_DEPRECATE_HARD
+       void *reserved;
+#else
+       /**
+        * Resolve URL before connecting to remote.
+        * The returned URL will be used to connect to the remote instead.
+        *
+        * This callback is deprecated; users should use
+        * git_remote_ready_cb and configure the instance URL instead.
+        */
+       git_url_resolve_cb resolve_url;
+#endif
 };
 
 #define GIT_REMOTE_CALLBACKS_VERSION 1
@@ -548,44 +661,400 @@ GIT_EXTERN(int) git_remote_init_callbacks(
        git_remote_callbacks *opts,
        unsigned int version);
 
+/** Acceptable prune settings when fetching */
+typedef enum {
+       /**
+        * Use the setting from the configuration
+        */
+       GIT_FETCH_PRUNE_UNSPECIFIED,
+       /**
+        * 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_UNSPECIFIED = 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;
+
+/**
+ * Fetch options structure.
+ *
+ * Zero out for defaults.  Initialize with `GIT_FETCH_OPTIONS_INIT` macro to
+ * correctly set the `version` field.  E.g.
+ *
+ *             git_fetch_options opts = GIT_FETCH_OPTIONS_INIT;
+ */
+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;
+
+       /**
+        * Proxy options to use, by default no proxy is used.
+        */
+       git_proxy_options proxy_opts;
+
+       /**
+        * Whether to allow off-site redirects.  If this is not
+        * specified, the `http.followRedirects` configuration setting
+        * will be consulted.
+        */
+       git_remote_redirect_t follow_redirects;
+
+       /**
+        * Extra headers for this fetch operation
+        */
+       git_strarray custom_headers;
+} git_fetch_options;
+
+#define GIT_FETCH_OPTIONS_VERSION 1
+#define GIT_FETCH_OPTIONS_INIT { GIT_FETCH_OPTIONS_VERSION, GIT_REMOTE_CALLBACKS_INIT, GIT_FETCH_PRUNE_UNSPECIFIED, 1, \
+                                GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED, GIT_PROXY_OPTIONS_INIT }
+
+/**
+ * Initialize git_fetch_options structure
+ *
+ * Initializes a `git_fetch_options` with default values. Equivalent to
+ * creating an instance with `GIT_FETCH_OPTIONS_INIT`.
+ *
+ * @param opts The `git_fetch_options` struct to initialize.
+ * @param version The struct version; pass `GIT_FETCH_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_fetch_options_init(
+       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;
+
+       /**
+       * Proxy options to use, by default no proxy is used.
+       */
+       git_proxy_options proxy_opts;
+
+       /**
+        * Whether to allow off-site redirects.  If this is not
+        * specified, the `http.followRedirects` configuration setting
+        * will be consulted.
+        */
+       git_remote_redirect_t follow_redirects;
+
+       /**
+        * Extra headers for this push operation
+        */
+       git_strarray custom_headers;
+} git_push_options;
+
+#define GIT_PUSH_OPTIONS_VERSION 1
+#define GIT_PUSH_OPTIONS_INIT { GIT_PUSH_OPTIONS_VERSION, 1, GIT_REMOTE_CALLBACKS_INIT, GIT_PROXY_OPTIONS_INIT }
+
+/**
+ * Initialize git_push_options structure
+ *
+ * Initializes a `git_push_options` with default values. Equivalent to
+ * creating an instance with `GIT_PUSH_OPTIONS_INIT`.
+ *
+ * @param opts The `git_push_options` struct to initialize.
+ * @param version The struct version; pass `GIT_PUSH_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_push_options_init(
+       git_push_options *opts,
+       unsigned int version);
+
+/**
+ * Remote creation options structure
+ *
+ * Initialize with `GIT_REMOTE_CREATE_OPTIONS_INIT`. Alternatively, you can
+ * use `git_remote_create_options_init`.
+ *
+ */
+typedef struct {
+       unsigned int version;
+
+       /** Callbacks to use for this connection */
+       git_remote_callbacks callbacks;
+
+       /** HTTP Proxy settings */
+       git_proxy_options proxy_opts;
+
+       /**
+        * Whether to allow off-site redirects.  If this is not
+        * specified, the `http.followRedirects` configuration setting
+        * will be consulted.
+        */
+       git_remote_redirect_t follow_redirects;
+
+       /** Extra HTTP headers to use in this connection */
+       git_strarray custom_headers;
+} git_remote_connect_options;
+
+#define GIT_REMOTE_CONNECT_OPTIONS_VERSION 1
+#define GIT_REMOTE_CONNECT_OPTIONS_INIT { \
+       GIT_REMOTE_CONNECT_OPTIONS_VERSION, \
+       GIT_REMOTE_CALLBACKS_INIT, \
+       GIT_PROXY_OPTIONS_INIT }
+
+/**
+ * Initialize git_remote_connect_options structure.
  *
- * 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.
+ * Initializes a `git_remote_connect_options` with default values.
+ * Equivalent to creating an instance with
+ * `GIT_REMOTE_CONNECT_OPTIONS_INIT`.
  *
- * @param remote the remote to configure
- * @param callbacks a pointer to the user's callback settings
+ * @param opts The `git_remote_connect_options` struct to initialize.
+ * @param version The struct version; pass `GIT_REMOTE_CONNECT_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_remote_connect_options_init(
+               git_remote_connect_options *opts,
+               unsigned int version);
+
+/**
+ * Open a connection to a remote.
+ *
+ * The transport is selected based on the URL; the direction argument
+ * is due to a limitation of the git protocol which starts up a
+ * specific binary which can only do the one or the other.
+ *
+ * @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
+ * @param proxy_opts proxy settings
+ * @param custom_headers extra HTTP headers to use in this connection
  * @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_connect(
+       git_remote *remote,
+       git_direction direction,
+       const git_remote_callbacks *callbacks,
+       const git_proxy_options *proxy_opts,
+       const git_strarray *custom_headers);
 
 /**
- * Retrieve the current callback structure
+ * Open a connection to a remote with extended options.
  *
- * This provides read access to the callbacks structure as the remote
- * sees it.
+ * The transport is selected based on the URL; the direction argument
+ * is due to a limitation of the git protocol which starts up a
+ * specific binary which can only do the one or the other.
  *
- * @param remote the remote to query
- * @return a pointer to the callbacks structure
+ * The given options structure will form the defaults for connection
+ * options and callback setup.  Callers may override these defaults
+ * by specifying `git_fetch_options` or `git_push_options` in
+ * subsequent calls.
+ *
+ * @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 opts the remote connection options
+ * @return 0 or an error code
  */
-GIT_EXTERN(const git_remote_callbacks *) git_remote_get_callbacks(git_remote *remote);
+GIT_EXTERN(int) git_remote_connect_ext(
+       git_remote *remote,
+       git_direction direction,
+       const git_remote_connect_options *opts);
 
 /**
- * Get the statistics structure that is filled in by the fetch operation.
+ * 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.
+ *
+ * If options are specified and this remote is already connected then
+ * the existing remote connection options will be discarded and the
+ * remote will now use the new options.
+ *
+ * @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 or NULL
+ * @return 0 or an error code
  */
-GIT_EXTERN(const git_transfer_progress *) git_remote_stats(git_remote *remote);
+ GIT_EXTERN(int) git_remote_download(
+       git_remote *remote,
+       const git_strarray *refspecs,
+       const git_fetch_options *opts);
 
 /**
- * Automatic tag following option
+ * Create a packfile and send it to the server
  *
- * Lets us select the --tags option to use.
+ * 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.
+ *
+ * If options are specified and this remote is already connected then
+ * the existing remote connection options will be discarded and the
+ * remote will now use the new options.
+ *
+ * @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
  */
-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_upload(
+       git_remote *remote,
+       const git_strarray *refspecs,
+       const git_push_options *opts);
+
+/**
+ * Update the tips to the new state.
+ *
+ * If callbacks are not specified then the callbacks specified to
+ * `git_remote_connect` will be used (if it was called).
+ *
+ * @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 or NULL
+ * @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(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);
+
+/**
+ * Download new data and update tips.
+ *
+ * Convenience function to connect to a remote, download the data,
+ * disconnect and update the remote-tracking branches.
+ *
+ * If options are specified and this remote is already connected then
+ * the existing remote connection options will be discarded and the
+ * remote will now use the new options.
+ *
+ * @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 or NULL
+ * @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 git_fetch_options *opts,
+               const char *reflog_message);
+
+/**
+ * Prune tracking refs that are no longer present on remote.
+ *
+ * If callbacks are not specified then the callbacks specified to
+ * `git_remote_connect` will be used (if it was called).
+ *
+ * @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.
+ *
+ * If options are specified and this remote is already connected then
+ * the existing remote connection options will be discarded and the
+ * remote will now use the new options.
+ *
+ * @param remote the remote to push to
+ * @param refspecs the refspecs to use for pushing. If NULL or an empty
+ *                 array, the configured refspecs will be used
+ * @param opts options to use for this push
+ * @return 0 or an error code.
+ */
+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_indexer_progress *) git_remote_stats(git_remote *remote);
 
 /**
  * Retrieve the tag auto-follow setting
@@ -596,14 +1065,17 @@ 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.
  *
- * @param remote the remote to configure
- * @param value a GIT_REMOTE_DOWNLOAD_TAGS value
+ * The change will be made in the configuration. No loaded remotes
+ * will be affected.
+ *
+ * @param repo the repository in which to make the change
+ * @param remote the name of the remote
+ * @param value the new value to take.
+ * @return 0, or an error code.
  */
-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
@@ -629,7 +1101,7 @@ GIT_EXTERN(int) git_remote_prune_refs(const git_remote *remote);
  * stored here for further processing by the caller. Always free this
  * strarray on successful return.
  * @param repo the repository in which to rename
- * @param name the current name of the reamote
+ * @param name the current name of the remote
  * @param new_name the new name the remote should bear
  * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
  */
@@ -639,30 +1111,14 @@ GIT_EXTERN(int) git_remote_rename(
        const char *name,
        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 valid output pointer to set with validity of given remote name
  * @param remote_name name to be checked.
- * @return 1 if the reference name is acceptable; 0 if it isn't
+ * @return 0 on success or an error code
  */
-GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name);
+GIT_EXTERN(int) git_remote_name_is_valid(int *valid, const char *remote_name);
 
 /**
 * Delete an existing persisted remote.
@@ -671,7 +1127,7 @@ GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name);
 * for the remote will be removed.
 *
 * @param repo the repository in which to act
-* @param name the name of the remove to delete
+* @param name the name of the remote to delete
 * @return 0 on success, or an error code.
 */
 GIT_EXTERN(int) git_remote_delete(git_repository *repo, const char *name);
@@ -687,7 +1143,7 @@ GIT_EXTERN(int) git_remote_delete(git_repository *repo, const char *name);
  *
  * This function must only be called after connecting.
  *
- * @param out the buffern in which to store the reference name
+ * @param out the buffer in which to store the reference name
  * @param remote the remote
  * @return 0, GIT_ENOTFOUND if the remote does not have any references
  * or none of them point to HEAD's commit, or an error message.