usethis can help you with many of the Git and GitHub tasks that arise when managing R projects and packages. Under the hood, two lower-level packages are critical to this:
git commit, and
Both packages need access to credentials in order to act on your behalf:
This article describes our recommendations for how to set up your Git and GitHub credentials. Our goal is a setup that works well for usethis and for other tools you may be using, such as command line Git and Git clients (including, but not limited to, RStudio).
Our main recommendations are:
Next we provide some context and a rationale for these recommendations. In the following section, we explain how to actually implement this.
Instead of HTTPS, you could use SSH. Many people have valid reasons for preferring SSH and they should carry on. Our recommendation for HTTPS is because it’s easier than SSH for newcomers to set up correctly, especially on Windows. GitHub has also long recommended HTTPS to new users. Finally, using HTTPS with a PAT kills two birds with one stone: this single credential can be used to authenticate to GitHub as a regular Git server and for its REST API. If you authenticate via SSH for “regular” Git work, you still have to set up a PAT for work that uses the REST API.
Turning on two-factor authentication for important online accounts is just a good idea, in general. For example, we make 2FA a hard requirement for all members of the tidyverse and r-lib GitHub organizations. With 2FA activated, GitHub will no longer let you send “username + password” as the credentials for an operation like
git push1. Instead, you must send “username + PAT”2. By turning on 2FA and using a PAT, you’re following better security practices and future-proofing your workflow.
It’s awkward to provide your credentials for every single Git transaction, so it’s customary to let your system remember your credentials. Git uses so-called credential helpers for this and, happily, they tend to “just work” these days (especially, on macOS and Windows) 3. Git credential helpers take advantage of official OS-provided credential stores, where possible, such as macOS Keychain and Windows Credential Manager.
Recent innovations in gert and gh mean that Git/GitHub operations from R can also store and discover credentials using these same official Git credential helpers. This means we can stop storing GitHub PATs in plain text in a startup file, like
.Renviron 4. This, in turn, reduces the risk of accidentally leaking your credentials.
How do you actually implement these recommendations? Many functions in usethis recommend calling
usethis::gh_token_help(), which displays similar advice and links here.
Make sure to use HTTPS URLs, not SSH, when cloning repos or adding new remotes:
It’s fine to adopt HTTPS for new work, even if some of your pre-existing repos use SSH.
It’s fine to use HTTPS for one remote in a repo and SSH for another.
It’s fine to use HTTPS remotes for one repo and SSH remotes for another.
It’s fine to interact with a GitHub repo via HTTPS from one computer and via SSH from another.
This is not an all-or-nothing or irreversible decision.
As long as the relevant tools can obtain the necessary credentials from a cache or you, you are good to go.
See GitHub’s most current instructions here:
If you don’t already use a password manager such as 1Password or LastPass, this is a great time to start! Among other benefits, these apps can serve as an authenticator for 2FA.
Turning on 2FA is recommended but optional.
You can still get and use a PAT, even if you have not turned 2FA on.
The difference is that, once you’ve activated 2FA, you absolutely must use a PAT as your HTTPS credential.
Assuming you’re signed into GitHub,
create_github_token() takes you to a pre-filled form to create a new PAT. You can get to the same page in the browser by clicking on “Generate new token” from https://github.com/settings/tokens. The advantage of
create_github_token() is that we have pre-selected some recommended scopes, which you can look over and adjust before clicking “Generate token”.
It is a very good idea to give the token a descriptive name, because one day you might have multiple PATs, e.g., one that’s configured on your main work computer and another that you use from a secondary computer or VM. Eventually, you’ll need to “spring clean” your PATs and this is much less nerve-wracking if you know which PAT is being used where and for what.
You must store this token somewhere, because you’ll never be able to see it again, once you leave this browser window. If you somehow goof this up, just generate a new PAT and, so you don’t confuse yourself, delete the lost token.
In the moment, we usually copy the PAT to the clipboard, anticipating what we’ll do next: trigger a prompt that lets us store the PAT in the Git credential store. If you use a password management app, such as 1Password or LastPass (highly recommended!), this is a great time to add your PAT to the entry for GitHub. Storing your PAT in the Git credential store is a semi-persistent convenience, sort of like a browser cache or “remember me” on a website, but it’s quite possible you will need to re-enter your PAT in the future.
At this point, we assume you’ve created a PAT and have it available on your clipboard.
If you don’t have a PAT stored already, it will prompt you to enter your PAT. Paste!
If you do already have a stored credential,
gitcreds::gitcreds_set() reveals this and will even let you inspect it. This helps you decide whether to keep the existing credential or replace it. When in doubt, embrace a new, known-to-be-good credential over an old one, of uncertain origins.
Here are two great ways to check that all is well:
Both of these functions reveal whether a GitHub PAT is discovered and provide information about the associated user, the PAT’s scopes, etc.
This step is something you do once. Or, rather, once per machine, per PAT. From this point on, usethis and its dependencies should be able to automatically retrieve and use this PAT.
Sidebar: the gitcreds package plays the same role for gh as the credentials package does for gert. Both gitcreds and credentials provide an R interface to the Git credential store, but are targeting slightly different use cases. The gitcreds and credentials packages are evolving convergently and may, in fact, merge into one. But in the meantime, there is some chance that they use a different “key”, in the “key-value” sense, when storing or retrieving your PAT. Therefore, it is conceivable that gert/credentials may also prompt you once for your PAT, in which case you should just provide it again. To explicitly check if credentials can discover your PAT, call
credentials::set_github_pat(). If it cannot, this will lead to a prompt where you can enter it.
Most users should be ready to work with Git and GitHub from R now, specifically with gert, gh, and usethis. In this section, we cover more specialized topics that only apply to certain users.
As of v2.0.0, usethis should fully support GitHub Enterprise deployments. If you find this is not true, please open an issue.
There are a few usethis functions that support an explicit
host argument, but in general, usethis honors the GitHub host implicit in URLs, e.g., the locally configured Git remotes, or inherits the default behaviour of gh. The gh package honors the
GITHUB_API_URL environment variable which, when unset, falls back to
In general, usethis, gh, and gitcreds should all work with GitHub Enterprise, as long as the intended GitHub host is discoverable or specified. For example, you can store a PAT for a GitHub Enterprise deployment like so:
At the time of writing,
credentials::set_github_pat() is hard-wired to “github.com”, but this may be generalized in the future.
In the past, the most common way to make a GitHub PAT available in R was to define it as the
GITHUB_PAT environment variable in the
.Renviron startup file. This still works, since gitcreds+gh and credentials+gert check environment variables before they consult the Git credential store. But the
.Renviron approach is less secure and generally unnecessary now. It is safer to keep your PAT in the Git credential store and to let packages that need it to discover it there upon first need.
When gitcreds and credentials retrieve a PAT from the Git credential store, they temporarily cache it in an environment variable, which persists for the duration of the current R session. This means that a discovered PAT can be reused, potentially by multiple packages, over the course of an R session.
If you still want to use the less secure
usethis::edit_r_environ() opens that file for editing.
Add a line like this, but substitute your PAT:
Make sure this file ends in a newline! Lack of a newline can lead to silent failure to load startup files, which can be tricky to debug. Take care that this file is not accidentally pushed to the cloud, e.g. Google Drive or GitHub.
Restart R for changes in
.Renviron to take effect.
On a headless system, such as on a CI/CD platform like GitHub Actions, you won’t be able to interactively store a PAT with
credentials::set_github_pat(). In the case of GitHub Actions, an access token is automatically available to the workflow and can be exposed to R as the
GITHUB_PAT environment variable like so:
If this automatic token doesn’t have sufficient permissions, you’ll need to create a suitable token and store it as a repository secret.
This is also the general approach for CI/CD platforms other than GitHub Actions:
Take care not to expose your PAT by, e.g., printing environment variables to a log file.
gh and gitcreds
gert and credentials
Password authentication is being deprecated at GitHub anyway, so you might as well face the music now.↩︎
In fact, when you send a PAT as the password, the email or username doesn’t actually matter, but you might as well send your username.↩︎
If you’re trying to follow the advice in this article and things don’t work the way we say they do, consider that you may need to update Git. Credential helpers are absolutely an area of Git that has improved rapidly in recent years and the gitcreds and credentials package work best with recent versions of Git.↩︎
An even more dangerous practice is to hard-code a PAT in an R script, which is never a good idea.↩︎
As always, the
usethis.protocol option can be configured to customize your own default.↩︎