diff mbox series

gpg-interface: allow selecting key id with env variable

Message ID 20211024193625.148-1-mbeck@eaddrinuse.net (mailing list archive)
State New, archived
Headers show
Series gpg-interface: allow selecting key id with env variable | expand

Commit Message

Marco Beck Oct. 24, 2021, 7:36 p.m. UTC
This allows selecting the gpg(1) key id to use for signing by setting the
environment variable GIT_GPG_SIGNINGKEY.

Signed-off-by: Marco Beck <mbeck@eaddrinuse.net>
---
 Documentation/git.txt | 6 ++++++
 gpg-interface.c       | 5 +++++
 2 files changed, 11 insertions(+)

Comments

Junio C Hamano Oct. 24, 2021, 8:35 p.m. UTC | #1
Marco Beck <mbeck@eaddrinuse.net> writes:

> This allows selecting the gpg(1) key id to use for signing by setting the
> environment variable GIT_GPG_SIGNINGKEY.

Can you explain why we want to add another way to specify the key?
It appears to me that user.signingkey is an adequate "set it once,
forget it, and keep using it" way to do so.  "I cannot write to the
config file" is unlikely, as the user must be capable of writing
into the repository to sign in the first place.

Is the driving motivation "I want to sign under a different identity
from the one the repository specifies in its local configuration"?
Wouldn't that be covered with a single-shot configuration syntax:

    $ git -c user.signingkey=mbeck@eaddrinuse.net tag -s ...

Unless there is a good reason to (and these days there aren't that
many), we prefer not to add new environment variables like this.

Thanks.
Marco Beck Oct. 24, 2021, 9:14 p.m. UTC | #2
On Sun, Oct 24, 2021 at 01:35:04PM -0700, Junio C Hamano wrote:

>Can you explain why we want to add another way to specify the key?

Motivation for that patch was that I usually use the same .gitconfig
(all dotfiles actually) with multiple identities (e.g. company and private
email address). It's really convenient to switch to a different identity
for the rest of the session by just setting e.g. $GIT_AUTHOR_EMAIL and not
needing to remember adding --author to every invocation of git-commit(1)
etc. Thought it would be nice to have that convenience for selecting a
signing key as well.
Fabian Stelzer Oct. 25, 2021, 7:31 a.m. UTC | #3
On 24.10.21 23:14, Marco Beck wrote:
> On Sun, Oct 24, 2021 at 01:35:04PM -0700, Junio C Hamano wrote:
> 
>> Can you explain why we want to add another way to specify the key?
> 
> Motivation for that patch was that I usually use the same .gitconfig
> (all dotfiles actually) with multiple identities (e.g. company and private
> email address). It's really convenient to switch to a different identity
> for the rest of the session by just setting e.g. $GIT_AUTHOR_EMAIL and not
> needing to remember adding --author to every invocation of git-commit(1)
> etc. Thought it would be nice to have that convenience for selecting a
> signing key as well.

If you only need to rarely change the key to sign with, the commands
usually have a direct parameter to do so:
git tag -s -u <keyid>
git commit -S<keyid>

Otherwise https://git-scm.com/docs/git-config#_conditional_includes
might be useful if you can store you private & work git in separate
directories or only have a few selected repos per identity. Put all your
defaults in your .gitconfig and use sth like:

[includeIf "gitdir:~/projects/work/"]
  path = ".gitconfig.work"

to override them.


Kind regards,
Fabian
Marco Beck Oct. 25, 2021, 8:24 a.m. UTC | #4
On Mon, Oct 25, 2021 at 09:31:33AM +0200, Fabian Stelzer wrote:

>[includeIf "gitdir:~/projects/work/"]
>  path = ".gitconfig.work"

Yeah, that's what I added to my config recently just for signing key
selection. I'm using direnv[1] for some time now to switch between
different "profiles" (more than just Git settings) by just setting
some environment variables and it was nice to have everything in one
place. That's why I disliked adding the includeIf to my .gitconfig.

Thanks anyway,
Marco

[1] https://direnv.net/
Fabian Stelzer Oct. 25, 2021, 8:46 a.m. UTC | #5
On 25.10.21 10:24, Marco Beck wrote:
> On Mon, Oct 25, 2021 at 09:31:33AM +0200, Fabian Stelzer wrote:
> 
>> [includeIf "gitdir:~/projects/work/"]
>>  path = ".gitconfig.work"
> 
> Yeah, that's what I added to my config recently just for signing key
> selection. I'm using direnv[1] for some time now to switch between
> different "profiles" (more than just Git settings) by just setting
> some environment variables and it was nice to have everything in one
> place. That's why I disliked adding the includeIf to my .gitconfig.
> 
> Thanks anyway,
> Marco
> 
> [1] https://direnv.net/

If you insist on using environment variables there is:
GIT_CONFIG_KEY_<n>
GIT_CONFIG_VALUE_<n>

https://git-scm.com/docs/git-config

A bit clunky in my opinion but you can set any config variable via env vars:

