Commit 3149547b by Carlos Martín Nieto

remote: introduce git_remote_push()

This function, similar in style to git_remote_fetch(), performs all the
steps required for a push, with a similar interface.

The remote callbacks struct has learnt about the push callbacks, letting
us set the callbacks a single time instead of setting some in the remote
and some in the push operation.
parent 4865cc3f
......@@ -14,6 +14,7 @@
#include "indexer.h"
#include "strarray.h"
#include "transport.h"
#include "push.h"
/**
* @file git2/remote.h
......@@ -390,6 +391,22 @@ GIT_EXTERN(int) git_remote_fetch(
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
* @param opts the options
* @param signature signature to use for the reflog of updated references
* @param reflog_message message to use for the reflog of upated references
*/
GIT_EXTERN(int) git_remote_push(git_remote *remote,
git_strarray *refspecs,
const git_push_options *opts,
const git_signature *signature, const char *reflog_message);
/**
* Get a list of the configured remotes for a repo
*
* The string array must be freed by the user.
......@@ -462,6 +479,28 @@ struct git_remote_callbacks {
int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data);
/**
* 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.
*/
git_packbuilder_progress pack_progress;
/**
* 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.
*/
git_push_transfer_progress 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.
*/
int (*push_update_reference)(const char *refname, const char *status, void *data);
/**
* This will be passed to each of the callbacks in this struct
* as the last parameter.
*/
......
......@@ -2111,3 +2111,53 @@ int git_remote_default_branch(git_buf *out, git_remote *remote)
return git_buf_puts(out, guess->name);
}
int git_remote_push(git_remote *remote, git_strarray *refspecs, const git_push_options *opts,
const git_signature *signature, const char *reflog_message)
{
int error;
size_t i;
git_push *push = NULL;
git_remote_callbacks *cbs;
assert(remote && refspecs);
if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH)) < 0)
return error;
if ((error = git_push_new(&push, remote)) < 0)
goto cleanup;
if (opts && (error = git_push_set_options(push, opts)) < 0)
goto cleanup;
for (i = 0; i < refspecs->count; i++) {
if ((error = git_push_add_refspec(push, refspecs->strings[i])) < 0)
goto cleanup;
}
cbs = &remote->callbacks;
if ((error = git_push_set_callbacks(push,
cbs->pack_progress, cbs->payload,
cbs->push_transfer_progress, cbs->payload)) < 0)
goto cleanup;
if ((error = git_push_finish(push)) < 0)
goto cleanup;
if (!git_push_unpack_ok(push)) {
error = -1;
giterr_set(GITERR_NET, "error in the remote while trying to unpack");
goto cleanup;
}
if ((error = git_push_status_foreach(push, cbs->push_update_reference, cbs->payload)) < 0)
goto cleanup;
error = git_push_update_tips(push, signature, reflog_message);
cleanup:
git_remote_disconnect(remote);
git_push_free(push);
return error;
}
......@@ -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, data }
{ GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, data }
typedef struct {
char *name;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment