Merge pull request #6439 from russell/push-options

Implement push options on push
This commit is contained in:
Edward Thomson
2024-02-07 11:31:24 +00:00
committed by GitHub
20 changed files with 274 additions and 42 deletions

View File

@@ -162,8 +162,9 @@ echo ""
if should_run "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
cp -R "${SOURCE_DIR}/tests/resources/pushoptions.git" "${GIT_STANDARD_DIR}/test.git"
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)..."
@@ -196,7 +197,8 @@ if should_run "NTLM_TESTS" || should_run "ONLINE_TESTS"; then
echo "Starting HTTP server..."
HTTP_DIR=`mktemp -d ${TMPDIR}/http.XXXXXXXX`
git init --bare "${HTTP_DIR}/test.git"
cp -R "${SOURCE_DIR}/tests/resources/pushoptions.git" "${HTTP_DIR}/test.git"
java -jar poxygit.jar --address 127.0.0.1 --port 9000 --credentials foo:baz --quiet "${HTTP_DIR}" &
HTTP_PID=$!
fi
@@ -204,7 +206,9 @@ fi
if should_run "SSH_TESTS"; then
echo "Starting SSH server..."
SSHD_DIR=`mktemp -d ${TMPDIR}/sshd.XXXXXXXX`
git init --bare "${SSHD_DIR}/test.git" >/dev/null
cp -R "${SOURCE_DIR}/tests/resources/pushoptions.git" "${SSHD_DIR}/test.git"
ls -FlasR "${SSHD_DIR}"
cat >"${SSHD_DIR}/sshd_config" <<-EOF
Port 2222
ListenAddress 0.0.0.0
@@ -321,8 +325,10 @@ if should_run "GITDAEMON_TESTS"; then
echo ""
export GITTEST_REMOTE_URL="git://localhost/test.git"
export GITTEST_PUSH_OPTIONS=true
run_test gitdaemon
unset GITTEST_REMOTE_URL
unset GITTEST_PUSH_OPTIONS
echo ""
echo "Running gitdaemon (namespace) tests"
@@ -377,10 +383,12 @@ if should_run "NTLM_TESTS"; then
export GITTEST_REMOTE_URL="http://localhost:9000/ntlm/test.git"
export GITTEST_REMOTE_USER="foo"
export GITTEST_REMOTE_PASS="baz"
export GITTEST_PUSH_OPTIONS=true
run_test auth_clone_and_push
unset GITTEST_REMOTE_URL
unset GITTEST_REMOTE_USER
unset GITTEST_REMOTE_PASS
unset GITTEST_PUSH_OPTIONS
echo ""
echo "Running NTLM tests (Apache emulation)"
@@ -389,10 +397,12 @@ if should_run "NTLM_TESTS"; then
export GITTEST_REMOTE_URL="http://localhost:9000/broken-ntlm/test.git"
export GITTEST_REMOTE_USER="foo"
export GITTEST_REMOTE_PASS="baz"
export GITTEST_PUSH_OPTIONS=true
run_test auth_clone_and_push
unset GITTEST_REMOTE_URL
unset GITTEST_REMOTE_USER
unset GITTEST_REMOTE_PASS
unset GITTEST_PUSH_OPTIONS
fi
if should_run "NEGOTIATE_TESTS" && -n "$GITTEST_NEGOTIATE_PASSWORD" ; then
@@ -442,16 +452,20 @@ if should_run "SSH_TESTS"; then
echo ""
export GITTEST_REMOTE_URL="ssh://localhost:2222/$SSHD_DIR/test.git"
export GITTEST_PUSH_OPTIONS=true
run_test ssh
unset GITTEST_REMOTE_URL
unset GITTEST_PUSH_OPTIONS
echo ""
echo "Running ssh tests (scp-style paths)"
echo ""
export GITTEST_REMOTE_URL="[localhost:2222]:$SSHD_DIR/test.git"
export GITTEST_PUSH_OPTIONS=true
run_test ssh
unset GITTEST_REMOTE_URL
unset GITTEST_PUSH_OPTIONS
unset GITTEST_SSH_CMD

View File

@@ -846,6 +846,11 @@ typedef struct {
* Extra headers for this push operation
*/
git_strarray custom_headers;
/**
* "Push options" to deliver to the remote.
*/
git_strarray remote_push_options;
} git_push_options;
#define GIT_PUSH_OPTIONS_VERSION 1

View File

