Browse Source

Merge branch 'db/push-sign-if-asked'

The client side codepaths in "git push" have been cleaned up
and the user can request to perform an optional "signed push",
i.e. sign only when the other end accepts signed push.

* db/push-sign-if-asked:
  push: add a config option push.gpgSign for default signed pushes
  push: support signing pushes iff the server supports it
  builtin/send-pack.c: use parse_options API
  config.c: rename git_config_maybe_bool_text and export it as git_parse_maybe_bool
  transport: remove git_transport_options.push_cert
  gitremote-helpers.txt: document pushcert option
  Documentation/git-send-pack.txt: document --signed
  Documentation/git-send-pack.txt: wrap long synopsis line
  Documentation/git-push.txt: document when --signed may fail
maint
Junio C Hamano 10 years ago
parent
commit
b21089db6a
  1. 8
      Documentation/config.txt
  2. 15
      Documentation/git-push.txt
  3. 16
      Documentation/git-send-pack.txt
  4. 3
      Documentation/gitremote-helpers.txt
  5. 42
      builtin/push.c
  6. 192
      builtin/send-pack.c
  7. 1
      cache.h
  8. 6
      config.c
  9. 16
      remote-curl.c
  10. 43
      send-pack.c
  11. 12
      send-pack.h
  12. 34
      transport-helper.c
  13. 11
      transport.c
  14. 6
      transport.h

8
Documentation/config.txt

@ -2213,6 +2213,14 @@ push.followTags:: @@ -2213,6 +2213,14 @@ push.followTags::
may override this configuration at time of push by specifying
'--no-follow-tags'.

push.gpgSign::
May be set to a boolean value, or the string 'if-asked'. A true
value causes all pushes to be GPG signed, as if '--signed' is
passed to linkgit:git-push[1]. The string 'if-asked' causes
pushes to be signed if the server supports it, as if
'--signed=if-asked' is passed to 'git push'. A false value may
override a value from a lower-priority config file. An explicit
command-line flag always overrides this config option.

rebase.stat::
Whether to show a diffstat of what changed upstream since the last

15
Documentation/git-push.txt

