Is there a way to cache GitHub credentials for pushing commits?

后端 未结 24 3263
囚心锁ツ
囚心锁ツ 2020-11-21 05:02

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 t

相关标签:
24条回答
  • 2020-11-21 05:08

    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: accept gpg 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 recent gpg4win-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.)

    • Trust 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: make PERL_PATH configurable

    Signed-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 the Makefile so that it generates git-credential-netrc from git-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 repo

    Signed-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 that git-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 use credential-store).
    For "read-only" password access, I find the combination of pass 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"
    
    0 讨论(0)
  • 2020-11-21 05:09

    You can also have Git store your credentials permanently using the 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
    
    0 讨论(0)
  • 2020-11-21 05:11

    I know this is not a secure solution, but sometimes you need just a simple solution - without installing anything else. And since helper = store did not work for me, I created a dummy helper:

    Create a script and put it in your users bin folder, here named credfake, this script will provide your username and your password:

    #!/bin/bash
    while read line
    do
      echo "$line"
    done < "/dev/stdin"
    echo username=mahuser
    echo password=MahSecret12345
    

    make it executable:

    chmod u+x /home/mahuser/bin/credfake
    

    then configure it in git:

    git config --global credential.helper /home/mahuser/bin/credfake
    

    (or use it without --global for the one repo only)

    and - voilá - git will use this user + password.

    0 讨论(0)
  • 2020-11-21 05:11

    I got my answer from gitcredentials(7) Manual Page. For my case, I don't have credential-cache in my Windows installation; I use credential-store.

    After I use credential-store, the username/password are stored in [user folder]/.git-credentials file. To remove the username/password, just delete the content of the file.

    0 讨论(0)
  • 2020-11-21 05:13

    OAuth

    You can create your own personal API token (OAuth) and use it the same way as you would use your normal credentials (at: /settings/tokens). For example:

    git remote add fork https://4UTHT0KEN@github.com/foo/bar
    git push fork
    

    .netrc

    Another method is to configure your user/password in ~/.netrc (_netrc on Windows), e.g.

    machine github.com
    login USERNAME
    password PASSWORD
    

    For HTTPS, add the extra line:

    protocol https
    

    A credential helper

    To cache your GitHub password in Git when using HTTPS, you can use a credential helper to tell Git to remember your GitHub username and password every time it talks to GitHub.

    • Mac: git config --global credential.helper osxkeychain (osxkeychain helper is required),
    • Windows: git config --global credential.helper wincred
    • Linux and other: git config --global credential.helper cache

    Related:

    • How to store your GitHub https password on Linux in a terminal keychain?
    • How do I ensure Git doesn't ask me for my GitHub username and password?
    • Configure Git clients, like GitHub for Windows, to not ask for authentication
    • Pushing a local repo to a GitHub repo which has dual-factor authentication
    0 讨论(0)
  • 2020-11-21 05:14

    For Windows you can use the Git Credential Manager (GCM) plugin. It is currently maintained by Microsoft. The nice thing is that it saves the password in the Windows Credential Store, not as plain text.

    There is an installer on the releases page of the project. This will also install the official version of Git for Windows with the credential manager built-in. It allows two-factor authentication for GitHub (and other servers). And has a graphical interface for initially logging in.

    For Cygwin users (or users already using the official Git for Windows), you might prefer the manual install. Download the zip package from the releases page. Extract the package, and then run the install.cmd file. This will install to your ~/bin folder. (Be sure your ~/bin directory is in your PATH.) You then configure it using this command:

    git config --global credential.helper manager
    

    Git will then run the git-credential-manager.exe when authenticating to any server.

    0 讨论(0)
提交回复
热议问题