# Managing code with git and GitHub

## What is git and GitHub and how do they help us?

Coding and analyzing data are complex tasks. We often need to try different approaches, step away from our code for a while, or share code with others to get their input and collaboration. We might often find ourselves in a situation like this: we make a script, say `analysis.R`, and then revise it based on feedback, but we don't want to loose our old work, so we call the new version `analysis_v2.R`. Then we can't figure out how to make a plot we want, so we email it to a friend, they edit it and send back a new file called `analysis_v2_ajr-edits.R`. We resolve those edits and add some other code and save the file with the date so we remember where we were: `analysis_2025-01-28.R`. But then we don't get a chance to work on the analysis again for two months. By that time, we can't remember if `analysis_v2.R` is the right version or `analysis_v2_ajr-edits.R` or `analysis_2025-01-28.R`. You can't even remember exactly what the edits were and why you needed them.

Avoiding this situation is the job for git and GitHub. Git is a kind of version control software that runs locally on your computer and tracks changes to files. Those files live in a project folder (usually called a "repo" short for "repository"). GitHub is a web-based platform that hosts git repositories online, allowing you to back up your work, share it with others, and contribute to others' projects too.

Together, git and GitHub help us in several ways. They provide a complete history of our work. Every change we make is recorded with a timestamp and a description we write about what is important in that change. If we make a mistake or want to try something experimental, we can easily revert back to an earlier version. GitHub and git facilitate collaboration. Multiple people can work on the same project simultaneously, and git helps merge their contributions together. Given the web-based hosting and backup, this is kind of like google docs for code (but a little less automated because we manually document and describe changes). GitHub makes it easy to share code, review changes, and give and receive feedback. The feedback bit is shockingly helpful via a tool called "issues" which we will discuss in the Workflow section. Hosting code on GitHub is also a real way to work toward open and reproducible science. Anyone can see exactly how we carried out our analysis.

As another important motivator: we will use git and GitHub for all class assignments moving forward.

## Using git and GitHub with help from RStudio

To start working with git and GitHub we will need to make a free GitHub account and to install the actual git software on our computers.  Here are external instructions for those tasks:

1. [make a free GitHub account](https://docs.github.com/en/get-started/start-your-journey/creating-an-account-on-github){target="_blank"}; no need to follow the "Next steps" (although eventually you should set up 2FA)
2. downloaded and installed git (click on your operating system [here](https://git-scm.com/install/){target="_blank"} for instruction)

Instead of step (2), if you think you have done this before, check if git is already on your machine by opening the terminal (from RStudio is fine) and run this command:

```bash
git --version
```

You will see a version number if git is available, you will see an error if it is not.

Now we can integrate git, GitHub, and RStudio. This is not necessary for using git and GitHub but it makes the experience easier, especially because we are already using RStudio.


We will use two R packages to help us connect RStudio and GitHub: *usethis* and *gitcreds*. Let's install those packages by typing the following in the R console

```{r}
#| eval: false

install.packages("usethis")
install.packages("gitcreds")
```

A common problem has been that *usethis* has a dependency on the package *crayon* which is currently not playing nice.  If you have errors involving *crayon* try this:

```{r}
#| eval: false

install.packages("crayon", type = "source")
install.packages("usethis")
```

Now we can use functions from those packages to help us continue.  First we use *usethis* to set up a personal access tokin that will serve as our login credential with GitHub.  We do that by typing this into the R console:

```{r}
#| eval: false

library(usethis)
create_github_token()
```

That should open up a web browser page where you might be promoted to log into your GitHub account. Do that and then on the next page scroll to the bottom and click the "Generate token" button.  You will then see on a new page a string of numbers and letters---that's the token. Copy that token and paste it somewhere temporarily, like a blank text editor document or a blank R script, where you paste it doesn't matter---you'll soon delete it.

Now come back to RStudio and run the following in the R console:

```{r}
#| eval: false
 
library(gitcreds)
gitcreds_set()
```


This will prompt you to enter a password or token; now you can paste the token you just generated here and hit enter.  You should now be good to go!

It's possible you've already gone through this process.  If that's the case you'll see this:

```
-> Your current credentials for 'https://github.com':

  protocol: https
  host    : github.com
  username: PersonalAccessToken
  password: <-- hidden -->

-> What would you like to do? 

1: Keep these credentials
2: Replace these credentials
3: See the password / token

Selection: 
```

Enter `1` for your selection. There might be be an error message but you can ignore it.

Now we should hopefully be all connected!

### Testing our connection

Now we'll double check that you've connected RStudio with GitHub by going to our GitHub profile and making a new repository.  We'll then copy (i.e. "clone") this repo to our computers, modify it locally, and send those changes back to GitHub via git (all this sounds overly technical right now, we will gain a deeper understanding in the next section on learning the git workflow).

First let's make a new repo. Go to your GitHub profile and click the plus sign in the top right, select "New repository".

![](/img/github_how2/fig_add_repo.png){width="100%"}


Give the repository a name, a description, make it public and select the option to add a README.  Then hit "Create repository"

![](/img/github_how2/fig_add_repo2.png){width="100%"}

Next hit the green "Code" button and copy the HTTPS URL to your clipboard.

![](/img/github_how2/fig_clone.png){width="100%"}


Now head back to RStudio and selection File > New Project. Then select "Version control" then "Git". Finally, paste the HTTPS URL that you copied from GitHub. The "Project directory name" should auto-population. Choose a meaningful place on your computer to house this project, select the option to open in a new session and hit "Create Project".

![](/img/github_how2/fig_git_project.png){width="50%"}

You should now have a new project open!  Navigate to the "Git" tab in RStudio and notice that two file names are listed with yellow question marks by them.  

![](/img/github_how2/fig_git_tab.png){width="100%"}



Those files were auto-generated by RStudio.  The question marks indicate that they are new files which git is currently not tracking.  Click the radio button next to each one under the "Staged" column.  Checking those buttons stages the files.  We can now hit "Commit" to add a commit message and commit the changes.  If you have success it should look something like this (possibly with a warning about username or email, that's ok!):

![](/img/github_how2/fig_commit.png){width="50%"}


Once we've committed the changes we can send those changes to GitHub by hitting the "push" button  Hopefully the result of hitting "push" looks something like this (possibly with a warning about username or email, again, that's ok!):

![](/img/github_how2/fig_push.png){width="50%"}

Go back to your web browser, refresh the GitHub repo page, and you should see the new files you just pushed! 

While committing and pushing you might get warning messages about your username and email. If you see these warnings you need to let git and GitHub know who you are.  You can do this through the Terminal. To open a terminal tab through RStudio go to Tools > Terminal > New Terminal. This will open a new terminal tab next to the R Console tab.  The terminal is different than the R Console. You can think of the terminal as accessing the guts of your computer. Raw R commands will not work here.  However, we *can* interact with git here and that's what we need to do to identify ourselves. So in the terminal type

```bash
git config --global user.name "github_user_name"
```

replace `github_user_name` with your actual username; hit enter. Then type 

```bash
git config --global user.email "my_email"
```

again replace `my_email` with the actual email address you used to register your GitHub account; hit enter.

Now your identity is known and you should be all set!

## Learning the git and GitHub workflow

We have in fact already seen a big part of this workflow when we confirmed that RStudio is properly communicating with GitHub. Now we will work toward really understanding it. 


### Clone

Cloning means copying a remote repo, like one on GitHub, to your local computer. This is how you typically first start a local git repo. Cloning is a little more complex than just downloading all the files: cloning also maintains the relationship between your local copy and the remote repo as well as all the version history.

### Stage and commit

Once you have your git repo locally, you will start changing things. "Staging" changes (hitting the radio button next to a file name in RStudio's "Git" panel) let's git know to pay attention to the changes you made. We can stage changes from one or multiple files at a time. Once staged, we can then write a commit message. This message briefly records what changes were made and (perhaps) why or how.  These messages should be brief, think of them as notes to your future self (or collaborators). Recall from the intro to this chapter that git enables you to roll back to previous versions of your code (for example if you messed something up). The commit message is your way of knowing which version to roll back to.  We will cover how to roll back or recover past versions soon.

These changes, and their commit messages, still only exist locally on your computer. The next steps are about interacting with the repo hosted on GitHub.

### Push and pull

If we want our local changes to be reflected in the GitHub repo, we need to "push" them. You can push from RStudio by hitting the green up arrow in the "Git" panel. Pushing does just that, it pushes all your committed changes to the GitHub repo. 

Conceptually, you should think of your local version of the repo as your temporary, personal copy of the official GitHub repo. Your computer could die, you could loose it, a cat could walk over the keys and mess it all up. Your local version is not permanent, but the GitHub version is. The fact that your local copy is ephemeral also means you should commit often, push often, and pull often.

Wait, what is pull?  Pull is how you keep your local copy up-to-date with the official copy on GitHub.  You can pull from RStudio by hitting the turquoise down arrow in the "Git" panel. But you might ask: how could the official copy change? Primarily through the commits and pushes of your collaborators. More on that in "Working collaboratively."

### Recovering past versions

To actually recover previous versions of your code, you have a few options. You can view the history of your repo (as it is preserved from within your local copy) right inside RStudio. On the "Git" panel, hit the watch icon and a window will pop-up showing the history of all commits along with their messages. You can click on any of those commits to see the past versions of your work. The easiest way to recover it is to copy the code of the past version and paste it into the script you're currently working on. This gives you maximum control to selectively recover specific parts of your past work. 
Another option is to use code in the terminal to roll back the entire repo to a past version. When you clicked a specific commit, you saw, amoung other information, a long SHA key. You can paste that SHA key into this code to roll back to that commit:

```bash
git revert <SHA-key>
```

Yet another option is to use the GitHub interface to view past versions. On the page for the GitHub repo you will see another watch-looking icon. Click that and again you can see a list of past commits which you can click through to see the associated versions of the files/scripts at the times of those commits. You can again copy-paste the code you might want from these past versions.

### Issues: toward working collaboratively 

### Working collaboratively: branches, forks, and pull requests

## Resources

One of the absolute best references on git, GitHub, and working with both through RStudio is Jenny Bryan's online book [Happy git with R](https://happygitwithr.com).