@ -11,7 +11,8 @@ SYNOPSIS @@ -11,7 +11,8 @@ SYNOPSIS
[verse]
'git push' [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
[--repo=<repository>] [-f | --force] [--prune] [-v | --verbose]
[-u | --set-upstream] [--signed]
[-u | --set-upstream]
[--[no-]signed|--sign=(true|false|if-asked)]
[--force-with-lease[=<refname>[:<expect>]]]
[--no-verify] [<repository> [<refspec>...]]

@ -132,12 +133,16 @@ already exists on the remote side. @@ -132,12 +133,16 @@ already exists on the remote side.
with configuration variable 'push.followTags'. For more
information, see 'push.followTags' in linkgit:git-config[1].


--signed::
--[no-]signed::
--sign=(true|false|if-asked)::
GPG-sign the push request to update refs on the receiving
side, to allow it to be checked by the hooks and/or be
logged. See linkgit:git-receive-pack[1] for the details
on the receiving end.
logged. If `false` or `--no-signed`, no signing will be
attempted. If `true` or `--signed`, the push will fail if the
server does not support signed pushes. If set to `if-asked`,
sign if and only if the server supports signed pushes. The push
will also fail if the actual call to `gpg --sign` fails. See
linkgit:git-receive-pack[1] for the details on the receiving end.

--[no-]atomic::
Use an atomic transaction on the remote side if available.

16
Documentation/git-send-pack.txt

@ -9,7 +9,10 @@ git-send-pack - Push objects over Git protocol to another repository @@ -9,7 +9,10 @@ git-send-pack - Push objects over Git protocol to another repository
SYNOPSIS
--------
[verse]
'git send-pack' [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> [<ref>...]
'git send-pack' [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>]
[--verbose] [--thin] [--atomic]
[--[no-]signed|--sign=(true|false|if-asked)]
[<host>:]<directory> [<ref>...]

DESCRIPTION
-----------
@ -67,6 +70,17 @@ be in a separate packet, and the list must end with a flush packet. @@ -67,6 +70,17 @@ be in a separate packet, and the list must end with a flush packet.
fails to update then the entire push will fail without changing any
refs.

--[no-]signed::
--sign=(true|false|if-asked)::
GPG-sign the push request to update refs on the receiving
side, to allow it to be checked by the hooks and/or be
logged. If `false` or `--no-signed`, no signing will be
attempted. If `true` or `--signed`, the push will fail if the
server does not support signed pushes. If set to `if-asked`,
sign if and only if the server supports signed pushes. The push
will also fail if the actual call to `gpg --sign` fails. See
linkgit:git-receive-pack[1] for the details on the receiving end.

<host>::
A remote host to house the repository. When this
part is specified, 'git-receive-pack' is invoked via

3
Documentation/gitremote-helpers.txt

@ -448,6 +448,9 @@ set by Git if the remote helper has the 'option' capability. @@ -448,6 +448,9 @@ set by Git if the remote helper has the 'option' capability.
'option update-shallow {'true'|'false'}::
Allow to extend .git/shallow if the new refs require it.

'option pushcert {'true'|'false'}::
GPG sign pushes.

SEE ALSO
--------
linkgit:git-remote[1]

42
builtin/push.c

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
#include "transport.h"
#include "parse-options.h"
#include "submodule.h"
#include "send-pack.h"

static const char * const push_usage[] = {
N_("git push [<options>] [<repository> [<refspec>...]]"),
@ -471,6 +472,24 @@ static int option_parse_recurse_submodules(const struct option *opt, @@ -471,6 +472,24 @@ static int option_parse_recurse_submodules(const struct option *opt,
return 0;
}

static void set_push_cert_flags(int *flags, int v)
{
switch (v) {
case SEND_PACK_PUSH_CERT_NEVER:
*flags &= ~(TRANSPORT_PUSH_CERT_ALWAYS | TRANSPORT_PUSH_CERT_IF_ASKED);
break;
case SEND_PACK_PUSH_CERT_ALWAYS:
*flags |= TRANSPORT_PUSH_CERT_ALWAYS;
*flags &= ~TRANSPORT_PUSH_CERT_IF_ASKED;
break;
case SEND_PACK_PUSH_CERT_IF_ASKED:
*flags |= TRANSPORT_PUSH_CERT_IF_ASKED;
*flags &= ~TRANSPORT_PUSH_CERT_ALWAYS;
break;
}
}


static int git_push_config(const char *k, const char *v, void *cb)
{
int *flags = cb;
@ -486,6 +505,23 @@ static int git_push_config(const char *k, const char *v, void *cb) @@ -486,6 +505,23 @@ static int git_push_config(const char *k, const char *v, void *cb)
else
*flags &= ~TRANSPORT_PUSH_FOLLOW_TAGS;
return 0;
} else if (!strcmp(k, "push.gpgsign")) {
const char *value;
if (!git_config_get_value("push.gpgsign", &value)) {
switch (git_config_maybe_bool("push.gpgsign", value)) {
case 0:
set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_NEVER);
break;
case 1:
set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_ALWAYS);
break;
default:
if (value && !strcasecmp(value, "if-asked"))
set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_IF_ASKED);
else
return error("Invalid value for '%s'", k);
}
}
}

return git_default_config(k, v, NULL);
@ -495,6 +531,7 @@ int cmd_push(int argc, const char **argv, const char *prefix) @@ -495,6 +531,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
{
int flags = 0;
int tags = 0;
int push_cert = -1;
int rc;
const char *repo = NULL; /* default repository */
struct option options[] = {
@ -526,7 +563,9 @@ int cmd_push(int argc, const char **argv, const char *prefix) @@ -526,7 +563,9 @@ int cmd_push(int argc, const char **argv, const char *prefix)
OPT_BIT(0, "no-verify", &flags, N_("bypass pre-push hook"), TRANSPORT_PUSH_NO_HOOK),
OPT_BIT(0, "follow-tags", &flags, N_("push missing but relevant tags"),
TRANSPORT_PUSH_FOLLOW_TAGS),
OPT_BIT(0, "signed", &flags, N_("GPG sign the push"), TRANSPORT_PUSH_CERT),
{ OPTION_CALLBACK,
0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"),
PARSE_OPT_OPTARG, option_parse_push_signed },
OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
OPT_END()
};
@ -534,6 +573,7 @@ int cmd_push(int argc, const char **argv, const char *prefix) @@ -534,6 +573,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
packet_trace_identity("push");
git_config(git_push_config, &flags);
argc = parse_options(argc, argv, prefix, options, push_usage, 0);
set_push_cert_flags(&flags, push_cert);

if (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR))))
die(_("--delete is incompatible with --all, --mirror and --tags"));

