30 Fork and clone
Use “fork and clone” to get a copy of someone else’s repo if there’s any chance you will want to propose a change to the owner, i.e. send a “pull request”. If you are waffling between “clone” and “fork and clone”, go with “fork and clone”.
30.1 Initial workflow
On GitHub, make sure you are signed in and navigate to the repo of interest. Think of this as OWNER/REPO
, where OWNER
is the user or organization who owns the repository named REPO
.
In the upper right hand corner, click Fork.
This creates a copy of REPO
in your GitHub account and takes you there in the browser. Now we are looking at YOU/REPO
.
Clone YOU/REPO
, which is your copy of the repo, a.k.a. your fork, to your local machine. You have two options:
-
Existing project, GitHub first, an RStudio workflow we’ve used before.
- Your fork
YOU/REPO
plays the role of the existing GitHub repo, in this case – not the original repo! - Make a conscious decision about the local destination directory and HTTPS vs SSH URL.
- Your fork
- Execute
git clone https://github.com/YOU/REPO.git
(orgit clone git@github.com:YOU/REPO.git
) in the shell (Appendix A).- Clone your fork
YOU/REPO
– not the original repo! -
cd
to the desired parent directory first. Make a conscious decision about HTTPS vs SSH URL.
- Clone your fork
We’re doing this:
30.2 usethis::create_from_github("OWNER/REPO")
The usethis package has a convenience function, create_from_github()
, that can do “fork and clone”.
In fact, it goes even further and configures the upstream
remote and sets the upstream tracking branch for main
(or whatever the default branch is) to upstream/main
.
Note that create_from_github()
requires that you have configured a GitHub personal access token.
It hides lots of detail and can feel quite magical.
Due to these difference, we won’t dwell on create_from_github()
here.
But once you get tired of doing all of this “by hand”, check it out!
30.3 Engage with the new repo
If you did “fork and clone” via Existing project, GitHub first, you are probably in an RStudio Project for this new repo.
Regardless, get yourself into this project, whatever that means for you, using your usual method.
Explore the new repo in some suitable way. If it is a package, you could run the tests or check it. If it is a data analysis project, run a script or render an Rmd. Convince yourself that you have gotten the code.
30.4 Don’t mess with master
If you make any commits in your local repository, I strongly recommend that you work in a new branch, not master
.
I strongly recommend that you do not make commits to master
of a repo you have forked.
This will make your life much easier if you want to pull upstream work into your copy. The OWNER
of REPO
will also be happier to receive your pull request from a non-master
branch.
30.5 The original repo as a remote
Remember we are here:
Here is the current situation in words:
- You have a fork
YOU/REPO
, which is a repo on GitHub. - You have a local clone of your fork.
- Your fork
YOU/REPO
is the remote known asorigin
for your local repo. - You are well positioned to make a pull request to
OWNER/REPO
.
But notice the lack of a direct connection between your local copy of this repo and the original OWNER/REPO
. This is a problem.
As time goes on, the original repository OWNER/REPO
will continue to evolve. You probably want the ability to keep your copy up-to-date. In Git lingo, you will need to get the “upstream changes”.
See the workflow Get upstream changes for a fork for how to inspect your remotes, add OWNER/REPO
as upstream
if necessary, and pull changes, i.e. how to complete the “triangle” in the figure above.
30.5.1 No, you can’t do this via GitHub
You might hope that GitHub could automatically keep your fork YOU/REPO
synced up with the original OWNER/REPO
. Or that you could do this in the browser interface. Then you could pull those upstream changes into your local repo.
But you can’t.
There are some tantalizing, janky ways to sort of do parts of this. But they have fatal flaws that make them unsustainable. I believe you really do need to add upstream
as a second remote on your repo and pull from there.