Skip to content

Content update: Git for Advanced 2026 - #170

Draft
mjaehn wants to merge 72 commits into
mainfrom
content-upate-advanced
Draft

Content update: Git for Advanced 2026#170
mjaehn wants to merge 72 commits into
mainfrom
content-upate-advanced

Conversation

@mjaehn

@mjaehn mjaehn commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Restructures the advanced course into two parts, replaces every slide image with a generated diagram, and rewrites the exercises so participants work things out instead of pasting commands.

Closes #147
Closes #155
Closes #156
Closes #162

Part of #165 (that issue also covers the beginner course, so it stays open).

Two-part structure

The old Parts 0–4 + Bonus become:

  • Part 1 · Your Git Toolboxlog/blame/diff/show, submodules, ignoring files, cherry-pick and rebase, stash and worktree, hooks, and git lfs.
  • Part 2 · Working Together on GitHub — why a shared workflow, the C2SM User Landing Page as a live example, issues, forks, pull requests, checks and previews, review, merging, and keeping a fork in sync.

git bisect is dropped (it moves to Expert_Topics.md), git lfs is added, and rebase is promoted from the bonus into Exercise 4 alongside cherry-pick.

Exercises are renumbered to follow the teaching order:

New Was
Exercise_1_examining-history.md Exercise_1_git-log-diff-show.md
Exercise_2_submodules.md Exercise_8_git-submodule.md
Exercise_3_ignoring-files.md Exercise_3_gitignore.md
Exercise_4_cherry-pick-rebase.md Exercise_6_git-cherry-pick.md + Exercise_bonus_rebase.md
Exercise_5_stash-worktree.md Exercise_4_git-stash-worktree.md
Exercise_6_hooks.md Exercise_7_git-hooks.md
Exercise_7_git-lfs.md new
Exercise_8_web-workflow.md Exercise_5_git-workflow.md, rewritten

Diagrams

All 14 third-party raster screenshots are gone. In their place are 13 Mermaid sources in advanced/slides/diagrams/, rendered to SVG by advanced/slides/build.sh, which CI now runs instead of an inline marp command — so a local build and the committed PDF cannot drift apart. The two images with no diagram equivalent (achtung.gif, tweet.png) became a .warning CSS class and a pros/cons list.

build.sh normalises one thing before committing: Mermaid gives a gitGraph cherry-pick commit a random id that lands in a CSS class name, which made cherry-pick.svg differ on every build. Since the workflow commits the rendered SVGs back to the branch, that would have produced a spurious "Update advanced slides diagrams and PDF" commit on every CI run. Two consecutive builds are now byte-identical.

