8000 Merge pull request #6439 from russell/push-options · libgit2/libgit2@8535fdb · GitHub
[go: up one dir, main page]

Skip to content

Commit 8535fdb

Browse files
authored
Merge pull request #6439 from russell/push-options
Implement push options on push
2 parents 5f9e67a + 85279f0 commit 8535fdb

File tree

20 files changed

+274
-42
lines changed

20 files changed

+274
-42
lines changed

ci/test.sh

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ echo ""
162162
if should_run "GITDAEMON_TESTS"; then
163163
echo "Starting git daemon (standard)..."
164164
GIT_STANDARD_DIR=`mktemp -d ${TMPDIR}/git_standard.XXXXXXXX`
165-
git init --bare "${GIT_STANDARD_DIR}/test.git" >/dev/null
165+
cp -R "${SOURCE_DIR}/tests/resources/pushoptions.git" "${GIT_STANDARD_DIR}/test.git"
166166
git daemon --listen=localhost --export-all --enable=receive-pack --base-path="${GIT_STANDARD_DIR}" "${GIT_STANDARD_DIR}" 2>/dev/null &
167+
167168
GIT_STANDARD_PID=$!
168169
169170
echo "Starting git daemon (namespace)..."
@@ -196,15 +197,18 @@ if should_run "NTLM_TESTS" || should_run "ONLINE_TESTS"; then
196197
197198
echo "Starting HTTP server..."
198199
HTTP_DIR=`mktemp -d ${TMPDIR}/http.XXXXXXXX`
199-
git init --bare "${HTTP_DIR}/test.git"
200+
cp -R "${SOURCE_DIR}/tests/resources/pushoptions.git" "${HTTP_DIR}/test.git"
201+
200202
java -jar poxygit.jar --address 127.0.0.1 --port 9000 --credentials foo:baz --quiet "${HTTP_DIR}" &
201203
HTTP_PID=$!
202204
fi
203205
204206
if should_run "SSH_TESTS"; then
205207
echo "Starting SSH server..."
206208
SSHD_DIR=`mktemp -d ${TMPDIR}/sshd.XXXXXXXX`
207-
git init --bare "${SSHD_DIR}/test.git" >/dev/null
209+
cp -R "${SOURCE_DIR}/tests/resources/pushoptions.git" "${SSHD_DIR}/test.git"
210+
ls -FlasR "${SSHD_DIR}"
211+
208212
cat >"${SSHD_DIR}/sshd_config" <<-EOF
209213
Port 2222
210214
ListenAddress 0.0.0.0
@@ -321,8 +325,10 @@ if should_run "GITDAEMON_TESTS"; then
321325
echo ""
322326
323327
export GITTEST_REMOTE_URL="git://localhost/test.git"
328+
export GITTEST_PUSH_OPTIONS=true
324329
run_test gitdaemon
325330
unset GITTEST_REMOTE_URL
331+
unset GITTEST_PUSH_OPTIONS
326332
327333
echo ""
328334
echo "Running gitdaemon (namespace) tests"
@@ -377,10 +383,12 @@ if should_run "NTLM_TESTS"; then
377383
export GITTEST_REMOTE_URL="http://localhost:9000/ntlm/test.git"
378384
export GITTEST_REMOTE_USER="foo"
379385
export GITTEST_REMOTE_PASS="baz"
386+
export GITTEST_PUSH_OPTIONS=true
380387
run_test auth_clone_and_push
381388
unset GITTEST_REMOTE_URL
382389
unset GITTEST_REMOTE_USER
383390
unset GITTEST_REMOTE_PASS
391+
unset GITTEST_PUSH_OPTIONS
384392
385393
echo ""
386394
echo "Running NTLM tests (Apache emulation)"
@@ -389,10 +397,12 @@ if should_run "NTLM_TESTS"; then
389397
export GITTEST_REMOTE_URL="http://localhost:9000/broken-ntlm/test.git"
390398
export GITTEST_REMOTE_USER="foo"
391399
export GITTEST_REMOTE_PASS="baz"
400+
export GITTEST_PUSH_OPTIONS=true
392401
run_test auth_clone_and_push
393402
unset GITTEST_REMOTE_URL
394403
unset GITTEST_REMOTE_USER
395404
unset GITTEST_REMOTE_PASS
405+
unset GITTEST_PUSH_OPTIONS
396406
fi
397407
398408
if should_run "NEGOTIATE_TESTS" && -n "$GITTEST_NEGOTIATE_PASSWORD" ; then
@@ -442,16 +452,20 @@ if should_run "SSH_TESTS"; then
442452
echo ""
443453
444454
export GITTEST_REMOTE_URL="ssh://localhost:2222/$SSHD_DIR/test.git"
455+
export GITTEST_PUSH_OPTIONS=true
445456
run_test ssh
446457
unset GITTEST_REMOTE_URL
458+
unset GITTEST_PUSH_OPTIONS
447459
448460
echo ""
449461
echo "Running ssh tests (scp-style paths)"
450462
echo ""
451463
452464
export GITTEST_REMOTE_URL="[localhost:2222]:$SSHD_DIR/test.git"
465+
export GITTEST_PUSH_OPTIONS=true
453466
run_test ssh
454467
unset GITTEST_REMOTE_URL
468+
unset GITTEST_PUSH_OPTIONS
455469
456470
unset GITTEST_SSH_CMD
457471

