Skip to content

Commit 511155d

Browse files
bmwillgitster
authored andcommitted
remote-curl: allow push options
Teach remote-curl to understand push options and to be able to convey them across HTTP. Signed-off-by: Brandon Williams <[email protected]> Reviewed-by: Jonathan Nieder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent eb7b974 commit 511155d

File tree

4 files changed

+50
-2
lines changed

4 files changed

+50
-2
lines changed

Documentation/git-send-pack.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ be in a separate packet, and the list must end with a flush packet.
8181
will also fail if the actual call to `gpg --sign` fails. See
8282
linkgit:git-receive-pack[1] for the details on the receiving end.
8383

84+
--push-option=<string>::
85+
Pass the specified string as a push option for consumption by
86+
hooks on the server side. If the server doesn't support push
87+
options, error out. See linkgit:git-push[1] and
88+
linkgit:githooks[5] for details.
89+
8490
<host>::
8591
A remote host to house the repository. When this
8692
part is specified, 'git-receive-pack' is invoked via

builtin/send-pack.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
144144
unsigned force_update = 0;
145145
unsigned quiet = 0;
146146
int push_cert = 0;
147+
struct string_list push_options = STRING_LIST_INIT_NODUP;
147148
unsigned use_thin_pack = 0;
148149
unsigned atomic = 0;
149150
unsigned stateless_rpc = 0;
@@ -165,6 +166,9 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
165166
{ OPTION_CALLBACK,
166167
0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"),
167168
PARSE_OPT_OPTARG, option_parse_push_signed },
169+
OPT_STRING_LIST(0, "push-option", &push_options,
170+
N_("server-specific"),
171+
N_("option to transmit")),
168172
OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
169173
OPT_BOOL(0, "thin", &use_thin_pack, N_("use thin pack")),
170174
OPT_BOOL(0, "atomic", &atomic, N_("request atomic transaction on remote side")),
@@ -199,6 +203,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
199203
args.use_thin_pack = use_thin_pack;
200204
args.atomic = atomic;
201205
args.stateless_rpc = stateless_rpc;
206+
args.push_options = push_options.nr ? &push_options : NULL;
202207

203208
if (from_stdin) {
204209
struct argv_array all_refspecs = ARGV_ARRAY_INIT;

remote-curl.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct options {
2222
unsigned long depth;
2323
char *deepen_since;
2424
struct string_list deepen_not;
25+
struct string_list push_options;
2526
unsigned progress : 1,
2627
check_self_contained_and_connected : 1,
2728
cloning : 1,
@@ -139,6 +140,9 @@ static int set_option(const char *name, const char *value)
139140
else
140141
return -1;
141142
return 0;
143+
} else if (!strcmp(name, "push-option")) {
144+
string_list_append(&options.push_options, value);
145+
return 0;
142146

143147
#if LIBCURL_VERSION_NUM >= 0x070a08
144148
} else if (!strcmp(name, "family")) {
@@ -943,6 +947,9 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs)
943947
argv_array_push(&args, "--quiet");
944948
else if (options.verbosity > 1)
945949
argv_array_push(&args, "--verbose");
950+
for (i = 0; i < options.push_options.nr; i++)
951+
argv_array_pushf(&args, "--push-option=%s",
952+
options.push_options.items[i].string);
946953
argv_array_push(&args, options.progress ? "--progress" : "--no-progress");
947954
for_each_string_list_item(cas_option, &cas_options)
948955
argv_array_push(&args, cas_option->string);
@@ -1028,6 +1035,7 @@ int cmd_main(int argc, const char **argv)
10281035
options.progress = !!isatty(2);
10291036
options.thin = 1;
10301037
string_list_init(&options.deepen_not, 1);
1038+
string_list_init(&options.push_options, 1);
10311039

10321040
remote = remote_get(argv[1]);
10331041

t/t5545-push-options.sh

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,46 @@ test_expect_success 'two push options work' '
102102
test_cmp expect upstream/.git/hooks/post-receive.push_options
103103
'
104104

105-
test_expect_success 'push option denied properly by http remote helper' '\
105+
test_expect_success 'push option denied properly by http server' '
106+
test_when_finished "rm -rf test_http_clone" &&
107+
test_when_finished "rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH\"/upstream.git" &&
106108
mk_repo_pair &&
107109
git -C upstream config receive.advertisePushOptions false &&
108110
git -C upstream config http.receivepack true &&
109111
cp -R upstream/.git "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git &&
110112
git clone "$HTTPD_URL"/smart/upstream test_http_clone &&
111113
test_commit -C test_http_clone one &&
112-
test_must_fail git -C test_http_clone push --push-option=asdf origin master &&
114+
test_must_fail git -C test_http_clone push --push-option=asdf origin master 2>actual &&
115+
test_i18ngrep "the receiving end does not support push options" actual &&
113116
git -C test_http_clone push origin master
114117
'
115118

119+
test_expect_success 'push options work properly across http' '
120+
test_when_finished "rm -rf test_http_clone" &&
121+
test_when_finished "rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH\"/upstream.git" &&
122+
mk_repo_pair &&
123+
git -C upstream config receive.advertisePushOptions true &&
124+
git -C upstream config http.receivepack true &&
125+
cp -R upstream/.git "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git &&
126+
git clone "$HTTPD_URL"/smart/upstream test_http_clone &&
127+
128+
test_commit -C test_http_clone one &&
129+
git -C test_http_clone push origin master &&
130+
git -C "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git rev-parse --verify master >expect &&
131+
git -C test_http_clone rev-parse --verify master >actual &&
132+
test_cmp expect actual &&
133+
134+
test_commit -C test_http_clone two &&
135+
git -C test_http_clone push --push-option=asdf --push-option="more structured text" origin master &&
136+
printf "asdf\nmore structured text\n" >expect &&
137+
test_cmp expect "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git/hooks/pre-receive.push_options &&
138+
test_cmp expect "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git/hooks/post-receive.push_options &&
139+
140+
git -C "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git rev-parse --verify master >expect &&
141+
git -C test_http_clone rev-parse --verify master >actual &&
142+
test_cmp expect actual
143+
'
144+
116145
stop_httpd
117146

118147
test_done

0 commit comments

Comments
 (0)