# [00:00] Day 2 intro (5 min)
[URL](https://github.com/coderefinery/workshop-intro/blob/master/daily_intro.md)
Primary: EG (saying hi; introducing the lesson)
Important links:
- [Workshop page](https://coderefinery.github.io/2026-03-17-workshop/)
<!-- # [00:05-00:55] Local Git workflow: cloning (50 min) -->
# [00:05] Local Git workflow: intro (10 min)
Material: [URL](https://coderefinery.github.io/git-intro/local-workflow/)
Mode: teacher/student
Primary: HM (saying hi! + sharing the screen)
Secondary: BB (responding to questions; commenting)
:::info
**Talk**
- What is a git repository?
- What is cloning?
- "GitHub is just a remote copy. Git itself lives locally."
- keywords: clone, fork, (origin, upstream)
:::
:::danger
**Important points to mention before the exercise.**
- [ ] Github repo options:
- https://github.com/cr-workshop-exercises/recipe-book -- you can use this one if you don’t want your fork and contributions to be visible on the stream or the recording
- https://github.com/cr-workshop-exercises/recipe-book-recorded -- we will use this one for the demonstration which is streamed and recorded
- [ ] The examples below assume you are cloning the original repository. If you are cloning your fork, you should replace `cr-workshop-exercises` with your GitHub username.
:::
# [00:15] Exercise: cloning + working locally (25 min)
[URL](https://coderefinery.github.io/git-intro/local-workflow/#exercise)
:::success
**Notes**
Check the notepad and select some topics
:::
# [00:35] Solution: cloning + working locally (15 min)
Material: [URL](https://coderefinery.github.io/git-intro/local-workflow/#solution-and-walk-through)
Mode: talker/typer
Primary: HM (saying hi!; sharing the screen)
Secondary: BB (commenting)
:::warning
**Key points**
- Your **local repo** is the Git repository stored on your own computer.
- created with `git init` or `git clone`
- exists only on your local machine; you can work offline
- A **remote repo** is a Git repository hosted somewhere else (usually online).
- `origin` is just the default name Git gives to the main remote repository when you clone a repo.
- `upstream` is usually used when you fork someone else's project.
- What actually happens when `git clone <repo-url>`
- Git clones the enitre respository history (all commits, all branches, all tags)
- Git creates one local branch -- the default branch of the remote (often `main`)
- Git creates remote-tracking branches for all other branches (e.g., `origin/feature-a`)
- You cannot commit to `origin/feature-a` branch
- These branches are updated with `git fetch`
- To start working on another branch, `git switch --track origin/feature-a`
- **Remote** is a Git term to indicate another repo.
- Github is another copy of a repo. It is possible to have multiple remote repos.
```text
Remote server
-------------
main
feature-a
feature-b
Local repo
----------
main (local branch)
origin/main (remote-tracking)
origin/feature-a
origin/feature-b
```
::spoiler
Other related commands
- `git push -u origin my-branch`
- `git remote add upstream <url>`
- `git branch -a`
-
:::
# [00:50-01:00] BREAK (10 min)
:::success
**BREAK**
:::
<!-- # [01:05-02:00] Investigating a Git Repository: (55 min) -->
# [01:00] Intro: Inspecting history (1 min)
Material: [URL](https://coderefinery.github.io/git-intro/archaeology/)
Mode: teacher/student
Primary: BB (saying hi + sharing the screen)
Secondary: HM (commenting; asking clarification questions)
## Demo: Browsing history
:::info
**Talk** -- _How did this code end up like this?_
> “Let’s say you open a repository and look at a file.
You understand what it does—but one question remains:
How did it end up like this?”
> “Who wrote this part?
Was it always like this?
What changed over time?”
> Let’s explore that evolution visually first.
:::
:::success
**Icebreaker**
@audiance: You join a project that has existed for several years. What do you think changed most often in a README over the lifetime of a project?
Examples:
- Installation instructions
- Project description
- Requirements
- Something else?
Type your guess.
:::
:::danger
**Action**
- [ ] STARTING POINT: the github repository https://github.com/networkx/networkx
- [ ] Navigate to `README.rst`
- [ ] Show _history_ of the file
- [ ] You can check code at particular commit or commit details
- [ ] click on commit hash
- [ ] click on `view code at this point`
- [ ] In the URL, replace `github.com` with `github.githistory.xyz`
- [ ] Use the **left and right arrow keys** to explore the file history
:::
:::warning
**Key points**
- [githistory.xyz](https://githistory.xyz/) is a clever developer tool that It lets you see **how code evolves over time in a simple, visual, step-by-step way**.
- It works with **any public GitHub repository**.
:::
## Demo: Searching text patterns
:::info
**Talk** -- _Where in the codebase does this appear?_
> We just looked at how a file changes over time.
But usually, we don’t start by browsing history—we start with a question.
For example: “Where is this function used?
To answer that, we need to search the repository.
Sometimes we are not investigating *history*, but *usage*.
Imagine these situations:
- You want to delete or modify a function.
You ask yourself:
> *Is this function used anywhere else in the repository?*
- You see something like: `status = "unavailable"` and wonder:
> *Is this value expected elsewhere?*
To answer questions like *Where is this used?*, Git provides a built-in search command `git grep <pattern>`.
:::
:::danger
**Action**
- [ ] Open VS Code and run the following commands in the terminal:
```bash
# clone the repo
$ git clone https://github.com/networkx/networkx
# change directory
$ cd networkx
# verify this is a git repository
$ git status
```
- [ ] Pose a question: _Where is this function used?_ `shortest_path`
```bash
$ git grep "shortest_path"
```
- [ ] Narrow down
```bash
$ git grep shortest_path -- '*.py'
```
- [ ] Was this already in the code a year ago?” “Was this always there?” Pick a tag
```bash
$ git tag
$ git grep shortest_path networkx-2.6.3 -- '*.py'
```
- [ ] This is also good to show
```bash
$ git grep -l "def shortest_path" -- "*algorithms*.py"
```
- [ ] Demonstrate useful flags:
```bash
$ git grep -i "fixme" # case-insensitive search
$ git grep -n "fixme" # show line numbers
$ git grep -w "fixme" # match whole words only
$ git grep -l "fixme" # show only filenames
```
- [ ] Demonstrate specific searches:
```bash
$ git grep <pattern> -- <path> # search only inside a specific file path or directory
$ git grep <pattern> <branch-name> # search in a specific branch
$ git grep <pattern> <commit-hash> # search inside a specific commit
```
:::
:::warning
**Key points:**
- `git grep <pattern>` searches for text patterns in files tracked by Git.
- By default, it searches the **current version of the repository** (the branch you are on).
:::
## Demo: Line-by-line code annotation with metadata
:::info
**Talk:** -- _Who wrote this line?_
`git show` helps us inspect **what changed in a commit**.
But sometimes the investigation starts somewhere else. You are reading the code and something looks strange. For example, you see a line like:
`MAX_RETRIES = 12`
Now you start asking questions:
> - *Why 12?*
> - *Who introduced this value?*
> - *When was this line added?*
Instead of manually searching through the history, Git can tell us **who last modified each line of a file**.
This is called **annotation** (also known as **blame** in Git terminology).
:::
:::danger
**Action:**
- [ ] Run
```bash
$ git annotate README.rst
# Example output
# a1b2c3d (Alice 2022-04-03) Installation instructions
# 9f8e7d6 (Bob 2023-01-10) Added examples
```
- [ ] Demonstrate useful options:
```bash
git annotate -w <file-path> # ignores whitespace changes
```
:::spoiler
compare to github with -w flag
::::
:::warning
**Key points:**
- `git annotate <file-path>` shows who last modified each line of a file and which commit introduced it.
- This is extremely useful when investigating:
- unexpected behaviour
- strange constants
- undocumented code decisions
:::
## Demo: Inspecting individual commits
:::info
**Talk** -- _What changed in this commit?_
`git grep` helps us answer the question:
> *Where is this used in the repository?*
But when exploring a project history, another common question appears:
> *What exactly changed in a particular commit?*
Sometimes we see commit messages like:
- *minor cleanup*
- *bugfix*
- *small change*
These messages don't always explain what really happened.
So we want to inspect the commit itself and see the exact modifications.
Git allows us to do this with the command `git show`.
:::
:::danger
**Action:**
- [ ] First, list recent commits:
```bash
$ git log --oneline
# Example output:
# a1b2c3d fix pagerank bug
# 9f8e7d6 improve documentation
# 4c3b2a1 minor cleanup
```
- [ ] Inspect one commit
```bash
# Shows changes between this commit and its parent
$ git show <commit-hash>
```
- [ ] Demonstrate useful features:
```bash
$ git show <commit-hash>:<file-path> # shows a specific file in a specific commit
$ git show --stat <commit-hash>
$ git show --no-patch <commit-hash> # hides the diff
```
- [ ] Demonstrate that we can inspect other objects:
```bash
$ git show <branch>
$ git show <tag>
```
:::spoiler
`https://github.com/<owner>/<repo>/commit/<commit-hash>`
:::
:::warning
**Key points:**
- `git show` displays detailed information about a Git object.
- Most commonly used for commits, but also works for branches, tags, and files.
- It helps us understand exactly what changed and why.
:::
## Demo: Inspecting code in the past
:::info
**Talk:** -- _What did the entire project look like then?_
`git annotate` tells us **who last modified a specific line** and in which commit.
Once we know the commit, another question often follows:
> *What did the project look like at that moment?*
Sometimes we want to **travel back in time** -- actually step into the past and explore it.
:::
:::danger
**Action:**
- [ ] If you only want to inspect the old code:
```bash
# find a commit
$ git log --oneline
# when looking for a specific term
$ git log --oneline --grep="bug" -i
# move to that commit
$ git switch <commit-hash>
# explore the repository
# read files, run code, inspect behavior
# return to the previous branch
$ git switch -
```
- [ ] If you want to experiment or make changes:
```bash
$ git log --oneline
# create a new branch starting from an old commit
$ git switch --create <new-branch> <commit-hash>
# experiment, modify code, make commits
# return to main branch
$ git switch main
# delete the temporary branch
$ git branch -d <new-branch>
```
:::spoiler
Explain how HEAD pointer works and why it is sometimes in DETACHED state.
```text
commit1 <- commit2 <- commit3 <- main <- HEAD
\
commit4 <- commit5 <- feature
\
HEAD (detached)
```
:::
:::warning
**Key points:**
- Git allows you to inspect any point in the project’s history.
- A detached HEAD is fine for exploration.
- If you want to commit changes, create a new branch from that commit.
:::
:::success
Introduce the exercise.
- Practice these commands on your own.
:::
# [01:40] Exercise: Explore basic archaeology commands (20 min)
[URL](https://coderefinery.github.io/git-intro/archaeology/#exercise)
:::success
**Notes**
Check the notepad and select some topics
:::
# [02:00-03:00] LUNCH BREAK (1 hour)
:::success
**Notes**
Relax + check the notepad.
:::
# [03:00] Git bisect demo (20 min)
Material: [URL](https://coderefinery.github.io/git-intro/archaeology/#finding-out-when-something-broke-changed-with-git-bisect)
Mode: teacher/student
Primary: BB (saying hi; sharing the screen)
Secondary: HM (commenting; asking clarification questions)
:::info
**Talk** -- _Finding out when something broke/changed_
_But I am sure it used to work! Strange._ -- Sometimes you realize that something broke. You know that it used to work. You do not know when precisely it broke.
Bug is difficult to see visually.
:::
:::danger
**Action**
- [ ] Clone https://github.com/coderefinery/git-bisect-exercise
- [ ] Demonstrate the bug
```bash
$ python get_pi.py # runs the script to show the bug
```
- [ ] Demonstrate `git bisect`
```bash
# find the first commit
$ git log --oneline | tail -n 1
# start bisecting
$ git bisect start
$ git bisect good <commit-hash> # first commit is good
$ git bisect bad main # last commit is bad
# ... testing commits ...
$ git bisect bad
$ git bisect good
# when done
$ git bisect reset
```
:::spoiler
Use `git show <commit-hash>` to find message. Trick: `git show HEAD`.
:::
:::warning
**Key points**
- Machinery:
- Define last known good version. Define bad version (bug present).
```text
[good] -- [ ] -- [ ] -- [ ] -- [ ] -- [ ] -- [bad]
```
- `git bisect` will pick a middle commit and ask you if it is good or bad.
```text
[good] -- [ ] -- [ ] -- [test] -- [ ] -- [ ] -- [bad]
```
- Narrow the search range and repeat until the exact commit is found.
```text
[good] -- [x] -- [x] -- [good] -- [ ] -- [ ] -- [bad]
```
- With 128 commits we have 128 manual checks but with bisect only 7 tests:
```text
128 -> 64 -> 32 -> 16 -> 8 -> 4 -> 2 -> 1
```
:::
<!-- # [01:58] Summary: code archeaology
:::warning
**Key points**
- Inspecting history means using Git to figure out what changed, where, and when.
- `git {log,grep,annotate,show,bisect}` is a powerful combination commands when doing archaeology.
:::
-->
# [03:20] Sharing work (40 min)
Material: [URL](https://coderefinery.github.io/git-intro/sharing/)
Mode: teacher/student
Primary: HM (saying hi; sharing the screen)
Secondary: BB
# [04:00-04:10] BREAK (10 min)
:::success
**Notes**
Check the notepad and select some topics.
:::
# [04:10-04:30] Practical advice (20 min)
Material: [URL](https://coderefinery.github.io/git-intro/level/)
Mode: Interviewer/expert?
Primary: BB (saying hi; sharing the screen)
Secondary: HM
:::success
**Discussion**
How do you use Git?
Please provide your input in the online collaborative document.
:::
## Status
:::info
Talk -- _dashboard for git repository_
Explain that `git status` is the first command to run when you're unsure what's going on. It is safe (read-only).
It tells you:
- which branch you are on
- what files have changed
- which files are staged
- which files are untracked
- what will be included in the next commit
`git status` is what Git _sees right now._
:::
:::danger
**Action**
- [ ] Check repository state
```bash
$ git status
# $ git status -s # short format
# Shows:
# - untracked files
# - modified files
# - staged files
# - branch info
```
:::
:::warning
**Key points:**
- Files can exist in several states depending on how they relate to the repository and the staging area.
```mermaid
sequenceDiagram
participant IG as Ignored
participant UT as Untracked
participant UM as Unmodified
participant M as Modified
participant S as Staged
UT->>IG: matches .gitignore
activate UT
deactivate UT
activate IG
UT->>S: git add
activate UT
deactivate UT
activate S
S->>UM: git commit
deactivate S
activate UM
UM->>M: edit
deactivate UM
activate M
M->>S: git add
deactivate M
activate S
S->>UM: git commit
deactivate S
activate UM
UM->>M: edit
deactivate UM
activate M
M->>S: git add
deactivate M
activate S
S->>M: edit (after staging)
activate M
Note right of S: file in <br> 2 states
M->>S: git add
deactivate M
S->>UM: git commit
deactivate S
IG-->>S: git add -f
deactivate IG
activate S
S-->>UM: git commit
deactivate S
```
:::
## Writing good commits
:::info
**Talk**
> Write commit messages like you’re explaining the change to a teammate reviewing the history six months later.
:::
:::warning
**Key points**
1. Use a clear structure
```text
<type>: <short summary>
<optional longer explanation>
<optional longer explanation>
<optional references (issue numbers, etc.)>
```
```text
feat: support password reset via email
Adds a password reset flow with expiring tokens.
Users receive a reset link that is valid for 15 minutes.
Closes #87
```
2. Use common commit types
| Type | Meaning |
| ---- | ------- |
| `fix:` | bug fix |
| `refactor:` | code restructure without behavior change |
| `test:` | add or update tests |
| `chore:` | maintenance tasks |
| `style:` | formatting, linting |
| `docs:` | documentation |
| `feat:` | new feature |
| `perf:` | improve performance |
3. Keep the first line short and specific
```text
feat: support dark mode in user settings
refactor: replace callbacks with async/await
docs: add setup instructions for development
test: add unit tests for payment service
```
4. Explain why, not just what
```text
fix: increase API timeout to prevent false failures
Some requests take ~8s during peak load.
Previous 5s timeout caused retries and duplicate jobs.
```
5. A good commit should represent **one logical change.**
:::
## Branching
:::info
**Talk**
> Create a branch for each task, keep it small, merge it quickly.
:::
:::warning
**Key points:**
1. Keep `main` always stable / working.
2. One branch = one purpose -- use short-lived branches
3. Use clear naming.
| Type | Example |
| --- | --- |
| Feature | `feature/flat-prior` |
| Bug fix | `fix/compilation-error` |
| Refactor | `refactor/simulations` |
| Docs | `docs/readme` |
For Bayesian analysis code:
| Type | Example |
| --- | --- |
| Model | `model/softmax` |
| Prior | `prior/weakly-informative` |
| Simulation | `sim/prior-predictive` |
| Analysis | `analysis/posterior-checks` |
| Results | `res/model-comparison` |
:::
:::success
**Q&A**
Answer some topics from the notepad.
:::
# [04:30-04:50] What to avoid (20 min)
Mode: Open discussion + others join (Richard, Diana)
:::warning
**Key points:**
- When commiting:
- sharing personal / sensitive information
- writting poor commit messages
- committing generated files -> use `.gitignore`
- commiting huge files -> use `.gitignore`
- postponing commits -> use `git commit --amend` (only local!!)
- committing unrelated changes -> use `git commit --amend`
- When working with branches:
- forgetting branch updating (when working with remote)
- creating too ambitious branches
- ...
:::
# [04:50] Wrap-up
Enrico