git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH v2 0/9] Flags and config to sign pushes by default
@ 2015-08-19 15:26 Dave Borowitz
  2015-08-19 15:26 ` [PATCH v2 1/9] Documentation/git-push.txt: Document when --signed may fail Dave Borowitz
                   ` (8 more replies)
  0 siblings, 9 replies; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 15:26 UTC (permalink / raw)
  To: git, gitster; +Cc: Dave Borowitz

Changes since v1:
 - Rebased on 44e02239
 - Use options --[no-]signed|--signed=(yes|no|if-asked)
 - Support general yes/true/1/etc. option parsing.
 - Convert builtin/send-pack.c to use option parsing API for better code
   reuse.
 - Various cleanups as suggested by Junio.

v1 can be found at:
http://thread.gmane.org/gmane.comp.version-control.git/275881

Dave Borowitz (9):
  Documentation/git-push.txt: Document when --signed may fail
  Documentation/git-send-pack.txt: Flow long synopsis line
  Documentation/git-send-pack.txt: Document --signed
  gitremote-helpers.txt: Document pushcert option
  transport: Remove git_transport_options.push_cert
  config.c: Expose git_parse_maybe_bool
  builtin/send-pack.c: Use option parsing API
  Support signing pushes iff the server supports it
  Add a config option push.gpgSign for default signed pushes

 Documentation/config.txt            |   8 ++
 Documentation/git-push.txt          |  15 ++-
 Documentation/git-send-pack.txt     |  16 ++-
 Documentation/gitremote-helpers.txt |   3 +
 builtin/push.c                      |  42 +++++++-
 builtin/send-pack.c                 | 192 ++++++++++++++++--------------------
 cache.h                             |   1 +
 config.c                            |   6 +-
 remote-curl.c                       |  16 ++-
 send-pack.c                         |  43 ++++++--
 send-pack.h                         |  12 ++-
 transport-helper.c                  |  34 +++----
 transport.c                         |  11 ++-
 transport.h                         |   6 +-
 14 files changed, 253 insertions(+), 152 deletions(-)

-- 
2.5.0.276.gf5e568e

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 1/9] Documentation/git-push.txt: Document when --signed may fail
  2015-08-19 15:26 [PATCH v2 0/9] Flags and config to sign pushes by default Dave Borowitz
@ 2015-08-19 15:26 ` Dave Borowitz
  2015-08-19 15:26 ` [PATCH v2 2/9] Documentation/git-send-pack.txt: Flow long synopsis line Dave Borowitz
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 15:26 UTC (permalink / raw)
  To: git, gitster; +Cc: Dave Borowitz

Like --atomic, --signed will fail if the server does not advertise the
necessary capability. In addition, it requires gpg on the client side.

Signed-off-by: Dave Borowitz <dborowitz@google.com>
---
 Documentation/git-push.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 135d810..da0a98d 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -137,7 +137,9 @@ already exists on the remote side.
 	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.
+	on the receiving end.  If the attempt to sign with `gpg` fails,
+	or if the server does not support signed pushes, the push will
+	fail.
 
 --[no-]atomic::
 	Use an atomic transaction on the remote side if available.
-- 
2.5.0.276.gf5e568e

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 2/9] Documentation/git-send-pack.txt: Flow long synopsis line
  2015-08-19 15:26 [PATCH v2 0/9] Flags and config to sign pushes by default Dave Borowitz
  2015-08-19 15:26 ` [PATCH v2 1/9] Documentation/git-push.txt: Document when --signed may fail Dave Borowitz
@ 2015-08-19 15:26 ` Dave Borowitz
  2015-08-19 19:56   ` Junio C Hamano
  2015-08-19 15:26 ` [PATCH v2 3/9] Documentation/git-send-pack.txt: Document --signed Dave Borowitz
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 15:26 UTC (permalink / raw)
  To: git, gitster; +Cc: Dave Borowitz

Signed-off-by: Dave Borowitz <dborowitz@google.com>
---
 Documentation/git-send-pack.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
index b5d09f7..6affff6 100644
--- a/Documentation/git-send-pack.txt
+++ b/Documentation/git-send-pack.txt
@@ -9,7 +9,8 @@ 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] [<host>:]<directory> [<ref>...]
 
 DESCRIPTION
 -----------
