8000 Implement push options on push by russell · Pull Request #6439 · libgit2/libgit2 · GitHub
[go: up one dir, main page]

Skip to content

Implement push options on push #6439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions ci/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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)..."
Expand Down Expand Up @@ -196,15 +197,18 @@ 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

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
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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)"
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down
5 changes: 5 additions & 0 deletions include/git2/remote.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions include/git2/sys/remote.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down
26 changes: 26 additions & 0 deletions src/libgit2/push.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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);
}

Expand Down
1 change: 1 addition & 0 deletions src/libgit2/push.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions src/libgit2/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
3 changes: 3 additions & 0 deletions src/libgit2/transports/smart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 3 additions & 1 deletion src/libgit2/transports/smart.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
19 changes: 19 additions & 0 deletions src/libgit2/transports/smart_protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -778,6 +784,7 @@ int git_smart__download_pack(
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];

Expand All @@ -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;
}

Expand All @@ -805,13 +814,23 @@ 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);
}

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;
}
Expand Down
Loading
0