push: accept push options
This implements everything that is required on the client side to make use of push options from the porcelain push command. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Stefan Beller committed
Jul 14, 2016 at 14:49 UTC
f6a4e61fbb647928d615a0befaec163a5d2bf4af
6 files changed
+63
-4
Documentation/git-push.txt
+7
-1
@@ -11,7 +11,7 @@ SYNOPSIS
11
[verse]
12
'git push' [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
13
[--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
14
- [-u | --set-upstream]
14
+ [-u | --set-upstream] [--push-option=<string>]
15
[--[no-]signed|--sign=(true|false|if-asked)]
16
[--force-with-lease[=<refname>[:<expect>]]]
17
[--no-verify] [<repository> [<refspec>...]]
@@ -156,6 +156,12 @@ already exists on the remote side.
156
Either all refs are updated, or on error, no refs are updated.
157
If the server does not support atomic pushes the push will fail.
158
159
+-o::
160
+--push-option::
161
+ Transmit the given string to the server, which passes them to
162
+ the pre-receive as well as the post-receive hook. The given string
163
+ must not contain a NUL or LF character.
164
+
165
--receive-pack=<git-receive-pack>::
166
--exec=<git-receive-pack>::
167
Path to the 'git-receive-pack' program on the remote
builtin/push.c
+18
-3
@@ -353,7 +353,8 @@ static int push_with_options(struct transport *transport, int flags)
353
return 1;
354
}
355
356
-static int do_push(const char *repo, int flags)
356
+static int do_push(const char *repo, int flags,
357
+ const struct string_list *push_options)
358
{
359
int i, errs;
360
struct remote *remote = pushremote_get(repo);
@@ -376,6 +377,9 @@ static int do_push(const char *repo, int flags)
377
if (remote->mirror)
378
flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
379
380
+ if (push_options->nr)
381
+ flags |= TRANSPORT_PUSH_OPTIONS;
382
+
383
if ((flags & TRANSPORT_PUSH_ALL) && refspec) {
384
if (!strcmp(*refspec, "refs/tags/*"))
385
return error(_("--all and --tags are incompatible"));
@@ -406,13 +410,16 @@ static int do_push(const char *repo, int flags)
410
for (i = 0; i < url_nr; i++) {
411
struct transport *transport =
412
transport_get(remote, url[i]);
413
+ if (flags & TRANSPORT_PUSH_OPTIONS)
414
+ transport->push_options = push_options;
415
if (push_with_options(transport, flags))
416
errs++;
417
}
418
} else {
419
struct transport *transport =
420
transport_get(remote, NULL);
415
-
421
+ if (flags & TRANSPORT_PUSH_OPTIONS)
422
+ transport->push_options = push_options;
423
if (push_with_options(transport, flags))
424
errs++;
425
}
@@ -500,6 +507,9 @@ int cmd_push(int argc, const char **argv, const char *prefix)
507
int push_cert = -1;
508
int rc;
509
const char *repo = NULL; /* default repository */
510
+ static struct string_list push_options = STRING_LIST_INIT_DUP;
511
+ static struct string_list_item *item;
512
+
513
struct option options[] = {
514
OPT__VERBOSITY(&verbosity),
515
OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
@@ -533,6 +543,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
543
0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"),
544
PARSE_OPT_OPTARG, option_parse_push_signed },
545
OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
546
+ OPT_STRING_LIST('o', "push-option", &push_options, N_("server-specific"), N_("option to transmit")),
547
OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
548
TRANSPORT_FAMILY_IPV4),
549
OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
@@ -563,7 +574,11 @@ int cmd_push(int argc, const char **argv, const char *prefix)
574
set_refspecs(argv + 1, argc - 1, repo);
575
}
576
566
- rc = do_push(repo, flags);
577
+ for_each_string_list_item(item, &push_options)
578
+ if (strchr(item->string, '\n'))
579
+ die(_("push options must not have new line characters"));
580
+
581
+ rc = do_push(repo, flags, &push_options);
582
if (rc == -1)
583
usage_with_options(push_usage, options);
584
else
send-pack.c
+27
@@ -260,6 +260,7 @@ static int generate_push_cert(struct strbuf *req_buf,
260
const char *push_cert_nonce)
261
{
262
const struct ref *ref;
263
+ struct string_list_item *item;
264
char *signing_key = xstrdup(get_signing_key());
265
const char *cp, *np;
266
struct strbuf cert = STRBUF_INIT;
@@ -276,6 +277,9 @@ static int generate_push_cert(struct strbuf *req_buf,
277
}
278
if (push_cert_nonce[0])
279
strbuf_addf(&cert, "nonce %s\n", push_cert_nonce);
280
+ if (args->push_options)
281
+ for_each_string_list_item(item, args->push_options)
282
+ strbuf_addf(&cert, "push-option %s\n", item->string);
283
strbuf_addstr(&cert, "\n");
284
285
for (ref = remote_refs; ref; ref = ref->next) {
@@ -370,6 +374,8 @@ int send_pack(struct send_pack_args *args,
374
int agent_supported = 0;
375
int use_atomic = 0;
376
int atomic_supported = 0;
377
+ int use_push_options = 0;
378
+ int push_options_supported = 0;
379
unsigned cmds_sent = 0;
380
int ret;
381
struct async demux;
@@ -392,6 +398,8 @@ int send_pack(struct send_pack_args *args,
398
args->use_thin_pack = 0;
399
if (server_supports("atomic"))
400
atomic_supported = 1;
401
+ if (server_supports("push-options"))
402
+ push_options_supported = 1;
403
404
if (args->push_cert != SEND_PACK_PUSH_CERT_NEVER) {
405
int len;
@@ -418,6 +426,11 @@ int send_pack(struct send_pack_args *args,
426
427
use_atomic = atomic_supported && args->atomic;
428
429
+ if (args->push_options && !push_options_supported)
430
+ die(_("the receiving end does not support push options"));
431
+
432
+ use_push_options = push_options_supported && args->push_options;
433
+
434
if (status_report)
435
strbuf_addstr(&cap_buf, " report-status");
436
if (use_sideband)
@@ -426,6 +439,8 @@ int send_pack(struct send_pack_args *args,
439
strbuf_addstr(&cap_buf, " quiet");
440
if (use_atomic)
441
strbuf_addstr(&cap_buf, " atomic");
442
+ if (use_push_options)
443
+ strbuf_addstr(&cap_buf, " push-options");
444
if (agent_supported)
445
strbuf_addf(&cap_buf, " agent=%s", git_user_agent_sanitized());
446
@@ -512,6 +527,18 @@ int send_pack(struct send_pack_args *args,
527
strbuf_release(&req_buf);
528
strbuf_release(&cap_buf);
529
530
+ if (use_push_options) {
531
+ struct string_list_item *item;
532
+ struct strbuf sb = STRBUF_INIT;
533
+
534
+ for_each_string_list_item(item, args->push_options)
535
+ packet_buf_write(&sb, "%s", item->string);
536
+
537
+ write_or_die(out, sb.buf, sb.len);
538
+ packet_flush(out);
539
+ strbuf_release(&sb);
540
+ }
541
+
542
if (use_sideband && cmds_sent) {
543
memset(&demux, 0, sizeof(demux));
544
demux.proc = sideband_demux;
send-pack.h
+3
@@ -1,6 +1,8 @@
1
#ifndef SEND_PACK_H
2
#define SEND_PACK_H
3
4
+#include "string-list.h"
5
+
6
/* Possible values for push_cert field in send_pack_args. */
7
#define SEND_PACK_PUSH_CERT_NEVER 0
8
#define SEND_PACK_PUSH_CERT_IF_ASKED 1
@@ -21,6 +23,7 @@ struct send_pack_args {
23
push_cert:2,
24
stateless_rpc:1,
25
atomic:1;
26
+ const struct string_list *push_options;
27
};
28
29
struct option;
transport.c
+1
@@ -510,6 +510,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
510
args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
511
args.porcelain = !!(flags & TRANSPORT_PUSH_PORCELAIN);
512
args.atomic = !!(flags & TRANSPORT_PUSH_ATOMIC);
513
+ args.push_options = transport->push_options;
514
args.url = transport->url;
515
516
if (flags & TRANSPORT_PUSH_CERT_ALWAYS)
transport.h
+7
@@ -48,6 +48,12 @@ struct transport {
48
*/
49
unsigned cloning : 1;
50
51
+ /*
52
+ * These strings will be passed to the {pre, post}-receive hook,
53
+ * on the remote side, if both sides support the push options capability.
54
+ */
55
+ const struct string_list *push_options;
56
+
57
/**
58
* Returns 0 if successful, positive if the option is not
59
* recognized or is inapplicable, and negative if the option
@@ -134,6 +140,7 @@ struct transport {
140
#define TRANSPORT_PUSH_CERT_ALWAYS 2048
141
#define TRANSPORT_PUSH_CERT_IF_ASKED 4096
142
#define TRANSPORT_PUSH_ATOMIC 8192
143
+#define TRANSPORT_PUSH_OPTIONS 16384
144
145
#define TRANSPORT_SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
146
#define TRANSPORT_SUMMARY(x) (int)(TRANSPORT_SUMMARY_WIDTH + strlen(x) - gettext_width(x)), (x)