gitstorecred - Store HTTPS Credentials for Git

UPDATE: Thanks to some help from Paul Betts this has been updated to use some new APIs in Git. Check out the blog post on the GitHub Blog for more info!

As you probably know, the ASP.Net team has moved to CodePlex for all of our out-of-band frameworks (MVC, WebPages, WebAPI, etc.). You probably also know that we are using the Git source control system on CodePlex. You may also know that CodePlex only supports the HTTPS transport for Git, which means that a username and password is required every time you push changes to the server:

image

You can bypass the first prompt by adding your remote with “https://username@server.com/path”, and can even bypass the second by using “https://username:password@server.com/path” as the URL, but that’s a really Bad Idea™. So, like most modern systems, Git probably has a way to store these credentials, right?

Nope.

However, it does have an interesting extension point called “AskPass”. If you set the “core.askpass” config setting, or the GIT_ASKPASS environment variable, to the path to an executable, Git will run that executable every time it needs a username or password. It will pass the prompt it would have written to the console as the command line arguments to this program and it expects the program to write the credential it is requesting (username or password) to the standard output stream. We can use this to our advantage!

GitStoreCred is a small tool I created for doing exactly that. It allows you to replace the Git username and password prompt with a standard Windows credential dialog AND it will store those credentials in the Windows Credential Store (if you check the “Remember” checkbox). Let’s see it in action:

image

Much better! Once we enter our credentials, everything works and Git pushes happily to the server. Let’s take a look at the Windows Credential Store now (this is in your Control Panel, go to User Accounts then Credential Manager):

image

See the highlighted entry? That’s my credentials for CodePlex (you’ll see I’ve also got credentials for GitHub there). If I try to push again, git won’t prompt me because gitstorecred just found the existing credential and outputted it.

Enough talking, gimme gimme gimme!

Ok, so you can download gitstorecred from GitHub and you can view the code there too. Just put the exe anywhere and set the GIT_ASKPASS environment variable to it’s full path. I use my PowerShell profile script to do it, since I’m always in PowerShell.

WARNING! HERE BE DRAGONS!

This is super hacky, I literally bashed it up over this weekend. It works, but I make no guarantees. The major known issues are the following:

First, if you type the wrong password, you have to go to Credential Manager (above) and either edit or just remove your credential. Gitstorecred has no way of getting feedback from Git so it doesn’t know that your password was wrong (for example) and will just keep sending the wrong password. If you checked “Remember” then the only way to get it to prompt you again is to remove the credentials.

Second, it doesn’t seem to get in the way of SSH-based pushing, but it might so be careful. If you ever find Git hanging when you run “git push”, just clear out the GIT_ASKPASS setting and try again. It’s entirely possible gitstorecred isn’t responding the way Git expects.

Third, we only store one set of credentials PER SERVER. That means that if you have two user accounts for some reason (say “anurse” and “bnurse”) for some server (say “github.com”), gitstorecred just stores the first one as the credentials for “github.com” and passes them along. Due to some issues with the Windows Credential API I use, it can’t easily key the credential off your user account. For that reason, I highly recommend adding your git remote WITHOUT the user name (i.e. “git remote add https://git01.codeplex.com/aspnetwebstack”). That way gitstorecred will handle the username and password and you won’t get in to weird issues. Of course, the credential store is per windows user, so if you have two separate users on the same machine, they can have different credentials for the same server.

Please do try it out though, the worst that should happen is it won’t work and you’ll have to turn it off. I’m happy to take pull requests to try and make it more powerful/robust (for example, there are better Windows Credential APIs I could use but they are harder to access from Managed Code). With a tool like this, and the fact that Git is much smarter about HTTP pushing now, I’m switching almost exclusively to HTTPS for my Git pushes.

Enjoy! Here’s the links again: Download EXE, Source Code on GitHub.