diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ec1c828d6..005d830b3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -84,6 +84,17 @@ jobs: strategy: matrix: platform: + - name: "Linux (Focal, Clang, mbedTLS, push-options)" + id: focal-clang-mbedtls + container: + name: focal + env: + CC: clang-10 + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON + RUN_PUSH_OPTONS_TESTS: true + SKIP_SSH_TESTS: true + os: ubuntu-latest - name: "Linux (Xenial, GCC, OpenSSL)" id: xenial-gcc-openssl container: diff --git a/ci/hooks/pre-receive b/ci/hooks/pre-receive new file mode 100755 index 000000000..92be65ce0 --- /dev/null +++ b/ci/hooks/pre-receive @@ -0,0 +1,2 @@ +#!/bin/sh +printf "$GIT_PUSH_OPTION_0$GIT_PUSH_OPTION_1$GIT_PUSH_OPTION_2" > %file% diff --git a/ci/test.sh b/ci/test.sh index 0e1d39e8d..63062f07f 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -e +set -ex if [ -n "$SKIP_TESTS" ]; then exit 0 @@ -106,7 +106,15 @@ if [ -z "$SKIP_GITDAEMON_TESTS" ]; then echo "Starting git daemon (standard)..." GIT_STANDARD_DIR=`mktemp -d ${TMPDIR}/git_standard.XXXXXXXX` git init --bare "${GIT_STANDARD_DIR}/test.git" >/dev/null + git config --file "${GIT_STANDARD_DIR}/test.git/config" receive.advertisePushOptions true + for f in $(ls ${SOURCE_DIR}/ci/hooks) + do + sed "s=%file%=${TMPDIR}/push-option-result-git-daemon=g" "${SOURCE_DIR}/ci/hooks/$f" > "${GIT_STANDARD_DIR}/test.git/hooks/${f}" + chmod +x "$GIT_STANDARD_DIR/test.git/hooks/${f}" + done + git daemon --listen=localhost --export-all --enable=receive-pack --base-path="${GIT_STANDARD_DIR}" "${GIT_STANDARD_DIR}" 2>/dev/null & + GIT_STANDARD_PID=$! echo "Starting git daemon (namespace)..." @@ -134,6 +142,14 @@ if [ -z "$SKIP_NTLM_TESTS" -o -z "$SKIP_ONLINE_TESTS" ]; then echo "Starting HTTP server..." HTTP_DIR=`mktemp -d ${TMPDIR}/http.XXXXXXXX` git init --bare "${HTTP_DIR}/test.git" + git config --file "${HTTP_DIR}/test.git/config" receive.advertisePushOptions true + + for f in $(ls ${SOURCE_DIR}/ci/hooks) + do + sed "s=%file%=${TMPDIR}/push-option-result-git-ntlm=g" "${SOURCE_DIR}/ci/hooks/$f" > "${HTTP_DIR}/test.git/hooks/${f}" + chmod +x "$HTTP_DIR/test.git/hooks/${f}" + done + java -jar poxygit.jar --address 127.0.0.1 --port 9000 --credentials foo:baz --quiet "${HTTP_DIR}" & HTTP_PID=$! fi @@ -143,6 +159,14 @@ if [ -z "$SKIP_SSH_TESTS" ]; then HOME=`mktemp -d ${TMPDIR}/home.XXXXXXXX` SSHD_DIR=`mktemp -d ${TMPDIR}/sshd.XXXXXXXX` git init --bare "${SSHD_DIR}/test.git" >/dev/null + git config --file "${SSHD_DIR}/test.git/config" receive.advertisePushOptions true + + for f in $(ls ${SOURCE_DIR}/ci/hooks) + do + sed "s=%file%=${TMPDIR}/push-option-result-git-ssh=g" "${SOURCE_DIR}/ci/hooks/$f" > "${SSHD_DIR}/test.git/hooks/${f}" + chmod +x "$SSHD_DIR/test.git/hooks/${f}" + done + cat >"${SSHD_DIR}/sshd_config" <<-EOF Port 2222 ListenAddress 0.0.0.0 @@ -243,8 +267,12 @@ if [ -z "$SKIP_GITDAEMON_TESTS" ]; then echo "Running gitdaemon (standard) tests" echo "" + if [[ "$RUN_PUSH_OPTONS_TESTS" = "true " ]]; then + export GITTEST_PUSH_OPTION_RESULT="${TMPDIR}/push-option-result-git-daemon" + fi export GITTEST_REMOTE_URL="git://localhost/test.git" run_test gitdaemon + unset GITTEST_PUSH_OPTION_RESULT unset GITTEST_REMOTE_URL echo "" @@ -289,10 +317,14 @@ if [ -z "$SKIP_NTLM_TESTS" ]; then echo "Running NTLM tests (IIS emulation)" echo "" + if [[ "$RUN_PUSH_OPTONS_TESTS" = "true " ]]; then + export GITTEST_PUSH_OPTION_RESULT="${TMPDIR}/push-option-result-git-ntlm" + fi export GITTEST_REMOTE_URL="http://localhost:9000/ntlm/test.git" export GITTEST_REMOTE_USER="foo" export GITTEST_REMOTE_PASS="baz" run_test auth_clone_and_push + unset GITTEST_PUSH_OPTION_RESULT unset GITTEST_REMOTE_URL unset GITTEST_REMOTE_USER unset GITTEST_REMOTE_PASS @@ -301,10 +333,14 @@ if [ -z "$SKIP_NTLM_TESTS" ]; then echo "Running NTLM tests (Apache emulation)" echo "" + if [[ "$RUN_PUSH_OPTONS_TESTS" == "true " ]]; then + export GITTEST_PUSH_OPTION_RESULT="${TMPDIR}/push-option-result-git-ntlm" + fi export GITTEST_REMOTE_URL="http://localhost:9000/broken-ntlm/test.git" export GITTEST_REMOTE_USER="foo" export GITTEST_REMOTE_PASS="baz" run_test auth_clone_and_push + unset GITTEST_PUSH_OPTION_RESULT unset GITTEST_REMOTE_URL unset GITTEST_REMOTE_USER unset GITTEST_REMOTE_PASS @@ -354,16 +390,24 @@ if [ -z "$SKIP_SSH_TESTS" ]; then echo "Running ssh tests" echo "" + if [[ "$RUN_PUSH_OPTONS_TESTS" == "true " ]]; then + export GITTEST_PUSH_OPTION_RESULT="${TMPDIR}/push-option-result-ssh" + fi export GITTEST_REMOTE_URL="ssh://localhost:2222/$SSHD_DIR/test.git" run_test ssh + unset GITTEST_PUSH_OPTION_RESULT unset GITTEST_REMOTE_URL echo "" echo "Running ssh tests (scp-style paths)" echo "" + if [[ "$RUN_PUSH_OPTONS_TESTS" == "true " ]]; then + export GITTEST_PUSH_OPTION_RESULT="${TMPDIR}/push-option-result-ssh" + fi export GITTEST_REMOTE_URL="[localhost:2222]:$SSHD_DIR/test.git" run_test ssh + unset GITTEST_PUSH_OPTION_RESULT unset GITTEST_REMOTE_URL unset GITTEST_REMOTE_USER diff --git a/tests/libgit2/online/push.c b/tests/libgit2/online/push.c index d9208d28a..d7dbda3bc 100644 --- a/tests/libgit2/online/push.c +++ b/tests/libgit2/online/push.c @@ -5,6 +5,7 @@ #include "push_util.h" #include "refspec.h" #include "remote.h" +#include "futils.h" static git_repository *_repo; @@ -20,6 +21,8 @@ static char *_remote_ssh_passphrase = NULL; static char *_remote_default = NULL; static char *_remote_expectcontinue = NULL; +static char *_remote_push_options_result = NULL; + static int cred_acquire_cb(git_credential **, const char *, const char *, unsigned int, void *); static git_remote *_remote; @@ -367,6 +370,7 @@ void test_online_push__initialize(void) _remote_ssh_passphrase = cl_getenv("GITTEST_REMOTE_SSH_PASSPHRASE"); _remote_default = cl_getenv("GITTEST_REMOTE_DEFAULT"); _remote_expectcontinue = cl_getenv("GITTEST_REMOTE_EXPECTCONTINUE"); + _remote_push_options_result = cl_getenv("GITTEST_PUSH_OPTION_RESULT"); _remote = NULL; /* Skip the test if we're missing the remote URL */ @@ -422,6 +426,7 @@ void test_online_push__cleanup(void) git__free(_remote_ssh_passphrase); git__free(_remote_default); git__free(_remote_expectcontinue); + git__free(_remote_push_options_result); /* Freed by cl_git_sandbox_cleanup */ _repo = NULL; @@ -472,7 +477,8 @@ static void do_push( const char *refspecs[], size_t refspecs_len, push_status expected_statuses[], size_t expected_statuses_len, expected_ref expected_refs[], size_t expected_refs_len, - int expected_ret, int check_progress_cb, int check_update_tips_cb) + int expected_ret, int check_progress_cb, int check_update_tips_cb, + git_strarray push_options) { git_push_options opts = GIT_PUSH_OPTIONS_INIT; size_t i; @@ -484,6 +490,9 @@ static void do_push( /* Auto-detect the number of threads to use */ opts.pb_parallelism = 0; + if(push_options.count != 0) + opts.push_options = push_options; + memcpy(&opts.callbacks, &_record_cbs, sizeof(git_remote_callbacks)); data = opts.callbacks.payload; @@ -533,7 +542,8 @@ static void do_push( /* Call push_finish() without ever calling git_push_add_refspec() */ void test_online_push__noop(void) { - do_push(NULL, 0, NULL, 0, NULL, 0, 0, 0, 1); + git_strarray push_options = { 0 }; + do_push(NULL, 0, NULL, 0, NULL, 0, 0, 0, 1, push_options); } void test_online_push__b1(void) @@ -541,9 +551,10 @@ void test_online_push__b1(void) const char *specs[] = { "refs/heads/b1:refs/heads/b1" }; push_status exp_stats[] = { { "refs/heads/b1", 1 } }; expected_ref exp_refs[] = { { "refs/heads/b1", &_oid_b1 } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); } void test_online_push__b2(void) @@ -551,9 +562,10 @@ void test_online_push__b2(void) const char *specs[] = { "refs/heads/b2:refs/heads/b2" }; push_status exp_stats[] = { { "refs/heads/b2", 1 } }; expected_ref exp_refs[] = { { "refs/heads/b2", &_oid_b2 } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); } void test_online_push__b3(void) @@ -561,9 +573,10 @@ void test_online_push__b3(void) const char *specs[] = { "refs/heads/b3:refs/heads/b3" }; push_status exp_stats[] = { { "refs/heads/b3", 1 } }; expected_ref exp_refs[] = { { "refs/heads/b3", &_oid_b3 } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); } void test_online_push__b4(void) @@ -571,9 +584,10 @@ void test_online_push__b4(void) const char *specs[] = { "refs/heads/b4:refs/heads/b4" }; push_status exp_stats[] = { { "refs/heads/b4", 1 } }; expected_ref exp_refs[] = { { "refs/heads/b4", &_oid_b4 } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); } void test_online_push__b5(void) @@ -581,15 +595,17 @@ void test_online_push__b5(void) const char *specs[] = { "refs/heads/b5:refs/heads/b5" }; push_status exp_stats[] = { { "refs/heads/b5", 1 } }; expected_ref exp_refs[] = { { "refs/heads/b5", &_oid_b5 } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); } void test_online_push__b5_cancel(void) { const char *specs[] = { "refs/heads/b5:refs/heads/b5" }; - do_push(specs, ARRAY_SIZE(specs), NULL, 0, NULL, 0, GIT_EUSER, 1, 1); + git_strarray push_options = { 0 }; + do_push(specs, ARRAY_SIZE(specs), NULL, 0, NULL, 0, GIT_EUSER, 1, 1, push_options); } void test_online_push__multi(void) @@ -618,9 +634,10 @@ void test_online_push__multi(void) { "refs/heads/b4", &_oid_b4 }, { "refs/heads/b5", &_oid_b5 } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); cl_git_pass(git_reflog_read(&log, _repo, "refs/remotes/test/b1")); entry = git_reflog_entry_byindex(log, 0); @@ -645,12 +662,14 @@ void test_online_push__implicit_tgt(void) { "refs/heads/b2", &_oid_b2 } }; + git_strarray push_options = { 0 }; do_push(specs1, ARRAY_SIZE(specs1), exp_stats1, ARRAY_SIZE(exp_stats1), - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1, push_options); + do_push(specs2, ARRAY_SIZE(specs2), exp_stats2, ARRAY_SIZE(exp_stats2), - exp_refs2, ARRAY_SIZE(exp_refs2), 0, 0, 0); + exp_refs2, ARRAY_SIZE(exp_refs2), 0, 0, 0, push_options); } void test_online_push__fast_fwd(void) @@ -670,21 +689,22 @@ void test_online_push__fast_fwd(void) /* Force should have no effect on a fast forward push */ const char *specs_ff_force[] = { "+refs/heads/b6:refs/heads/b1" }; + git_strarray push_options = { 0 }; do_push(specs_init, ARRAY_SIZE(specs_init), exp_stats_init, ARRAY_SIZE(exp_stats_init), - exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 1, 1); + exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 1, 1, push_options); do_push(specs_ff, ARRAY_SIZE(specs_ff), exp_stats_ff, ARRAY_SIZE(exp_stats_ff), - exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0); + exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0, push_options); do_push(specs_reset, ARRAY_SIZE(specs_reset), exp_stats_init, ARRAY_SIZE(exp_stats_init), - exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 0, 0); + exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 0, 0, push_options); do_push(specs_ff_force, ARRAY_SIZE(specs_ff_force), exp_stats_ff, ARRAY_SIZE(exp_stats_ff), - exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0); + exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0, push_options); } void test_online_push__tag_commit(void) @@ -692,9 +712,10 @@ void test_online_push__tag_commit(void) const char *specs[] = { "refs/tags/tag-commit:refs/tags/tag-commit" }; push_status exp_stats[] = { { "refs/tags/tag-commit", 1 } }; expected_ref exp_refs[] = { { "refs/tags/tag-commit", &_tag_commit } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); } void test_online_push__tag_tree(void) @@ -702,9 +723,10 @@ void test_online_push__tag_tree(void) const char *specs[] = { "refs/tags/tag-tree:refs/tags/tag-tree" }; push_status exp_stats[] = { { "refs/tags/tag-tree", 1 } }; expected_ref exp_refs[] = { { "refs/tags/tag-tree", &_tag_tree } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); } void test_online_push__tag_blob(void) @@ -712,9 +734,10 @@ void test_online_push__tag_blob(void) const char *specs[] = { "refs/tags/tag-blob:refs/tags/tag-blob" }; push_status exp_stats[] = { { "refs/tags/tag-blob", 1 } }; expected_ref exp_refs[] = { { "refs/tags/tag-blob", &_tag_blob } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); } void test_online_push__tag_lightweight(void) @@ -722,9 +745,10 @@ void test_online_push__tag_lightweight(void) const char *specs[] = { "refs/tags/tag-lightweight:refs/tags/tag-lightweight" }; push_status exp_stats[] = { { "refs/tags/tag-lightweight", 1 } }; expected_ref exp_refs[] = { { "refs/tags/tag-lightweight", &_tag_lightweight } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); } void test_online_push__tag_to_tag(void) @@ -732,9 +756,10 @@ void test_online_push__tag_to_tag(void) const char *specs[] = { "refs/tags/tag-tag:refs/tags/tag-tag" }; push_status exp_stats[] = { { "refs/tags/tag-tag", 1 } }; expected_ref exp_refs[] = { { "refs/tags/tag-tag", &_tag_tag } }; + git_strarray push_options = { 0 }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 0, 0); + exp_refs, ARRAY_SIZE(exp_refs), 0, 0, 0, push_options); } void test_online_push__force(void) @@ -749,19 +774,64 @@ void test_online_push__force(void) push_status exp_stats2_force[] = { { "refs/heads/tgt", 1 } }; expected_ref exp_refs2_force[] = { { "refs/heads/tgt", &_oid_b4 } }; + git_strarray push_options = { 0 }; do_push(specs1, ARRAY_SIZE(specs1), exp_stats1, ARRAY_SIZE(exp_stats1), - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1, push_options); do_push(specs2, ARRAY_SIZE(specs2), NULL, 0, - exp_refs1, ARRAY_SIZE(exp_refs1), GIT_ENONFASTFORWARD, 0, 0); + exp_refs1, ARRAY_SIZE(exp_refs1), GIT_ENONFASTFORWARD, 0, 0, push_options); /* Non-fast-forward update with force should pass. */ record_callbacks_data_clear(&_record_cbs_data); do_push(specs2_force, ARRAY_SIZE(specs2_force), exp_stats2_force, ARRAY_SIZE(exp_stats2_force), - exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0, 1, 1); + exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0, 1, 1, push_options); +} + +static void push_option_test(git_strarray push_options, const char *expected_option) +{ + const char *specs[] = { "refs/heads/b1:refs/heads/b1" }; + push_status exp_stats[] = { { "refs/heads/b1", 1 } }; + expected_ref exp_refs[] = { { "refs/heads/b1", &_oid_b1 } }; + git_str push_options_result = GIT_STR_INIT; + + /* Skip the test if we're missing the push options result file */ + if (!_remote_push_options_result) + cl_skip(); + + do_push(specs, ARRAY_SIZE(specs), + exp_stats, ARRAY_SIZE(exp_stats), + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); + + if (git_futils_readbuffer(&push_options_result, _remote_push_options_result) < 0) + cl_fail("Failed to read push options result file"); + + cl_assert_equal_strn(expected_option, git_str_cstr(&push_options_result), + strlen(expected_option)); + + git_str_dispose(&push_options_result); +} + +void test_online_push__options(void) +{ + char *push_options_string_args_test_1[1] = { "test_string" }; + git_strarray push_options_test_1 = { push_options_string_args_test_1, 1 }; + + char *push_options_string_args_test_2[2] = { "test_string", "another arg?" }; + git_strarray push_options_test_2 = { push_options_string_args_test_2, 2 }; + + char *push_options_string_args_test_3[1] = { "πŸ‘¨πŸΏβ€πŸ’» but can it do unicode? πŸ‡ΊπŸ‡¦" }; + git_strarray push_options_test_3 = { push_options_string_args_test_3, 1 }; + + char *push_options_string_args_test_4[3] = { "\0", "\0", "\0" }; + git_strarray push_options_test_4 = { push_options_string_args_test_4, 3 }; + + push_option_test(push_options_test_1, "test_string"); + push_option_test(push_options_test_2, "test_stringanother arg?"); + push_option_test(push_options_test_3, "πŸ‘¨πŸΏβ€πŸ’» but can it do unicode? πŸ‡ΊπŸ‡¦"); + push_option_test(push_options_test_4, "\0\0\0"); } void test_online_push__delete(void) @@ -790,9 +860,10 @@ void test_online_push__delete(void) /* Force has no effect for delete. */ const char *specs_delete_force[] = { "+:refs/heads/tgt1" }; + git_strarray push_options = { 0 }; do_push(specs1, ARRAY_SIZE(specs1), exp_stats1, ARRAY_SIZE(exp_stats1), - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1, push_options); /* When deleting a non-existent branch, the git client sends zero for both * the old and new commit id. This should succeed on the server with the @@ -802,23 +873,25 @@ void test_online_push__delete(void) */ do_push(specs_del_fake, ARRAY_SIZE(specs_del_fake), exp_stats_fake, 1, - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0, push_options); + do_push(specs_del_fake_force, ARRAY_SIZE(specs_del_fake_force), exp_stats_fake, 1, - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0, push_options); /* Delete one of the pushed branches. */ do_push(specs_delete, ARRAY_SIZE(specs_delete), exp_stats_delete, ARRAY_SIZE(exp_stats_delete), - exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0); + exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0, push_options); /* Re-push branches and retry delete with force. */ do_push(specs1, ARRAY_SIZE(specs1), exp_stats1, ARRAY_SIZE(exp_stats1), - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0, push_options); + do_push(specs_delete_force, ARRAY_SIZE(specs_delete_force), exp_stats_delete, ARRAY_SIZE(exp_stats_delete), - exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0); + exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0, push_options); } void test_online_push__bad_refspecs(void) @@ -845,15 +918,17 @@ void test_online_push__expressions(void) const char *specs_left_expr[] = { "refs/heads/b2~1:refs/heads/b2" }; /* TODO: Find a more precise way of checking errors than a exit code of -1. */ + git_strarray push_options = { 0 }; do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr), NULL, 0, - NULL, 0, -1, 0, 0); + NULL, 0, -1, 0, 0, push_options); } void test_online_push__notes(void) { git_oid note_oid, *target_oid, expected_oid; git_signature *signature; + git_strarray push_options = { 0 }; const char *specs[] = { "refs/notes/commits:refs/notes/commits" }; push_status exp_stats[] = { { "refs/notes/commits", 1 } }; expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } }; @@ -869,13 +944,13 @@ void test_online_push__notes(void) do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); /* And make sure to delete the note */ do_push(specs_del, ARRAY_SIZE(specs_del), exp_stats, 1, - NULL, 0, 0, 0, 0); + NULL, 0, 0, 0, 0, push_options); git_signature_free(signature); } @@ -885,6 +960,7 @@ void test_online_push__configured(void) git_oid note_oid, *target_oid, expected_oid; git_signature *signature; git_remote *old_remote; + git_strarray push_options = { 0 }; const char *specs[] = { "refs/notes/commits:refs/notes/commits" }; push_status exp_stats[] = { { "refs/notes/commits", 1 } }; expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } }; @@ -905,13 +981,13 @@ void test_online_push__configured(void) do_push(NULL, 0, exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1, push_options); /* And make sure to delete the note */ do_push(specs_del, ARRAY_SIZE(specs_del), exp_stats, 1, - NULL, 0, 0, 0, 0); + NULL, 0, 0, 0, 0, push_options); git_signature_free(signature); }