-- 
2.5.0.276.gf5e568e

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 3/9] Documentation/git-send-pack.txt: Document --signed
  2015-08-19 15:26 [PATCH v2 0/9] Flags and config to sign pushes by default Dave Borowitz
  2015-08-19 15:26 ` [PATCH v2 1/9] Documentation/git-push.txt: Document when --signed may fail Dave Borowitz
  2015-08-19 15:26 ` [PATCH v2 2/9] Documentation/git-send-pack.txt: Flow long synopsis line Dave Borowitz
@ 2015-08-19 15:26 ` Dave Borowitz
  2015-08-19 15:26 ` [PATCH v2 4/9] gitremote-helpers.txt: Document pushcert option Dave Borowitz
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 15:26 UTC (permalink / raw)
  To: git, gitster; +Cc: Dave Borowitz

Signed-off-by: Dave Borowitz <dborowitz@google.com>
---
 Documentation/git-send-pack.txt | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
index 6affff6..0a0a3fb 100644
--- a/Documentation/git-send-pack.txt
+++ b/Documentation/git-send-pack.txt
@@ -10,7 +10,8 @@ SYNOPSIS
 --------
 [verse]
 'git send-pack' [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>]
-		[--verbose] [--thin] [--atomic] [<host>:]<directory> [<ref>...]
+		[--verbose] [--thin] [--atomic] [--signed]
+		[<host>:]<directory> [<ref>...]
 
 DESCRIPTION
 -----------
@@ -68,6 +69,14 @@ 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.
 
+--signed::
+	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.  If the attempt to sign with `gpg` fails,
+	or if the server does not support signed pushes, the push will
+	fail.
+
 <host>::
 	A remote host to house the repository.  When this
 	part is specified, 'git-receive-pack' is invoked via
-- 
2.5.0.276.gf5e568e

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 4/9] gitremote-helpers.txt: Document pushcert option
  2015-08-19 15:26 [PATCH v2 0/9] Flags and config to sign pushes by default Dave Borowitz
                   ` (2 preceding siblings ...)
  2015-08-19 15:26 ` [PATCH v2 3/9] Documentation/git-send-pack.txt: Document --signed Dave Borowitz
@ 2015-08-19 15:26 ` Dave Borowitz
  2015-08-19 15:26 ` [PATCH v2 5/9] transport: Remove git_transport_options.push_cert Dave Borowitz
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 15:26 UTC (permalink / raw)
  To: git, gitster; +Cc: Dave Borowitz

Signed-off-by: Dave Borowitz <dborowitz@google.com>
---
 Documentation/gitremote-helpers.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt
index 82e2d15..78e0b27 100644
--- a/Documentation/gitremote-helpers.txt
+++ b/Documentation/gitremote-helpers.txt
@@ -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]
-- 
2.5.0.276.gf5e568e

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 5/9] transport: Remove git_transport_options.push_cert
  2015-08-19 15:26 [PATCH v2 0/9] Flags and config to sign pushes by default Dave Borowitz
                   ` (3 preceding siblings ...)
  2015-08-19 15:26 ` [PATCH v2 4/9] gitremote-helpers.txt: Document pushcert option Dave Borowitz
@ 2015-08-19 15:26 ` Dave Borowitz
  2015-08-19 15:26 ` [PATCH v2 6/9] config.c: Expose git_parse_maybe_bool Dave Borowitz
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 15:26 UTC (permalink / raw)
  To: git, gitster; +Cc: Dave Borowitz

This field was set in transport_set_option, but never read in the push
code. The push code basically ignores the smart_options field
entirely, and derives its options from the flags arguments to the
push* callbacks. Note that in git_transport_push there are already
several args set from flags that have no corresponding field in
git_transport_options; after this change, push_cert is just like
those.

Signed-off-by: Dave Borowitz <dborowitz@google.com>
---
 transport.c | 3 ---
 transport.h | 1 -
 2 files changed, 4 deletions(-)

diff --git a/transport.c b/transport.c
index 40692f8..3dd6e30 100644
--- a/transport.c
+++ b/transport.c
@@ -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;
 }
