Skip to content

Commit 59b3865

Browse files
peffgitster
authored andcommitted
credential: let helpers tell us to quit
When we are trying to fill a credential, we loop over the set of defined credential-helpers, then fall back to running askpass, and then finally prompt on the terminal. Helpers which cannot find a credential are free to tell us nothing, but they cannot currently ask us to stop prompting. This patch lets them provide a "quit" attribute, which asks us to stop the process entirely (avoiding running more helpers, as well as the askpass/terminal prompt). This has a few possible uses: 1. A helper which prompts the user itself (e.g., in a dialog) can provide a "cancel" button to the user to stop further prompts. 2. Some helpers may know that prompting cannot possibly work. For example, if their role is to broker a ticket from an external auth system and that auth system cannot be contacted, there is no point in continuing (we need a ticket to authenticate, and the user cannot provide one by typing it in). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 7fa1365 commit 59b3865

4 files changed

Lines changed: 19 additions & 1 deletion

File tree

Documentation/technical/api-credentials.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,10 @@ FORMAT` in linkgit:git-credential[7] for a detailed specification).
248248
For a `get` operation, the helper should produce a list of attributes
249249
on stdout in the same format. A helper is free to produce a subset, or
250250
even no values at all if it has nothing useful to provide. Any provided
251-
attributes will overwrite those already known about by Git.
251+
attributes will overwrite those already known about by Git. If a helper
252+
outputs a `quit` attribute with a value of `true` or `1`, no further
253+
helpers will be consulted, nor will the user be prompted (if no
254+
credential has been provided, the operation will then fail).
252255

253256
For a `store` or `erase` operation, the helper's output is ignored.
254257
If it fails to perform the requested operation, it may complain to

credential.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ int credential_read(struct credential *c, FILE *fp)
173173
c->path = xstrdup(value);
174174
} else if (!strcmp(key, "url")) {
175175
credential_from_url(c, value);
176+
} else if (!strcmp(key, "quit")) {
177+
c->quit = !!git_config_bool("quit", value);
176178
}
177179
/*
178180
* Ignore other lines; we don't know what they mean, but
@@ -275,6 +277,9 @@ void credential_fill(struct credential *c)
275277
credential_do(c, c->helpers.items[i].string, "get");
276278
if (c->username && c->password)
277279
return;
280+
if (c->quit)
281+
die("credential helper '%s' told us to quit",
282+
c->helpers.items[i].string);
278283
}
279284

280285
credential_getpass(c);

credential.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ struct credential {
77
struct string_list helpers;
88
unsigned approved:1,
99
configured:1,
10+
quit:1,
1011
use_http_path:1;
1112

1213
char *username;

t/t0300-credentials.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,13 @@ test_expect_success 'http paths can be part of context' '
289289
EOF
290290
'
291291

292+
test_expect_success 'helpers can abort the process' '
293+
test_must_fail git \
294+
-c credential.helper="!f() { echo quit=1; }; f" \
295+
-c credential.helper="verbatim foo bar" \
296+
credential fill >stdout &&
297+
>expect &&
298+
test_cmp expect stdout
299+
'
300+
292301
test_done

0 commit comments

Comments
 (0)