122

I just enabled 2FA (I can't think of any other changes I made) and git asked for my username and password. I provided both, but they were "wrong". I tried many of the solutions here: Git push requires username and password but that didn't work. In particular, when switching from https to ssh, the ssh key gives

Permission denied (publickey). fatal: Could not read from remote repository.

$ git push
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Username for 'https://github.com': **********
Password for 'https://mlbileschi@github.com': 
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/mlbileschi/scala.git/'

Any tips?

Community
  • 1
  • 1
Max Bileschi
  • 1,618
  • 2
  • 15
  • 18
  • 1
    "Permission denied (publickey). fatal: Could not read from remote repository." is a separate issue which can be solved by setting up an SSH key for your account: https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/ – Ajedi32 Oct 21 '16 at 17:14
  • 1
    often times this is not a 2FA issue but instead resolved by changing from https to git – SCBuergel Mar 12 '20 at 18:22
  • If you just setup GitHub CLI, this problem goes away, and you are not asked for authentication anymore. Install and authenticate GitHub CLI (`gh`) and the problem goes away. First, download GH CLI using the instructions from [the project README](https://github.com/cli/cli#installation), and then follow the [manual](https://cli.github.com/manual/) to authenticate it. Follow the instructions in the terminal, and when GH CLI has finished authenticating, you don't require a password anymore for `git push`. – truth May 05 '21 at 19:05

10 Answers10

163

You need to generate an access token. You can create one by going to your settings page.

enter image description here

Use this access token as your password in the command line.

brianlmerritt
  • 2,095
  • 1
  • 27
  • 36
Gergo Erdosi
  • 36,694
  • 21
  • 106
  • 90
  • hm, i tried that after set-url to https, and it didn't work. I also tried set-url back to ssh, and removing the .ssh/known_hosts entry, but to no avail. – Max Bileschi Aug 29 '14 at 14:44
  • Can you add the command line output to your question? Including the commands you are executing. – Gergo Erdosi Aug 29 '14 at 18:23
  • I had some weird issue where I had to begin a clone and input my new access token. After this (without even waiting for the clone to finish) I was able to give my new access token to my original directory that I was trying to run `git pull` in. Probably a local issue, but this might help someone. – s g Nov 11 '15 at 23:24
  • I get `The requested URL returned error: 403` when I use the token for password, for a push over https – stelios Aug 21 '18 at 15:05
  • so just from a security standpoint: if someone gets hold of my local copy of the repo and subsequently the remote url, he or she can access the github account and if I would not know about there would be no way for me to revoke the key in time? Wouldn't it be safer to not cache passwords at all? – niid Sep 16 '20 at 20:56
47

An end-to-end solution takes 3 steps.

  1. Kudos to Gergo Erdosi. His answer is largely right, it is just that Github changes that setting page. As of late 2016, you need to generate an access token from your Personal access tokens page.

    enter image description here

    Use this access token as your password in the command line.

  2. You can persist your user name by including it into your project remote url. One of the way to do it is to edit your .git/config to modify the url line into the following format:

    url = https://YOUR_USERNAME_HERE@github.com/owner/repo.git

  3. You can persist your password by run this for one time only:

    $ git config credential.helper store

    and then your future git password(s) will be stored in ~/.git-credentials, in plaintext, using the format https://user:PlaintextPassword@example.com.

    Storing password(s) in plaintext would normally be considered as a security risk. But in this 2FA case, the credential is NOT your real password, it is a randomly generated string. So it is as secure as using a ssh private key a passphrase-less ssh private key. CAVEAT: keep in mind that, if you happen to also use another git account(s) without 2FA on this machine, those real password(s) will also be stored in plaintext.

PS: Alternatively, you could choose to use ssh-based login, using a passphrase-protected ssh private key, which would be more secure and less convenient, but it is outside the scope of this answer.

RayLuo
  • 12,405
  • 4
  • 73
  • 65
  • 1
    this worked for me and enabled me to not have to type un and pw everytime i interact with git. i use windows with cygwin and was never able to get the ssh keys to work - this does! – liltitus27 Apr 04 '17 at 16:37
  • about last para: `...the credential is NOT your real password, it is a randomly generated string. So it is as secure as using ssh private key.` — **it is not true at all**. SSH keys could be easy protected by **passphrase** out of the box. Plain `~./git-credentials` ­— is not secured at all! – maxkoryukov Apr 13 '17 at 00:20
  • moreover, this API KEY stored in plaintext file allows to: **access GitHub API** (depends on scope, but probably, everybody who have apikey will have an access to repo's source code) and **perform any** git operation (push, pull). In other words, such _plaintext_ file is a awesome gift, especially, if you have an access to private repositories (probably, they will become public very soon) – maxkoryukov Apr 13 '17 at 02:40
  • @maxkoryukov OK, how about I rephrase the last sentence as "as secure as using a passphrase-less ssh private key"? Because the whole point of step 3 is trying to bypass the prompt for a password (assuming you are working on your own computer, of course). In such case, if someone manages to get a hold of your ~/.git-credentials OR your passphrase-less ssh private key, the consequence would be the same. I do agree with you that a passphrase-protected ssh key would be more secure (and less convenient). – RayLuo Apr 13 '17 at 21:20
  • @RayLuo, LGFM;) – maxkoryukov Apr 15 '17 at 19:49
  • If I use that token as the password over 'https' I get 403, the rest of the answer is irrelevant with the question – stelios Aug 21 '18 at 15:29
  • @chefarov The token generated by step 1 WOULD work and apparently 15 other people also confirmed that (by up-voting). If you encountered http 403, that was probably a copy-and-paste error that you need to check from your side. And, if you could manage to accomplish step 1, you would then realize how step 2 and 3 are surprisingly relevant to help you prevent those cheap error in the first place. Hopefully, at that time you would revoke your down-vote. – RayLuo Aug 22 '18 at 18:17
  • @RayLuo Thanks for the answer. It's not a copy-paste error, I use `git remote -v` to be sure about repo urls, and I have also added all permissions to the token. I have apparently revoked it and do again that process. It seems like a github bug, I will report it. Maybe I shouldn't have downvoted all those similar answers like yours but I can't undo (SO setting). – stelios Aug 22 '18 at 19:07
  • One note for Windows users: If you've already stored your login / password in **Windows Credential Manager** during your first push / pull without 2FA enabled yet. Git continues to use them even after you enabled 2FA. That's why you have to replace your current password with **Private Access Token** in 'Windows Credential Manager'. Go to path in the File Explorer `Control Panel\All Control Panel Items\Credential Manager`, find your github / gitlab / etc. credentials and change password. After that you will no need to use your token as plain text of URL. – hotenov Oct 10 '20 at 08:18
17

I had a similar problem. I had to alter the url used in the git command to include my username.

git push https://YOUR_USERNAME_HERE@github.com/mlbileschi/scala.git

Then when it asks for PW use the access token you created from following the instructions in Gergo Erdosi's answer.

Jester
  • 261
  • 2
  • 7
16

You can set an SSH key (on both Linux and Windows)

Note for Windows users
Make sure HOME environment variable is defined and set on your user's directory
e.g. C:\Users\jossef (learn more)


1) Generating a new SSH key (source)

Open terminal / cmd and paste the text below, (replace with your GitHub email address)

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

2) Link the public key to your GitHub account

  • On Linux / macOS, run in terminal:

    cat ~/.ssh/id_rsa.pub
    
  • On Windows, run in cmd:

    type %HOME%\.ssh\id_rsa.pub
    

