You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
How to use credentials from git-credential helper #4873
Is it possible to make libgit2 authenticate using credentials that the user has previously stored via the command line git? Specifically Git for Windows defaults to storing credentials in Git Credential Manager for Windows which speaks the credential helper protocol.
I think this involves shelling out to git credential fill but maybe there is more to it. Is there an example that implements something like this? A git_cred_ helper function would also be very useful.
As you've noted, this isn't something that we have built-in support for - we don't exec programs directly for a plurality of reasons. But indeed, it should be relatively straightforward to call out to the git credential fill command from a credential callback.
We do have an example of credential callbacks but we don't have an example for one that exec's something.
So for future reference, to get credentials from e.g. github.com the callback needs to invoke a shell command equivalent to this:
printf"protocol=https\nhost=github.com\n"| git credential fill
If credential for the given host is stored, those are returned, and otherwise the user is prompted for a username/password. The output is then printed to stdout like this:
I already wrote a (GPLed) framework executing external commands from libgit2 (for filters and ssh; cf. https://gitlab.com/tortoisegit/tortoisegit/tree/master/src/libgit2). I haven't found the time for extending it for the credential API, yet, but I'm open for contributions.
So for future reference, to get credentials from e.g. github.com the callback needs to invoke a shell command equivalent to this:
printf"protocol=https\nhost=github.com\n"| git credential fill
If credential for the given host is stored, those are returned, and otherwise the user is prompted for a username/password. The output is then printed to stdout like this:
To adapt this to a windows C/C++ environment, I needed to use _popen("git credential fill < temp_file.txt", "r"), which opens a pipe to read the stdout output of git credential fill. The temp_file.txt was previously populated with
protocol=https
host=github.com
The reason I used a file instead of piping it in on the command line is passing input and reading output on the same pipe is not possible. The output string was constructed by reading from the pipe using fgets. Don't forget _pclose() as well.
Activity
ethomson commentedon Oct 31, 2018
As you've noted, this isn't something that we have built-in support for - we don't exec programs directly for a plurality of reasons. But indeed, it should be relatively straightforward to call out to the
git credential fillcommand from a credential callback.We do have an example of credential callbacks but we don't have an example for one that exec's something.
jeroen commentedon Oct 31, 2018
So for future reference, to get credentials from e.g.
github.comthe callback needs to invoke a shell command equivalent to this:If credential for the given host is stored, those are returned, and otherwise the user is prompted for a username/password. The output is then printed to stdout like this:
Which you can then feed back to git_cred_userpass_plaintext_new in the callback.
csware commentedon Jan 3, 2019
I already wrote a (GPLed) framework executing external commands from libgit2 (for filters and ssh; cf. https://gitlab.com/tortoisegit/tortoisegit/tree/master/src/libgit2). I haven't found the time for extending it for the credential API, yet, but I'm open for contributions.
connorjak commentedon Oct 16, 2024
To adapt this to a windows C/C++ environment, I needed to use
_popen("git credential fill < temp_file.txt", "r"), which opens a pipe to read the stdout output of git credential fill. The temp_file.txt was previously populated withThe reason I used a file instead of piping it in on the command line is passing input and reading output on the same pipe is not possible. The output string was constructed by reading from the pipe using
fgets. Don't forget_pclose()as well.