diff options
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | cmake/Modules/FindIconv.cmake | 3 | ||||
| -rw-r--r-- | examples/network/git2.c | 17 | ||||
| -rw-r--r-- | include/git2/merge.h | 3 | ||||
| -rw-r--r-- | include/git2/push.h | 30 | ||||
| -rw-r--r-- | include/git2/remote.h | 6 | ||||
| -rw-r--r-- | include/git2/types.h | 1 | ||||
| -rw-r--r-- | src/checkout.c | 2 | ||||
| -rw-r--r-- | src/config.c | 5 | ||||
| -rw-r--r-- | src/filter.c | 6 | ||||
| -rw-r--r-- | src/push.c | 47 | ||||
| -rw-r--r-- | src/push.h | 9 | ||||
| -rw-r--r-- | src/remote.c | 11 | ||||
| -rw-r--r-- | tests/online/push_util.h | 2 | ||||
| -rw-r--r-- | tests/rebase/merge.c | 5 |
15 files changed, 122 insertions, 27 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c97a18b50..4067e48f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,8 @@ support for HTTPS connections insead of OpenSSL. ### Breaking API changes +* `git_smart_subtransport_cb` now has a `param` parameter. + * The `git_merge_options` structure member `flags` has been renamed to `tree_flags`. diff --git a/cmake/Modules/FindIconv.cmake b/cmake/Modules/FindIconv.cmake index c5a419011..95414bda6 100644 --- a/cmake/Modules/FindIconv.cmake +++ b/cmake/Modules/FindIconv.cmake @@ -11,10 +11,7 @@ IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) SET(ICONV_FIND_QUIETLY TRUE) ENDIF() -FIND_PATH(ICONV_INCLUDE_DIR iconv.h PATHS /opt/local/include NO_DEFAULT_PATH) FIND_PATH(ICONV_INCLUDE_DIR iconv.h) - -FIND_LIBRARY(iconv_lib NAMES iconv libiconv libiconv-2 c NO_DEFAULT_PATH PATHS /opt/local/lib) FIND_LIBRARY(iconv_lib NAMES iconv libiconv libiconv-2 c) IF(ICONV_INCLUDE_DIR AND iconv_lib) diff --git a/examples/network/git2.c b/examples/network/git2.c index d44334b85..448103c46 100644 --- a/examples/network/git2.c +++ b/examples/network/git2.c @@ -23,8 +23,8 @@ static int run_command(git_cb fn, int argc, char **argv) int error; git_repository *repo; -// Before running the actual command, create an instance of the local -// repository and pass it to the function. + // Before running the actual command, create an instance of the local + // repository and pass it to the function. error = git_repository_open(&repo, ".git"); if (error < 0) @@ -48,6 +48,7 @@ static int run_command(git_cb fn, int argc, char **argv) int main(int argc, char **argv) { int i; + int return_code = 1; if (argc < 2) { fprintf(stderr, "usage: %s <cmd> [repo]\n", argv[0]); @@ -57,10 +58,16 @@ int main(int argc, char **argv) git_libgit2_init(); for (i = 0; commands[i].name != NULL; ++i) { - if (!strcmp(argv[1], commands[i].name)) - return run_command(commands[i].fn, --argc, ++argv); + if (!strcmp(argv[1], commands[i].name)) { + return_code = run_command(commands[i].fn, --argc, ++argv); + goto shutdown; + } } fprintf(stderr, "Command not found: %s\n", argv[1]); - return 1; + +shutdown: + git_libgit2_shutdown(); + + return return_code; } diff --git a/include/git2/merge.h b/include/git2/merge.h index d3360a7e0..5fef452b9 100644 --- a/include/git2/merge.h +++ b/include/git2/merge.h @@ -169,7 +169,7 @@ typedef struct { /** The file to favor in region conflicts. */ git_merge_file_favor_t favor; - /** Merge file flags. */ + /** see `git_merge_file_flags_t` above */ unsigned int flags; } git_merge_file_options; @@ -246,6 +246,7 @@ typedef struct { /** Flags for handling conflicting content. */ git_merge_file_favor_t file_favor; + /** see `git_merge_file_flags_t` above */ unsigned int file_flags; } git_merge_options; diff --git a/include/git2/push.h b/include/git2/push.h index ecabff397..3f850453d 100644 --- a/include/git2/push.h +++ b/include/git2/push.h @@ -59,6 +59,36 @@ typedef int (*git_push_transfer_progress)( 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 f85c38429..6e88a4680 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -521,6 +521,12 @@ struct git_remote_callbacks { int (*push_update_reference)(const char *refname, const char *status, void *data); /** + * Called once between the negotiation step and the upload. It + * provides information about what updates will be performed. + */ + git_push_negotiation push_negotiation; + + /** * This will be passed to each of the callbacks in this struct * as the last parameter. */ diff --git a/include/git2/types.h b/include/git2/types.h index c90ac4776..fdb5f2b09 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -273,6 +273,7 @@ typedef int (*git_transfer_progress_cb)(const git_transfer_progress *stats, void */ typedef int (*git_transport_message_cb)(const char *str, int len, void *payload); + /** * Type of host certificate structure that is passed to the check callback */ diff --git a/src/checkout.c b/src/checkout.c index 0b6e298a0..478130879 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -1457,7 +1457,7 @@ static int blob_content_to_file( writer.fd = fd; writer.open = 1; - error = git_filter_list_stream_blob(fl, blob, (git_writestream *)&writer); + error = git_filter_list_stream_blob(fl, blob, &writer.base); assert(writer.open == 0); diff --git a/src/config.c b/src/config.c index 550b22723..1400b9513 100644 --- a/src/config.c +++ b/src/config.c @@ -343,7 +343,6 @@ typedef struct { git_config_iterator *current; const git_config *cfg; regex_t regex; - int has_regex; size_t i; } all_iter; @@ -480,7 +479,6 @@ int git_config_iterator_glob_new(git_config_iterator **out, const git_config *cf if ((result = regcomp(&iter->regex, regexp, REG_EXTENDED)) != 0) { giterr_set_regex(&iter->regex, result); - regfree(&iter->regex); git__free(iter); return -1; } @@ -983,7 +981,8 @@ void multivar_iter_free(git_config_iterator *_iter) iter->iter->free(iter->iter); git__free(iter->name); - regfree(&iter->regex); + if (iter->have_regex) + regfree(&iter->regex); git__free(iter); } diff --git a/src/filter.c b/src/filter.c index 8bd7f4d07..19c793e89 100644 --- a/src/filter.c +++ b/src/filter.c @@ -671,7 +671,7 @@ int git_filter_list_apply_to_data( buf_stream_init(&writer, tgt); if ((error = git_filter_list_stream_data(filters, src, - (git_writestream *)&writer)) < 0) + &writer.parent)) < 0) return error; assert(writer.complete); @@ -690,7 +690,7 @@ int git_filter_list_apply_to_file( buf_stream_init(&writer, out); if ((error = git_filter_list_stream_file( - filters, repo, path, (git_writestream *)&writer)) < 0) + filters, repo, path, &writer.parent)) < 0) return error; assert(writer.complete); @@ -721,7 +721,7 @@ int git_filter_list_apply_to_blob( buf_stream_init(&writer, out); if ((error = git_filter_list_stream_blob( - filters, blob, (git_writestream *)&writer)) < 0) + filters, blob, &writer.parent)) < 0) return error; assert(writer.complete); diff --git a/src/push.c b/src/push.c index d4171bbd6..3ac6fbf63 100644 --- a/src/push.c +++ b/src/push.c @@ -54,6 +54,13 @@ int git_push_new(git_push **out, git_remote *remote) return -1; } + if (git_vector_init(&p->updates, 0, NULL) < 0) { + git_vector_free(&p->status); + git_vector_free(&p->specs); + git__free(p); + return -1; + } + *out = p; return 0; } @@ -75,7 +82,9 @@ int git_push_set_callbacks( git_packbuilder_progress pack_progress_cb, void *pack_progress_cb_payload, git_push_transfer_progress transfer_progress_cb, - void *transfer_progress_cb_payload) + void *transfer_progress_cb_payload, + git_push_negotiation negotiation_cb, + void *negotiation_cb_payload) { if (!push) return -1; @@ -86,6 +95,9 @@ int git_push_set_callbacks( 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; } @@ -534,6 +546,22 @@ on_error: return error; } +static int add_update(git_push *push, push_spec *spec) +{ + git_push_update *u = git__calloc(1, sizeof(git_push_update)); + GITERR_CHECK_ALLOC(u); + + u->src_refname = git__strdup(spec->refspec.src); + GITERR_CHECK_ALLOC(u->src_refname); + u->dst_refname = git__strdup(spec->refspec.src); + GITERR_CHECK_ALLOC(u->dst_refname); + + git_oid_cpy(&u->src, &spec->loid); + git_oid_cpy(&u->dst, &spec->roid); + + return git_vector_insert(&push->updates, u); +} + static int calculate_work(git_push *push) { git_remote_head *head; @@ -559,6 +587,9 @@ static int calculate_work(git_push *push) break; } } + + if (add_update(push, spec) < 0) + return -1; } return 0; @@ -590,9 +621,17 @@ static int do_push(git_push *push) if ((error = git_packbuilder_set_callbacks(push->pb, push->pack_progress_cb, push->pack_progress_cb_payload)) < 0) goto on_error; - if ((error = calculate_work(push)) < 0 || - (error = queue_objects(push)) < 0 || - (error = transport->push(transport, push)) < 0) + 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))) + goto on_error; + + if ((error = queue_objects(push)) < 0 || + (error = transport->push(transport, push)) < 0) goto on_error; on_error: diff --git a/src/push.h b/src/push.h index b19d40e03..fb5f01480 100644 --- a/src/push.h +++ b/src/push.h @@ -29,6 +29,7 @@ struct git_push { git_packbuilder *pb; git_remote *remote; git_vector specs; + git_vector updates; bool report_status; /* report-status */ @@ -42,6 +43,8 @@ struct git_push { 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; }; /** @@ -85,6 +88,8 @@ int git_push_set_options( * 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( @@ -92,7 +97,9 @@ int git_push_set_callbacks( git_packbuilder_progress pack_progress_cb, void *pack_progress_cb_payload, git_push_transfer_progress transfer_progress_cb, - void *transfer_progress_cb_payload); + void *transfer_progress_cb_payload, + git_push_negotiation negotiation_cb, + void *negotiation_cb_payload); /** * Add a refspec to be pushed diff --git a/src/remote.c b/src/remote.c index ac7c43c78..5257e85f3 100644 --- a/src/remote.c +++ b/src/remote.c @@ -171,11 +171,11 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n if ((error = git_repository_config_snapshot(&config, repo)) < 0) goto on_error; - if (lookup_remote_prune_config(remote, config, name) < 0) + if ((error = lookup_remote_prune_config(remote, config, name)) < 0) goto on_error; /* Move the data over to where the matching functions can find them */ - if (dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs) < 0) + if ((error = dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs)) < 0) goto on_error; } @@ -457,7 +457,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) goto cleanup; /* Move the data over to where the matching functions can find them */ - if (dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs) < 0) + if ((error = dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs)) < 0) goto cleanup; *out = remote; @@ -2330,7 +2330,7 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi goto cleanup; free_refspecs(&remote->active_refspecs); - if (dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs) < 0) + if ((error = dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs)) < 0) goto cleanup; if (remote->push) { @@ -2363,7 +2363,8 @@ 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)) < 0) + cbs->push_transfer_progress, cbs->payload, + cbs->push_negotiation, cbs->payload)) < 0) goto cleanup; if ((error = git_push_finish(push)) < 0) diff --git a/tests/online/push_util.h b/tests/online/push_util.h index 2e05c4ed7..83d46b506 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, data } + { GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, data } typedef struct { char *name; diff --git a/tests/rebase/merge.c b/tests/rebase/merge.c index 12f0de5a0..33eadb7ed 100644 --- a/tests/rebase/merge.c +++ b/tests/rebase/merge.c @@ -517,6 +517,11 @@ void rebase_checkout_progress_cb( void *payload) { int *called = payload; + + GIT_UNUSED(path); + GIT_UNUSED(completed_steps); + GIT_UNUSED(total_steps); + *called = 1; } |