e.g.:
GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=user.name GIT_CONFIG_VALUE_0=testing
Junio C Hamano Oct. 25, 2021, 10:38 a.m. UTC | #6
Marco Beck <mbeck@eaddrinuse.net> writes:

> On Sun, Oct 24, 2021 at 01:35:04PM -0700, Junio C Hamano wrote:
>
>>Can you explain why we want to add another way to specify the key?
>
> Motivation for that patch was that I usually use the same .gitconfig
> (all dotfiles actually) with multiple identities (e.g. company and private
> email address). It's really convenient to switch to a different identity
> for the rest of the session by just setting e.g. $GIT_AUTHOR_EMAIL and not
> needing to remember adding --author to every invocation of git-commit(1)
> etc. Thought it would be nice to have that convenience for selecting a
> signing key as well.

If you are flipping between two (or more) idents using GIT_AUTHOR_*
but not doing the same for GIT_COMMITTER_*, then your commits may be
made under the same committer identity for both work and hobby
projects, which may not be what you want.  And if you are flipping
between multiple committer idents via GIT_COMMITTER_* environment
variables, the GPG signing key should follow the committer ident at
no extra cost, I would think.
Ævar Arnfjörð Bjarmason Oct. 25, 2021, 2:38 p.m. UTC | #7
On Mon, Oct 25 2021, Fabian Stelzer wrote:

> On 25.10.21 10:24, Marco Beck wrote:
>> On Mon, Oct 25, 2021 at 09:31:33AM +0200, Fabian Stelzer wrote:
>> 
>>> [includeIf "gitdir:~/projects/work/"]
>>>  path = ".gitconfig.work"
>> 
>> Yeah, that's what I added to my config recently just for signing key
>> selection. I'm using direnv[1] for some time now to switch between
>> different "profiles" (more than just Git settings) by just setting
>> some environment variables and it was nice to have everything in one
>> place. That's why I disliked adding the includeIf to my .gitconfig.
>> 
>> Thanks anyway,
>> Marco
>> 
>> [1] https://direnv.net/
>
> If you insist on using environment variables there is:
> GIT_CONFIG_KEY_<n>
> GIT_CONFIG_VALUE_<n>
>
> https://git-scm.com/docs/git-config
>
> A bit clunky in my opinion but you can set any config variable via env vars:
>
> e.g.:
> GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=user.name GIT_CONFIG_VALUE_0=testing

Although to be fair that's quite clunky if you're setting N number of
these.

Marco: Would the "include by env" method discussed in the thread at
https://lore.kernel.org/git/patch-1.1-1fe6f60d2bf-20210924T005553Z-avarab@gmail.com
be a better fit for what you're trying to do here, and eliminate the
need for you to have an env variable setting for this config key in
particular?

Anyway, aside from that I wonder if we shouldn't just have this env
variable anyway for consistency with the user.name, user.email
etc. equivalents, which we probaby wouldn't add today if they didn't
exist, but since we have them already...
Marco Beck Nov. 7, 2021, 4:27 p.m. UTC | #8
On Mon, Oct 25, 2021 at 10:46:56AM +0200, Fabian Stelzer wrote:
>
>If you insist on using environment variables there is:
>GIT_CONFIG_KEY_<n>
>GIT_CONFIG_VALUE_<n>
>
>https://git-scm.com/docs/git-config
>
>A bit clunky in my opinion but you can set any config variable via env vars:
>
>e.g.:
>GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=user.name GIT_CONFIG_VALUE_0=testing

Works for me, thank you.

Marco
diff mbox series

Patch

diff --git Documentation/git.txt Documentation/git.txt
index d63c65e67d..ab032f2760 100644
--- Documentation/git.txt
+++ Documentation/git.txt
@@ -941,6 +941,12 @@  corresponding standard handle, and if `GIT_REDIRECT_STDERR` is
 `2>&1`, standard error will be redirected to the same handle as
 standard output.
 
+`GIT_GPG_SIGNINGKEY`::
+	If this environment variable is set, then Git commands which use
+	`gpg(1)` for signing (e.g. linkgit:git-commit[1], linkgit:git-tag[1])
+	will use the specified key. See also the `user.signingkey` option in
+	linkgit:git-config[1].
+
 `GIT_PRINT_SHA1_ELLIPSIS` (deprecated)::
 	If set to `yes`, print an ellipsis following an
 	(abbreviated) SHA-1 value.  This affects indications of
diff --git gpg-interface.c gpg-interface.c
index 127aecfc2b..10e923140c 100644
--- gpg-interface.c
+++ gpg-interface.c
@@ -435,6 +435,11 @@  int git_gpg_config(const char *var, const char *value, void *cb)
 
 const char *get_signing_key(void)
 {
+	const char *signing_key;
+
+	if ((signing_key = getenv("GIT_GPG_SIGNINGKEY")))
+		return signing_key;
+
 	if (configured_signing_key)
 		return configured_signing_key;
 	return git_committer_info(IDENT_STRICT|IDENT_NO_DATE);