diff --git a/builtin/clone.c b/builtin/clone.c index 67e0948a77bcaf..ec761982e7a36c 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -47,6 +47,7 @@ #include "hook.h" #include "bundle.h" #include "bundle-uri.h" +#include "credential.h" /* * Overall FIXMEs: @@ -963,8 +964,14 @@ static int path_exists(const char *path) static const char sanitized_url_advice[] = N_( "The URL you provided to Git contains a password. It will be\n" "used to clone the repository, but to avoid accidental disclosure\n" -"the password will not be recorded. Further fetches from the remote\n" -"may require you to provide the password interactively.\n" +"the password will not be recorded in the repository config.\n" +"Since you have no credential helper configured, the \"store\" helper\n" +"has been enabled for this repository, and will provide the password\n" +"for further fetches.\n" +"\n" +"Note that the password is still stored in plaintext in the filesystem;\n" +"consider configuring a more secure helper. See \"git help gitcredentials\"\n" +"and \"git help git-credential-store\" for details.\n" ); int cmd_clone(int argc, @@ -1298,7 +1305,13 @@ int cmd_clone(int argc, if (display_repo && strcmp(repo, display_repo)) { warning(_("omitting password while storing URL in on-disk config")); - advise(_(sanitized_url_advice)); + if (!url_has_credential_helper(display_repo)) { + strbuf_addf(&key, "credential.%s.helper", + display_repo); + git_config_set(key.buf, "store"); + strbuf_reset(&key); + advise(_(sanitized_url_advice)); + } } strbuf_addf(&key, "remote.%s.url", remote_name); git_config_set(key.buf, display_repo ? display_repo : repo); diff --git a/credential.c b/credential.c index a995031c5f5d84..e2698d75cf54ec 100644 --- a/credential.c +++ b/credential.c @@ -695,3 +695,16 @@ void credential_from_url(struct credential *c, const char *url) if (credential_from_url_gently(c, url, 0) < 0) die(_("credential url cannot be parsed: %s"), url); } + +int url_has_credential_helper(const char *url) +{ + struct credential c = CREDENTIAL_INIT; + int ret; + + credential_from_url(&c, url); + credential_apply_config(&c); + ret = c.helpers.nr > 0; + + credential_clear(&c); + return ret; +} diff --git a/credential.h b/credential.h index 5f9e6ff2efef55..1173814cf269a9 100644 --- a/credential.h +++ b/credential.h @@ -301,4 +301,10 @@ int credential_from_url_gently(struct credential *, const char *url, int quiet); int credential_match(const struct credential *want, const struct credential *have, int match_password); +/* + * Return true if feeding "url" to the credential system would trigger one + * or more helpers. + */ +int url_has_credential_helper(const char *url); + #endif /* CREDENTIAL_H */ diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh index ae3287e2f4e7ef..f2fc76ceec259d 100755 --- a/t/t5550-http-fetch-dumb.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -114,7 +114,7 @@ test_expect_success 'username is retained in URL, password is not' ' ! grep pass url ' -test_expect_failure 'fetch of password-URL clone uses stored auth' ' +test_expect_success 'fetch of password-URL clone uses stored auth' ' set_askpass wrong && git -C clone-auth-none fetch && expect_askpass none