Subject: Re: [PATCH v4] Add the tag.gpgsign option to sign annotated tags

From: Junio C Hamano <[email-masked]>
Date: Mon, 21 Mar 2016 14:26:23 -0700

Laurent Arnoud <[email-masked]> writes:

> @@ -326,7 +332,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
>  	struct create_tag_options opt;
>  	char *cleanup_arg = NULL;
>  	int create_reflog = 0;
> -	int annotate = 0, force = 0;
> +	int annotate = -1, force = 0;

I really do not like this part of the change.  The original code is
already bad in the sense that it uses "annotate" to mean "we need to
create a tag object, not just a lightweight tag" in some places
which already needs careful reading, but with this it no longer is
clear what this argument even means.  It sometimes means "we are
creating a tag object" and some other times means "we did not see
'-a' on the command line" but only until the variable gets assigned
by existing "if opt.sign is there, set it to true" tweaking.

I wonder if an approach like the following would result in a cleaner
code that is easier to maintain:

 - Leave this to be initialized to 0, allow it to be toggled upon
   seeing "-a" via the parse_options() mechanism, but redefine its
   meaning to be "-a option was passed".  Make it never be touched
   by anything else (e.g. "if (opt.sign) annotate = 1;" is wrong).

 - Introduce a new "create_tag_object" variable, initialized to 0.
   Existing code that sets "annotate = 1" (e.g. "-s" is passed,
   "-m/-F" is passed, etc.) will instead set this variable.  The
   condition of if() statement to call create_tag() would also be
   looking at this variable, not "annotate".

 - Before calling create_tag(), look at the value of your new
   configuration and "annotate", and set opt.sign as needed.

A patch to do so might look something like this (totally untested).

 builtin/tag.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/builtin/tag.c b/builtin/tag.c
index 1705c94..d262f92 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -29,6 +29,7 @@ static const char * const git_tag_usage[] = {
 };
 
 static unsigned int colopts;
+static int force_sign_annotate;
 
 static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, const char *format)
 {
@@ -168,6 +169,10 @@ static int git_tag_config(const char *var, const char *value, void *cb)
 		return status;
 	if (starts_with(var, "column."))
 		return git_column_config(var, value, "tag", &colopts);
+	if (!strcmp(var, "tag.forcesignannotated")) {
+		force_sign_annotate = git_config_bool(var, value);
+		return 0;
+	}
 	return git_default_config(var, value, cb);
 }
 
@@ -327,7 +332,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 	char *cleanup_arg = NULL;
 	int create_reflog = 0;
 	int annotate = 0, force = 0;
-	int cmdmode = 0;
+	int cmdmode = 0, create_tag_object = 0;
 	const char *msgfile = NULL, *keyid = NULL;
 	struct msg_arg msg = { 0, STRBUF_INIT };
 	struct ref_transaction *transaction;
@@ -385,12 +390,12 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 		opt.sign = 1;
 		set_signing_key(keyid);
 	}
-	if (opt.sign)
-		annotate = 1;
+	if (opt.sign || annotate)
+		create_tag_object = 1;
 	if (argc == 0 && !cmdmode)
 		cmdmode = 'l';
 
-	if ((annotate || msg.given || msgfile || force) && (cmdmode != 0))
+	if ((create_tag_object || msg.given || msgfile || force) && (cmdmode != 0))
 		usage_with_options(git_tag_usage, options);
 
 	finalize_colopts(&colopts, -1);
@@ -431,7 +436,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 	if (msg.given || msgfile) {
 		if (msg.given && msgfile)
 			die(_("only one -F or -m option is allowed."));
-		annotate = 1;
+		create_tag_object = 1;
 		if (msg.given)
 			strbuf_addbuf(&buf, &(msg.buf));
 		else {
@@ -474,8 +479,11 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 	else
 		die(_("Invalid cleanup mode %s"), cleanup_arg);
 
-	if (annotate)
+	if (create_tag_object) {
+		if (force_sign_annotate && !annotate)
+			opt.sign = 1;
 		create_tag(object, tag, &buf, &opt, prev, object);
+	}
 
 	transaction = ref_transaction_begin(&err);
 	if (!transaction ||