Lecture II: Version Control with Git

AI-Assisted Programming for PhD Researchers

Author
Affiliation

Dr. Tobias Vlćek

Helmut Schmidt University, August 2026

Why Git

Code Now Changes Fast

  • An agent can rewrite half your project in a minute
  • That is genuinely useful, and genuinely dangerous
  • Without a history, you cannot see what changed

. . .

  • You cannot judge it, and you cannot undo it

What Git Gives You

  • A time machine: undo any change, back to any point
  • A microscope: see exactly what changed, line by line
  • A safety net: branch off and experiment without fear
  • A lab notebook: a dated, labeled record of every step

Git and Reproducibility

  • “Which version of the code produced Figure 3?”
  • A commit hash answers that: exactly, forever (Ram 2013)
  • Version control is a core skill for reproducible research (Bryan 2018)
  • Journals and supervisors increasingly ask you to prove it

Setup

Install Git

Pick the line for your system:

# macOS: installs with the developer tools
xcode-select --install       # or: brew install git

# Windows: winget, or the installer from git-scm.com (accept the defaults)
winget install Git.Git

# Linux: use the package manager of your distro
sudo apt install git         # Debian / Ubuntu

Windows: the installer brings Git Bash. Run every lab command there.

Your Turn: Introduce Yourself

Your turn: confirm Git works, then tell it who you are.

git --version
git config --global user.name "Your Name"
git config --global user.email "you@example.com"

Use the same email you will use on GitHub: it links your commits to your account.

Your Turn: Check Your Toolchain

Your turn: confirm the uv you installed this morning is working.

uv --version

If uv didn’t land during setup, one command fixes it now:

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Every lab runs Python through uv run, nothing else to configure.

Repositories

What Is a Repository?

  • A folder whose full history lives in a hidden .git directory
  • Every version of every file, back to the first commit
  • It is entirely local: on your machine, in your control
  • Nothing leaves your computer unless you explicitly push it

Getting One: init or clone

  • git init: start tracking a new folder of your own
  • git clone URL: copy an existing repository to your machine
git init                      # new project, here
git clone URL                 # existing project, from a remote

Your Turn: Clone the Course Project

Your turn: get the starter project and look around.

git clone https://github.com/beyondsimulations/aiprog-lab-starter
cd aiprog-lab-starter
ls
git log --oneline

The log output is the project’s history: every commit before you arrived.

What You Just Inherited

  • A data set and an analysis script from a previous postdoc
  • It will not run yet: dependencies, paths, and assumptions are stale
  • That is not a mistake; it is the normal starting point
  • Fixing inherited code is tomorrow’s reality, and today’s material

The Everyday Loop

Status, Add, Commit

  • git status: what have I changed?
  • git add: put changes in the staging area
  • git commit: record what is staged, with a message

. . .

The staging area is a shopping cart: you fill it deliberately, then check out.

Anatomy of a Good Commit

  • One logical change per commit, not a day’s worth of work
  • Message in the imperative, and it says why

. . .

bad:   git commit -m "stuff"
good:  git commit -m "Fix humidity parsing for n/a values"

Your Turn: First Commit

Your turn: create notes.md in Zed with one line about the project state, or from the shell, then commit it.

echo "Inherited analysis script; paths and stats look broken." > notes.md
git add notes.md
git commit -m "Add project state notes"
git log --oneline

Your commit is now the newest line in the history.

Partial Staging

  • git add -p walks you through changes hunk by hunk
  • Say yes or no to each piece before it is staged
  • This is exactly how you accept an agent’s diff selectively

. . .

  • Take a good change, drop a bad one: review at staging time

Looking at History

log: What Happened

  • git log --oneline --graph: compact history with branch structure
git log --oneline --graph
  • Each line is one commit; each hash is a citable state of your project
  • Point at a hash and you point at an exact, reproducible version

diff: What Changed

  • git diff: changes you have not staged yet
  • git diff --staged: changes about to go into your next commit
  • git show HEAD: the full content of the last commit

. . .

This is the tool for reviewing what an agent actually did.

Your Turn: Inspect

Your turn: read the starter repo’s history.

git log --oneline --graph
git show --stat HEAD

Scroll the log and find the commit where the data set was first added.

Undoing

Three Levels of Undo

Match the command to how far you want to go back:

Command Undoes
git restore <file> An unstaged change in your working file
git restore --staged <file> Staging: keeps the edit, unstages it
git reset --soft HEAD~1 The last commit: keeps its changes staged

In Zed, git: restore file (Command Palette) does the first row.

Your Turn: Break and Restore

Your turn: break a file on purpose, then bring it back.

# in your editor, delete half of legacy_analysis.py and save
git diff                      # confirm the damage
git restore legacy_analysis.py
git diff                      # clean again, nothing to show

Nothing is scary while your last commit is safe.

