summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2014-10-10 12:39:53 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2014-11-09 00:01:58 +0100
commit3149547b5ae526f28412574d64d874a4dfd2ed9c (patch)
tree9943060f2c2991865c61f4ec1ccdc55f9d0639db
parent4865cc3f0631a8a4e0e1de897865df0e552c70cb (diff)
downloadlibgit2-3149547b5ae526f28412574d64d874a4dfd2ed9c.tar.gz
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.
-rw-r--r--include/git2/remote.h39
-rw-r--r--src/remote.c50
-rw-r--r--tests/online/push_util.h2
3 files changed, 90 insertions, 1 deletions
diff --git a/include/git2/remote.h b/include/git2/remote.h
index 0d7fd230f..bb5aac4e1 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -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.
*/
diff --git a/src/remote.c b/src/remote.c
index cc9f85cd1..524d5a3d4 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -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;
+}
diff --git a/tests/online/push_util.h b/tests/online/push_util.h
index 7736912d6..3d4a38834 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, data }
+ { GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, data }
typedef struct {
char *name;