mirror of
https://github.com/libgit2/libgit2.git
synced 2026-01-25 02:56:17 +00:00
Merge pull request #6439 from russell/push-options
Implement push options on push
This commit is contained in:
20
ci/test.sh
20
ci/test.sh
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
1
tests/resources/pushoptions.git/HEAD
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ref: refs/heads/main
|
||||
0
tests/resources/pushoptions.git/branches/.gitignore
vendored
Normal file
0
tests/resources/pushoptions.git/branches/.gitignore
vendored
Normal file
8
tests/resources/pushoptions.git/config
vendored
Normal file
8
tests/resources/pushoptions.git/config
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = true
|
||||
ignorecase = true
|
||||
precomposeunicode = true
|
||||
[receive]
|
||||
advertisePushOptions = true
|
||||
1
tests/resources/pushoptions.git/description
vendored
Normal file
1
tests/resources/pushoptions.git/description
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Unnamed repository; edit this file 'description' to name the repository.
|
||||
3
tests/resources/pushoptions.git/hooks/pre-receive
vendored
Executable file
3
tests/resources/pushoptions.git/hooks/pre-receive
vendored
Executable 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
|
||||
6
tests/resources/pushoptions.git/info/exclude
vendored
Normal file
6
tests/resources/pushoptions.git/info/exclude
vendored
Normal 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]
|
||||
# *~
|
||||
0
tests/resources/pushoptions.git/objects/info/.gitignore
vendored
Normal file
0
tests/resources/pushoptions.git/objects/info/.gitignore
vendored
Normal file
0
tests/resources/pushoptions.git/objects/pack/.gitignore
vendored
Normal file
0
tests/resources/pushoptions.git/objects/pack/.gitignore
vendored
Normal file
0
tests/resources/pushoptions.git/refs/heads/.gitignore
vendored
Normal file
0
tests/resources/pushoptions.git/refs/heads/.gitignore
vendored
Normal file
0
tests/resources/pushoptions.git/refs/tags/.gitignore
vendored
Normal file
0
tests/resources/pushoptions.git/refs/tags/.gitignore
vendored
Normal file
Reference in New Issue
Block a user