The One Safety Rule

Never rewrite history you have already pushed or shared: others may have built on it. Everything still local and unpushed is yours to rewrite freely.

Branches

Why Branches (Especially with Agents)

  • A branch is an isolated line of work off your main history
  • Let the agent go wild on a branch; main stays clean
  • Experiment fails? Delete the branch; main never knew
  • Merge back only what you have reviewed and understood

Branch Basics

git switch -c try-idea        # create a branch and move onto it
# ... make changes and commit them ...
git switch main               # go back to main
git merge try-idea            # bring the work in

Four commands: branch, work, return, merge.

Your Turn: Branch and Merge

Your turn: run the full branch cycle once.

git switch -c add-readme-note
# edit README, then:
git add README.md && git commit -m "Add note to README"
git switch main
git merge add-readme-note
git branch -d add-readme-note

Tags and Checkpoints

Tags Mark Moments

  • The labs tag reference states: clean checkpoints you can jump to
  • Fell behind or broke something? Jump to a known-good tag:
git fetch --tags
git stash -u                        # park your work (tracked and untracked)
git switch -C main tags/lab-01-done

(-C moves your main to that state, safe as long as nothing is pushed.)

No shame in catching up: the goal is the next exercise, not pride.

Remotes (Just Enough)

GitHub in One Slide

  • A remote is a copy of your repository somewhere else (e.g. GitHub)
  • git push sends your commits up; git pull brings others’ down
  • Zed’s Git Panel has Fetch, Push, and Pull buttons for the same jobs
  • You will push your capstone if you want feedback on it; the cheatsheet has the exact push and pull commands

Git in Zed

Same Git, Faster Workflow

  • You learned the manual loop first (status, add, commit), so you know exactly what every button does
  • Day to day, the Git Panel in Zed does the same job with fewer keystrokes
  • The panel and the command line talk to the same .git directory; nothing here is a different Git

. . .

Zed’s Git support does not replace the terminal: for anything it does not cover (interactive rebase, cherry-pick, …), drop into the integrated terminal and use the commands you already know.

The Git Panel

  • Open it from the Command Palette with git panel: toggle focus, or click the Git icon in the status bar
  • Shows the active repository and branch, every changed file, and each file’s staging state
  • Zed watches your repository: a commit from the terminal, or from an agent, appears here immediately

Staging and Committing

  • Click a file’s checkbox to stage it, or press space to toggle staging on the selected file (git: toggle staged)
  • git: stage all / git: unstage all: stage or clear everything at once
  • Type a message in the commit box at the bottom of the panel, then commit with cmd-enter (macOS) or ctrl-enter (Windows/Linux)

Same shopping cart, same staging area, just checkboxes instead of git add.

Mind the Auto-Stage

If you stage nothing, Zed stages all tracked files and commits them. Check the panel before you hit commit.

Diff Views: Review Before You Commit

  • git: diff opens the Project Diff (ctrl-g d on macOS, Windows, and Linux)
  • Every changed hunk in the project, in one editable view: your on-screen git diff and git diff --staged
  • Stage or unstage a single hunk, or a whole file, from the buttons in the tab bar

The Project Diff Is a Multibuffer

  • That Project Diff view is a multibuffer: one editable surface excerpting many files at once
  • Project Search results open the same way: one excerpt per match, across the whole project
  • Edit inside it and you edit the real underlying files; this is not a preview
  • editor: open excerpts jumps from an excerpt straight to its source file

Multi-Cursor Touch-Ups Across Files

  • cmd-d / ctrl-d selects the next match of the word under your cursor
  • cmd-shift-l / ctrl-shift-l (editor: select all matches) selects every match at once

. . .

  • This is how you clean up an agent’s multi-file change without hopping between tabs

Switching Branches

  • git: branch creates a new branch; git: switch (or git: checkout branch) opens a picker to switch to an existing one
  • The same picker deletes a branch, except the one you currently have checked out
  • Reach both from the Command Palette; neither has a default keybinding

Your Turn: The Loop, Again, in Zed

Your turn: redo status → stage → commit → diff, entirely inside Zed, in aiprog-lab-starter.

  • Add another line to notes.md in Zed’s editor
  • Open the Git Panel and check that notes.md shows up as changed
  • Stage it, write a commit message, and commit
  • Open the Project Diff (ctrl-g d) and confirm there is nothing left to review

Continue Your Journey

Next Up

References

Bryan, Jennifer. 2018. “Excuse Me, Do You Have a Moment to Talk About Version Control?” The American Statistician 72 (1): 20–27. https://doi.org/10.1080/00031305.2017.1399928.
Ram, Karthik. 2013. “Git Can Facilitate Greater Reproducibility and Increased Transparency in Science.” Source Code for Biology and Medicine 8 (1): 7. https://doi.org/10.1186/1751-0473-8-7.