This will output the public key:

ssh-rsa AAAAB3NzaC1y ... mKAKw== your_email@example.com

Navigate to https://github.com/settings/keys

  • Click New SSH Key
  • Give it a title
  • Copy-paste the public key from the previous command output

enter image description here


3) Change git origin from https:// to ssh

Open terminal / cmd and cd to your cloned repository directory and run:

git remote set-url origin git@github.com:<github username>/<repository name>
Jossef Harush
  • 24,765
  • 7
  • 95
  • 103
  • 1
    True, but irrelevant with the question. Authenticated via `https` is sometimes usefull, e.g when keeping upstream over `https` while having your fork over `ssh`, so that you avoid accidentally pushing to upstream, since `https` will ask for the password and remind you that you targeted the wrong repo – stelios Aug 21 '18 at 15:21
6

If you are already using ssh keys, after enabling 2FA it will enforce you to read/write remote with SSH. You don't really need to add personal tokens rather keep using your existing SSH key pair.

Just change your remote url from HTTPS to SSH:

git remote set-url origin git@github.com:<github-username>/<repo-name>
Sakhi Mansoor
  • 6,103
  • 4
  • 17
  • 31
3

This worked for me:

  • Go to [your-git-repo]/.git/config

  • Under [remote "origin"] Change the URL key from http protocol to git.

Example

If the value of url is https://github.com/.git change it to git@github.com:<repo-url>.git

imsinu9
  • 664
  • 7
  • 12
1

This worked for me after enabling 2FA on Github:

  1. Create a Personal Access Token: https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line.
    NOTE: Remember to select the correct permissions for the token.

  2. Run:
    git clone https://github.com/username/repo.git
    Username: your_username
    Password: your_token

Further reading: https://help.github.com/en/github/using-git/which-remote-url-should-i-use

Ofek Hod
  • 2,122
  • 9
  • 21
ravikcm
  • 11
  • 3
1

2021 update

Not sure if this is going to work for everyone but updating my git version from 2.27.0 to the latest one (currently 2.30.0) solved my issue, whereas trying to use a personal access token as a password in the command line didn't.

After the update, when trying to push, I was prompted to login into GitHub through the browser, instead of typing my credentials in a dialog or in the command line.

Yulian
  • 4,544
  • 5
  • 46
  • 69
0

I was facing this problem on existing repo when I enabled 2FA(two factor authentication) for one of my private repos. I was able to solve it following below steps on my ubuntu 19.0 terminal:-

  1. Add your ssh key to github so that you dont need to use your password again,as now you have enabled 2FA.Visit github page to know how to do it easily.
  2. Once key is added, go to your terminal, and update the origin url

    git remote set-url origin git@github.com:<USERNAME>/<BRANCH-NAME>

Thats it.Hope it helps

Milind
  • 4,136
  • 1
  • 21
  • 51
0

I came across this issue when switching to an old laptop. Really the issue was just that I was running an old version of git. Once I updated to the most recent version of git with the new cross platform credential manager it was able to sign me w/ 2FA perfectly fine (looks like it automatically creates a PAT for you).

Jason Masters
  • 101
  • 2
  • 7