Version Control with Git and GitHub

Applied Data Science - Session 4

Prof. Dr. Claudius Gräbner-Radkowitsch

Europa-Universität Flensburg

2026-10-19

Debrief

Report 1

  • Most common failure: typed numbers in prose
  • What nobody got wrong: nobody averaged stars

Worth repeating once

Vienna’s confounder inflated the gap. Barcelona’s hid it. Same control, opposite direction.

The better way to build and share projects

  • You wrote a document that rebuilds itself
  • You zipped it and sent it to me
  • It arrived in one version, from one machine

Today: better ways to share projects, and to work on them in the first place.

Four scenes

Scene 1 — which file is it?

report1_Musterfrau.qmd
report1_Musterfrau_v2.qmd
report1_Musterfrau_v2_NEU.qmd
report1_final.qmd
report1_final_korrigiert.qmd
report1_FINAL_really.qmd

Two questions you cannot answer:

  • Which one do I submit?
  • What changed between any two of them?

Scene 2 — it worked on Thursday

  • Thursday: renders, numbers look right
  • Sunday: you tidy up a chunk
  • Sunday, 23:10: it errors

How long to find it?

Without a history

You reread everything. You do not know what you changed.

The same evening, with a history

Four lines changed since Thursday. One is the bug:

 hotels <- read_csv("data/hotels.csv")
-central <- hotels |> filter(distance < 1)
+central <- hotels |> filter(distance > 1)
 outer   <- hotels |> filter(distance >= 1)

One character. Six seconds, not two hours.

Scene 3 — my laptop died

  • Coffee · theft · a dead drive · a bad update
  • Your report exists in exactly one place

The rescue

A backup that also knows what changed, and when.

Scene 4 — “send me your analysis”

A zip

  • 40 MB by email
  • “which version is this?”
  • three follow-up emails

A link

  • code, data, history
  • always current
  • readable in a browser

So what is it

Git, in one sentence

Version control is a tool that remembers what your project looked like each time you save a version.

  • Git — the program. On your laptop, needs no internet.
  • GitHub — a website that keeps a copy. A different thing.
  • Key concepts: commits and a repository

The four ingredients to a commit

  1. A snapshot of everything Git is tracking
  2. A message you wrote, saying why
  3. Your name
  4. A time

A snapshot, not a list of edits.

And it spans the project, not one file.

A repository

  • Your project folder
  • Plus every commit ever made in it

Where this resides

The history sits in a hidden .git folder in your project folder.

A repository is your project plus its Git history.

Two copies, two purposes

Local — your laptop

Where you work. Fast. Offline. Mortal.

Remote — GitHub

Where it survives. Shareable. Visible.

Not synced automatically. You move things across, deliberately.

Getting a copy: clone

Up — use_github()

Started on your laptop. Put it on GitHub.

Once per project.

Down — clone

Already on GitHub. Bring it to a laptop.

Once per machine.

A clone is the whole repository — files and history — still connected to GitHub. After that: the same Pull and Push.

RStudio: File → New Project → Version Control → Git, paste the URL.

Not Download ZIP

Files only. No history, no connection — nothing you can ever push.

Four places, and their names

Your laptop
1 · Working filesWhat is in the folder right now
2 · StagedPicked out for the next commit
Git’s own word for it: the index
3 · HistoryEvery commit you have made
HEAD = the one you are standing on
GitHub
4 · The remote — originThe copy that outlives your laptop

origin is just the name Git gives
the remote it was told about

Four places. Nothing moves between them by itself.

Four key actions

Pull bring GitHub’s commits down to you
Stage choose what goes in the next commit
Commit record it, with a message
Push send your commits up to GitHub

In that order. Every time.

One loop, four verbs

Your laptop
Working files
Staged
History
GitHub
History
Wed · fix filter
Wed · fix filter

Wednesday, in the library, you committed and pushed. This laptop knows nothing about it.

One loop, four verbs

Your laptop
Working files
Staged
History
Wed · fix filter
GitHub
History
Wed · fix filter

Pull. The commit copies down to you — GitHub keeps its own.

One loop, four verbs

Your laptop
Working files
Add limits section
Staged
History
Wed · fix filter
GitHub
History
Wed · fix filter

You write the limits section and save. Git notices: M report1.qmd

One loop, four verbs

Your laptop
Working files
Staged
Add limits section
History
Wed · fix filter
GitHub
History
Wed · fix filter

Stage. Tick the box — this goes in the next commit.

One loop, four verbs

Your laptop
Working files
Staged
History
Wed · fix filter
Add limits section
GitHub
History
Wed · fix filter

Commit. It becomes a commit, on your laptop. GitHub knows nothing yet.

One loop, four verbs

Your laptop
Working files
Staged
History
Wed · fix filter
Add limits section
GitHub
History
Wed · fix filter
Add limits section

Push. It copies up to GitHub — and stays yours.

All four are buttons

The RStudio Git pane: tabs across the top with Git selected; a toolbar with Diff, Commit, a blue down arrow for Pull, a green up arrow for Push, a clock for History and the branch name main; below it a file list with Staged checkboxes and a Status column showing a yellow question mark for NewScript.R and a blue M for references.bib.

