diff --git a/CHANGELOG.md b/CHANGELOG.md index 0009547a90..5097749db9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * The username and hostname that appear in the operation log are now configurable via config options `operation.username` and `operation.hostname`. +* `jj git` subcommands now support credential helpers. + ### Fixed bugs * (#463) A bug in the export of branches to Git caused spurious conflicted diff --git a/docs/git-compatibility.md b/docs/git-compatibility.md index ced37c07e6..4e8b52ebcc 100644 --- a/docs/git-compatibility.md +++ b/docs/git-compatibility.md @@ -20,8 +20,8 @@ a comparison with Git, including how workflows are different, see the you miss any particular configuration options. * The configuration of remotes (`[remote ""]`). * `core.excludesFile` -* **Authentication: Partial.** Only `ssh-agent` or a password-less key file at - `~/.ssh/id_rsa` (and only at exactly that path). +* **Authentication: Partial.** Only `ssh-agent`, a password-less key file at + `~/.ssh/id_rsa` (and only at exactly that path), or a `credential.helper`. * **Branches: Yes.** You can read more about [how branches work in Jujutsu](branches.md) and [how they interoperate with Git](#branches). diff --git a/lib/src/git.rs b/lib/src/git.rs index d5a846f1bb..56190c0d2f 100644 --- a/lib/src/git.rs +++ b/lib/src/git.rs @@ -553,7 +553,12 @@ impl<'a> RemoteCallbacks<'a> { // TODO: We should expose the callbacks to the caller instead -- the library // crate shouldn't read environment variables. callbacks.credentials(move |url, username_from_url, allowed_types| { - if let Some(username) = username_from_url { + let git_config = git2::Config::open_default(); + let credential_helper = git_config + .and_then(|conf| git2::Cred::credential_helper(&conf, url, username_from_url)); + if let Ok(creds) = credential_helper { + return Ok(creds); + } else if let Some(username) = username_from_url { if allowed_types.contains(git2::CredentialType::SSH_KEY) { if std::env::var("SSH_AUTH_SOCK").is_ok() || std::env::var("SSH_AGENT_PID").is_ok()