diff --git a/transport.h b/transport.h
index 18d2cf8..79190df 100644
--- a/transport.h
+++ b/transport.h
@@ -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;
-- 
2.5.0.276.gf5e568e

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 6/9] config.c: Expose git_parse_maybe_bool
  2015-08-19 15:26 [PATCH v2 0/9] Flags and config to sign pushes by default Dave Borowitz
                   ` (4 preceding siblings ...)
  2015-08-19 15:26 ` [PATCH v2 5/9] transport: Remove git_transport_options.push_cert Dave Borowitz
@ 2015-08-19 15:26 ` Dave Borowitz
  2015-08-19 15:26 ` [PATCH v2 7/9] builtin/send-pack.c: Use option parsing API Dave Borowitz
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 15:26 UTC (permalink / raw)
  To: git, gitster; +Cc: Dave Borowitz

Signed-off-by: Dave Borowitz <dborowitz@google.com>
---
 cache.h  | 1 +
 config.c | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/cache.h b/cache.h
index 6bb7119..95d9594 100644
--- a/cache.h
+++ b/cache.h
@@ -1392,6 +1392,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 *);
diff --git a/config.c b/config.c
index 9fd275f..e5d7959 100644
--- a/config.c
+++ b/config.c
@@ -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)
 
 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)
 
 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;
-- 
2.5.0.276.gf5e568e

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 7/9] builtin/send-pack.c: Use option parsing API
  2015-08-19 15:26 [PATCH v2 0/9] Flags and config to sign pushes by default Dave Borowitz
                   ` (5 preceding siblings ...)
  2015-08-19 15:26 ` [PATCH v2 6/9] config.c: Expose git_parse_maybe_bool Dave Borowitz
@ 2015-08-19 15:26 ` Dave Borowitz
  2015-08-19 18:00   ` Stefan Beller
  2015-08-19 15:26 ` [PATCH v2 8/9] Support signing pushes iff the server supports it Dave Borowitz
  2015-08-19 15:26 ` [PATCH v2 9/9] Add a config option push.gpgSign for default signed pushes Dave Borowitz
  8 siblings, 1 reply; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 15:26 UTC (permalink / raw)
  To: git, gitster; +Cc: Dave Borowitz

The old option parsing code in this plumbing command predates this
API, so option parsing was done more manually. Using the new API
brings send-pack more in line with push, and accepts new variants
like --no-* for negating options.

Signed-off-by: Dave Borowitz <dborowitz@google.com>
---
 builtin/send-pack.c | 163 +++++++++++++++++++---------------------------------
 1 file changed, 59 insertions(+), 104 deletions(-)

diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 23b2962..5f2c744 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -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;
 
@@ -107,116 +112,66 @@ 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;
+	unsigned 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);
+	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")),
+		OPT_BOOL(0, "signed", &push_cert, N_("GPG sign the push")),
+		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()
+	};
 
-	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;
+	git_config(git_gpg_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 +200,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);
-- 
2.5.0.276.gf5e568e

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 8/9] Support signing pushes iff the server supports it
  2015-08-19 15:26 [PATCH v2 0/9] Flags and config to sign pushes by default Dave Borowitz
                   ` (6 preceding siblings ...)
  2015-08-19 15:26 ` [PATCH v2 7/9] builtin/send-pack.c: Use option parsing API Dave Borowitz