The commit window

The RStudio Review Changes window: Changes and History tabs, buttons for Stage, Revert, Ignore, Pull and Push; a file list with Staged checkboxes and the same question-mark and M statuses; a Commit message box with a Commit button; and below, a diff of references.bib showing unchanged context lines and one added line highlighted in green.

What you should track in Git

Git watches files one at a time

Every file in your folder is in one of two states:

Tracked Git knows it. Every change from now on is recorded.
Untracked Git has never been told to care about it.

Both were on that last screenshot: M is tracked and changed, ? is untracked.

Nothing is tracked until you stage it once. So — which files should Git watch?

Sources in, outputs out

In

  • .qmd
  • data/
  • .Rproj
  • README.md

Out

  • .html
  • _files/
  • .Rhistory
  • .RData

The decisive question

One question: Can code recreate this file?

Otherwise the pane fills with noise

After one render:

report1.qmd
report1.html
report1_files/
  • report1.qmd is the relevant source file
  • The .html amd the _files directory are rebuildable rubbish
  • If you need them, rebuild from report1.qmd
  • Otherwise they float your repo with rubbish

The solution: .gitignore

One file, one pattern per line:

*.html
*_files/
.Rhistory
.RData
.Rproj.user
  • use_git() writes the bottom three for you
  • The rest is yours to decide → check before every commit

Write .gitignore first

.gitignore is not retroactive. Commit a file, then ignore it — it stays tracked. Forever.

  • Getting it back out needs the command line.
  • ⚠️: your folder already contains a rendered HTML → .gitignore should be step one

README.md

The first thing anybody sees when check a repo.

  1. What this project is
  2. What the data is, and where it came from
  3. How to reproduce it
  4. Who wrote it

Six lines is enough. But think about your future-you!

Working with Git in practice

Once per laptop

usethis::use_git_config(
  user.name  = "Anna Musterfrau",
  user.email = "anna.musterfrau@stud.uni-flensburg.de")

usethis::create_github_token()   # browser opens
gitcreds::gitcreds_set()         # paste the token here

Who you are, and proof that you are you. Once per machine.

The token is a password

Shown once. Not recoverable. Never in a .qmd.

Setting a project up is another three lines, once — we do them together in the live coding, and they are on the exercise sheet.

Then the general workflow

  1. Pull
  2. Write a bit. Render. Check it.
  3. It works? Stage it — a checkpoint, not a commit
  4. Broke it? Revert to that checkpoint, and carry on
  5. Something achieved? Commit, with a message
  6. Leaving the laptop? Push

Stage often. Commit when a piece of work is done — not when the clock says so.

Commits are safety anchors

You can always revert every file to the state of the last commit. When using the terminal, you can also go back to the last staged version of a file.

A commit message

No

update
changes
asdf
final
stuff

Yes

Add star-tier table
Fix distance filter
Drop the €1012 outlier
Write the limits section

Finish the sentence: “If you apply this commit, it will …”

Be kind to future-you

Messages should help you in six week to find out when you have changed what.

And if you already committed it

  • No button. No way to fix it via R-Studio.
  • GitHub → the file → History → the commit before
  • Copy the old version, paste it back, commit

The Terminal is worth it

R-Studio Git integration is super useful. But there is a payoff in learning to use the Terminal.

Two machines

Pull before you push

  • Seminar room laptop on Monday
  • Library machine on Wednesday
  • Same repository, two copies

Push without pulling, and GitHub refuses:

 ! [rejected]        main -> main (fetch first)
hint: Updates were rejected because the remote contains
hint: work that you do not have locally.
hint: ... use 'git pull' before pushing again.

Usually, pulling just works

Edits in different places merge by themselves:

Auto-merging report1.qmd
Merge made by the 'ort' strategy.

Both edits present. Nothing for you to do.

So the habit is cheap

Click Pull first. Almost always, nothing happens.

When it does collide

Same lines, two versions — Git will not guess:

CONFLICT (content): Merge conflict in report1.qmd
<<<<<<< HEAD
central <- hotels |> filter(distance < 1)
=======
central <- hotels |> filter(distance <= 1)
>>>>>>> b324c85

Delete the markers, keep the version you want, commit. That is all it is.

Outlook

Not today

  • Branches — change things without disturbing the main version
  • Pull requests — how a team reviews code before it lands
  • Merge conflicts, on purpose rather than by accident
  • The command line

Real, and how professional teams work. No report needs them.

Worked walkthrough in the solution, for whoever wants it.

Take-home until session 5

The Classroom 50 practice assignment

A repository made for you. Accept it, clone it, three commits, push.

Exercise sheet and manual on the session page. Nothing is marked. It exists so problems surface now, and not the night Report 2 is due.

Then session 5 — the grammar of graphics. The first thing in this course you have genuinely never done.

Today

  • A commit: snapshot, message, name, time
  • Pull · Stage · Commit · Push — buttons, in that order
  • Sources in, outputs out, .gitignore first
  • A README, because somebody else reads this

Your Report 1 is on GitHub. Report 2 starts there.