@@ -26,6 +26,9 @@ typedef enum {
/** Remote supports fetching an individual reachable object. */
GIT_REMOTE_CAPABILITY_REACHABLE_OID = (1 << 1),
/** Remote supports push options. */
GIT_REMOTE_CAPABILITY_PUSH_OPTIONS = (1 << 2),
} git_remote_capability_t;
/**

View File

@@ -68,6 +68,14 @@ int git_push_new(git_push **out, git_remote *remote, const git_push_options *opt
return -1;
}
if (git_vector_init(&p->remote_push_options, 0, git__strcmp_cb) < 0) {
git_vector_free(&p->status);
git_vector_free(&p->specs);
git_vector_free(&p->updates);
git__free(p);
return -1;
}
*out = p;
return 0;
}
@@ -490,12 +498,24 @@ static int filter_refs(git_remote *remote)
int git_push_finish(git_push *push)
{
int error;
unsigned int remote_caps;
if (!git_remote_connected(push->remote)) {
git_error_set(GIT_ERROR_NET, "remote is disconnected");
return -1;
}
if ((error = git_remote_capabilities(&remote_caps, push->remote)) < 0) {
git_error_set(GIT_ERROR_INVALID, "remote capabilities not available");
return -1;
}
if (git_vector_length(&push->remote_push_options) > 0 &&
!(remote_caps & GIT_REMOTE_CAPABILITY_PUSH_OPTIONS)) {
git_error_set(GIT_ERROR_INVALID, "push-options not supported by remote");
return -1;
}
if ((error = filter_refs(push->remote)) < 0 ||
(error = do_push(push)) < 0)
return error;
@@ -539,6 +559,7 @@ void git_push_free(git_push *push)
push_spec *spec;
push_status *status;
git_push_update *update;
char *option;
unsigned int i;
if (push == NULL)
@@ -561,6 +582,11 @@ void git_push_free(git_push *push)
}
git_vector_free(&push->updates);
git_vector_foreach(&push->remote_push_options, i, option) {
git__free(option);
}
git_vector_free(&push->remote_push_options);
git__free(push);
}

View File

@@ -34,6 +34,7 @@ struct git_push {
git_vector specs;
git_vector updates;
bool report_status;
git_vector remote_push_options;
/* report-status */
bool unpack_ok;

View File

@@ -2982,6 +2982,15 @@ int git_remote_upload(
}
}
if (opts && opts->remote_push_options.count > 0)
for (i = 0; i < opts->remote_push_options.count; ++i) {
char *optstr = git__strdup(opts->remote_push_options.strings[i]);
GIT_ERROR_CHECK_ALLOC(optstr);
if ((error = git_vector_insert(&push->remote_push_options, optstr)) < 0)
goto cleanup;
}
if ((error = git_push_finish(push)) < 0)
goto cleanup;

View File

@@ -249,6 +249,9 @@ static int git_smart__capabilities(unsigned int *capabilities, git_transport *tr
*capabilities = 0;
if (t->caps.push_options)
*capabilities |= GIT_REMOTE_CAPABILITY_PUSH_OPTIONS;
if (t->caps.want_tip_sha1)
*capabilities |= GIT_REMOTE_CAPABILITY_TIP_OID;

View File

@@ -38,6 +38,7 @@
#define GIT_CAP_SHALLOW "shallow"
#define GIT_CAP_OBJECT_FORMAT "object-format="
#define GIT_CAP_AGENT "agent="
#define GIT_CAP_PUSH_OPTIONS "push-options"
extern bool git_smart__ofs_delta_enabled;
@@ -146,7 +147,8 @@ typedef struct transport_smart_caps {
thin_pack:1,
want_tip_sha1:1,
want_reachable_sha1:1,
shallow:1;
shallow:1,
push_options:1;
char *object_format;
char *agent;
} transport_smart_caps;

View File

@@ -194,6 +194,12 @@ int git_smart__detect_caps(
continue;
}
if (!git__prefixcmp(ptr, GIT_CAP_PUSH_OPTIONS)) {
caps->common = caps->push_options = 1;
ptr += strlen(GIT_CAP_PUSH_OPTIONS);
continue;
}
if (!git__prefixcmp(ptr, GIT_CAP_THIN_PACK)) {
caps->common = caps->thin_pack = 1;
ptr += strlen(GIT_CAP_THIN_PACK);
@@ -778,6 +784,7 @@ done:
static int gen_pktline(git_str *buf, git_push *push)
{
push_spec *spec;
char *option;
size_t i, len;
char old_id[GIT_OID_SHA1_HEXSIZE+1], new_id[GIT_OID_SHA1_HEXSIZE+1];
@@ -790,6 +797,8 @@ static int gen_pktline(git_str *buf, git_push *push)
++len; /* '\0' */
if (push->report_status)
len += strlen(GIT_CAP_REPORT_STATUS) + 1;
if (git_vector_length(&push->remote_push_options) > 0)
len += strlen(GIT_CAP_PUSH_OPTIONS) + 1;
len += strlen(GIT_CAP_SIDE_BAND_64K) + 1;
}
@@ -805,6 +814,10 @@ static int gen_pktline(git_str *buf, git_push *push)
git_str_putc(buf, ' ');
git_str_printf(buf, GIT_CAP_REPORT_STATUS);
}
if (git_vector_length(&push->remote_push_options) > 0) {
git_str_putc(buf, ' ');
git_str_printf(buf, GIT_CAP_PUSH_OPTIONS);
}
git_str_putc(buf, ' ');
git_str_printf(buf, GIT_CAP_SIDE_BAND_64K);
}
@@ -812,6 +825,12 @@ static int gen_pktline(git_str *buf, git_push *push)
git_str_putc(buf, '\n');
}
if (git_vector_length(&push->remote_push_options) > 0) {
git_str_printf(buf, "0000");
git_vector_foreach(&push->remote_push_options, i, option) {
git_str_printf(buf, "%04"PRIxZ"%s", strlen(option) + 4 , option);
}
}
git_str_puts(buf, "0000");
return git_str_oom(buf) ? -1 : 0;
}

