Chapter 24 Common remote setups

We only consider a very constrained set of remotes here:

  • The remote is on GitHub, e.g. its URL looks something like https://github.com/OWNER/REPO.git or git@github.com:OWNER/REPO.git.
  • The remote is named origin or upstream. These may not be the most evocative names in the world, but they are the most common choices.

If you use a different host or different remote names, you should still be able to translate these examples to your setting.

Along the way we note how these setups relate to the usethis package, i.e. how usethis can help you get into a favorable setup or how a favorable setup unlocks the full power of usethis. Many of these operations require that you have configured a GitHub personal access token. If you don’t use usethis, feel free to ignore these asides. 2020-06 note: this currently refers to features in a development version of usethis. These features are not in v1.6.1 = the current CRAN version.

24.1 No GitHub

As a starting point, consider a local Git repo that is not yet connected to GitHub.

This is not very exciting, but sets the stage for what’s to come. We introduce the icon we use for a Git repo, which looks like a stack of coins or a barrel. This one is blue, which indicates you have write permission.

usethis::use_git() can create this setup in a local project, i.e. it initializes a Git repo. usethis describes this setup as “no_github”.

24.2 Ours (more specifically, mine)

A common next step is to associate a local repo with a copy on GitHub, owned by you.

A remote named origin is configured and you have permission to push to (and pull from) origin. (That’s why origin is colored blue and there are solid arrows going both directions.) The origin remote on GitHub is what we’ll call a primary repo, meaning it is not a fork (or copy) of anything else on GitHub.

usethis::use_github() can create this setup from a local repository, as long as you have configured a GITHUB_PAT. usethis describes this setup as “ours”.

24.3 Ours

Here is a variation on “ours” that is equivalent in practice.

A remote named origin is configured and you can push to (and pull from) origin. As above, origin is a primary repo, meaning it is not a fork (or copy) of anything else on GitHub. The origin remote is, however, not owned by you. Instead it’s owned by another GitHub user or organisation.

How does this happen?

  1. The primary repo is owned by an organisation and your role in this organisation confers enough power to create repos or to push to this repo.
  2. The owner of the primary repo has added you, specifically, as a collaborator to this specific repo.

Way to get here with usethis:

  • GitHub repo exists first: usethis::create_from_github("OWNER/REPO", fork = FALSE).
  • Local repo exists first: usethis::use_github(organisation = "OWNER").

usethis describes this setup as “ours”.

24.4 Theirs

This is a setup that many people get themselves into, when it’s not actually what they need. It’s not broken per se, but it’s limiting.

You cannot push to the primary repo, which is configured as the origin remote. (This is indicated by the orange color of origin and the greyed out, dashed “push” arrow.) The primary repo is read-only for you.

If you are taking a repo for a quick test drive, this configuration is fine. But there is no way to get changes back into the primary repo, since you cannot push to it and you haven’t created a fork, which is necessary for a pull request.

How does this happen?

  • Cloning the primary repo, either via git clone in the shell or through a Git client, such as RStudio.
  • Calling usethis::create_from_github() when you haven’t configured a GitHub personal access token, which forces fork = FALSE, because we can’t create a fork.

usethis describes this setup as “theirs”.

What if you do want to make a pull request? This means you should have done fork-and-clone instead of clone. If you’ve made no changes or they’re easy to save somewhere temporarily, just start over with a fork-and-clone workflow (see below) and re-introduce your changes. It is also possible to preserve your work in a local branch, fork the primary repo, re-configure your remotes, re-sync up with the primary repo, and get back on track. But this is much easier to goof up.

24.5 Fork (of theirs)

This is an ideal setup if you want to make a pull request and generally follow the development of a primary repo owned by someone else.

This shows a successful “fork-and-clone”. Your local repo can pull changes from the primary repo, which is configured as upstream, which you cannot push to (but you can pull from). You have a fork of the primary repo (a very special copy, on GitHub) and it is configured as origin. You can push to and pull from your fork. You can make a pull request back to the primary repo via your fork.

How do we get here?

usethis::create_from_github("OWNER/REPO", fork = TRUE) can create this setup, as long as you have configured a GITHUB_PAT. usethis describes this setup as “fork”.

24.6 Fork (of ours)

This is a less common variation on the fork setup.

In this case, you have permission to push to the primary repo, but you elect to create a personal fork anyway. Certain projects favor this approach and it offers maximum development flexibility for advanced users. However, most users are better served by the simpler “ours” setup in this case.

usethis::create_from_github("OWNER/REPO", fork = TRUE) can create this setup, as long as you have configured a GITHUB_PAT. usethis describes this setup as “fork”.

24.7 Fork (salvageable)

Here is one last fork setup that’s sub-optimal, but it can be salvaged.

This is what happens when you do fork-and-clone and you only do fork-and-clone. What’s missing is a connection back to the primary repo.

How does this happen?

  • Cloning your own fork, either via git clone in the shell or through a Git client, such as RStudio. And then stopping here.

If you only plan to make one pull request, this setup is fine. When the exchange is done, delete your local repo and your fork and move on with your life. You can always re-fork in the future. But if your pull request stays open for a while or if you plan to make repeated contributions, you’ll need to pull ongoing developments in the primary repo into your local copy.

You can add the primary repo as upstream in the shell or with usethis::use_git_remote(). Next time you do fork-and-clone, consider using usethis::create_from_github(fork = TRUE) instead. In addition to configuring the necessary remotes, create_from_github() implements other config that is favorable for making pull requests.

usethis describes this setup as “fork_no_upstream”.