include/git2/remote.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,11 @@ typedef struct {
846846
* Extra headers for this push operation
847847
*/
848848
git_strarray custom_headers;
849+
850+
/**
851+
* "Push options" to deliver to the remote.
852+
*/
853+
git_strarray remote_push_options;
849854
} git_push_options;
850855

851856
#define GIT_PUSH_OPTIONS_VERSION 1

include/git2/sys/remote.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ typedef enum {
2626

2727
/** Remote supports fetching an individual reachable object. */
2828
GIT_REMOTE_CAPABILITY_REACHABLE_OID = (1 << 1),
29+
30+
/** Remote supports push options. */
31+
GIT_REMOTE_CAPABILITY_PUSH_OPTIONS = (1 << 2),
2932
} git_remote_capability_t;
3033

3134
/**

src/libgit2/push.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ int git_push_new(git_push **out, git_remote *remote, const git_push_options *opt
6868
return -1;
6969
}
7070

71+
if (git_vector_init(&p->remote_push_options, 0, git__strcmp_cb) < 0) {
72+
git_vector_free(&p->status);
73+
git_vector_free(&p->specs);
74+
git_vector_free(&p->updates);
75+
git__free(p);
76+
return -1;
77+
}
78+
7179
*out = p;
7280
return 0;
7381
}
@@ -490,12 +498,24 @@ static int filter_refs(git_remote *remote)
490498
int git_push_finish(git_push *push)
491499
{
492500
int error;
501+
unsigned int remote_caps;
493502

494503
if (!git_remote_connected(push->remote)) {
495504
git_error_set(GIT_ERROR_NET, "remote is disconnected");
496505
return -1;
497506
}
498507

508+
if ((error = git_remote_capabilities(&remote_caps, push->remote)) < 0) {
509+
git_error_set(GIT_ERROR_INVALID, "remote capabilities not available");
510+
return -1;
511+
}
512+
513+
if (git_vector_length(&push->remote_push_options) > 0 &&
514+
!(remote_caps & GIT_REMOTE_CAPABILITY_PUSH_OPTIONS)) {
515+
git_error_set(GIT_ERROR_INVALID, "push-options not supported by remote");
516+
return -1;
517+
}
518+
499519
if ((error = filter_refs(push->remote)) < 0 ||
500520
(error = do_push(push)) < 0)
501521
return error;
@@ -539,6 +559,7 @@ void git_push_free(git_push *push)
539559
push_spec *spec;
540560
push_status *status;
541561
git_push_update *update;
562+
char *option;
542563
unsigned int i;
543564

544565
if (push == NULL)
@@ -561,6 +582,11 @@ void git_push_free(git_push *push)
561582
}
562583
git_vector_free(&push->updates);
563584

585+
git_vector_foreach(&push->remote_push_options, i, option) {
586+
git__free(option);
587+
}
588+
git_vector_free(&push->remote_push_options);
589+
564590
git__free(push);
565591
}
566592

src/libgit2/push.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct git_push {
3434
git_vector specs;
3535
git_vector updates;
3636
bool report_status;
37+
git_vector remote_push_options;
3738

3839
/* report-status */
3940
bool unpack_ok;

src/libgit2/remote.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2982,6 +2982,15 @@ int git_remote_upload(
29822982
}
29832983
}
29842984