View File

@@ -5,6 +5,7 @@
#include "push_util.h"
#include "refspec.h"
#include "remote.h"
#include "futils.h"
static git_repository *_repo;
@@ -20,10 +21,12 @@ static char *_remote_ssh_passphrase = NULL;
static char *_remote_default = NULL;
static char *_remote_expectcontinue = NULL;
static char *_remote_push_options = NULL;
static char *_orig_ssh_cmd = NULL;
static char *_ssh_cmd = NULL;
static int cred_acquire_cb(git_credential **, const char *, const char *, unsigned int, void *);
static int cred_acquire_cb(git_credential **, const char *, const char *, unsigned int, void *);
static git_remote *_remote;
static record_callbacks_data _record_cbs_data = {{ 0 }};
@@ -370,6 +373,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 = cl_getenv("GITTEST_PUSH_OPTIONS");
_remote = NULL;
_orig_ssh_cmd = cl_getenv("GIT_SSH");
@@ -433,6 +437,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);
git__free(_orig_ssh_cmd);
git__free(_ssh_cmd);
@@ -444,6 +449,7 @@ void test_online_push__cleanup(void)
record_callbacks_data_clear(&_record_cbs_data);
cl_fixture_cleanup("push-options-result");
cl_fixture_cleanup("testrepo.git");
cl_git_sandbox_cleanup();
}
@@ -486,7 +492,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 *remote_push_options)
{
git_push_options opts = GIT_PUSH_OPTIONS_INIT;
size_t i;
@@ -498,6 +505,9 @@ static void do_push(
/* Auto-detect the number of threads to use */
opts.pb_parallelism = 0;
if (remote_push_options)
memcpy(&opts.remote_push_options, remote_push_options, sizeof(git_strarray));
memcpy(&opts.callbacks, &_record_cbs, sizeof(git_remote_callbacks));
data = opts.callbacks.payload;
@@ -541,13 +551,12 @@ static void do_push(
verify_update_tips_callback(_remote, expected_refs, expected_refs_len);
}
}
/* 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);
do_push(NULL, 0, NULL, 0, NULL, 0, 0, 0, 1, NULL);
}
void test_online_push__b1(void)
@@ -557,7 +566,9 @@ void test_online_push__b1(void)
expected_ref exp_refs[] = { { "refs/heads/b1", &_oid_b1 } };
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,
NULL);
}
void test_online_push__b2(void)
@@ -567,7 +578,9 @@ void test_online_push__b2(void)
expected_ref exp_refs[] = { { "refs/heads/b2", &_oid_b2 } };
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,
NULL);
}
void test_online_push__b3(void)
@@ -577,7 +590,9 @@ void test_online_push__b3(void)
expected_ref exp_refs[] = { { "refs/heads/b3", &_oid_b3 } };
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,
NULL);
}
void test_online_push__b4(void)
@@ -587,7 +602,9 @@ void test_online_push__b4(void)
expected_ref exp_refs[] = { { "refs/heads/b4", &_oid_b4 } };
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,
NULL);
}
void test_online_push__b5(void)
@@ -597,13 +614,15 @@ void test_online_push__b5(void)
expected_ref exp_refs[] = { { "refs/heads/b5", &_oid_b5 } };
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,
NULL);
}
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);
do_push(specs, ARRAY_SIZE(specs), NULL, 0, NULL, 0, GIT_EUSER, 1, 1, NULL);
}
void test_online_push__multi(void)
@@ -634,7 +653,9 @@ void test_online_push__multi(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,
NULL);
cl_git_pass(git_reflog_read(&log, _repo, "refs/remotes/test/b1"));
entry = git_reflog_entry_byindex(log, 0);
@@ -655,16 +676,21 @@ void test_online_push__implicit_tgt(void)
const char *specs2[] = { "refs/heads/b2" };
push_status exp_stats2[] = { { "refs/heads/b2", 1 } };
expected_ref exp_refs2[] = {
{ "refs/heads/b1", &_oid_b1 },
{ "refs/heads/b2", &_oid_b2 }
{ "refs/heads/b1", &_oid_b1 },
{ "refs/heads/b2", &_oid_b2 }
};
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,
NULL);
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,
NULL);
}
void test_online_push__fast_fwd(void)
@@ -686,19 +712,27 @@ void test_online_push__fast_fwd(void)
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,
NULL);
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,
NULL);
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,
NULL);
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,
NULL);
}
void test_online_push__tag_commit(void)
@@ -708,7 +742,9 @@ void test_online_push__tag_commit(void)
expected_ref exp_refs[] = { { "refs/tags/tag-commit", &_tag_commit } };
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,
NULL);
}
void test_online_push__tag_tree(void)
@@ -718,7 +754,9 @@ void test_online_push__tag_tree(void)
expected_ref exp_refs[] = { { "refs/tags/tag-tree", &_tag_tree } };
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,
NULL);
}
void test_online_push__tag_blob(void)
@@ -728,7 +766,9 @@ void test_online_push__tag_blob(void)
expected_ref exp_refs[] = { { "refs/tags/tag-blob", &_tag_blob } };
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,
NULL);
}
void test_online_push__tag_lightweight(void)
@@ -738,7 +778,9 @@ void test_online_push__tag_lightweight(void)
expected_ref exp_refs[] = { { "refs/tags/tag-lightweight", &_tag_lightweight } };
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,
NULL);
}
void test_online_push__tag_to_tag(void)
@@ -748,7 +790,9 @@ void test_online_push__tag_to_tag(void)
expected_ref exp_refs[] = { { "refs/tags/tag-tag", &_tag_tag } };
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,
NULL);
}
void test_online_push__force(void)
@@ -765,17 +809,80 @@ void test_online_push__force(void)
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,
NULL);
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,
NULL);
/* 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,
NULL);
}
static void push_option_test(git_strarray given_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_path = GIT_STR_INIT;
git_str push_options_result = GIT_STR_INIT;
char *options[16];
git_strarray push_options = { options, given_options.count + 1 };
size_t i;
/* Skip the test if we're missing the push options result file */
if (!_remote_push_options)
cl_skip();
cl_assert(given_options.count < 16);
cl_git_pass(git_str_joinpath(&push_options_path, clar_sandbox_path(), "push-options-result"));
options[0] = push_options_path.ptr;
for (i = 0; i < given_options.count; i++)
options[i + 1] = given_options.strings[i];
do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs),
0, 1, 1,
&push_options);
cl_assert(git_fs_path_exists(push_options_path.ptr));
cl_git_pass(git_futils_readbuffer(&push_options_result, push_options_path.ptr));
cl_assert_equal_s(expected_option, git_str_cstr(&push_options_result));
git_str_dispose(&push_options_result);
git_str_dispose(&push_options_path);
}
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)
@@ -806,7 +913,9 @@ void test_online_push__delete(void)
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,
NULL);
/* 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
@@ -816,23 +925,35 @@ 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,
NULL);
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,
NULL);
/* 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,
NULL);
/* 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,
NULL);
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,
NULL);
}
void test_online_push__bad_refspecs(void)
@@ -876,7 +997,9 @@ void test_online_push__expressions(void)
do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr),
exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
exp_refs, ARRAY_SIZE(exp_refs),
0, 1, 1,
NULL);
}
void test_online_push__notes(void)
@@ -898,13 +1021,17 @@ 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,
NULL);
/* 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,
NULL);
git_signature_free(signature);
}
@@ -934,13 +1061,17 @@ 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,
NULL);
/* 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,
NULL);
git_signature_free(signature);
}

1
tests/resources/pushoptions.git/HEAD vendored Normal file
View File

@@ -0,0 +1 @@
ref: refs/heads/main

View File

View File

@@ -0,0 +1,8 @@
[core]
repositoryformatversion = 0
filemode = true
bare = true
ignorecase = true
precomposeunicode = true
[receive]
advertisePushOptions = true

View File

@@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@@ -0,0 +1,3 @@
#!/bin/sh
printf "${GIT_PUSH_OPTION_1}${GIT_PUSH_OPTION_2}${GIT_PUSH_OPTION_3}" > "${GIT_PUSH_OPTION_0}"
exit 0

View File

@@ -0,0 +1,6 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

View File

View File