Course renaming (#162)

"Git for Advanced" implied an expertise gate that does not exist. Under the umbrella name C2SM Git Courses, which is what the landing page already publishes, the two courses are now:

  • Git: First Steps (was Git for Beginners)
  • Git: Next Steps (was Git for Advanced), containing the two Parts above

The advanced/ and beginner/ directories keep their names — renaming them would break the published landing-page links, the check_requirements.sh --beginner flag and every bookmark.

Still to do outside this repo: the landing-page entry docs/events/git_courses.md in C2SM/c2sm.github.io, and the ETH technical training website.

Which folder for which exercise (#156)

Six working directories become four. Dropping bisect removes git-bisect-exercise/, and worktrees are now created as siblings of conference_planning instead of inside a separate conference_worktree/ clone.

advanced/README.md gains a directory map and an exercise → directory table, and every exercise opens with a > [!IMPORTANT] Working directory: box using the same wording helpers.sh prints.

Less guided exercises (#155)

Every exercise is now Goal → Tasks → collapsed Hint → collapsed Solution, with tasks stated as outcomes ("Find all commits that touch helpers.sh") rather than commands. Anything unguessable or destructive stays visible: hook bodies, git lfs track syntax, and every --force-adjacent command. Each exercise ends with a Check yourself list.

The time comes from the ~20 minutes bisect used to take.

Portability (#147)

advanced/helpers.sh used sed -i '/program/a text', which is GNU-only — so init_advanced_repo, the bootstrap five exercises depend on, failed on macOS. It now uses the same portable idiom the beginner course adopted in #140 (no -i, POSIX a\ + newline, write-to-temp-then-move), and exposes it as an insert_after helper the exercises use too.

Also:

  • git stash savegit stash push -m (deprecated since Git 2.16)
  • Python is gone from the advanced course entirely, along with requirements.txt — it existed only for the bisect checker script. This removes the Git Bash blocker raised in Make sure Git course works on Linux and Git Bash terminal #147.
  • pandoc in Exercise 3 replaced with tar, which needs no extra install anywhere
  • CRLF note added to Exercise 6, where it would otherwise make the whitespace hook misfire
  • Root README now leads with Git Bash for Windows, WSL2 as the alternative

New advanced/tests/test_helpers.sh (10 assertions) mirrors the beginner harness, and a new test_helpers.yml workflow runs both suites on ubuntu-latest, macos-latest and windows-latest.

Note

Two pre-existing problems surfaced while wiring that up and are fixed here: neither test script exited non-zero on failure (so a CI job would always have passed), and the beginner script tested get_default_branch_name from outside any repository — it only passed locally because developers happen to have a git repo above their checkout.

Git Bash is genuinely covered, not merely reviewed. windows-latest ships Git for Windows, and a step with shell: bash runs under its Git Bash, so the workflow exercises the exact platform this issue was raised about rather than a stand-in for it. No manual pre-course check is needed.

New: C2SM/c2sm-git-example

Part 2 needs somewhere safe to practise. https://github.com/C2SM/c2sm-git-example is now populated: Markdown pages about C2SM, a CONTRIBUTING.md, issue and pull request templates, and a checks.yml workflow so participants see real status checks.

Two content shapes are deliberate:

  • participants/<handle>.md — every participant's PR touches a unique file, so they never conflict
  • glossary.md — shared and alphabetical, so PRs touching it do conflict, which is the point of the last part of Exercise 8

Verified live: both checks pass on main and on a pull request (smoke-test PR opened, confirmed, then closed).

C2SM/git-workflow-practice is superseded and no longer referenced.

New checks against future drift

This update was needed largely because the slides were migrated to Marp in July and the exercises were never updated to match — and nothing detected that. Two workflows now make the same drift fail a pull request.

content_consistency.yml runs advanced/tests/check_consistency.sh, which verifies that the slides and the exercises reference each other in both directions, that every diagram used has a Mermaid source and no source is orphaned, that no raster images creep back in, that internal links and in-page anchors resolve, that advanced/README.md lists every exercise, and that files have no accidental trailing whitespace and end with a newline. It runs locally too, like build.sh.

The whitespace and newline rules are scoped to advanced/ plus the root files this update owns: the beginner course uses trailing two spaces deliberately for Markdown hard breaks, so a repository-wide rule would misfire on it constantly.

shellcheck.yml lints the shell scripts at severity=warning. beginner/helpers.sh is excluded — it has 16 pre-existing warnings about unquoted variables and unchecked cd, which are a separate cleanup rather than a regression to gate on here.

Also

  • Expert_Topics.md at the repo root — a backlog of what neither course covers (internals, history rewriting, recovery, bisect, large repositories, signing, collaboration at scale), and a syllabus draft should there ever be a Part 3
  • GitHub vs GitLab comparison on a slide and in Exercise 8, since C2SM uses gitlab.ethz.ch too
  • advanced/schedule.md rewritten for the two-part structure with a '26 column
  • Modernised tools slide: gh, lazygit, delta/difftastic, GitHub Desktop, JetBrains
  • Fixed .vscode/settings.json pointing at slides_theme/c2sm.css, which does not exist
  • Fixed the .gitkeep speaker notes, which were a verbatim copy of the .gitignore ones

Verification

  • Slides build to 46 pages; every slide inspected as an image, no overflow, all 13 diagrams legible
  • Exercises 3–7 walked end to end on Linux running every command verbatim; Exercise 1 commands checked against this repository's real history
  • Both helper test suites pass (19 assertions) in an isolated layout with no ancestor git repo, and the consistency script passes all 10 of its checks — both verified against a clean clone of the committed branch, not just the working tree
  • The consistency script and ShellCheck were both confirmed to fail on deliberately broken input, so they are not merely reporting success
  • All internal Markdown links and in-page anchors resolve; no reference to a deleted exercise survives; every referenced SVG has a .mmd source and no .mmd is orphaned
  • All 49 external URLs return OK, except the pr-<number> placeholder (inside backticks, not a link) and the Expert_Topics.md link, which resolves once this merges

@mjaehn mjaehn added advanced Relevant for Advanced course slides Changes to presentation slides labels Aug 18, 2026
@mjaehn
mjaehn marked this pull request as draft August 18, 2026 09:58
mjaehn and others added 13 commits August 18, 2026 14:47
Renumber the exercises to follow the teaching order of the new two-part
structure, and rewrite each one as tasks with optional hints instead of
commands to paste.

Exercises now state a goal and let participants work out the command, with
Hint and Solution in collapsed blocks. Commands that are unguessable or
destructive stay visible: hook bodies, git lfs syntax, anything near --force.
Each exercise opens with a "Working directory" box and closes with a short
"Check yourself" list.

  Exercise_1_git-log-diff-show.md -> Exercise_1_examining-history.md
  Exercise_8_git-submodule.md     -> Exercise_2_submodules.md
  Exercise_3_gitignore.md         -> Exercise_3_ignoring-files.md
  Exercise_6_git-cherry-pick.md   -> Exercise_4_cherry-pick-rebase.md
  Exercise_4_git-stash-worktree.md-> Exercise_5_stash-worktree.md
  Exercise_7_git-hooks.md         -> Exercise_6_hooks.md
  Exercise_5_git-workflow.md      -> Exercise_8_web-workflow.md

Exercise 4 absorbs Exercise_bonus_rebase.md, so merge and rebase are compared
side by side rather than rebase being an optional extra. Exercise 7 on git lfs
is new. Exercise 2 on git bisect is dropped and moves to Expert_Topics.md.

Content fixes along the way:
- git stash save -> git stash push -m (deprecated since Git 2.16)
- hard-coded SHAs replaced with relative refs so Exercise 1 cannot rot
- submodule target moved off a personal account to C2SM/c2sm-git-example
- pandoc dropped from Exercise 3 in favour of tar, which needs no install
- corrected the claim that pre-commit run --all-files only checks staged files
- "master script" renamed to "dispatcher script"

Closes #155
Closes #156
Three additions to the C2SM Marp themes, needed by the restructured slides:

- .warning, an amber callout, replacing the achtung.gif used until now
- .quote, a pull quote with attribution
- table styling, since the themes had no table rule and the inherited Marp
  default is hard to read on the dark background

Both the light and the dark theme get the same set, so a deck can switch
between them without losing styling.
Adds 13 Mermaid diagram sources under advanced/slides/diagrams/, a shared
mermaid-config.json carrying the C2SM palette, and build.sh, which renders
them to SVG and then builds the PDF.

CI now calls build.sh instead of an inline marp command, so a local build and
the committed PDF cannot drift apart, and commits the rendered SVGs alongside
the PDF so the VS Code Marp preview works without a render step.

Note that marp-core's default HTML allow-list has no svg entry, so inline
<svg> would be silently stripped. Referencing external .svg files as ordinary
Markdown images avoids that entirely and needs no --html flag.

Also adds a concurrency group to the build workflow, which previously pushed
to the PR branch with no guard against racing itself.
Replaces the Parts 0-4 plus Bonus structure with a two-way split:

- Part 1, Your Git Toolbox: log/blame/diff/show, submodules, ignoring files,
  cherry-pick and rebase, stash and worktree, hooks, git lfs
- Part 2, Working Together on GitHub: why a shared workflow, the C2SM User
  Landing Page as a live example, issues, forks, pull requests, checks and
  previews, review, merging, keeping a fork in sync

Deletes all 14 third-party raster screenshots, which came from dev.to,
scaler.com, gitkraken.com, dzone.com and a 2019 tweet. They were 1.4 MB, could
not be edited, were off-brand and blurred in the PDF. Twelve are replaced by
the generated diagrams; achtung.gif becomes the .warning class and tweet.png
becomes a pros and cons list.

Every exercise signpost slide now names the working directory, so the
information is in front of participants at the moment they need it.

Also adds a GitHub and GitLab comparison slide, since C2SM works on both
github.com and gitlab.ethz.ch and only the web interface and CI file differ;
modernises the tools slide with gh, lazygit, delta and difftastic; and fixes
the .gitkeep speaker notes, which were a verbatim copy of the .gitignore ones.

The PDF drops from 2.4 MB to 1.7 MB.
init_advanced_repo used sed -i '/program/a text', which is GNU-only. BSD sed
on macOS requires an argument to -i and does not accept that append syntax, so
the helper that five exercises bootstrap from failed outright on a Mac.

Replaces it with the idiom the beginner course adopted in #140: no -i, the
POSIX "a\" plus literal newline form, and write-to-temp-then-move. Exposes it
as an insert_after helper so the exercises can use it too instead of carrying
their own sed one-liners.

Also:
- mkdir -> mkdir -p, since re-running the function used to fail
- git init followed by git branch -m main -> git init -b main
- adds reset_advanced_repo, so participants can start an exercise over; the
  beginner course has had an equivalent for a while

Part of #147
Adds advanced/tests/test_helpers.sh, mirroring the beginner harness, with 10
assertions over insert_after, init_advanced_repo and reset_advanced_repo,
including that the bootstrap is repeatable.

Adds a workflow running both suites on ubuntu-latest, macos-latest and
windows-latest. On Windows the steps use shell: bash, which is the Git Bash
that ships with Git for Windows, so this exercises the platform #147 was
raised about rather than a stand-in for it.

Two pre-existing problems surfaced while wiring this up:

- Neither harness exited non-zero on failure, so a CI job running them would
  have passed unconditionally. Both now propagate a failure.
- The beginner harness tested get_default_branch_name before any repository
  existed, from a directory outside one. It only passed locally because
  developers tend to have a git repository above their checkout; on a clean
  runner the function would exit 1 and take the script with it. Moved to after
  init_simple_repo.

Closes #147
The exercises used to span six working directories with no map anywhere, which
was the most common source of confusion.

Cuts that to four: dropping git bisect removes git-bisect-exercise, and
worktrees are now created as siblings of conference_planning rather than
inside a separate conference_worktree clone.

advanced/README.md gains a directory tree, an exercise-to-directory table, and
a Setup section. Moving the bootstrap here also decouples the exercises from
each other: they used to link to Exercise 3 for it, which forced gitignore to
come before submodules.

schedule.md is rewritten for the two-part structure with a '26 column, plus
notes for the next run: participants need to pair up for Exercise 8, and
should fork c2sm-git-example once at the start rather than twice.

Closes #156
"Git for Advanced" implied an expertise gate that does not exist: the course
needs nothing beyond the everyday basics. The name described a level rather
than a prerequisite, and put people off who were exactly the intended
audience.

  Git for Beginners -> Git: First Steps
  Git for Advanced  -> Git: Next Steps

"Next" states the actual entry requirement, which is having done "First".

The advanced/ and beginner/ directories deliberately keep their names.
Renaming them would break the published landing-page links, the
check_requirements.sh --beginner flag and every bookmark participants hold,
and the issue is about how the courses are advertised rather than how the
repository is laid out.

Still to do outside this repository: the landing page entry in
C2SM/c2sm.github.io, which also still advertises the 2025 slides, and the ETH
technical training catalogue.

Closes #162
A reading list of Git topics neither course covers: internals and the object
model, history rewriting, recovery, debugging with history, merging in depth,
large repositories, signing and automation, collaboration at scale, and
configuration.

Each entry says why it matters and names the commands to look up, rather than
teaching them. It doubles as a syllabus draft should there ever be a third
part.

git bisect lands here, having been dropped from the advanced course.
Python was only ever needed for the git bisect checker script, and that
exercise is gone. Removes requirements.txt, whose jupyterlab and bash_kernel
entries had been stale since the 2025 move from JupyterLab to a plain
terminal, and swaps the Python check in check_requirements.sh for a git lfs
check, which Exercise 7 does need.

This also removes the last obstacle to running the advanced course under Git
Bash, which was getting a Python interpreter working there.

Separately, .vscode/settings.json listed slides_theme/c2sm.css, which has not
existed since the theme was split into light and dark variants during the Marp
migration.
This content update was needed largely because the slides were migrated to
Marp in July and the exercises were never updated to match. Nothing detected
that drift; it was found by reading. These checks make the same drift fail a
pull request instead.

advanced/tests/check_consistency.sh verifies that:

  1-2. the slides and the exercises on disk reference each other, both ways
  3-4. every diagram used has a Mermaid source, and no source is orphaned
  5.   no raster images creep back into the slides
  6-7. internal Markdown links and in-page anchors resolve
  8.   advanced/README.md lists every exercise
  9-10. no accidental trailing whitespace, and files end with a newline

It runs locally as well as in CI, like build.sh.

Checks 9 and 10 are scoped to advanced/ and the root files this update owns.
The beginner course uses trailing two spaces deliberately for Markdown hard
breaks, so a repository-wide rule would misfire on it constantly; the check
allows exactly-two-space breaks and flags everything else.

Adds a ShellCheck workflow at severity=warning. beginner/helpers.sh is
excluded: it has 16 pre-existing warnings about unquoted variables and
unchecked cd, which are a separate cleanup rather than a regression to gate
on here.
mjaehn added a commit to C2SM/c2sm-git-example that referenced this pull request Aug 18, 2026
Matches the naming settled in C2SM/git-course#170 and what the landing page
already publishes.
mjaehn and others added 7 commits August 18, 2026 15:15
Settles the umbrella name over the two courses, and drops the outer numbering
that an earlier draft of the pull request description had used.

  C2SM Git Courses
  |-- Git: First Steps        (beginner/)
  `-- Git: Next Steps         (advanced/)
      |-- Part 1: Your Git Toolbox
      `-- Part 2: Working Together on GitHub

The courses are deliberately not numbered. "First" and "Next" already carry
the sequence, so a "Part 1" and "Part 2" prefix would say it twice, and it
would collide with the two Parts inside the second course, leaving a Part 2
that contains a Part 1 and a Part 2.

It would also work against #162: labelling them Part 1 and Part 2 suggests you
need both, when they are separately attendable courses held months apart, and
making the second one approachable on its own was the point of that issue.

"C2SM Git Courses" also matches what the landing page already publishes.
Mermaid assigns a gitGraph cherry-pick commit a randomly generated id, which
lands in a CSS class name in the SVG. It has no effect on how the diagram
looks, but it made cherry-pick.svg differ on every single build.

Since the build workflow commits the rendered SVGs back to the branch, that
meant every CI run produced a spurious "Update advanced slides diagrams and
PDF" commit for a diagram nobody had touched. Normalising the class name in
build.sh makes two consecutive builds byte-identical.

Uses the write-to-temp-then-move form rather than sed -i, for the same reason
as advanced/helpers.sh: BSD sed on macOS requires an argument to -i, and
build.sh is meant to run locally as well as on a runner.
mjaehn and others added 3 commits August 19, 2026 07:43
Marp stamps CreationDate/ModDate with the current time on every build,
so the PDF differs byte-for-byte even when nothing changed. That made
CI commit a new PDF on every run, retriggering the workflow and
requiring repeated approval. Pin both dates to the epoch after render.
Comment thread advanced/slides/slides.md Outdated
<div class="note">

**Where you work:** `advanced_git/conference_submodule`
You will need a fork of <https://github.com/C2SM/c2sm-git-example> - the same one you use in Exercise 8.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioning already Exercise 8 might confuse them into going to Exercise 8 before

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 73fcb22 - keeping the submodules exercise local (without fork)

Comment thread advanced/slides/slides.md Outdated
---

# .gitignore
# Ignoring Files

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't mention that this goes in the '.gitignore' file and that it should be committed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in fa28d8c

Comment thread advanced/slides/slides.md
# A Submodule Is a Pointer to One Commit

Exercises can be found at: <https://github.com/C2SM/git-course/tree/main/advanced>
![w:1000](images/submodule-pointer.svg)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this diagram it might suggest that the 'gitlink: poster' is a separate concept from '.gitmodules'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to make it more clear: 7dcfa89

Comment thread advanced/slides/slides.md Outdated
- Exercise 3: `.gitignore`
- Exercise 4: `git stash` and `git worktree`
- Exercise 5: practice the git workflow
![w:420](images/merge.svg)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two diagrams in this slide are a bit confusing in that in the merge diagram it looks like it is merged into main, while in the rebase diagram it looks like it is being rebased into feature.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I re-made the slide covering merge and rebase: d8699e3

mjaehn and others added 10 commits August 20, 2026 10:01
Both build workflows shared the concurrency group build-slides-${{ github.ref }},
so triggering both on the same push caused one to cancel the other.
Give participants a sense of pacing per exercise and make the
collapsible Hint/Solution sections easier to scan.
Marp Core's default emoji handling converts Unicode emoji into <img> tags
loading Twemoji SVGs from a CDN. Chromium's PDF/screenshot layout isolates
that <img> onto its own line, even with plenty of horizontal space left.
Disabling the conversion leaves emoji as plain Unicode text, rendered
inline by the system font as expected, and drops a CDN dependency from
the render step.
mjaehn and others added 17 commits August 20, 2026 11:09
build_advanced_slides.yml and build_beginner_slides.yml each auto-commit
their rebuilt PDF back to the PR branch, but sit in separate concurrency
groups, so they don't serialize against each other. A push touching a
path both watch (slides_theme/**) fires both workflows at once; whichever
pushes second gets rejected as a non-fast-forward, since neither retried.

Both jobs only ever touch their own deck's files, so a fetch+rebase can't
conflict. Retry the push a few times with a rebase in between instead of
failing outright on the first rejection.
The per-check rundown is only useful when diagnosing a failure; on a
passing commit it's just noise scrolling past. Capture the consistency
script's output and print it in full only on failure, otherwise just the
final "All consistency checks passed." line.
Exercise 2 used to require a GitHub fork and SSH key, duplicating what
Exercise 8 introduces later. Replace it with a local bare repository
(glossary-tool.git) built by two new helpers, init_submodule_remote and
commit_to_submodule_remote_by_colleague, so the whole exercise runs
without network access.

Also corrects the detached-HEAD note, which claimed it happens right
after `git submodule add` - verified against Git 2.51 that it does not;
the submodule stays on `main` until a later `git submodule update`
actually detaches it, so the note and Task 15 now reflect that.
Marp turns every non-directive comment in slides.md into a presenter note,
shown in the HTML deck's presenter view and dropped by the PDF renderer. Add
one to each of the 47 advanced slides: timing cues, what to emphasise, the
misconceptions worth pre-empting, and what to watch for while walking the room
during an exercise.

Both build.sh scripts now render HTML next to the PDF, and a new workflow
assembles the two decks plus a landing page and deploys them on every push to
main. The site mirrors the repository layout on purpose: the theme stylesheets
reference the C2SM logo relative to the deck, so the <course>/slides/ depth has
to survive into the published site.

The generated HTML is gitignored. The deployed site is the artifact, so there is
no second build product to keep in sync with the source.

Publishing needs Pages set to the GitHub Actions source once, in the repository
settings.
Convert speaker notes from prose to nested bullets for faster scanning during the live session.
Replace the A/B/C placeholder commit ids in the gitGraph diagrams with
messages from the conference planning example used in Exercise 4.

Merge and rebase now share one three-panel diagram: the common starting
point, the merge result and the rebase result. The replayed commits are
marked F' G' H' to show they are new commits, not moved ones.

Check every slide for content clipped by the 1280x720 page and re-fit
the five that overflowed: schedule, cherry-pick, rebase, worktree and
the fork sync slide, which now puts its bullets and diagram side by side.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

advanced Relevant for Advanced course ci exercises slides Changes to presentation slides

Projects

None yet

3 participants