@ 2015-08-19 15:26 ` Dave Borowitz
  2015-08-19 19:58   ` Junio C Hamano
  2015-08-19 15:26 ` [PATCH v2 9/9] Add a config option push.gpgSign for default signed pushes Dave Borowitz
  8 siblings, 1 reply; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 15:26 UTC (permalink / raw)
  To: git, gitster; +Cc: Dave Borowitz

Add a new flag --signed-if-possible to push and send-pack that sends a
push certificate if and only if the server advertised a push cert
nonce. If not, at least warn the user that their push may not be as
secure as they thought.

Signed-off-by: Dave Borowitz <dborowitz@google.com>
---
 Documentation/git-push.txt      | 17 +++++++++-------
 Documentation/git-send-pack.txt | 16 +++++++++------
 builtin/push.c                  | 20 ++++++++++++++++++-
 builtin/send-pack.c             |  6 ++++--
 remote-curl.c                   | 16 ++++++++++-----
 send-pack.c                     | 43 ++++++++++++++++++++++++++++++++++-------
 send-pack.h                     | 12 +++++++++++-
 transport-helper.c              | 34 ++++++++++++++++----------------
 transport.c                     |  8 +++++++-
 transport.h                     |  5 +++--
 10 files changed, 128 insertions(+), 49 deletions(-)

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index da0a98d..1495e34 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -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,14 +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.  If the attempt to sign with `gpg` fails,
-	or if the server does not support signed pushes, the push will
-	fail.
+	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.
diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
index 0a0a3fb..6aa91e8 100644
--- a/Documentation/git-send-pack.txt
+++ b/Documentation/git-send-pack.txt
@@ -10,7 +10,8 @@ SYNOPSIS
 --------
 [verse]
 'git send-pack' [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>]
-		[--verbose] [--thin] [--atomic] [--signed]
+		[--verbose] [--thin] [--atomic]
+		[--[no-]signed|--sign=(true|false|if-asked)]
 		[<host>:]<directory> [<ref>...]
 
 DESCRIPTION
@@ -69,13 +70,16 @@ 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.
 
---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.  If the attempt to sign with `gpg` fails,
-	or if the server does not support signed pushes, the push will
-	fail.
+	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
diff --git a/builtin/push.c b/builtin/push.c
index 57c138b..85a82cd 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -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>...]]"),
@@ -495,6 +496,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 +528,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()
 	};
@@ -548,6 +552,20 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		set_refspecs(argv + 1, argc - 1, repo);
 	}
 
+	switch (push_cert) {
+	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;
+	}
+
 	rc = do_push(repo, flags);
 	if (rc == -1)
 		usage_with_options(push_usage, options);
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 5f2c744..0ce3bc8 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -118,7 +118,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 	unsigned send_mirror = 0;
 	unsigned force_update = 0;
 	unsigned quiet = 0;
-	unsigned push_cert = 0;
+	int push_cert = 0;
 	unsigned use_thin_pack = 0;
 	unsigned atomic = 0;
 	unsigned stateless_rpc = 0;
@@ -137,7 +137,9 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 		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")),
-		OPT_BOOL(0, "signed", &push_cert, N_("GPG sign the push")),
+		{ 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")),
diff --git a/remote-curl.c b/remote-curl.c
index af7b678..71fbbb6 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -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 {
 		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)
 		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)
 		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)
diff --git a/send-pack.c b/send-pack.c
index 2a64fec..c6a4030 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -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,
 		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,
 	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,
 	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)
diff --git a/send-pack.h b/send-pack.h
index b664648..57f222a 100644
--- a/send-pack.h
+++ b/send-pack.h
@@ -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 {
 		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);
diff --git a/transport-helper.c b/transport-helper.c
index 5d99a6b..fd5723f 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -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,
@@ -763,6 +762,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)
 {
@@ -830,14 +844,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);
@@ -858,14 +865,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);
diff --git a/transport.c b/transport.c
index 3dd6e30..ebe3b3b 100644
--- a/transport.c
+++ b/transport.c
@@ -826,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);
 
diff --git a/transport.h b/transport.h
index 79190df..d682b77 100644
--- a/transport.h
+++ b/transport.h
@@ -123,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)
-- 
2.5.0.276.gf5e568e

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 9/9] Add a config option push.gpgSign for default signed pushes
  2015-08-19 15:26 [PATCH v2 0/9] Flags and config to sign pushes by default Dave Borowitz
                   ` (7 preceding siblings ...)
  2015-08-19 15:26 ` [PATCH v2 8/9] Support signing pushes iff the server supports it Dave Borowitz
@ 2015-08-19 15:26 ` Dave Borowitz
  8 siblings, 0 replies; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 15:26 UTC (permalink / raw)
  To: git, gitster; +Cc: Dave Borowitz

Signed-off-by: Dave Borowitz <dborowitz@google.com>
---
 Documentation/config.txt |  8 ++++++++
 builtin/push.c           | 50 ++++++++++++++++++++++++++++++++++--------------
 builtin/send-pack.c      | 27 +++++++++++++++++++++++++-
 3 files changed, 70 insertions(+), 15 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 016f6e9..4ba0e4b 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2178,6 +2178,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
