gpg-interface: lazily initialize and read the configuration

Instead of forcing the porcelain commands to always read the configuration variables related to the signing and verifying signatures, lazily initialize the necessary subsystem on demand upon the first use. This hopefully would make it more future-proof as we do not have to think and decide whether we should call git_gpg_config() in the git_config() callback for each command. A few git_config() callback functions that used to be custom callbacks are now just a thin wrapper around git_default_config(). We could further remove, git_FOO_config and replace calls to git_config(git_FOO_config) with git_config(git_default_config), but to make it clear which ones are affected and the effect is only the removal of git_gpg_config(), it is vastly preferred not to do such a change in this step (they can be done on top once the dust settled). Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Feb 9, 2023 at 12:24 UTC fd2d4c135ed974fdddf2af687748d28c58575984
17 files changed +33 -57
builtin/am.c
-6
@@ -2314,12 +2314,6 @@ static int parse_opt_show_current_patch(const struct option *opt, const char *ar
2314
2315 static int git_am_config(const char *k, const char *v, void *cb UNUSED)
2316 {
2317 - int status;
2318 -
2319 - status = git_gpg_config(k, v, NULL);
2320 - if (status)
2321 - return status;
2322 -
2317 return git_default_config(k, v, NULL);
2318 }
2319
builtin/commit-tree.c
-3
@@ -39,9 +39,6 @@ static void new_parent(struct commit *parent, struct commit_list **parents_p)
39
40 static int commit_tree_config(const char *var, const char *value, void *cb)
41 {
42 - int status = git_gpg_config(var, value, NULL);
43 - if (status)
44 - return status;
42 return git_default_config(var, value, cb);
43 }
44
builtin/commit.c
-4
@@ -1600,7 +1600,6 @@ int cmd_status(int argc, const char **argv, const char *prefix)
1600 static int git_commit_config(const char *k, const char *v, void *cb)
1601 {
1602 struct wt_status *s = cb;
1603 - int status;
1603
1604 if (!strcmp(k, "commit.template"))
1605 return git_config_pathname(&template_file, k, v);
@@ -1620,9 +1619,6 @@ static int git_commit_config(const char *k, const char *v, void *cb)
1619 return 0;
1620 }
1621
1623 - status = git_gpg_config(k, v, NULL);
1624 - if (status)
1625 - return status;
1622 return git_status_config(k, v, s);
1623 }
1624
builtin/log.c
-2
@@ -601,8 +601,6 @@ static int git_log_config(const char *var, const char *value, void *cb)
601 return 0;
602 }
603
604 - if (git_gpg_config(var, value, cb) < 0)
605 - return -1;
604 return git_diff_ui_config(var, value, cb);
605 }
606
builtin/merge.c
-3
@@ -659,9 +659,6 @@ static int git_merge_config(const char *k, const char *v, void *cb)
659 }
660
661 status = fmt_merge_msg_config(k, v, cb);
662 - if (status)
663 - return status;
664 - status = git_gpg_config(k, v, NULL);
662 if (status)
663 return status;
664 return git_diff_ui_config(k, v, cb);
builtin/pull.c
-6
@@ -359,8 +359,6 @@ static enum rebase_type config_get_rebase(int *rebase_unspecified)
359 */
360 static int git_pull_config(const char *var, const char *value, void *cb)
361 {
362 - int status;
363 -
362 if (!strcmp(var, "rebase.autostash")) {
363 config_autostash = git_config_bool(var, value);
364 return 0;
@@ -372,10 +370,6 @@ static int git_pull_config(const char *var, const char *value, void *cb)
370 check_trust_level = 0;
371 }
372
375 - status = git_gpg_config(var, value, cb);
376 - if (status)
377 - return status;
378 -
373 return git_default_config(var, value, cb);
374 }
375
builtin/push.c
-5
@@ -502,11 +502,6 @@ static int git_push_config(const char *k, const char *v, void *cb)
502 {
503 const char *slot_name;
504 int *flags = cb;
505 - int status;
506 -
507 - status = git_gpg_config(k, v, NULL);
508 - if (status)
509 - return status;
505
506 if (!strcmp(k, "push.followtags")) {
507 if (git_config_bool(k, v))
builtin/receive-pack.c
-4
@@ -133,10 +133,6 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
133 {
134 int status = parse_hide_refs_config(var, value, "receive", &hidden_refs);
135
136 - if (status)
137 - return status;
138 -
139 - status = git_gpg_config(var, value, NULL);
136 if (status)
137 return status;
138
builtin/send-pack.c
-2
@@ -130,8 +130,6 @@ static void print_helper_status(struct ref *ref)
130
131 static int send_pack_config(const char *k, const char *v, void *cb)
132 {
133 - git_gpg_config(k, v, NULL);
134 -
133 if (!strcmp(k, "push.gpgsign")) {
134 const char *value;
135 if (!git_config_get_value("push.gpgsign", &value)) {
builtin/tag.c
-5
@@ -180,8 +180,6 @@ static const char tag_template_nocleanup[] =
180
181 static int git_tag_config(const char *var, const char *value, void *cb)
182 {
183 - int status;
184 -
183 if (!strcmp(var, "tag.gpgsign")) {
184 config_sign_tag = git_config_bool(var, value);
185 return 0;
@@ -194,9 +192,6 @@ static int git_tag_config(const char *var, const char *value, void *cb)
192 return 0;
193 }
194
197 - status = git_gpg_config(var, value, cb);
198 - if (status)
199 - return status;
195 if (!strcmp(var, "tag.forcesignannotated")) {
196 force_sign_annotate = git_config_bool(var, value);
197 return 0;
builtin/verify-commit.c
-3
@@ -54,9 +54,6 @@ static int verify_commit(const char *name, unsigned flags)
54
55 static int git_verify_commit_config(const char *var, const char *value, void *cb)
56 {
57 - int status = git_gpg_config(var, value, cb);
58 - if (status)
59 - return status;
57 return git_default_config(var, value, cb);
58 }
59
builtin/verify-tag.c
-3
@@ -21,9 +21,6 @@ static const char * const verify_tag_usage[] = {
21
22 static int git_verify_tag_config(const char *var, const char *value, void *cb)
23 {
24 - int status = git_gpg_config(var, value, cb);
25 - if (status)
26 - return status;
24 return git_default_config(var, value, cb);
25 }
26
fmt-merge-msg.c
-5
@@ -17,8 +17,6 @@ static struct string_list suppress_dest_patterns = STRING_LIST_INIT_DUP;
17
18 int fmt_merge_msg_config(const char *key, const char *value, void *cb)
19 {
20 - int status = 0;
21 -
20 if (!strcmp(key, "merge.log") || !strcmp(key, "merge.summary")) {
21 int is_bool;
22 merge_log_config = git_config_bool_or_int(key, value, &is_bool);
@@ -37,9 +35,6 @@ int fmt_merge_msg_config(const char *key, const char *value, void *cb)
35 string_list_append(&suppress_dest_patterns, value);
36 suppress_dest_pattern_seen = 1;
37 } else {
40 - status = git_gpg_config(key, value, NULL);
41 - if (status)
42 - return status;
38 return git_default_config(key, value, cb);
39 }
40 return 0;
gpg-interface.c
+23 -1
@@ -9,6 +9,18 @@
9 #include "tempfile.h"
10 #include "alias.h"
11
12 +static int git_gpg_config(const char *, const char *, void *);
13 +
14 +static void gpg_interface_lazy_init(void)
15 +{
16 + static int done;
17 +
18 + if (done)
19 + return;
20 + done = 1;
21 + git_config(git_gpg_config, NULL);
22 +}
23 +
24 static char *configured_signing_key;
25 static const char *ssh_default_key_command, *ssh_allowed_signers, *ssh_revocation_file;
26 static enum signature_trust_level configured_min_trust_level = TRUST_UNDEFINED;
@@ -632,6 +644,8 @@ int check_signature(struct signature_check *sigc,
644 struct gpg_format *fmt;
645 int status;
646
647 + gpg_interface_lazy_init();
648 +
649 sigc->result = 'N';
650 sigc->trust_level = -1;
651
@@ -695,11 +709,13 @@ int parse_signature(const char *buf, size_t size, struct strbuf *payload, struct
709
710 void set_signing_key(const char *key)
711 {
712 + gpg_interface_lazy_init();
713 +
714 free(configured_signing_key);
715 configured_signing_key = xstrdup(key);
716 }
717
702 -int git_gpg_config(const char *var, const char *value, void *cb UNUSED)
718 +static int git_gpg_config(const char *var, const char *value, void *cb UNUSED)
719 {
720 struct gpg_format *fmt = NULL;
721 char *fmtname = NULL;
@@ -888,6 +904,8 @@ static const char *get_ssh_key_id(void) {
904 /* Returns a textual but unique representation of the signing key */
905 const char *get_signing_key_id(void)
906 {
907 + gpg_interface_lazy_init();
908 +
909 if (use_format->get_key_id) {
910 return use_format->get_key_id();
911 }
@@ -898,6 +916,8 @@ const char *get_signing_key_id(void)
916
917 const char *get_signing_key(void)
918 {
919 + gpg_interface_lazy_init();
920 +
921 if (configured_signing_key)
922 return configured_signing_key;
923 if (use_format->get_default_key) {
@@ -923,6 +943,8 @@ const char *gpg_trust_level_to_str(enum signature_trust_level level)
943
944 int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key)
945 {
946 + gpg_interface_lazy_init();
947 +
948 return use_format->sign_buffer(buffer, signature, signing_key);
949 }
950
gpg-interface.h
-1
@@ -79,7 +79,6 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature,
79 */
80 const char *gpg_trust_level_to_str(enum signature_trust_level level);
81
82 -int git_gpg_config(const char *, const char *, void *);
82 void set_signing_key(const char *);
83 const char *get_signing_key(void);
84
sequencer.c
-4
@@ -263,10 +263,6 @@ static int git_sequencer_config(const char *k, const char *v, void *cb)
263 if (opts->action == REPLAY_REVERT && !strcmp(k, "revert.reference"))
264 opts->commit_use_reference = git_config_bool(k, v);
265
266 - status = git_gpg_config(k, v, NULL);
267 - if (status)
268 - return status;
269 -
266 return git_diff_basic_config(k, v, NULL);
267 }
268
t/t7031-verify-tag-signed-ssh.sh
+10
@@ -200,4 +200,14 @@ test_expect_success GPGSSH 'verifying a forged tag with --format should fail sil
200 test_must_be_empty actual-forged
201 '
202
203 +test_expect_success GPGSSH 'rev-list --format=%G' '
204 + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
205 + git rev-list -1 --format="%G? %H" sixth-signed >actual &&
206 + cat >expect <<-EOF &&
207 + commit $(git rev-parse sixth-signed^0)
208 + G $(git rev-parse sixth-signed^0)
209 + EOF
210 + test_cmp expect actual
211 +'
212 +
213 test_done