192
builtin/send-pack.c

@ -12,10 +12,15 @@ @@ -12,10 +12,15 @@
#include "version.h"
#include "sha1-array.h"
#include "gpg-interface.h"
#include "gettext.h"

static const char send_pack_usage[] =
"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> [<ref>...]\n"
" --all and explicit <ref> specification are mutually exclusive.";
static const char * const send_pack_usage[] = {
N_("git send-pack [--all | --mirror] [--dry-run] [--force] "
"[--receive-pack=<git-receive-pack>] [--verbose] [--thin] [--atomic] "
"[<host>:]<directory> [<ref>...]\n"
" --all and explicit <ref> specification are mutually exclusive."),
NULL,
};

static struct send_pack_args args;

@ -92,6 +97,31 @@ static void print_helper_status(struct ref *ref) @@ -92,6 +97,31 @@ static void print_helper_status(struct ref *ref)
strbuf_release(&buf);
}

static int send_pack_config(const char *k, const char *v, void *cb)
{
git_gpg_config(k, v, NULL);

if (!strcmp(k, "push.gpgsign")) {
const char *value;
if (!git_config_get_value("push.gpgsign", &value)) {
switch (git_config_maybe_bool("push.gpgsign", value)) {
case 0:
args.push_cert = SEND_PACK_PUSH_CERT_NEVER;
break;
case 1:
args.push_cert = SEND_PACK_PUSH_CERT_ALWAYS;
break;
default:
if (value && !strcasecmp(value, "if-asked"))
args.push_cert = SEND_PACK_PUSH_CERT_IF_ASKED;
else
return error("Invalid value for '%s'", k);
}
}
}
return 0;
}

int cmd_send_pack(int argc, const char **argv, const char *prefix)
{
int i, nr_refspecs = 0;
@ -107,116 +137,68 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) @@ -107,116 +137,68 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
int ret;
int helper_status = 0;
int send_all = 0;
int verbose = 0;
const char *receivepack = "git-receive-pack";
unsigned dry_run = 0;
unsigned send_mirror = 0;
unsigned force_update = 0;
unsigned quiet = 0;
int push_cert = 0;
unsigned use_thin_pack = 0;
unsigned atomic = 0;
unsigned stateless_rpc = 0;
int flags;
unsigned int reject_reasons;
int progress = -1;
int from_stdin = 0;
struct push_cas_option cas = {0};

git_config(git_gpg_config, NULL);