diff --git a/builtin/push.c b/builtin/push.c
index 85a82cd..3bda430 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -472,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;
@@ -487,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);
@@ -538,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"));
@@ -552,20 +588,6 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		set_refspecs(argv + 1, argc - 1, repo);
 	}
 
-	switch (push_cert) {
-	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;
-	}
-
 	rc = do_push(repo, flags);
 	if (rc == -1)
 		usage_with_options(push_usage, options);
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 0ce3bc8..f6e5d64 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -97,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;
@@ -153,7 +178,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 		OPT_END()
 	};
 
-	git_config(git_gpg_config, NULL);
+	git_config(send_pack_config, NULL);
 	argc = parse_options(argc, argv, prefix, options, send_pack_usage, 0);
 	if (argc > 0) {
 		dest = argv[0];
-- 
2.5.0.276.gf5e568e

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 7/9] builtin/send-pack.c: Use option parsing API
  2015-08-19 15:26 ` [PATCH v2 7/9] builtin/send-pack.c: Use option parsing API Dave Borowitz
@ 2015-08-19 18:00   ` Stefan Beller
  2015-08-19 19:46     ` Dave Borowitz
  0 siblings, 1 reply; 19+ messages in thread
From: Stefan Beller @ 2015-08-19 18:00 UTC (permalink / raw)
  To: Dave Borowitz; +Cc: git@vger.kernel.org, Junio C Hamano

On Wed, Aug 19, 2015 at 8:26 AM, Dave Borowitz <dborowitz@google.com> wrote:
> The old option parsing code in this plumbing command predates this
> API, so option parsing was done more manually. Using the new API
> brings send-pack more in line with push, and accepts new variants
> like --no-* for negating options.
>
> Signed-off-by: Dave Borowitz <dborowitz@google.com>
> ---
>  builtin/send-pack.c | 163 +++++++++++++++++++---------------------------------
>  1 file changed, 59 insertions(+), 104 deletions(-)
>
> diff --git a/builtin/send-pack.c b/builtin/send-pack.c
> index 23b2962..5f2c744 100644
> --- a/builtin/send-pack.c
> +++ b/builtin/send-pack.c
> @@ -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;
>
> @@ -107,116 +112,66 @@ 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;
> +       unsigned push_cert = 0;
> +       unsigned use_thin_pack = 0;
> +       unsigned atomic = 0;
> +       unsigned stateless_rpc = 0;

First I thought:
    You could write to the args flags directly from the options. No
need to have (most of)
    the variables around here and copy over the values. You'd need to
use OPT_BIT instead
    for setting a specific bit though
but then I realized we do not have a direct bit field in args, which
would make it a bit unreadable.

>         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);
> +       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")),

-f and -n are new here now?

> +               OPT_BOOL(0, "signed", &push_cert, N_("GPG sign the push")),
> +               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()
> +       };
>
> -       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;
> +       git_config(git_gpg_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 +200,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);
> --
> 2.5.0.276.gf5e568e
>
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 7/9] builtin/send-pack.c: Use option parsing API
  2015-08-19 18:00   ` Stefan Beller
@ 2015-08-19 19:46     ` Dave Borowitz
  2015-08-21 15:06       ` Jeff King
  0 siblings, 1 reply; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 19:46 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git@vger.kernel.org, Junio C Hamano

On Wed, Aug 19, 2015 at 2:00 PM, Stefan Beller <sbeller@google.com> wrote:
> On Wed, Aug 19, 2015 at 8:26 AM, Dave Borowitz <dborowitz@google.com> wrote:
>> The old option parsing code in this plumbing command predates this
>> API, so option parsing was done more manually. Using the new API
>> brings send-pack more in line with push, and accepts new variants
>> like --no-* for negating options.
>>
>> Signed-off-by: Dave Borowitz <dborowitz@google.com>
>> ---
>>  builtin/send-pack.c | 163 +++++++++++++++++++---------------------------------
>>  1 file changed, 59 insertions(+), 104 deletions(-)
>>
>> diff --git a/builtin/send-pack.c b/builtin/send-pack.c
>> index 23b2962..5f2c744 100644
>> --- a/builtin/send-pack.c
>> +++ b/builtin/send-pack.c
>> @@ -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;
>>
>> @@ -107,116 +112,66 @@ 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;
>> +       unsigned push_cert = 0;
>> +       unsigned use_thin_pack = 0;
>> +       unsigned atomic = 0;
>> +       unsigned stateless_rpc = 0;
>
> First I thought:
>     You could write to the args flags directly from the options. No
> need to have (most of)
>     the variables around here and copy over the values. You'd need to
> use OPT_BIT instead
>     for setting a specific bit though
> but then I realized we do not have a direct bit field in args, which
> would make it a bit unreadable.