2985+
if (opts && opts->remote_push_options.count > 0)
2986+
for (i = 0; i < opts->remote_push_options.count; ++i) {
2987+
char *optstr = git__strdup(opts->remote_push_options.strings[i]);
2988+
GIT_ERROR_CHECK_ALLOC(optstr);
2989+
2990+
if ((error = git_vector_insert(&push->remote_push_options, optstr)) < 0)
2991+
goto cleanup;
2992+
}
2993+
29852994
if ((error = git_push_finish(push)) < 0)
29862995
goto cleanup;
29872996

src/libgit2/transports/smart.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ static int git_smart__capabilities(unsigned int *capabilities, git_transport *tr
249249

250250
*capabilities = 0;
251251

252+
if (t->caps.push_options)
253+
*capabilities |= GIT_REMOTE_CAPABILITY_PUSH_OPTIONS;
254+
252255
if (t->caps.want_tip_sha1)
253256
*capabilities |= GIT_REMOTE_CAPABILITY_TIP_OID;
254257

src/libgit2/transports/smart.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#define GIT_CAP_SHALLOW "shallow"
3939
#define GIT_CAP_OBJECT_FORMAT "object-format="
4040
#define GIT_CAP_AGENT "agent="
41+
#define GIT_CAP_PUSH_OPTIONS "push-options"
4142

4243
extern bool git_smart__ofs_delta_enabled;
4344

@@ -146,7 +147,8 @@ typedef struct transport_smart_caps {
146147
thin_pack:1,
147148
want_tip_sha1:1,
148149
want_reachable_sha1:1,
149-
shallow:1;
150+
shallow:1,
151+
push_options:1;
150152
char *object_format;
151153
char *agent;
152154
} transport_smart_caps;

src/libgit2/transports/smart_protocol.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ int git_smart__detect_caps(
194194
continue;
195195
}
196196

197+
if (!git__prefixcmp(ptr, GIT_CAP_PUSH_OPTIONS)) {
198+
caps->common = caps->push_options = 1;
199+
ptr += strlen(GIT_CAP_PUSH_OPTIONS);
200+
continue;
201+
}
202+
197203
if (!git__prefixcmp(ptr, GIT_CAP_THIN_PACK)) {
198204
caps->common = caps->thin_pack = 1;
199205
ptr += strlen(GIT_CAP_THIN_PACK);
@@ -778,6 +784,7 @@ int git_smart__download_pack(
778784
static int gen_pktline(git_str *buf, git_push *push)
779785
{
780786
push_spec *spec;
787+
char *option;
781788
size_t i, len;
782789
char old_id[GIT_OID_SHA1_HEXSIZE+1], new_id[GIT_OID_SHA1_HEXSIZE+1];
783790

@@ -790,6 +797,8 @@ static int gen_pktline(git_str *buf, git_push *push)
790797
++len; /* '\0' */
791798
if (push->report_status)
792799
len += strlen(GIT_CAP_REPORT_STATUS) + 1;
800+
if (git_vector_length(&push->remote_push_options) > 0)
801+
len += strlen(GIT_CAP_PUSH_OPTIONS) + 1;
793802
len += strlen(GIT_CAP_SIDE_BAND_64K) + 1;
794803
}
795804

@@ -805,13 +814,23 @@ static int gen_pktline(git_str *buf, git_push *push)
805814
git_str_putc(buf, ' ');
806815
git_str_printf(buf, GIT_CAP_REPORT_STATUS);
807816
}
817+
if (git_vector_length(&push->remote_push_options) > 0) {
818+
git_str_putc(buf, ' ');
819+
git_str_printf(buf, GIT_CAP_PUSH_OPTIONS);
820+
}
808821
git_str_putc(buf, ' ');
809822
git_str_printf(buf, GIT_CAP_SIDE_BAND_64K);
810823
}
811824

812825
git_str_putc(buf, '\n');
813826
}
814827

828+
if (git_vector_length(&push->remote_push_options) > 0) {
829+
git_str_printf(buf, "0000");
830+
git_vector_foreach(&push->remote_push_options, i, option) {
831+
git_str_printf(buf, "%04"PRIxZ"%s", strlen(option) + 4 , option);
832+
}
833+
}
815834
git_str_puts(buf, "0000");
816835
return git_str_oom(buf) ? -1 : 0;
817836
}

0 commit comments

Comments
 (0)
0