Is there a way to cache https credentials for pushing commits?
Solution 1
Since Git 1.7.9 (released 2012), there is a neat mechanism in Git to avoid having to type your password all the time for HTTP / HTTPS, called credential helpers.
You can just use one of the following credential helpers:
git config --global credential.helper cache
The credential.helper cache value tells Git to keep your password cached in memory for a particular amount of minutes. The default is 15 minutes, you can set a longer timeout with:
# Cache for 1 hour
git config --global credential.helper "cache --timeout=3600"
# Cache for 1 day
git config --global credential.helper "cache --timeout=86400"
# Cache for 1 week
git config --global credential.helper "cache --timeout=604800"
You can also store your credentials permanently if so desired, see the other answers below.
GitHub's help also suggests that if you're on Mac OS X and used Homebrew to install Git, you can use the native Mac OS X keystore with:
git config --global credential.helper osxkeychain
For Windows, there is a helper called Git Credential Manager for Windows or wincred in msysgit.
git config --global credential.helper wincred # obsolete
With Git for Windows 2.7.3+ (March 2016):
git config --global credential.helper manager
For Linux, you would use (in 2011) gnome-keyring
(or other keyring implementation such as KWallet).
Nowadays (2020), that would be (on Linux)
Fedora
sudo dnf install git-credential-libsecret
git config --global credential.helper /usr/libexec/git-core/git-credential-libsecret
Ubuntu
sudo apt-get install libsecret-1-0 libsecret-1-dev
cd /usr/share/doc/git/contrib/credential/libsecret
sudo make
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret
Solution 2
You can also have Git store your credentials permanently using git-credential-store as following:
git config credential.helper store
Note: While this is convenient, Git will store your credentials in clear text in a local file (.git-credentials) under your project directory (see below for the "home" directory). If you don't like this, delete this file and switch to using the cache option.
If you want Git to resume to asking you for credentials every time it needs to connect to the remote repository, you can run this command:
git config --unset credential.helper
To store the passwords in .git-credentials
in your %HOME%
directory as opposed to the project directory: use the --global
flag
git config --global credential.helper store
Solution 3
TLDR; Use an encrypted netrc file with Git 1.8.3+.
Saving a password for a Git repository HTTPS URL is possible with a ~/.netrc
(Unix) or %HOME%/_netrc
(note the _
) on Windows.
But: That file would store your password in plain text.
Solution: Encrypt that file with GPG (GNU Privacy Guard), and make Git decrypt it each time it needs a password (for push
/pull
/fetch
/clone
operation).
Note: with Git 2.18 (Q2 2018), you now can customize the GPG used to decrypt the encrypted .netrc
file.
See commit 786ef50, commit f07eeed (12 May 2018) by Luis Marsano (``).
(Merged by Junio C Hamano -- gitster
-- in commit 017b7c5, 30 May 2018)
git-credential-netrc
: acceptgpg
option
git-credential-netrc
was hardcoded to decrypt with 'gpg
' regardless of the gpg.program option.
This is a problem on distributions like Debian that call modern GnuPG something else, like 'gpg2
'
Step-by-Step instructions for Windows
With Windows:
(Git has a gpg.exe
in its distribution, but using a full GPG installation includes a gpg-agent.exe
, which will memorize your passphrase associated to your GPG key.)
-
Install
gpg4Win Lite
, the minimum gnupg command-line interface (take the most recentgpg4win-vanilla-2.X.Y-betaZZ.exe
), and complete your PATH with the GPG installation directory:set PATH=%PATH%:C:\path\to\gpg copy C:\path\to\gpg\gpg2.exe C:\path\to\gpg\gpg.exe
(Note the 'copy
' command: Git will need a Bash script to execute the command 'gpg
'. Since gpg4win-vanilla-2
comes with gpg2.exe
, you need to duplicate it.)
-
Create or import a GPG key, and trust it:
gpgp --import aKey # or gpg --gen-key
(Make sure to put a passphrase to that key.)
-
Install the credential helper script in a directory within your
%PATH%
:cd c:\a\fodler\in\your\path curl -o c:\prgs\bin\git-credential-netrc https://raw.githubusercontent.com/git/git/master/contrib/credential/netrc/git-credential-netrc.perl
(Beware: the script is renamed in Git 2.25.x/2.26, see below)
(Yes, this is a Bash script, but it will work on Windows since it will be called by Git.)
-
Make a _netrc file in clear text
machine a_server.corp.com login a_login password a_password protocol https machine a_server2.corp.com login a_login2 password a_password2 protocol https
(Don't forget the 'protocol
' part: 'http
' or 'https
' depending on the URL you will use.)
-
Encrypt that file:
gpg -e -r a_recipient _netrc
(You now can delete the _netrc
file, keeping only the _netrc.gpg
encrypted one.)
-
Use that encrypted file:
git config --local credential.helper "netrc -f C:/path/to/_netrc.gpg -v"
(Note the '/
': C:\path\to...
wouldn't work at all.) (You can use at first -v -d
to see what is going on.)
From now on, any Git command using an HTTP(S) URL which requires authentication will decrypt that _netrc.gpg
file and use the login/password associated to the server you are contacting.
The first time, GPG will ask you for the passphrase of your GPG key, to decrypt the file.
The other times, the gpg-agent launched automatically by the first GPG call will provide that passphrase for you.
That way, you can memorize several URLs/logins/passwords in one file, and have it stored on your disk encrypted.
I find it more convenient than a "cache" helper", where you need to remember and type (once per session) a different password for each of your remote services, for said password to be cached in memory.
With Git 2.26 (Q1 2020), the sample credential helper for using .netrc
has been updated to work out of the box. See patch/discussion.
See commit 6579d93, commit 1c78c78 (20 Dec 2019) by Denton Liu (Denton-L
).
(Merged by Junio C Hamano -- gitster
-- in commit 1fd27f8, 25 Dec 2019)
contrib/credential/netrc
: makePERL_PATH
configurableSigned-off-by: Denton Liu
The shebang path for the Perl interpreter in
git-credential-netrc
was hardcoded.
However, some users may have it located at a different location and thus, would have had to manually edit the script.Add a
.perl
prefix to the script to denote it as a template and ignore the generated version.
Augment theMakefile
so that it generatesgit-credential-netrc
fromgit-credential-netrc.perl
, just like other Perl scripts.The Makefile recipes were shamelessly stolen from
contrib/mw-to-git/Makefile
.
And:
With 2.26 (Q1 2020), Sample credential helper for using .netrc has been updated to work out of the box.
See commit 6579d93, commit 1c78c78 (20 Dec 2019) by Denton Liu (Denton-L
).
(Merged by Junio C Hamano -- gitster
-- in commit 1fd27f8, 25 Dec 2019)
contrib/credential/netrc
: work outside a repoSigned-off-by: Denton Liu
Currently,
git-credential-netrc
does not work outside of a git repository. It fails with the following error:fatal: Not a git repository: . at /usr/share/perl5/Git.pm line 214.
There is no real reason why need to be within a repository, though. Credential helpers should be able to work just fine outside the repository as well.
Call the non-self version of
config()
so thatgit-credential-netrc
no longer needs to be run within a repository.
Jeff King (peff
) adds:
I assume you're using a gpg-encrypted
netrc
(if not, you should probably just usecredential-store
).
For "read-only" password access, I find the combination ofpass
with config like this is a bit nicer:[credential "https://github.com"] username = peff helper = "!f() { test $1 = get && echo password=`pass github/oauth`; }; f"
Solution 4
Use a credential store.
For Git 2.11+ on OS X and Linux, use Git's built in credential store:
git config --global credential.helper libsecret
For msysgit 1.7.9+ on Windows:
git config --global credential.helper wincred
For Git 1.7.9+ on OS X use:
git config --global credential.helper osxkeychain
Solution 5
There's an easy, old-fashioned way to store user credentials in an HTTPS URL:
https://user:[email protected]/...
You can change the URL with git remote set-url <remote-repo> <URL>
The obvious downside to that approach is that you have to store the password in plain text. You can still just enter the user name (https://[email protected]/...
) which will at least save you half the hassle.
You might prefer to switch to SSH or to use the GitHub client software.
Zepplock
Updated on July 08, 2022Comments
-
Zepplock almost 2 years
I recently switched to synchronizing my repositories to https:// on GitHub (due to firewall issues), and it asks for a password every time.
Is there a way to cache the credentials, instead of authenticating every time that
git push
?-
VonC over 10 yearsYou now can use a credential helper to encrypt the
_netrc
file containing your credentials. See my answer below. I found that safer that thegit-credential-winstore.exe
(memory cache) which is a bit buggy on Windows. -
Admin over 10 years
-
Colonel Panic about 2 yearsA secure user-friendly alternative to SSH or personal access tokens is OAuth via Git Credential Manager, see my answer stackoverflow.com/a/71286601/284795
-
-
dazonic almost 12 yearsDon't store your password in plain text. As of Git 1.7.9 you can use credential helpers.
git config --global credential.helper osxkeychain
on OS X. For other OS see help.github.com/articles/set-up-git -
Contango over 11 yearsOn Windows, you can download a helper utility configures things to store an encrypted version of your GIT password in the Windows Creditial Store, see confluence.atlassian.com/display/STASH/…
-
synthesizerpatel about 11 yearsFWIW, the osx keychain stuff is part of base GIT source code, it's not an exclusive component of Brew or MacPorts or whatever the flavor of the month is. And you don't even need to build git from scratch - just cd contrib/credential/osxkeychain/ and run make.
-
Rag about 11 yearsI found that I had to specify --global or it would try to store the settings in the current repository:
git config --global credential.helper store
-
poolie almost 11 yearsMake sure to also
chmod 0600 ~/.netrc
. -
Michael J. Calkins over 10 yearsWhy would do the cache instead of storing permanently? Sharing computers or something?
-
chovy over 10 yearsis the osxkeychain only for
https
repos urls? or does it work also when usingssh
repos urls + keys? -
sunny over 10 yearstrying the same thing on linux .. git config --local credential.helper "netrc -f /home/me/.netrc.gpg -v -d" ..and i get "git : 'credential-netrc' is not a git command. see 'git --help'"
-
VonC over 10 years@sunny That is what the
curl -o c:\prgs\bin\git-credential-netrc https://raw.github.com/git/git/master/contrib/credential/netrc/git-credential-netrc
is for: you need to copy thegit-credential-netrc
anywhere in your path ($PATH
), in order for git to be able to call 'credential-netrc
'. -
Russell Stuart about 10 yearsWith two factor authentication you have to use what github calls a Person Access Token. In fact you should always use one, as unlike a password you can control what access it gives. Just replace the password in the url so you end up with
https://username:[email protected]/username/project.git
. It makes plain text passwords stored on disk almost safe enough to use. -
Dan Albert about 10 years@chovy The osxkeychain credential helper is unnecessary if you're using ssh. Instead, you can use ssh-agent. If you're using a Linux desktop or OS X, the keyring should automatically pick up the ssh key passphrase for you (you may need to run
ssh-add
). Windows can use Pageant if you have PuTTY. If you're using Linux in a headless environment, there's a little more set up required, but you can easily find a guide on Google. -
Victor Eijkhout almost 10 yearsHm "store permanently using the following" after what? I'm getting an error that it can't lock ".git/config". Who creates that file?
-
StarNix almost 10 years@VictorEijkhout - use the command from within the repository directory or use the global option as Brian Gordon suggested a couple of comments above.
-
osirisgothra almost 10 yearsinstead of storing maybe it would be better to just cache it at some long value for like a week or two, to figure out the maximum that it will allow use the largest values first, if you dont then you wont know if that value was accepted. I've successfully set the timeout to 99999 which is about 11 days, I'm not sure what the max is, but most programmers elect to align values on the byte (powers of 256) or metric boundary (powers of 10), metric is more likely for text-stored values. Use git config --global --get-all credential.helper to find out your current value(s).
-
laggingreflex almost 10 years@dazonic Would the password that is stored in my local .git directory be accessible by anyone else who clones from my github? In other words, would the password stored in plain text ever leave my machine?
-
dazonic almost 10 years@laggingreflex if you're using credential helper, it's not stored in plain text in .git, it's stored in the OS's password keychain which is encrypted. It won't even leave your machine, no.
-
laggingreflex almost 10 years@dazonic No I meant in plain text file (using
you:password@
URL)? When it's stored in my .git directory, and I push updates, and then someone else pulls it from remote, do they have the text file that has my password (you:password@
URL)? -
dazonic almost 10 years@laggingreflex no.
.git/config
isn't pushed up. But it's still bad practice to store plain text passwords locally. -
Dan Ochiana over 9 yearsbest solution. Thanks.
-
Charan over 9 yearsIt is number of seconds ... Some genius updated it as milliseconds and everyone approved it without checking. Please don't mislead people if you don't know the answer. Thanks!
-
Notinlist over 9 yearsCan you give a link to a place where
store
,cache
and other common things are listed and explained? -
Jorge_Freitas over 9 years
git config --global credential.helper cache
doesn't work on windows: stackoverflow.com/questions/11693074/… use gitcredentialstore on Windows an be happy -
zacharydl over 9 yearsJust want to leave a link here to the Ubuntu netrc manpage. I needed to create it for another user (/home/git/.netrc) then change ownership to that user.
-
Iulian Onofrei about 9 yearsWell, the
_netrc
didn't work for me on aWindows 7
PC, but the.netrc
worked for youtube-dl with the--netrc
argument passed to it. -
Charles Oppermann almost 9 yearsNot certain what this answer has to do with the original question.
-
sudo almost 9 yearsAny way to set this timeout to infinity?
-
jFrenetic over 8 years@BrianGordon I'm using GIT 1.9.5 on Windows, and
--global
flag was redundant. Even without this flag, the credentials file was created in%USER_HOME%
directory. -
Bulma over 8 yearsIt means after 3600 seconds , we have to input password again ??? How to save them permanently ?
-
Asped over 8 yearsMaybe you can try a very big number, like 999999999
-
quadroid over 8 years'git config --global credential.helper store' does store the password. git-scm.com/docs/git-credential-store/1.7.12.1
-
PlantationGator over 8 years$ git config credential.helper 'cache --timeout=3600' error: could not lock config file .git/config: No such file or directory
-
PlantationGator over 8 yearsThis worked: git config --global credential.helper 'cache --timeout=3600'
-
Rosdi Kasim over 8 yearsFast forward to 2015, this should no longer recommended because the password is not encrypted. Please refer to this answer instead: stackoverflow.com/a/32470658/193634
-
crisron over 8 yearsUbuntu users can try this gnome-keyring-helper
-
MrTux over 8 yearsThe username/password might need to be encoded, see stackoverflow.com/a/34611311/3906760
-
Cruncher about 8 yearsif not storing in plain text, what is it protected with? Your password? Wouldn't it then have to ask you for your admin password when you connect to git? Isn't having to enter a password to get another password a little strange?
-
socom1880 about 8 yearsFollow-up on @osirisgothra answer: Just set a very long timeout.
git config --global credential.helper "cache --timeout=9999999999"
. That worked for me and is 317 years. -
eQ19 about 8 yearsWhen you don't have credential-cache in your windows, I would suggest to use
git config --global credential.helper wincred
this store the password permanently. -
Tarun Gupta about 8 yearsit will work you have to escape @ with %40 in your email id
-
killjoy almost 8 yearsWhat if we have a '+' in the email id ? I tried the same escape but the push said 'repo not found'
-
Tarun Gupta almost 8 yearshave %2B instead of +
-
hfrmobile almost 8 years"git config --global credential.helper wincred" worked fine for me under Windows 10. At the first time you have to enter the credentials, but 2nd, 3rd etc. it works as expected.
-
sudo almost 8 yearsWell... I just use the git cache (with timeout 999999999999) because it's just one command I can enter once without any moving parts. I've had a bad time trying to make SSH keys work in the past.
-
VonC over 7 yearsFor Git for Windows 2.7.3 (March 2016): github.com/git-for-windows/git/releases?after=v2.8.4.windows.1, that would be
git config credential.helper manager
instead -
Stéphane Laurent over 7 yearsWorks for me with
helper = manager
(but I'm asked for username+repo for the first push). -
codepleb over 7 yearsI'm sure that this is the way to go, but I get an error sadly:
git: 'credential-gnome-keyring' is not a git command. See 'git --help'.
-
actual_kangaroo over 7 years@TrudleR I updated my answer to recomend upgrading git to
2.11
and then usinggit config --global credential.helper libsecret
it appears that gnome-keyring is deprecated stackoverflow.com/questions/13385690/… -
codepleb about 7 yearsThanks, but I get the same error somehow. Am I doing something wrong? I type the command and nothing happens. As soon as I push, I'm asked for the credentials, which I successfully insert, but I get the error, that it is not a git command after doing that.
-
Sergiy Ostrovsky about 7 years
git config --global credential.helper cache
didn't work for me on Ubuntu either. -
PapaDiHatti about 7 yearswith helper=manager I am getting error credential-manager is not a git command
-
Lavamantis about 7 yearsBefore libsecret will work on Linux, you need to do these steps: stackoverflow.com/a/40312117/775800
-
Lavamantis about 7 yearsOne other thing - if you have 2FA enabled on Github, your password won't work. But you can create a personal access token on your Github "Settings" page and that token works as your password. github.com/github/hub/issues/822
-
VonC almost 7 yearsI agree. Simple (if unsecure) solution indeed. +1, as long as you know what you are doing.
-
Triynko over 6 yearsCare to mention the fact that this does jack shit unless you call another specific command to use the 'cache' as the manager first? This stuff is so cryptic, all of these answers are incomplete, and none of them work. Incredibly frustrating. See this instead: stackoverflow.com/a/24800870/88409
-
Triynko over 6 yearsthe level of complexity involved in these tools in 2017 is insane. This command-line stuff should have went out with the 1980's. Git config credential-manager=wincred??? wtf. and this .bash_history file in your user folder stores all the passwords you ever typed in bash in plaintext. insane.
-
cjs about 6 yearsSecurity Issue: the Windows credential manager stores your password in plaintext accessible to anybody logged in to your Windows account. All they need to do is send a request to the credential manager such as
printf "protocol=https\nhost=git.mycompany.com\n" | git credential-manager get
(more details here). You should always use a personal access token with this, and of course use 2FA on your GitHub account. -
cjs about 6 yearsSecurity Issue: the Windows credential manager makes your plaintext password accessible to anybody logged in to your Windows account. All they need to do is send a request to the credential manager such as
printf "protocol=https\nhost=git.mycompany.com\n" | git credential-manager get
(more details here). You should always use a personal access token with this, and of course use 2FA on your GitHub account. -
cjs about 6 yearsAnybody logged into your account does have easy access to the plaintext of the password. All they need to do is send a request to the credential manager such as
printf "protocol=https\nhost=git.mycompany.com\n" | git credential-manager get
(more details here). You should always use a personal access token with this, and of course use 2FA on your GitHub account. -
Admin about 6 yearsMy version of git on macOS seems to support osxkeychain
git version 2.14.3 (Apple Git-98)
-
Avamander about 6 yearsUnfortunately git ignores the password in the config file. .git_credentials with credential.store is the only option.
-
FeRD almost 6 years@Triynko That's why you don't type passwords on the command line. Any decent command-line tool which handles passwords either doesn't take them on the command line, or strongly discourages it. It's always recommended to provide credentials interactively. You run the command, it prompts
Password:
, and no other process sees what you enter. Anyone who uses passwords in shell commandlines deserves what they get. (Shows up inps
while the command is running, too.) But, those of us who don't freak out at the mere sight of a command prompt learned that way back in the 1990s. -
Peter Mortensen over 5 yearsWill this work inside a Docker container (based on
windowsservercore
)? -
reducing activity over 5 yearsStoring password in plaintext and easily accessible one may not be the optimal solution.
-
Ben Yitzhaki about 5 yearswhen using 2 way authentication, you use the "access token" as the password. the username stays the same as always
-
tripulse over 4 years@sudo, to set the timeout to ~(Infinity) you should mess up with the Integer, set it to
-1
it should be in the maximum value. -
sudo over 4 years@nullptr I wouldn't rely on that unless it's documented behavior. Maybe your version of git does that, dunno if all of them do.
-
tripulse over 4 yearsWell, time is always positive and never negative. So,
git
should be using a Unsigned Integer to store the timeout. For understanding purposes see this example, it explains the trick. -
tripulse over 4 yearsIf timeout is set to the maximum positive value then it would last about
~138
years. Which might be a bit unrealistic. -
Gwyneth Llewelyn about 4 years@VonC the current URL seems to be
https://raw.githubusercontent.com/git/git/master/contrib/credential/netrc/git-credential-netrc.perl
(piping in seven years later 😉) -
VonC about 4 years@GwynethLlewelyn Thank you. I have edited the answer accordingly. Don't hesitate to edit it yourself if you see any other obsolete information.
-
Gwyneth Llewelyn about 4 years@VonC all looks great to me — awesome update on the original answer, BTW! Well done :-)
-
jdhao over 3 years@NeilChowdhury that is not true. According to the official doc, by default, the password will be kept for 15 min. Do not spread ungrounded words like this!
-
aldokkani over 3 yearsCan you add how to do it on linux? Beacuse it not clear at all what you are doing here.
-
VonC over 3 years@aldokkani Sorry for the delay, I was at work. This old (2013) answer was for Windows, at a time it did not benefit from a good credential helper (like the ones for Linux). I would not use it today, where GCM4W exists: github.com/microsoft/Git-Credential-Manager-for-Windows. I have edited Mark Longair's answer to add Linux updated credential helpers: stackoverflow.com/posts/5343146/revisions
-
cchwala over 3 yearsSimple but great answer! This worked for me out of the box on openSUSE 13.2, even though it seems to be a fairly old installation.
-
truthadjustr about 2 yearsI like this solution. It is the best. No hassle, no frazzle.