Right, and &args->push_cert etc. is invalid, and I didn't know if it
was ok to expand the args struct to be several words longer. But I'm
not a C programmer so I'm happy to take suggestions how to make this
more idiomatic.

>>         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);
>> +       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")),
>
> -f and -n are new here now?

Yeah, I was going for consistency with push.c (and also just copy/pasted ;)

>> +               OPT_BOOL(0, "signed", &push_cert, N_("GPG sign the push")),
>> +               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()
>> +       };
>>
>> -       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;
>> +       git_config(git_gpg_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 +200,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);
>> --
>> 2.5.0.276.gf5e568e
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe git" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/9] Documentation/git-send-pack.txt: Flow long synopsis line
  2015-08-19 15:26 ` [PATCH v2 2/9] Documentation/git-send-pack.txt: Flow long synopsis line Dave Borowitz
@ 2015-08-19 19:56   ` Junio C Hamano
  2015-08-19 19:59     ` Dave Borowitz
  0 siblings, 1 reply; 19+ messages in thread
From: Junio C Hamano @ 2015-08-19 19:56 UTC (permalink / raw)
  To: Dave Borowitz; +Cc: git

Dave Borowitz <dborowitz@google.com> writes:

> Signed-off-by: Dave Borowitz <dborowitz@google.com>
> ---
>  Documentation/git-send-pack.txt | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
> index b5d09f7..6affff6 100644
> --- a/Documentation/git-send-pack.txt
> +++ b/Documentation/git-send-pack.txt
> @@ -9,7 +9,8 @@ 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] [<host>:]<directory> [<ref>...]
>  
>  DESCRIPTION
>  -----------

As can be expected from the Subject: line, this patch is
line-wrapped and does not apply ;-)

I've done a trivial fix-up and took the liberty of making the result
of this step into three lines, not two.  That would make 3/9 look
more trivial.

Thanks.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 8/9] Support signing pushes iff the server supports it
  2015-08-19 15:26 ` [PATCH v2 8/9] Support signing pushes iff the server supports it Dave Borowitz
@ 2015-08-19 19:58   ` Junio C Hamano
  2015-08-19 20:00     ` Dave Borowitz
  0 siblings, 1 reply; 19+ messages in thread
From: Junio C Hamano @ 2015-08-19 19:58 UTC (permalink / raw)
  To: Dave Borowitz; +Cc: git

Dave Borowitz <dborowitz@google.com> writes:

> Add a new flag --signed-if-possible to push and send-pack that sends a
> push certificate if and only if the server advertised a push cert
> nonce. If not, at least warn the user that their push may not be as
> secure as they thought.
>
> Signed-off-by: Dave Borowitz <dborowitz@google.com>
> ---

Obviously, the above description needs updating.  Here is what I've
queued tentatively.

Thanks.

commit 32d273dfabb0a70b2839971f5afff7fa86a8f4c2
Author: Dave Borowitz <dborowitz@google.com>
Date:   Wed Aug 19 11:26:46 2015 -0400

    push: support signing pushes iff the server supports it
    
    Add a new flag --sign=true (or --sign=false), which means the same
    thing as the original --signed (or --no-signed).  Give it a third
    value --sign=if-asked to tell push and send-pack to send a push
    certificate if and only if the server advertised a push cert nonce.
    
    If not, warn the user that their push may not be as secure as they
    thought.
    
    Signed-off-by: Dave Borowitz <dborowitz@google.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/9] Documentation/git-send-pack.txt: Flow long synopsis line
  2015-08-19 19:56   ` Junio C Hamano
@ 2015-08-19 19:59     ` Dave Borowitz
  2015-08-19 20:10       ` Junio C Hamano
  0 siblings, 1 reply; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 19:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Wed, Aug 19, 2015 at 3:56 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Dave Borowitz <dborowitz@google.com> writes:
>
>> Signed-off-by: Dave Borowitz <dborowitz@google.com>
>> ---
>>  Documentation/git-send-pack.txt | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
>> index b5d09f7..6affff6 100644
>> --- a/Documentation/git-send-pack.txt
>> +++ b/Documentation/git-send-pack.txt
>> @@ -9,7 +9,8 @@ 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] [<host>:]<directory> [<ref>...]
>>
>>  DESCRIPTION
>>  -----------
>
> As can be expected from the Subject: line, this patch is
> line-wrapped and does not apply ;-)

I produced the patch with "git format-patch --subject-prefix='PATCH
v2' --cover-letter @{u}.." and mailed with "git send-email
--to=git@vger.kernel.org,gitster@pobox.com 0*.patch"; is there a way
that would have preserved whitespace better?

> I've done a trivial fix-up and took the liberty of making the result
> of this step into three lines, not two.  That would make 3/9 look
> more trivial.

Ok by me.

> Thanks.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 8/9] Support signing pushes iff the server supports it
  2015-08-19 19:58   ` Junio C Hamano