argv++;
for (i = 1; i < argc; i++, argv++) {
const char *arg = *argv;

if (*arg == '-') {
if (starts_with(arg, "--receive-pack=")) {
receivepack = arg + 15;
continue;
}
if (starts_with(arg, "--exec=")) {
receivepack = arg + 7;
continue;
}
if (starts_with(arg, "--remote=")) {
remote_name = arg + 9;
continue;
}
if (!strcmp(arg, "--all")) {
send_all = 1;
continue;
}
if (!strcmp(arg, "--dry-run")) {
args.dry_run = 1;
continue;
}
if (!strcmp(arg, "--mirror")) {
args.send_mirror = 1;
continue;
}
if (!strcmp(arg, "--force")) {
args.force_update = 1;
continue;
}
if (!strcmp(arg, "--quiet")) {
args.quiet = 1;
continue;
}
if (!strcmp(arg, "--verbose")) {
args.verbose = 1;
continue;
}
if (!strcmp(arg, "--signed")) {
args.push_cert = 1;
continue;
}
if (!strcmp(arg, "--progress")) {
progress = 1;
continue;
}
if (!strcmp(arg, "--no-progress")) {
progress = 0;
continue;
}
if (!strcmp(arg, "--thin")) {
args.use_thin_pack = 1;
continue;
}
if (!strcmp(arg, "--atomic")) {
args.atomic = 1;
continue;
}
if (!strcmp(arg, "--stateless-rpc")) {
args.stateless_rpc = 1;
continue;
}
if (!strcmp(arg, "--stdin")) {
from_stdin = 1;
continue;
}
if (!strcmp(arg, "--helper-status")) {
helper_status = 1;
continue;
}
if (!strcmp(arg, "--" CAS_OPT_NAME)) {
if (parse_push_cas_option(&cas, NULL, 0) < 0)
exit(1);
continue;
}
if (!strcmp(arg, "--no-" CAS_OPT_NAME)) {
if (parse_push_cas_option(&cas, NULL, 1) < 0)
exit(1);
continue;
}
if (starts_with(arg, "--" CAS_OPT_NAME "=")) {
if (parse_push_cas_option(&cas,
strchr(arg, '=') + 1, 0) < 0)
exit(1);
continue;
}
usage(send_pack_usage);
}
if (!dest) {
dest = arg;
continue;
}
refspecs = (const char **) argv;
nr_refspecs = argc - i;
break;
struct option options[] = {
OPT__VERBOSITY(&verbose),
OPT_STRING(0, "receive-pack", &receivepack, "receive-pack", N_("receive pack program")),
OPT_STRING(0, "exec", &receivepack, "receive-pack", N_("receive pack program")),
OPT_STRING(0, "remote", &remote_name, "remote", N_("remote name")),
OPT_BOOL(0, "all", &send_all, N_("push all refs")),
OPT_BOOL('n' , "dry-run", &dry_run, N_("dry run")),
OPT_BOOL(0, "mirror", &send_mirror, N_("mirror all refs")),
OPT_BOOL('f', "force", &force_update, N_("force updates")),
{ OPTION_CALLBACK,
0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"),
PARSE_OPT_OPTARG, option_parse_push_signed },
OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
OPT_BOOL(0, "thin", &use_thin_pack, N_("use thin pack")),
OPT_BOOL(0, "atomic", &atomic, N_("request atomic transaction on remote side")),
OPT_BOOL(0, "stateless-rpc", &stateless_rpc, N_("use stateless RPC protocol")),
OPT_BOOL(0, "stdin", &from_stdin, N_("read refs from stdin")),
OPT_BOOL(0, "helper-status", &helper_status, N_("print status from remote helper")),
{ OPTION_CALLBACK,
0, CAS_OPT_NAME, &cas, N_("refname>:<expect"),
N_("require old value of ref to be at this value"),
PARSE_OPT_OPTARG, parseopt_push_cas_option },
OPT_END()
};

git_config(send_pack_config, NULL);
argc = parse_options(argc, argv, prefix, options, send_pack_usage, 0);
if (argc > 0) {
dest = argv[0];
refspecs = (const char **)(argv + 1);
nr_refspecs = argc - 1;
}

if (!dest)
usage(send_pack_usage);
usage_with_options(send_pack_usage, options);

args.verbose = verbose;
args.dry_run = dry_run;
args.send_mirror = send_mirror;
args.force_update = force_update;
args.quiet = quiet;
args.push_cert = push_cert;
args.progress = progress;
args.use_thin_pack = use_thin_pack;
args.atomic = atomic;
args.stateless_rpc = stateless_rpc;

if (from_stdin) {
struct argv_array all_refspecs = ARGV_ARRAY_INIT;
@ -245,7 +227,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) @@ -245,7 +227,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
*/
if ((refspecs && (send_all || args.send_mirror)) ||
(send_all && args.send_mirror))
usage(send_pack_usage);
usage_with_options(send_pack_usage, options);

if (remote_name) {
remote = remote_get(remote_name);

1
cache.h

@ -1429,6 +1429,7 @@ extern int git_config_with_options(config_fn_t fn, void *, @@ -1429,6 +1429,7 @@ extern int git_config_with_options(config_fn_t fn, void *,
int respect_includes);
extern int git_config_early(config_fn_t fn, void *, const char *repo_config);
extern int git_parse_ulong(const char *, unsigned long *);
extern int git_parse_maybe_bool(const char *);
extern int git_config_int(const char *, const char *);
extern int64_t git_config_int64(const char *, const char *);
extern unsigned long git_config_ulong(const char *, const char *);

6
config.c

@ -618,7 +618,7 @@ unsigned long git_config_ulong(const char *name, const char *value) @@ -618,7 +618,7 @@ unsigned long git_config_ulong(const char *name, const char *value)
return ret;
}

static int git_config_maybe_bool_text(const char *name, const char *value)
int git_parse_maybe_bool(const char *value)
{
if (!value)
return 1;
@ -637,7 +637,7 @@ static int git_config_maybe_bool_text(const char *name, const char *value) @@ -637,7 +637,7 @@ static int git_config_maybe_bool_text(const char *name, const char *value)

int git_config_maybe_bool(const char *name, const char *value)
{
int v = git_config_maybe_bool_text(name, value);
int v = git_parse_maybe_bool(value);
if (0 <= v)
return v;
if (git_parse_int(value, &v))
@ -647,7 +647,7 @@ int git_config_maybe_bool(const char *name, const char *value) @@ -647,7 +647,7 @@ int git_config_maybe_bool(const char *name, const char *value)

int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
{
int v = git_config_maybe_bool_text(name, value);
int v = git_parse_maybe_bool(value);
if (0 <= v) {
*is_bool = 1;
return v;

16
remote-curl.c

@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
#include "argv-array.h"
#include "credential.h"
#include "sha1-array.h"
#include "send-pack.h"

static struct remote *remote;
/* always ends with a trailing slash */
@ -26,7 +27,8 @@ struct options { @@ -26,7 +27,8 @@ struct options {
followtags : 1,
dry_run : 1,
thin : 1,
push_cert : 1;
/* One of the SEND_PACK_PUSH_CERT_* constants. */
push_cert : 2;
};
static struct options options;
static struct string_list cas_options = STRING_LIST_INIT_DUP;
@ -109,9 +111,11 @@ static int set_option(const char *name, const char *value) @@ -109,9 +111,11 @@ static int set_option(const char *name, const char *value)
return 0;
} else if (!strcmp(name, "pushcert")) {
if (!strcmp(value, "true"))
options.push_cert = 1;
options.push_cert = SEND_PACK_PUSH_CERT_ALWAYS;
else if (!strcmp(value, "false"))
options.push_cert = 0;
options.push_cert = SEND_PACK_PUSH_CERT_NEVER;
else if (!strcmp(value, "if-asked"))
options.push_cert = SEND_PACK_PUSH_CERT_IF_ASKED;
else
return -1;
return 0;
@ -880,8 +884,10 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs) @@ -880,8 +884,10 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs)
argv_array_push(&args, "--thin");
if (options.dry_run)
argv_array_push(&args, "--dry-run");
if (options.push_cert)
argv_array_push(&args, "--signed");
if (options.push_cert == SEND_PACK_PUSH_CERT_ALWAYS)
argv_array_push(&args, "--signed=yes");
else if (options.push_cert == SEND_PACK_PUSH_CERT_IF_ASKED)
argv_array_push(&args, "--signed=if-asked");
if (options.verbosity == 0)
argv_array_push(&args, "--quiet");
else if (options.verbosity > 1)

43
send-pack.c

@ -12,6 +12,29 @@ @@ -12,6 +12,29 @@
#include "version.h"
#include "sha1-array.h"
#include "gpg-interface.h"
#include "cache.h"

int option_parse_push_signed(const struct option *opt,
const char *arg, int unset)
{
if (unset) {
*(int *)(opt->value) = SEND_PACK_PUSH_CERT_NEVER;
return 0;
}
switch (git_parse_maybe_bool(arg)) {
case 1:
*(int *)(opt->value) = SEND_PACK_PUSH_CERT_ALWAYS;
return 0;
case 0:
*(int *)(opt->value) = SEND_PACK_PUSH_CERT_NEVER;
return 0;
}
if (!strcasecmp("if-asked", arg)) {
*(int *)(opt->value) = SEND_PACK_PUSH_CERT_IF_ASKED;
return 0;
}
die("bad %s argument: %s", opt->long_name, arg);
}

static int feed_object(const unsigned char *sha1, int fd, int negative)
{
@ -370,14 +393,20 @@ int send_pack(struct send_pack_args *args, @@ -370,14 +393,20 @@ int send_pack(struct send_pack_args *args,
args->use_thin_pack = 0;
if (server_supports("atomic"))
atomic_supported = 1;
if (args->push_cert) {
int len;

if (args->push_cert != SEND_PACK_PUSH_CERT_NEVER) {
int len;
push_cert_nonce = server_feature_value("push-cert", &len);
if (!push_cert_nonce)
if (push_cert_nonce) {
reject_invalid_nonce(push_cert_nonce, len);
push_cert_nonce = xmemdupz(push_cert_nonce, len);
} else if (args->push_cert == SEND_PACK_PUSH_CERT_ALWAYS) {
die(_("the receiving end does not support --signed push"));
reject_invalid_nonce(push_cert_nonce, len);
push_cert_nonce = xmemdupz(push_cert_nonce, len);
} else if (args->push_cert == SEND_PACK_PUSH_CERT_IF_ASKED) {
warning(_("not sending a push certificate since the"
" receiving end does not support --signed"
" push"));
}
}

if (!remote_refs) {
@ -413,7 +442,7 @@ int send_pack(struct send_pack_args *args, @@ -413,7 +442,7 @@ int send_pack(struct send_pack_args *args,
if (!args->dry_run)
advertise_shallow_grafts_buf(&req_buf);

if (!args->dry_run && args->push_cert)
if (!args->dry_run && push_cert_nonce)
cmds_sent = generate_push_cert(&req_buf, remote_refs, args,
cap_buf.buf, push_cert_nonce);

@ -452,7 +481,7 @@ int send_pack(struct send_pack_args *args, @@ -452,7 +481,7 @@ int send_pack(struct send_pack_args *args,
for (ref = remote_refs; ref; ref = ref->next) {
char *old_hex, *new_hex;

if (args->dry_run || args->push_cert)
if (args->dry_run || push_cert_nonce)
continue;

if (check_to_send_update(ref, args) < 0)

12
send-pack.h

@ -1,6 +1,11 @@ @@ -1,6 +1,11 @@
#ifndef SEND_PACK_H
#define SEND_PACK_H

/* Possible values for push_cert field in send_pack_args. */
#define SEND_PACK_PUSH_CERT_NEVER 0
#define SEND_PACK_PUSH_CERT_IF_ASKED 1
#define SEND_PACK_PUSH_CERT_ALWAYS 2

struct send_pack_args {
const char *url;
unsigned verbose:1,
@ -12,11 +17,16 @@ struct send_pack_args { @@ -12,11 +17,16 @@ struct send_pack_args {
use_thin_pack:1,
use_ofs_delta:1,
dry_run:1,
push_cert:1,
/* One of the SEND_PACK_PUSH_CERT_* constants. */
push_cert:2,
stateless_rpc:1,
atomic:1;
};

struct option;
int option_parse_push_signed(const struct option *opt,
const char *arg, int unset);

int send_pack(struct send_pack_args *args,
int fd[], struct child_process *conn,
struct ref *remote_refs, struct sha1_array *extra_have);

34
transport-helper.c

@ -257,7 +257,6 @@ static const char *boolean_options[] = { @@ -257,7 +257,6 @@ static const char *boolean_options[] = {
TRANS_OPT_THIN,
TRANS_OPT_KEEP,
TRANS_OPT_FOLLOWTAGS,
TRANS_OPT_PUSH_CERT
};

static int set_helper_option(struct transport *transport,
@ -764,6 +763,21 @@ static int push_update_refs_status(struct helper_data *data, @@ -764,6 +763,21 @@ static int push_update_refs_status(struct helper_data *data,
return ret;
}

static void set_common_push_options(struct transport *transport,
const char *name, int flags)
{
if (flags & TRANSPORT_PUSH_DRY_RUN) {
if (set_helper_option(transport, "dry-run", "true") != 0)
die("helper %s does not support dry-run", name);
} else if (flags & TRANSPORT_PUSH_CERT_ALWAYS) {
if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0)
die("helper %s does not support --signed", name);
} else if (flags & TRANSPORT_PUSH_CERT_IF_ASKED) {
if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "if-asked") != 0)
die("helper %s does not support --signed=if-asked", name);
}
}

static int push_refs_with_push(struct transport *transport,
struct ref *remote_refs, int flags)
{
@ -831,14 +845,7 @@ static int push_refs_with_push(struct transport *transport, @@ -831,14 +845,7 @@ static int push_refs_with_push(struct transport *transport,

for_each_string_list_item(cas_option, &cas_options)
set_helper_option(transport, "cas", cas_option->string);

if (flags & TRANSPORT_PUSH_DRY_RUN) {
if (set_helper_option(transport, "dry-run", "true") != 0)
die("helper %s does not support dry-run", data->name);
} else if (flags & TRANSPORT_PUSH_CERT) {
if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0)
die("helper %s does not support --signed", data->name);
}
set_common_push_options(transport, data->name, flags);

strbuf_addch(&buf, '\n');
sendline(data, &buf);
@ -859,14 +866,7 @@ static int push_refs_with_export(struct transport *transport, @@ -859,14 +866,7 @@ static int push_refs_with_export(struct transport *transport,
if (!data->refspecs)
die("remote-helper doesn't support push; refspec needed");

if (flags & TRANSPORT_PUSH_DRY_RUN) {
if (set_helper_option(transport, "dry-run", "true") != 0)
die("helper %s does not support dry-run", data->name);
} else if (flags & TRANSPORT_PUSH_CERT) {
if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0)
die("helper %s does not support --signed", data->name);
}

set_common_push_options(transport, data->name, flags);
if (flags & TRANSPORT_PUSH_FORCE) {
if (set_helper_option(transport, "force", "true") != 0)
warning("helper %s does not support 'force'", data->name);

11
transport.c

@ -476,9 +476,6 @@ static int set_git_option(struct git_transport_options *opts, @@ -476,9 +476,6 @@ static int set_git_option(struct git_transport_options *opts,
die("transport: invalid depth option '%s'", value);
}
return 0;
} else if (!strcmp(name, TRANS_OPT_PUSH_CERT)) {
opts->push_cert = !!value;
return 0;
}
return 1;
}
@ -829,10 +826,16 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re @@ -829,10 +826,16 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
args.progress = transport->progress;
args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
args.porcelain = !!(flags & TRANSPORT_PUSH_PORCELAIN);
args.push_cert = !!(flags & TRANSPORT_PUSH_CERT);
args.atomic = !!(flags & TRANSPORT_PUSH_ATOMIC);
args.url = transport->url;

if (flags & TRANSPORT_PUSH_CERT_ALWAYS)
args.push_cert = SEND_PACK_PUSH_CERT_ALWAYS;
else if (flags & TRANSPORT_PUSH_CERT_IF_ASKED)
args.push_cert = SEND_PACK_PUSH_CERT_IF_ASKED;
else
args.push_cert = SEND_PACK_PUSH_CERT_NEVER;

ret = send_pack(&args, data->fd, data->conn, remote_refs,
&data->extra_have);


6
transport.h

@ -12,7 +12,6 @@ struct git_transport_options { @@ -12,7 +12,6 @@ struct git_transport_options {
unsigned check_self_contained_and_connected : 1;
unsigned self_contained_and_connected : 1;
unsigned update_shallow : 1;
unsigned push_cert : 1;
int depth;
const char *uploadpack;
const char *receivepack;
@ -124,8 +123,9 @@ struct transport { @@ -124,8 +123,9 @@ struct transport {
#define TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND 256
#define TRANSPORT_PUSH_NO_HOOK 512
#define TRANSPORT_PUSH_FOLLOW_TAGS 1024
#define TRANSPORT_PUSH_CERT 2048
#define TRANSPORT_PUSH_ATOMIC 4096
#define TRANSPORT_PUSH_CERT_ALWAYS 2048
#define TRANSPORT_PUSH_CERT_IF_ASKED 4096
#define TRANSPORT_PUSH_ATOMIC 8192

#define TRANSPORT_SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
#define TRANSPORT_SUMMARY(x) (int)(TRANSPORT_SUMMARY_WIDTH + strlen(x) - gettext_width(x)), (x)

Loading…
Cancel
Save