Git & GitHub

Version Control & Workflow — WPM Summer School

Cosima Meyer · 2026

Version control

  • analysis_FINAL_v3_REALLYFINAL_USE_THIS.R
  • regression_new_new_ACTUALLY_final.R
  • data_cleaning (1) (kopie) (fixed).R


That is what version control can look like.


This afternoon, we’ll learn how to make it better and how to work collaboratively 😊

What is Git?

  • Software that lets you track changes → version control
  • It lets you work collaboratively in teams
  • But it’s also great for your own personal version control!

Git is a time machine

  • Git takes snapshots of your work
  • Not like Dropbox — Dropbox silently overwrites
  • With Git, you decide when to take a snapshot
  • Every snapshot is labelled and reversible


Think of a commit as a checkpoint you can always travel back to

Git vs. GitHub


Git

The engine on your laptop that takes the snapshots.


Works with no internet.

GitHub

The platform that hosts a copy. Back it up, share it, collaborate.


Needs internet.


  • Git is the engine
  • GitHub is the parking garage where everyone can use the car

Intuition — How does Git work?

Intuition — How does Git work?

Intuition — How does Git work?

Intuition — How does Git work?

Intuition — How does Git work?

Intuition — How does Git work?

Intuition — How does Git work?

Intuition — How does Git work?

Intuition — How does Git work?

From linear snapshots …

So far, your version control is one straight line of snapshots

editcommiteditcommit

But research isn’t linear.

You try a new model,
play around with your EDA,
your co-author has another idea,

But you don’t want working things to break.

… to branches 🌱

Growing trees 🌳

Growing trees 🌳

Growing trees 🌳

Growing trees 🌳

main

Growing trees 🌳

main

Growing trees 🌳

main

Growing trees 🌳

main

Growing trees 🌳

main

Growing trees 🌳

main

Growing trees 🌳

main

You can run the commands in the terminal…

git pull 
git status 
git add code.R 
git commit -m "feat: Function add_code() added" 
git push origin main 
git status

… but it’s built right into Positron / RStudio 👩🏼‍💻

Frequently used commands


status add commit push pull checkout

What each command does

status see what’s changed

add stage a file for the next commit

commit save a labelled snapshot

push send your commits to GitHub

pull bring others’ commits down to you

checkout switch to another branch

Setup 💻

Quick check-in for everyone

Open the terminal in Positron (View → Terminal) and run:

git --version
git config --global user.name
git config --global credential.helper

A version, your name, and a credential helper (e.g., osxkeychain) → 🎉

No token yet? → github.com → Settings → Developer settings → Tokens (classic) → scope repo.

Your first commit

mkdir git-warmup && cd git-warmup
git init
echo 'mean(c(2, 4, 6))' > first_script.R
git status               # untracked
git add first_script.R   # move to "staging area"
git commit -m "feat: Add first R script"
git status               # your first milestone 🎉

The everyday loop

…and the loop begins again 1 2 3 4 add commit push pull


Your first commit lives only on your laptop.

Let’s connect them to GitHub.

🖥️ Demo

Get a repo, then the loop

git clone https://github.com/<username>/git-practice.git
cd git-practice
git remote -v            # connected to GitHub as "origin"

First git push asks you to log in → paste your token as the password (not your GitHub password).

# write clean_colnames.R with a small clean_colnames() function, then:
git status
git add clean_colnames.R
git commit -m "Add clean_colnames() function"
git pull                 # grab others' work FIRST
git push                 # send yours up

Good commit messages

Specific. Small. Finish the sentence: “This commit will…”

❌ Not the best


"update"

"fixed"

"asdf"

"try"

✅ Good

"Add clean_colnames() to snake_case columns"

"Fix clean_colnames() returning names, not df"

"Update docs for make_stats()"

"Add tests for clean_colnames()"

✨ Better

"feat: Add clean_colnames() to snake_case columns"

"fix: Fix clean_colnames() returning names, not df"

"doc: Update docs for make_stats()"

"test: Add tests for clean_colnames()"

.gitignore - your safety guard

.Renviron        # secrets — NEVER commit
data/raw/        # sensitive / large data
*.csv
*.rds
.DS_Store

⚠️ .gitignore only stops future tracking

Your turn 💻

Break things on purpose

It’s a sandbox — you can’t lose committed work, no matter what.

  • Edit clean_colnames.R again, don’t commit yet → git status then git diff: what’s the difference?
  • Commit it with a good message — specific, like the ✅ or ✨ examples

Bonus

  • Stage another change, then unstage it: git restore --staged <f>
  • Discard an edit you don’t want: git restore <f>
  • git log --oneline for your trail of (good!) messages → git show HEAD to peek inside one
10:00

☕ Break

10:00

Collaboration

Everything so far has been you, on your own laptop.

Git’s magic is working with other people.

Branches = growing trees 🌳

main

main is where your working version lives. A branch is a path where you try things without breaking it.

git checkout -b feat/analysis

Merge it back when it’s good; delete it if it’s not.

Pull requests

“Here’s me trying out things — please review it and move it to the working version.”

  • Write what changed and why
  • Reviewers comment, request changes, approve
  • Then Merge 🎉

Get everyone’s work

Once a PR is merged, bring the new work down to your machine:

git checkout main    # back to main
git pull             # receive everyone's merged branches


Watch everyone’s files appear 🎉

Merge conflicts

Two branches changed the same line:

<<<<<<< HEAD
  "USA" = "United States"
=======
  "USA" = "United States of America"
>>>>>>> main


  1. Delete the markers
  2. Keep the line you want
  3. Then git addgit commit -m "fix: Solve merge conflict" (or git commit --no-edit)

🖥️ Demo: A merge conflict

Your turn - working on a shared repo

Follow 1_exercises/EXERCISE.md in the shared repo:

  1. Clone → your own branch
  2. You can add your own function in 2_functions/<you>.RPull Request (take 2_functions/EXAMPLE.R as inspiration - this is the “happy path”)
  3. Swap with your pair → comment on their PR → Approve it
  4. Fill the same country line of 2_functions/country_names.R as your pair → conflict → resolve it
  5. Do it once more (practice is what counts! 😊)
30:00

And now it’s about you 👩‍💻


You can now track, version, and collaborate

Let’s end with something just for you — making you findable

GitHub profile README

Create a public repo named exactly your username → add a README.md → it shows on your profile.

# Hi, I'm <Name> 👋
PhD candidate in Political Science at <University>. I research <topic> using R.

- 🔭 Working on <project>
- 🌐 [Website](…) · [Google Scholar](…) · 📫 you@university.edu

Recap - what did we learn

status add commit push pull checkout


  1. .gitignore first — on anything with data or secrets
  2. git status whenever you’re confused
  3. Commit small, commit often, and write meaningful messages

More resources

Thank you!