@ 2015-08-19 20:00     ` Dave Borowitz
  0 siblings, 0 replies; 19+ messages in thread
From: Dave Borowitz @ 2015-08-19 20:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Wed, Aug 19, 2015 at 3:58 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Dave Borowitz <dborowitz@google.com> writes:
>
>> Add a new flag --signed-if-possible to push and send-pack that sends a
>> push certificate if and only if the server advertised a push cert
>> nonce. If not, at least warn the user that their push may not be as
>> secure as they thought.
>>
>> Signed-off-by: Dave Borowitz <dborowitz@google.com>
>> ---
>
> Obviously, the above description needs updating.  Here is what I've
> queued tentatively.

Sound good.

> Thanks.
>
> commit 32d273dfabb0a70b2839971f5afff7fa86a8f4c2
> Author: Dave Borowitz <dborowitz@google.com>
> Date:   Wed Aug 19 11:26:46 2015 -0400
>
>     push: support signing pushes iff the server supports it
>
>     Add a new flag --sign=true (or --sign=false), which means the same
>     thing as the original --signed (or --no-signed).  Give it a third
>     value --sign=if-asked to tell push and send-pack to send a push
>     certificate if and only if the server advertised a push cert nonce.
>
>     If not, warn the user that their push may not be as secure as they
>     thought.
>
>     Signed-off-by: Dave Borowitz <dborowitz@google.com>
>     Signed-off-by: Junio C Hamano <gitster@pobox.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/9] Documentation/git-send-pack.txt: Flow long synopsis line
  2015-08-19 19:59     ` Dave Borowitz
@ 2015-08-19 20:10       ` Junio C Hamano
  2015-09-11 16:22         ` Junio C Hamano
  0 siblings, 1 reply; 19+ messages in thread
From: Junio C Hamano @ 2015-08-19 20:10 UTC (permalink / raw)
  To: Dave Borowitz; +Cc: git

Dave Borowitz <dborowitz@google.com> writes:

> I produced the patch with "git format-patch --subject-prefix='PATCH
> v2' --cover-letter @{u}.." and mailed with "git send-email
> --to=git@vger.kernel.org,gitster@pobox.com 0*.patch"; is there a way
> that would have preserved whitespace better?

No need to worry, I suspect that this is a local Emacs/GNUS glitch
on the receiving end.  Sorry for a noise.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 7/9] builtin/send-pack.c: Use option parsing API
  2015-08-19 19:46     ` Dave Borowitz
@ 2015-08-21 15:06       ` Jeff King
  0 siblings, 0 replies; 19+ messages in thread
From: Jeff King @ 2015-08-21 15:06 UTC (permalink / raw)
  To: Dave Borowitz; +Cc: Stefan Beller, git@vger.kernel.org, Junio C Hamano

On Wed, Aug 19, 2015 at 03:46:25PM -0400, Dave Borowitz wrote:

> >> +       unsigned dry_run = 0;
> >> +       unsigned send_mirror = 0;
> >> +       unsigned force_update = 0;
> >> +       unsigned quiet = 0;
> >> +       unsigned push_cert = 0;
> >> +       unsigned use_thin_pack = 0;
> >> +       unsigned atomic = 0;
> >> +       unsigned stateless_rpc = 0;
> >
> > First I thought:
> >     You could write to the args flags directly from the options. No
> > need to have (most of)
> >     the variables around here and copy over the values. You'd need to
> > use OPT_BIT instead
> >     for setting a specific bit though
> > but then I realized we do not have a direct bit field in args, which
> > would make it a bit unreadable.
> 
> Right, and &args->push_cert etc. is invalid, and I didn't know if it
> was ok to expand the args struct to be several words longer. But I'm
> not a C programmer so I'm happy to take suggestions how to make this
> more idiomatic.

I think it would be fine to expand it. The reason to use bitfields is to
save memory, and there is literally only one of these structs per
program. I'm sure we can afford the extra dozen bytes.

Making the struct members single-bits also communicates to readers that
they are true booleans, but I think a comment in the declaration of
send_pack_args could do the same.

-Peff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/9] Documentation/git-send-pack.txt: Flow long synopsis line
  2015-08-19 20:10       ` Junio C Hamano
@ 2015-09-11 16:22         ` Junio C Hamano
  0 siblings, 0 replies; 19+ messages in thread
From: Junio C Hamano @ 2015-09-11 16:22 UTC (permalink / raw)
  To: git; +Cc: Dave Borowitz

Junio C Hamano <gitster@pobox.com> writes:

> Dave Borowitz <dborowitz@google.com> writes:
>
>> I produced the patch with "git format-patch --subject-prefix='PATCH
>> v2' --cover-letter @{u}.." and mailed with "git send-email
>> --to=git@vger.kernel.org,gitster@pobox.com 0*.patch"; is there a way
>> that would have preserved whitespace better?
>
> No need to worry, I suspect that this is a local Emacs/GNUS glitch
> on the receiving end.  Sorry for a noise.

PSA, as I figured this out.

It turns out that gnus-treat-fill-long-lines was set to (typep
"text/plain"), which meant that I cannot trust what I see in my MUA
as an exact copy of the patch the sender intended to give me.

Here is what "Describe variable" gave me (after I fixed it, that is).

    ---
    gnus-treat-fill-long-lines's value is nil
    Original value was 
    (typep "text/plain")


    Documentation:
    Fill long lines.
    Valid values are nil, t, `head', `first', `last', an integer or a
    predicate.  See Info node `(gnus)Customizing Articles'.

    You can customize this variable.

    This variable was introduced, or its default value was changed, in
    version 24.1 of Emacs.
    ---

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2015-09-11 16:22 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-19 15:26 [PATCH v2 0/9] Flags and config to sign pushes by default Dave Borowitz
2015-08-19 15:26 ` [PATCH v2 1/9] Documentation/git-push.txt: Document when --signed may fail Dave Borowitz
2015-08-19 15:26 ` [PATCH v2 2/9] Documentation/git-send-pack.txt: Flow long synopsis line Dave Borowitz
2015-08-19 19:56   ` Junio C Hamano
2015-08-19 19:59     ` Dave Borowitz
2015-08-19 20:10       ` Junio C Hamano
2015-09-11 16:22         ` Junio C Hamano
2015-08-19 15:26 ` [PATCH v2 3/9] Documentation/git-send-pack.txt: Document --signed Dave Borowitz
2015-08-19 15:26 ` [PATCH v2 4/9] gitremote-helpers.txt: Document pushcert option Dave Borowitz
2015-08-19 15:26 ` [PATCH v2 5/9] transport: Remove git_transport_options.push_cert Dave Borowitz
2015-08-19 15:26 ` [PATCH v2 6/9] config.c: Expose git_parse_maybe_bool Dave Borowitz
2015-08-19 15:26 ` [PATCH v2 7/9] builtin/send-pack.c: Use option parsing API Dave Borowitz
2015-08-19 18:00   ` Stefan Beller
2015-08-19 19:46     ` Dave Borowitz
2015-08-21 15:06       ` Jeff King
2015-08-19 15:26 ` [PATCH v2 8/9] Support signing pushes iff the server supports it Dave Borowitz
2015-08-19 19:58   ` Junio C Hamano
2015-08-19 20:00     ` Dave Borowitz
2015-08-19 15:26 ` [PATCH v2 9/9] Add a config option push.gpgSign for default signed pushes Dave Borowitz

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).