diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/push.h | 110 | ||||
-rw-r--r-- | src/remote.c | 53 | ||||
-rw-r--r-- | src/remote.h | 1 |
3 files changed, 152 insertions, 12 deletions
diff --git a/src/push.h b/src/push.h index 68fa868dd..264ecad8c 100644 --- a/src/push.h +++ b/src/push.h @@ -51,4 +51,114 @@ struct git_push { */ void git_push_status_free(push_status *status); +/** + * Create a new push object + * + * @param out New push object + * @param remote Remote instance + * + * @return 0 or an error code + */ +int git_push_new(git_push **out, git_remote *remote); + +/** + * Set options on a push object + * + * @param push The push object + * @param opts The options to set on the push object + * + * @return 0 or an error code + */ +int git_push_set_options( + git_push *push, + 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. + * @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); + +/** + * Add a refspec to be pushed + * + * @param push The push object + * @param refspec Refspec string + * + * @return 0 or an error code + */ +int git_push_add_refspec(git_push *push, const char *refspec); + +/** + * Update remote tips after a push + * + * @param push The push object + * @param signature The identity to use when updating reflogs + * @param reflog_message The message to insert into the reflogs. If NULL, the + * default is "update by push". + * + * @return 0 or an error code + */ +int git_push_update_tips( + git_push *push, + const git_signature *signature, + const char *reflog_message); + +/** + * Perform the push + * + * This function will return an error in case of a protocol error or + * the server being unable to unpack the data we sent. + * + * The return value does not reflect whether the server accepted or + * refused any reference updates. Use `git_push_status_foreach()` in + * order to find out which updates were accepted or rejected. + * + * @param push The push object + * + * @return 0 or an error code + */ +int git_push_finish(git_push *push); + +/** + * Invoke callback `cb' on each status entry + * + * For each of the updated references, we receive a status report in the + * form of `ok refs/heads/master` or `ng refs/heads/master <msg>`. + * `msg != NULL` means the reference has not been updated for the given + * reason. + * + * Return a non-zero value from the callback to stop the loop. + * + * @param push The push object + * @param cb The callback to call on each object + * + * @return 0 on success, non-zero callback return value, or error code + */ +int git_push_status_foreach(git_push *push, + int (*cb)(const char *ref, const char *msg, void *data), + void *data); + +/** + * Free the given push object + * + * @param push The push object + */ +void git_push_free(git_push *push); + #endif diff --git a/src/remote.c b/src/remote.c index dd9b17854..af6c3ff60 100644 --- a/src/remote.c +++ b/src/remote.c @@ -18,6 +18,7 @@ #include "refs.h" #include "refspec.h" #include "fetchhead.h" +#include "push.h" static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs); @@ -1275,6 +1276,11 @@ int git_remote_update_tips( 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, signature, reflog_message); + } + if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0) return -1; @@ -1355,6 +1361,7 @@ void git_remote_free(git_remote *remote) free_refspecs(&remote->passive_refspecs); git_vector_free(&remote->passive_refspecs); + git_push_free(remote->push); git__free(remote->url); git__free(remote->pushurl); git__free(remote->name); @@ -2117,22 +2124,29 @@ 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 git_remote_upload(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts) { - int error; size_t i; - git_push *push = NULL; - git_remote_callbacks *cbs; + int error; + git_push *push; git_refspec *spec; + git_remote_callbacks *cbs; - assert(remote && refspecs); + assert(remote); - if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH)) < 0) + if (!git_remote_connected(remote) && + (error = git_remote_connect(remote, GIT_DIRECTION_PUSH)) < 0) + goto cleanup; + + if (remote->push) { + git_push_free(remote->push); + remote->push = NULL; + } + + if ((error = git_push_new(&remote->push, remote)) < 0) return error; - if ((error = git_push_new(&push, remote)) < 0) - goto cleanup; + push = remote->push; if (opts && (error = git_push_set_options(push, opts)) < 0) goto cleanup; @@ -2164,10 +2178,25 @@ int git_remote_push(git_remote *remote, git_strarray *refspecs, const git_push_o (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: + return error; +} + +int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts, + const git_signature *signature, const char *reflog_message) +{ + int error; + + assert(remote && refspecs); + + if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH)) < 0) + return error; + + if ((error = git_remote_upload(remote, refspecs, opts)) < 0) + return error; + + error = git_remote_update_tips(remote, signature, reflog_message); + git_remote_disconnect(remote); - git_push_free(push); return error; } diff --git a/src/remote.h b/src/remote.h index b79ace438..ba7d6b0d9 100644 --- a/src/remote.h +++ b/src/remote.h @@ -28,6 +28,7 @@ struct git_remote { 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; |