From 25e2bd942f6c26997b22588628a6402e37ddb659 Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Tue, 12 Mar 2024 14:03:53 +0100
Subject: [PATCH 01/20] =?UTF-8?q?Changes=20according=20to=20the=20review?=
 =?UTF-8?q?=20by=20S=C3=A9bastien=20(sections=200=20through=202)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 00-what-why.md          |  2 +-
 01-setup.md             | 22 +++++++++++++++++++---
 02-creating-projects.md |  9 ++++++---
 3 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/00-what-why.md b/00-what-why.md
index 5eae05e..1824b73 100644
--- a/00-what-why.md
+++ b/00-what-why.md
@@ -39,7 +39,7 @@ A lot of other Git-based development platforms exist (GitHub, Gitea, Bitbucket,
 Everything on `gitlab.inria.fr` and `gitlab-int.inria.fr` is hosted on Inria's own servers, which guarantees that your code is safe!
 
 {: .box-warning}
-This is why you should **not** use `gitlab.com` or `github.com` for your software projects!
+In most cases, you should **not** use `gitlab.com` or `github.com` for your software projects. If you are only working with specific collaborators, including a few who do not have an Inria account, the Inria instances of GitLab should still be used: you can very simply [invite external collaborators to `gitlab.inria.fr`](https://external-account.inria.fr). The use of external platforms like `gitlab.com` and `github.com` can be envisioned for open-source software, for which external contributions can be expected (...and in that case, you should also probably discuss the legal aspects with the right people at Inria before making any move), but as long as there is no stringent need, you should keep your codebase safe.
 
 It is impossible to overstate how the use of GitLab makes collaborating on a software project easier and faster, and you can learn how to use it **one step at a time**.
 
diff --git a/01-setup.md b/01-setup.md
index afc9d8a..660dbde 100644
--- a/01-setup.md
+++ b/01-setup.md
@@ -8,6 +8,8 @@ Enough chit-chat, let us delve right into it.
 
 # Installing Git {#git}
 
+There are different ways of installing Git based on the operating system you are using. Once this is done, please ***do not skip [the last subsection]({{'/01-setup#git-config' | relative_url }})***: it is a required configuration step (if you skip it, Git will ask you before you can change the contents of a project).
+
 ## Linux-based distributions
 
 All package managers know Git. Here are a few examples:
@@ -56,16 +58,29 @@ sudo port install git
 
 Standalone installers (both 32-bit and 64-bit) are provided [here](https://git-scm.com/download/win).
 
+## Local configuration {#git-config}
+
+Once Git is installed, you may configure it as you want. There are [a lot of options](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration), most of which will not make sense before we delve further into Git. The only thing that is necessary is telling Git your name and e-mail address; this information will not be spread on the Internet and/or sold to companies (this is not Honey!), it will just be written in the metadata of your *commits* (we will be talking about these [later on]({{'/03-linear-git-project#repo' | relative_url }})) so that your collaborators know who contributed which piece of code.
+
+Only two commands are needed from the terminal (or Powershell for Windows users):
+
+```bash
+git config --global user.name "Your Name"
+git config --global user.email "youremail@yourdomain.com"
+```
+
+Great, you have Git on your computer and it's good to go!
+
 # Connecting to GitLab {#gitlab}
 
 {: .box-note}
-From now on, every use of the word "GitLab" refers to the `gitlab.inria.fr` instance. Things work in a very similar fashion on `gitlab-int.inria.fr`, except that one cannot invite external collaborators there. Other instances, including `gitlab.com`, are not covered here, but they are basically the same tool: you might just have less options on `gitlab.com` as a simple, non-paying user... and your data would be stored on some server somewhere, potentially accessible by Gosh-knows-whom.
+From now on, every use of the word "GitLab" refers to the `gitlab.inria.fr` instance. Things work in a very similar fashion on `gitlab-int.inria.fr`, except that one cannot [invite external collaborators](https://external-account.inria.fr/) there. Other instances, including `gitlab.com`, are not covered here, but they are basically the same tool: you might just have less options on `gitlab.com` as a simple, non-paying user... and your data would be stored on some server somewhere, potentially accessible by Gosh-knows-whom.
 
 ## Accessing the website
 
 This one is easy:
 
-* Go to `gitlab.inria.fr` with your favorite Web browser (even if it is Safari or Microsoft Edge, we will let it slide).
+* Go to `gitlab.inria.fr` with your favorite Web browser (even if it is Safari, Chrome or Microsoft Edge, we will let it slide).
 * Connect with ILDAP, using your usual CAS username-password pair.
 * Well, that's it. Welcome to GitLab. You should be welcomed with the list of projects hosted on GitLab that you have access to, and you can filter out the ones you did not create yourself by clicking on "Personal". We shall explore the interface pretty soon.
 
@@ -92,8 +107,9 @@ If you already have an SSH key that you want to use, you can (of course) skip th
 * From the Terminal (Linux/MacOS) or the PowerShell (Windows), run either `ssh-keygen -t ed25519` or `ssh-keygen -t rsa -b 4096` (Ed25519 and RSA are two different cryptosystems: Ed25519 is considered safer, but the additional parameter in the second command tells the tool to create a 4096-bit key, which is basically [unbreakable in the foreseeable future](https://security.stackexchange.com/questions/90077/ssh-key-ed25519-vs-rsa)).
 
     * When asked for the full path of the file in which the key should be saved, just press Enter to keep the default path.
-    * When prompted, enter (twice) a passphrase for your key. You technically can just press Enter so as not to set any passphrase, but this additional layer of security is strongly recommended. (However, you will have to type this passphrase every time you have to communicate with GitLab from your computer, that is, every time a command such as `git fetch`, `git pull`, `git push`... is run. Thus, I would advise against setting a 100-character passphrase for your SSH key. Your CAS password, on the other hand...)
+    * When prompted, enter (twice) a passphrase for your key. You technically can just press Enter so as not to set any passphrase, but this additional layer of security is strongly recommended. (By default, you will have to type this passphrase every time a command such as `git fetch`, `git pull`, `git push`... is run. However, there is a way to alleviate this: see below.)
     * Done! You are told where you public and private keys are, plus a long string of seemingly random characters and a weird abstract ASCII art. You may totally ignore these last two things.
+    * If you are afraid about this "having-to-type-your-huge-passphrase-100-ties-a-day" thing, good news are coming your way. What if you were only asked your passphrase once per session? Pretty simple: just type `ssh-add ~/.ssh/<name-of-the-private-key>` (where the name of the private key should be either `id_rsa` or `id_ed25519`). This will definitely make your life easier. You may now say "good night" to your private key: this should be the last time you explicitly use it.
 
 ### Giving your public key to GitLab
 
diff --git a/02-creating-projects.md b/02-creating-projects.md
index dbfa893..da2b772 100644
--- a/02-creating-projects.md
+++ b/02-creating-projects.md
@@ -55,7 +55,7 @@ But wait! Before we reach this page, we need to know **where** to create the pro
 
 Back when paper existed (aaaah, good ol' times), we organized our actual, physical files in folders, themselves sorted in different drawers and file cabinets. This basic organization was projected into our computers, with, once again, files in folders, but this time, we could have any (limited, but already potentially huge) tree-like hierarchy of folders ans subfolders. Would you have any trust in a tool designed to manage your software projects that just throws all these projects on the same pile?
 
-Yeah, exacty.
+Yeah, exactly.
 
 {: .box-success}
 **Groups** are exactly what it says on the label. If you have (or *will* have in the foreseeable future) several related projects, you should create a group for them. You can think of a group as a folder for projects... with a sophisticated lock.
@@ -205,7 +205,10 @@ Once your project is created, you are welcomed with instructions on how to actua
 
 ![](../assets/img/02-creating-projects/project-from-local-4.jpg){: .mx-auto.d-block :}
 
-This is exactly what you want! Just follow these instructions, and the contents of the folder you `cd` into will be pushed into your fresh GitLab project.
+This is exactly what you want! *If you want to push **all** the contents of the local folder you `cd` into*, just follow these instructions, and the whole folder will be pushed into your fresh GitLab project.
+
+{: .box-warning}
+**Think about cleaning up your project before pushing it:** you should not push temporary files, local configuration files, and so on. If there are specific files or subfolders that you do not want to push (the `build` or `_build` folders are typical examples), you can choose what you actually want to push. Just replace command `git add .` with several commands of the form `git add path/to/subfolder` or `git add path/to/file`. While the former tells Git to push the whole directory (this is what `.` means), the latter specifies which subfolders and files should be tracked. We will see later on how to [prevent specific files from being added]({{'/05-good-practices#gitignore' | relative_url }}).
 
 {: .box-warning}
 If the `-initial-branch` option is not recognized, you have a version of Git that is too old (maybe you installed it a few years ago and forgot to update it). Just update your Git installation and retry.
@@ -216,7 +219,7 @@ Understanding these lines requires knowledge about how Git works, including some
 In short, the Git commands given here basically amount to the following:
 * setup the current directory so that it is "Git-ready", and ensure that the name of the default branch is the right one (older projects might have `master` as the name of their default branch, but this was changed in 2020);
 * tell Git that this local directory should be linked to the one at the given address (it is exactly the one that is provided to you by *Clone → Clone with SSH* on the project page; **do not use the `https` address instead**: this would require you to use HTTPS authentication on this project, which is way more cumbersome);
-* take all the current contents of your local folder and push them to the GitLab project (plus, the `-u` option tells Git that the remote project to which you just pushed will indeed be the default remote).
+* take all the current contents of your local folder (read the box below before continuing) and push them to the GitLab project (plus, the `-u` option tells Git that the remote project to which you just pushed will indeed be the default remote).
 </div>
 
 Done! Refresh the webpage for your project, and this is what you will see:
-- 
GitLab


From 8ee66fc3c72b3fa17c4904960dbfbd533c8de20f Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Wed, 13 Mar 2024 08:53:19 +0100
Subject: [PATCH 02/20] Add setup options for Mac and Win + explain detached
 HEAD

---
 01-setup.md          | 27 +++++++++++++++++++++++----
 05-good-practices.md | 19 +++++++++++++++++--
 2 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/01-setup.md b/01-setup.md
index 660dbde..357c527 100644
--- a/01-setup.md
+++ b/01-setup.md
@@ -12,7 +12,7 @@ There are different ways of installing Git based on the operating system you are
 
 ## Linux-based distributions
 
-All package managers know Git. Here are a few examples:
+For starters, you can just type `git` in a terminal to see if you have it pre-installed or not. If a pretty long prompt describing "basic" usage of the command is displayed, congratulations: you may skip this part. Otherwise, you will have to install it... which is not difficult at all, because all package managers know Git. Here are a few examples:
 
 * On Ubuntu/Debian:
 
@@ -42,7 +42,13 @@ Replace `dnf` with `yum` if you are using Fedora 21 or below.
 
 ## MacOS
 
-As always (*sigh*), you will need either [Homebrew](https://brew.sh/) or [Macports](https://www.macports.org/). Then, with Homebrew:
+Start by just typing `git` in a terminal: if a pretty long prompt describing "basic" usage is displayed, Git is already installed on your system. Otherwise, you should get a prompt to install Xcode Command Line Tools. Just so you know: while Xcode itself is a monster (over 40GB!), the Command Line Tools can be installed as a standalone and "only" require between 1 and 2GB. An alternative is this command:
+
+```shell
+xcode-select --install
+```
+
+In both cases, you will end up with the version of Git that is packaged with the Xcode Command Line Tools, which may not be the most up-to-date. If you want the latest version, well... As always (*sigh*), you will need either [Homebrew](https://brew.sh/) or [Macports](https://www.macports.org/). Then, with Homebrew:
 
 ```shell
 brew install git
@@ -56,13 +62,26 @@ sudo port install git
 
 ## Windows
 
-Standalone installers (both 32-bit and 64-bit) are provided [here](https://git-scm.com/download/win).
+If you really love your standalone installers, both 32-bit and 64-bit installers are provided [here](https://git-scm.com/download/win).
+
+There is another option that I would warmly recommend, as it will likely save you several other times in the future: [Scoop](https://scoop.sh/#/) is a package manager that you can very easily install and run from the PowerShell, and it installs packages without requiring specific permissions (i.e., no permission popup windows and no inputting passwords every minute). The website provides you with simple instructions for installation; basically just input these two commands in a PowerShell terminal:
+
+```shell
+Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
+Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
+```
+
+You can then install Git with a simple
+
+```shell
+scoop install git
+```
 
 ## Local configuration {#git-config}
 
 Once Git is installed, you may configure it as you want. There are [a lot of options](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration), most of which will not make sense before we delve further into Git. The only thing that is necessary is telling Git your name and e-mail address; this information will not be spread on the Internet and/or sold to companies (this is not Honey!), it will just be written in the metadata of your *commits* (we will be talking about these [later on]({{'/03-linear-git-project#repo' | relative_url }})) so that your collaborators know who contributed which piece of code.
 
-Only two commands are needed from the terminal (or Powershell for Windows users):
+Only two commands are needed from the terminal (or the PowerShell terminal for Windows users):
 
 ```bash
 git config --global user.name "Your Name"
diff --git a/05-good-practices.md b/05-good-practices.md
index fb99495..01a908e 100644
--- a/05-good-practices.md
+++ b/05-good-practices.md
@@ -421,9 +421,24 @@ Branch `main` can still grow: you made sure that this specific version of our co
 
 ![](../assets/img/05-good-practices/E-tags/git-tag-9.jpg){: .mx-auto.d-block :}
 
-We will not be delving into what this "detached HEAD" stuff actually means. I know I had a hard time wrapping my head (...ah ah) around this. Just remember that you can basically "just have a look" at the tagged version of the code, but changes you make from there will not be saved unless you explicitly ask Git to put them in a fresh branch.
+The question of what "detached HEAD" means is one that pops up *a lot* in discussions around Git. If you just want some very pragmatic recap, here it is:
 
-At this stage, we should just switch back to the main branch:
+* You can basically "just have a look" at the tagged version of the code (or any commit for that matter, as checking out a commit using its hash is possible but will get you in a "detached HEAD" state.
+* However, *changes you commit in a "detached HEAD" state will **not** be saved when you switch back to a branch, unless you create a new branch or tag that references your commit*.
+
+If you want more information, the following info box is for you. You may skip it if you want. No hard feelings.
+
+<div class="box-note" markdown="1">
+Git deals with a data structure that is at its core a directed graph of commits, where each commit points to its parent commit (or commit*s*, as is the case for merge commits for example). To keep this graph as small as possible, Git implements a **garbage collection** which, among others, removes all unreachable objects; in particular, "hanging" commits are deleted.
+
+The basic idea of garbage collection is reclaiming memory that is allocated, but not (or no longer) referenced. A [very common way](https://en.wikipedia.org/wiki/Tracing_garbage_collection) of doing this is by tracing which objects are reachable from certain *root objects*, and purging everything that is left (i.e., unreachable).
+
+This is what Git does, and its root objects are *branches and tags* (both of these objects are references to specific commits). When you add a commit to a branch, the branch itself (as in "the underlying object in memory") is updated so that it now references your fresh commit. A tag, on the other hand, will always point to the same commit.
+
+When you checkout anything other than a branch, any commits you add from this point are unreferenced: there is no branch or tag pointing to the new chain of commits you created. This is what "detached HEAD" means: where you currently are (your HEAD) is not attached to a specific branch or tag. As a result, your new commits are hanging, and if you do not solve this by creating a branch or tag that is "attached" to your latest commit, the garbage collector will remove these fresh commits next time it runs.
+</div>
+
+At this stage, we may just switch back to the main branch:
 
 ![](../assets/img/05-good-practices/E-tags/git-tag-10.jpg){: .mx-auto.d-block :}
 
-- 
GitLab


From b35143143259d7a1a34a212e24b2e9244fc052ae Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Thu, 14 Mar 2024 15:20:51 +0100
Subject: [PATCH 03/20] Talk about hooks, local excludes, personal namespace +
 be sweeter with git fetch

---
 02-creating-projects.md  |  4 ++
 03-linear-git-project.md | 13 +++---
 05-good-practices.md     |  3 ++
 08-advanced.md           | 88 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 102 insertions(+), 6 deletions(-)

diff --git a/02-creating-projects.md b/02-creating-projects.md
index da2b772..a927fc8 100644
--- a/02-creating-projects.md
+++ b/02-creating-projects.md
@@ -53,6 +53,10 @@ But wait! Before we reach this page, we need to know **where** to create the pro
 
 # Groups {#groups}
 
+GitLab provides you with a *personal namespace*, based on your username. It is the most obvious solution when you want to create a project, but the fact that it is *personal* probably means that it is not the best idea to put everything in here. Plus, well... it would not be a great idea either to put every project in the same place anyways, would it? There are also a lot of limitations on what you can do there, including a strict limit on the number of projects you can create inside it.
+
+So... What are our alternatives?
+
 Back when paper existed (aaaah, good ol' times), we organized our actual, physical files in folders, themselves sorted in different drawers and file cabinets. This basic organization was projected into our computers, with, once again, files in folders, but this time, we could have any (limited, but already potentially huge) tree-like hierarchy of folders ans subfolders. Would you have any trust in a tool designed to manage your software projects that just throws all these projects on the same pile?
 
 Yeah, exactly.
diff --git a/03-linear-git-project.md b/03-linear-git-project.md
index 2c5a58c..55eef77 100644
--- a/03-linear-git-project.md
+++ b/03-linear-git-project.md
@@ -40,7 +40,10 @@ Type your SSH key passphrase when asked, then wait for the cloning operation to
 
 ![](../assets/img/03-linear-git-project/A-cloning/local-1.jpg){: .mx-auto.d-block :}
 
-The `.git` folder is hidden by default (if you do not see it in your working copy, do not worry, you still have it). This is where the magic actually happens, but we are not delving into this before getting the grip of how to use Git. For the moment, just remember that **there is no reason in the world for you to edit anything in the `.git` folder**. For all intents and purposes, the whole project is a `README.md` file and nothing more.
+The `.git` folder is hidden by default (if you do not see it in your working copy, do not worry, you still have it). This is where the magic actually happens, but we are not delving into this before getting the grip of how to use Git. For the moment, you may assume (for convenience) that *there is no reason for you to edit anything in the `.git` folder*. For all intents and purposes, the whole project is a `README.md` file and nothing more.
+
+{: .box-note}
+This is kind of a white lie: there are a few very good, but a bit more advanced, reasons to change the contents of this folder. You may learn more about this in [this additional content]({{'/08-advanced#hooks-excludes' | relative_url }}).
 
 From now on, Git will remember where my folder came from. As long as I am working in the folder (or a subfolder) of the working copy, Git knows to which repository it is linked. I can now, whenever I want, fetch the changes that were submitted by my collaborators, change the code, and decide whether I want to push all or some of my changes back to the repo (thus adding my own brick to the repo's history). Okay, simple enough.
 
@@ -182,12 +185,10 @@ The one question that is important to us right now is the first one: I just fetc
 {: .box-success}
 **Pulling** is a two-stage process: first, changes are *fetched* from the origin; second, the changes that were done on the origin are *merged* with the changes that were already made in the working copy.
 
-This means two things:
-
-* You will not be using `git fetch` that often, as `git pull` is actually more convenient and starts by calling `git fetch`!
-* Even if you just fetched, `git pull` will call `git fetch` anyway, so that your computer will indeed communicate with the origin, hence the need to type your passphrase. (There is a way to merge fetched changes with your local changes without having to call `git fetch` again, but it is way more convoluted, so that Git would rather advise you to just pull.)
+This means, in particular, that even if you just fetched, `git pull` will call `git fetch` anyway, so that your computer will indeed communicate with the origin once again. (There is a way to merge fetched changes with your local changes without having to call `git fetch` again, but it is way more convoluted, so that Git would rather advise you to just pull.)
 
-Why did I tell you about fetching, then? Two reasons: (i) so that you get a better understanding of what happens under the hood, and (ii) because calling `git fetch` with optional arguments will prove pretty useful later on.
+{: .box-info}
+There are interesting opinions out there about [why you should not always use `git pull`](http://longair.net/blog/2009/04/16/git-fetch-and-merge/), but for our purposes, using `git pull` should be fine. You should still, at some point, read the article linked in this very paragraph to know more about the differences between "pulling" and "fetching then merging": the more complex your Git project is, the more important it may become. Also, calling `git fetch` with optional arguments will prove pretty useful later on, so even at this stage, it is nice to know that `git pull` is all but an atomic command.
 
 For now, we have to adapt our workflow so that changes on the remote are handled. Let's say that I just have teeny tiny changes to make, and I pulled pretty recently. After I made my changes, but before I push them, I should be pulling again! The part of the workflow that has to be changed is the following:
 
diff --git a/05-good-practices.md b/05-good-practices.md
index 01a908e..0998256 100644
--- a/05-good-practices.md
+++ b/05-good-practices.md
@@ -259,6 +259,9 @@ By listing all files, folders and file/folder "name templates" (the exact term i
 {: .box-warning}
 It is actually possible to create several `.gitignore` files in several subfolders of your project, but it makes exclusion rules less clear, clutters your project, and is generally considered bad practice.
 
+{: .box-note}
+On the other hand, one should note that the `.gitignore` file is meant to be pushed to the repo, thus providing rules for which files should be ignored *in every working copy*. You might also want to exclude some of your own files, that you moved in your local copy for convenience but should not push (and yes, this includes your `passwords.txt` file... we definitely have to talk about this). In this case, what you want is exclusion rules that are local to your working copy: [this small appendix is about this]({{'/08-advanced#local-excludes' | relative_url }}).
+
 ## MR templates and parameters {#mr}
 
 Badly written issues were a problem we did not want to face, which is why we created issue templates. For MRs, we want to avoid the exact same problem, and we can use the exact same solution!
diff --git a/08-advanced.md b/08-advanced.md
index bbf2f78..66f66c1 100644
--- a/08-advanced.md
+++ b/08-advanced.md
@@ -315,6 +315,94 @@ This is a nice summary of why your project maybe should not be deleted: the high
 
 Regarding forks, there is a simple rule to be remembered: ***If you delete a private project, its forks will be deleted too.*** If you delete a *public* project, one of its forks will be automatically picked as the new "original project" from which all other forks are forked off.
 
+# About the `.git` folder {#hooks-excludes}
+
+[Earlier on in this tutorial]({{'/03-linear-git-project#clone' | relative_url }}), I told you that you might just pretend that there is no reason to touch anything in the `.git` folder that is automatically created when you initialize or clone a project.
+
+*Well, actually*, there are a few neat tricks that you can use there. Let us have a look at two of them: Git hooks, and local excludes.
+
+## Git hooks {#git-hooks}
+
+{: .box-success}
+A ***hook*** is a script that gets executed when certain actions occur.
+
+Hooks can be *client-side* (triggered by actions such as committing and merging), or *server-side* (triggered by actions such as receiving pushed commits); we will just have a look at client-side hooks in this section. Here are a few examples of such hooks ([there are way more](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)):
+
+* `pre-commit` may be used for running test suites or inspecting code (linting, formatting, etc.) before it gets committed. These are used quite a lot in practice: they help the project owner ensure that every pushed code complies with the standards of the project, they tell contributors what they should do to make their code comply with them, and they save time for everyone during MRs.
+* `prepare-commit-msg` provides the text editor with a template, or default, commit message.
+* `commit-msg` checks the validity of a commit message (generally in terms of conformance to a pattern) before creating the commit.
+* `pre-rebase` may be used to ensure that a rebase will not go wrong before actually running it.
+
+In all the cases above, the current operation (committing or rebasing) will be aborted if the hook returns a non-zero value.
+
+Hooks may be written in any scripting language. Of course, the most common examples are shell scripts, like this very basic `pre-rebase` hook that would just prevent you from rebasing *at all*:
+
+```bash
+#!/bin/sh
+
+echo "pre-rebase: Rebasing is dangerous. Don't do it."
+exit 1
+```
+
+or Python scripts, like this `prepare-commit-msg` hook that fetches the issue number from the name of the branch and includes it to the commit message:
+
+```python
+#!/usr/bin/env python
+
+import sys, os, re
+from subprocess import check_output
+
+# Collect the parameters
+commit_msg_filepath = sys.argv[1]
+if len(sys.argv) > 2:
+    commit_type = sys.argv[2]
+else:
+    commit_type = ''
+if len(sys.argv) > 3:
+    commit_hash = sys.argv[3]
+else:
+    commit_hash = ''
+
+print "prepare-commit-msg: File: %s\nType: %s\nHash: %s" % (commit_msg_filepath, commit_type, commit_hash)
+
+# Figure out which branch we're on
+branch = check_output(['git', 'symbolic-ref', '--short', 'HEAD']).strip()
+print "prepare-commit-msg: On branch '%s'" % branch
+
+# Populate the commit message with the issue #, if there is one
+if branch.startswith('issue-'):
+    print "prepare-commit-msg: Oh hey, it's an issue branch."
+    result = re.match('issue-(.*)', branch)
+    issue_number = result.group(1)
+
+    with open(commit_msg_filepath, 'r+') as f:
+        content = f.read()
+        f.seek(0, 0)
+        f.write("ISSUE-%s %s" % (issue_number, content))
+```
+
+(Both of these examples were blatantly stolen from [this more complete tutorial on Git hooks](https://www.atlassian.com/git/tutorials/git-hooks). If you are still not entertained, [here is the full reference](https://git-scm.com/docs/githooks).)
+
+{: .box-note}
+When a repository is initialized (with `git init`), sample hooks are created in the `.git/hooks` folder, with extensions `.sample`. The "dummy" codes inside them provides you with information about the inputs of the scripts.
+
+In order for these hooks to be run, they must be renamed to the name of the hook (without any extension) and copied to `.git/hooks`.
+
+<div class="box-warning" markdown="1">
+***The `.git` folder is not under version control***: the hooks must be installed "manually" by each collaborator who wants to use them, and as a project maintainer, you probably **want** these hooks to be used by every single one of them.
+
+* One solution is to provide hooks in another folder of the project and to give clear installation instructions to the developers, but the process might be made difficult for them by dependencies.
+* To alleviate these problems, you should have a look at the [pre-commit framework](https://pre-commit.com/), which will only ask your collaborators to install it (via `pip install pre-commit` for example) and run it (with `pre-commit install`). Despite its name, this framework not only supports the `pre-commit` hook but also 9 other client-side hooks (at the time of writing).
+</div>
+
+## Local exclusion rules {#local-excludes}
+
+We talked about [the `.gitignore` file]({{'/05-good-practices#gitignore' | relative_url }}), a file that you place under version control and that helps prevent files and folders from being committed: build folders, `.tmp` or `.lock` files, VSCode workspace files, and the like.
+
+However, if there are a few files and folders that *you* put in your working copy for convenience but do not want to push, it might be inappropriate to add their paths to the `.gitignore` file for everyone to see (and, hopefully, no one else will ever create this `my-personal-stuff/secret-project-notes.md` document).
+
+In this case, you can use the exact same way of declaring what should be left out of versioning, but write it in your "local exclude file": `.git/info/exclude`. (If it does not exist, just create it.) As is the case for the whole `.git` folder, this file will not be pushed to the origin in any case, but it will provide additional instructions to Git on which files/folders from your working copy should be ignored (for instance if you `git add` a folder that contains some of them).
+
 # CI pipelines: `.gitlab-ci.yml` examples {#gitlab-ci}
 
 Because of how CI pipelines can be configured, **no Git workflow is incompatible with CI**. A few examples are given here, in order to illustrate various use cases.
-- 
GitLab


From 2f38f1f573bafe83930ba5d8bde7745a7f2167b9 Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Fri, 15 Mar 2024 15:31:30 +0100
Subject: [PATCH 04/20] Fix TOC + add command for removing all branches with
 upstream gone

---
 04-branches-issues.md | 26 +++++++++++++++++++++++++-
 08-advanced.md        |  8 ++++----
 index.md              | 10 ++++++++--
 3 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/04-branches-issues.md b/04-branches-issues.md
index 44c0ae5..6f10ca4 100644
--- a/04-branches-issues.md
+++ b/04-branches-issues.md
@@ -716,7 +716,31 @@ I guess I should just switch back to `main`, and remove my local `add-quantities
 
 ![](../assets/img/04-branches-issues/J-cleaning-up/branch-cleanup-8.jpg){: .mx-auto.d-block :}
 
-And that was it!
+If you need it at some point, there is a way of getting a list of existing branches on your working copy, with some useful information attached, and it is this:
+
+```shell
+git branch -vv
+```
+
+For each branch in your working copy, you can see whether it is only local, linked to a branch in the repo, or linked to a branch that *used to* exist on the repo but is now gone. This is a simple output you may have:
+
+```raw
+  fix-time-shift       4092ee0 [origin/fix-time-shift: gone] Check Internet connection
+  fix-deployment       68c6200 [origin/fix-deployment] Handle playbook updating
+  fix-licences         126421b Update license years
+```
+Here, branch `fix-time-shift` used to be linked to a branch of the same name on the `origin`, but that branch is gone (probably because it was merged). Branch `fix-deployment` still has its counterpart on the origin. Finally, `fix-licences` is only local. (The remaining information is about the commit that the branch points to.)
+
+Depending on the merging options you use in your MRs, you might end up with a lot of branches whose `origin` counterparts were deleted. [A post on Stack Overflow]() proposes a pretty radical solution:
+
+```shell
+git fetch --prune
+git branch -vv | grep ': gone]'|  grep -v "\*" | awk '{ print $1; }' | xargs -r git branch -d
+```
+
+We already know the first half: this make Git aware of which branches were deleted from the `origin`. What the second one does is using `git branch -vv` to get the same information as above, keep only the lines for branches whose `origin` counterpart is gone and that do not contain an asterisk (like the line for the branch you are currently on), fetch the corresponding branch names and call `git branch -d` on these.
+
+Of course, **use this trick with caution** (but note that it will never do anything to branches that are only local).
 
 ----
 
diff --git a/08-advanced.md b/08-advanced.md
index 66f66c1..20a08ab 100644
--- a/08-advanced.md
+++ b/08-advanced.md
@@ -218,7 +218,7 @@ Do not forget to type `git bisect reset` once this is over, or if you get tired
 
 For more information and options, [the Git SCM website is there for you](https://git-scm.com/docs/git-bisect).
 
-# Forks and pull requests {#fork}
+# Forks and merge requests {#fork}
 
 I was recently told by a friend of mine that, in the company he is working for, MRs for branches basically do not exist; instead, they rely on MRs for *forks*. For advanced and experienced users, there are indeed advantages to this workflow.
 
@@ -228,7 +228,7 @@ Let us work with this last scenario. There is an open source software that I am
 
 This is where forking happens.
 
-## Forking
+## Forking {#forking}
 
 {: .box-success}
 A ***fork*** is a fresh repository that contains an exact copy of an already existing repository. This new repository is now yours, in the sense that you have all permissions on it, but GitLab still knows where it comes from.
@@ -268,7 +268,7 @@ Click.
 
 A few seconds later, you have a project. It is yours (kind of). You can work on it.
 
-## Merge request
+## Merge request {#fork-mr}
 
 Remember when I told you that a MR is about bringing the contents of a branch into another branch? Well, here is a nice little detail for you: *these branches do not need to be in the same project*. You can suggest merging contents of a fork into the original project.
 
@@ -295,7 +295,7 @@ The form you have to fill to actually create the MR is basically the same, excep
 1. If the original project is not a private project, that basically means that you are offering some code to a "public" codebase. It can make sense for the community that developed this codebase in the first place to have their word, and what better way of letting them contribute than directly allowing them to commit?
 2. This "Contribution guidelines" stuff does not come from nowhere. Well... Turns out there is a reason why GitLab suggests you (and so did I) to create a file named `CONTRIBUTING.md` at the root of any project to which other people might contribute. This link is a pointer to the `CONTRIBUTING.md` file of the project you forked. The closer you follow these guidelines, the higher the chances of your MR being accepted.
 
-## Closing remarks
+## Closing remarks {#fork-closing}
 
 **As a forker**, remember that the project you forked will probably evolve while you are working on your own personal copy. In other words, you will sometimes fall behind the original project, which will make things pretty complicated if you want to submit an MR at some point. (Also, maybe some of the commits that were pushed on the original project solve bugs you would have encountered at some point... so, it is also in *your* best interest to stay up to date.)
 
diff --git a/index.md b/index.md
index 5e6f074..faf5cbf 100644
--- a/index.md
+++ b/index.md
@@ -85,14 +85,20 @@ If you are already somewhat accustomed to Git and GitLab, you may also directly
   * [Consequences]({{'/07-internals#consequences' | relative_url }})
 
 * [**Extra: Advanced Git commands and troubleshooting hints**]({{'/08-advanced' | relative_url }})
-  * [Branch management: `git fetch --all/--prune`]({{'/08-advanced#git-fetch' | relative_url }})
+  * [Branch management: `git fetch` and `git fetch --prune`]({{'/08-advanced#git-fetch' | relative_url }})
   * [Cleaning up your local copy]({{'/08-advanced#cleanup' | relative_url }})
   * [Juggling with branches]({{'/08-advanced#juggling' | relative_url }})
     * [Rebasing (how to keep up with a source branch)]({{'/08-advanced#rebase' | relative_url }})
     * [Interactive rebasing (how to clean up your mess before pushing)]({{'/08-advanced#irebase' | relative_url }})
     * [Cherrypicking (how to move commits around)]({{'/08-advanced#cherrypick' | relative_url }})
   * [Searching for bugs with `git-bisect`]({{'/08-advanced#git-bisect' | relative_url }})
-  * [Forks and pull requests]({{'/08-advanced#fork' | relative_url }})
+  * [Forks and merge requests]({{'/08-advanced#fork' | relative_url }})
+    * [Forking]({{'/08-advanced#forking' | relative_url }})
+    * [Merge request]({{'/08-advanced#fork-mr' | relative_url }})
+    * [Closing remarks]({{'/08-advanced#fork-closing' | relative_url }})
+  * [About the `.git` folder]({{'/08-advanced#hooks-excludes' | relative_url }})
+    * [Git hooks]({{'/08-advanced#git-hooks' | relative_url }})
+    * [Local exclusion rules]({{'/08-advanced#local-excludes' | relative_url }})
   * [CI pipelines: `.gitlab-ci.yml` examples]({{'/08-advanced#gitlab-ci' | relative_url }})
   * [How to fix a commit to the wrong branch?]({{'/08-advanced#wrong-branch' | relative_url }})
       * [Moving local commits around]({{'/08-advanced#wrong-branch-local' | relative_url }})
-- 
GitLab


From a3d978e5d8762be1d1f8a1e1b5a01a9c867b8a6f Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Tue, 30 Jul 2024 10:29:28 +0200
Subject: [PATCH 05/20] Fix typos + update README + remove original LICENSE
 file

---
 01-setup.md             |   4 +-
 02-creating-projects.md |   2 +-
 04-branches-issues.md   |   8 +-
 05-good-practices.md    |   4 +-
 07-internals.md         |   2 +-
 08-advanced.md          |   4 +-
 CHANGELOG.md            | 239 ----------------------------------------
 LICENSE                 |  21 ----
 README.md               | 238 +--------------------------------------
 9 files changed, 18 insertions(+), 504 deletions(-)
 delete mode 100644 CHANGELOG.md
 delete mode 100644 LICENSE

diff --git a/01-setup.md b/01-setup.md
index 357c527..fbb28d6 100644
--- a/01-setup.md
+++ b/01-setup.md
@@ -109,7 +109,7 @@ There are two possibilities: using HTTPS (the same protocol used for logging you
 
 ## Configuring SSH authentication
 
-SSH authentication uses *assymetrical cryptography*. Basically, you need a pair of keys, a private key and a public key, that are related in some mathematical way. The public key can be used to encrypt messages, but only the private key can be used to decrypt them. This is basically how it is used for client-server authentication:
+SSH authentication uses *asymmetrical cryptography*. Basically, you need a pair of keys, a private key and a public key, that are related in some mathematical way. The public key can be used to encrypt messages, but only the private key can be used to decrypt them. This is basically how it is used for client-server authentication:
 
 * GitLab (the server) uses your public key to encrypt a message and sends you the cipher.
 * Your computer (the client) uses the private key to decrypt the message and send it back to the server.
@@ -128,7 +128,7 @@ If you already have an SSH key that you want to use, you can (of course) skip th
     * When asked for the full path of the file in which the key should be saved, just press Enter to keep the default path.
     * When prompted, enter (twice) a passphrase for your key. You technically can just press Enter so as not to set any passphrase, but this additional layer of security is strongly recommended. (By default, you will have to type this passphrase every time a command such as `git fetch`, `git pull`, `git push`... is run. However, there is a way to alleviate this: see below.)
     * Done! You are told where you public and private keys are, plus a long string of seemingly random characters and a weird abstract ASCII art. You may totally ignore these last two things.
-    * If you are afraid about this "having-to-type-your-huge-passphrase-100-ties-a-day" thing, good news are coming your way. What if you were only asked your passphrase once per session? Pretty simple: just type `ssh-add ~/.ssh/<name-of-the-private-key>` (where the name of the private key should be either `id_rsa` or `id_ed25519`). This will definitely make your life easier. You may now say "good night" to your private key: this should be the last time you explicitly use it.
+    * If you are afraid about this "having-to-type-your-huge-passphrase-100-times-a-day" thing, good news are coming your way. What if you were only asked your passphrase once per session? Pretty simple: just type `ssh-add ~/.ssh/<name-of-the-private-key>` (where the name of the private key should be either `id_rsa` or `id_ed25519`). This will definitely make your life easier. You may now say "good night" to your private key: this should be the last time you explicitly use it.
 
 ### Giving your public key to GitLab
 
diff --git a/02-creating-projects.md b/02-creating-projects.md
index a927fc8..ee66750 100644
--- a/02-creating-projects.md
+++ b/02-creating-projects.md
@@ -57,7 +57,7 @@ GitLab provides you with a *personal namespace*, based on your username. It is t
 
 So... What are our alternatives?
 
-Back when paper existed (aaaah, good ol' times), we organized our actual, physical files in folders, themselves sorted in different drawers and file cabinets. This basic organization was projected into our computers, with, once again, files in folders, but this time, we could have any (limited, but already potentially huge) tree-like hierarchy of folders ans subfolders. Would you have any trust in a tool designed to manage your software projects that just throws all these projects on the same pile?
+Back when paper existed (aaaah, good ol' times), we organized our actual, physical files in folders, themselves sorted in different drawers and file cabinets. This basic organization was projected into our computers, with, once again, files in folders, but this time, we could have any (limited, but already potentially huge) tree-like hierarchy of folders and subfolders. Would you have any trust in a tool designed to manage your software projects that just throws all these projects on the same pile?
 
 Yeah, exactly.
 
diff --git a/04-branches-issues.md b/04-branches-issues.md
index 6f10ca4..263ad22 100644
--- a/04-branches-issues.md
+++ b/04-branches-issues.md
@@ -295,7 +295,7 @@ We switched from `add-quantities` to `main` with ease; let's just go back to `ad
 
 ![](../assets/img/04-branches-issues/D-switch-branch/switch-4.jpg){: .mx-auto.d-block :}
 
-`Nothing to commit, working tree clean` is basically your greenlight for switching to another branch without taking any risk. As for the fact that your commit on the feature branch is not pushed, remember that it's perfectly okay! This only means that, for now, this commit only exists on your computer. This can even be a desireable situation (for advanced use).
+`Nothing to commit, working tree clean` is basically your greenlight for switching to another branch without taking any risk. As for the fact that your commit on the feature branch is not pushed, remember that it's perfectly okay! This only means that, for now, this commit only exists on your computer. This can even be a desirable situation (for advanced use).
 
 Time to safely switch back to `main` and (as usual) start by pulling the most recent changes:
 
@@ -332,7 +332,7 @@ My new feature is now fully implemented, and should be integrated into the main
 
 * I get a nice clean web interface that makes the process way simpler than having to type the right commands.
 * I can submit my code to collaborators who can review my changes and suggest fixes if needed (which is a very important feature for actual code: maybe I could have used more adapted data structures or algorithms, or the way I wrote my code does not fully comply to the coding standards of the project).
-* Finally, a lot of automatic checks can be performed in order to chek that I did not break the software in some way: this is called a CI pipeline, and is an advanced feature that will be briefly presented later on.
+* Finally, a lot of automatic checks can be performed in order to check that I did not break the software in some way: this is called a CI pipeline, and is an advanced feature that will be briefly presented later on.
 
 {: .box-success}
 A **merge request** (or MR) is the mechanism by which a member of a GitLab project proposes that the changes made in a branch be incorporated in another branch. An assignee and a reviewer can (and should!) be picked for a MR; the former will act as a "manager" of sorts for this MR, while the latter will be in charge of checking the actual changes and suggest fixes if necessary.
@@ -343,7 +343,7 @@ As the whole merging process will be carried out on the server site, the most re
 
 ![](../assets/img/04-branches-issues/E-merge-requests/merge-2.jpg){: .mx-auto.d-block :}
 
-As I push, I get once again a URL that I can just copy-paste in my browser to get on the right page, but I could also go to te page of the project, click on "Merge requests" in the left-hand menu...
+As I push, I get once again a URL that I can just copy-paste in my browser to get on the right page, but I could also go to the page of the project, click on "Merge requests" in the left-hand menu...
 
 ![](../assets/img/04-branches-issues/E-merge-requests/merge-3.jpg){: .mx-auto.d-block :}
 > ...the one in "Code", **not the one in "Pinned"!** Once again, "Pinned" is for all projects, the rest is for the current project only.
@@ -408,7 +408,7 @@ One click later, here it is: our first MR, in all its unfathomable glory! A pinn
 
 ## Solving merge conflicts
 
-Did you think that pull conflits would be the only conflicts we would encounter? Time for **merge conflicts**. In this case, changes were made on the main branch that conflict with our own.
+Did you think that pull conflicts would be the only conflicts we would encounter? Time for **merge conflicts**. In this case, changes were made on the main branch that conflict with our own.
 
 GitLab gives you a choice between "Resolve locally" and "Resolve conflicts". The former option basically amounts to GitLab opening a small window with instructions about what you should do, on your computer, to resolve things. This is the hard way of fixing conflicts. We want to avoid that. Let us click on "Resolve conflicts" instead and hope that GitLab will hold our hand:
 
diff --git a/05-good-practices.md b/05-good-practices.md
index 0998256..de2f7cf 100644
--- a/05-good-practices.md
+++ b/05-good-practices.md
@@ -370,7 +370,7 @@ To impact the `main` branch of every project in a group, you can go to the setti
 
 ![](../assets/img/05-good-practices/D-mr-templates-and-options/settings-protect-4.jpg){: .mx-auto.d-block :}
 
-You can choose another name for your initial branch (although choosing a name other than `main` only makes sense for specific Git workflows that are not addressed here), and pick default protection options for every project in this group -- these options can be overriden for any individual project, and are just the "default" options that are applied to a project when it is created in this group or one of its subgroups.
+You can choose another name for your initial branch (although choosing a name other than `main` only makes sense for specific Git workflows that are not addressed here), and pick default protection options for every project in this group -- these options can be overridden for any individual project, and are just the "default" options that are applied to a project when it is created in this group or one of its subgroups.
 
 However, notice that even the strongest level of protection proposed here is the one that I insisted was *not strong enough* for our needs: maintainers can push on `main`! If you want to prevent anyone from pushing to `main`, you will have to change the settings of every individual project. Sorry about that. Still strongly recommended, and it's just a few clicks for each project, so why not?
 
@@ -564,7 +564,7 @@ Note that opening subbranches may not even be required in the first place. For e
 Once you really feel at ease with Git, you may want to have a look at two specific features of Git.
 
 * **Rebasing:** Frequent rebases is how you guarantee that the branch you are working on is up-to-date with the branch onto which it will be merged at some point, so that you will not have to face major conflicts when merging. The [Atlassian documentation](https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase) on `git rebase` is a pretty good starting point.
-* **Interactive rebasing:** It is pretty hard to grasp the actual relationship with rebasing as we defined it just above, but you may just live with it. Interactive rebasing is how you reorganize the commits on a given branch so that the history of this branch becomes nice and clean. In other words, you can implement things in disorder, make stupid mistakes that you fix five commits later, come back to a task because you forgot to implement unit tests... and, once everything works as expected, "tidy up your room" so that the branch you will actually be pushing has the best possible commits with clear messages. (Yes, this is also a way of turning terrible commmit messages into readable and informative ones.) [This article on the GitLab blog](https://about.gitlab.com/blog/2020/11/23/keep-git-history-clean-with-interactive-rebase/) provides pretty good explanations.
+* **Interactive rebasing:** It is pretty hard to grasp the actual relationship with rebasing as we defined it just above, but you may just live with it. Interactive rebasing is how you reorganize the commits on a given branch so that the history of this branch becomes nice and clean. In other words, you can implement things in disorder, make stupid mistakes that you fix five commits later, come back to a task because you forgot to implement unit tests... and, once everything works as expected, "tidy up your room" so that the branch you will actually be pushing has the best possible commits with clear messages. (Yes, this is also a way of turning terrible commit messages into readable and informative ones.) [This article on the GitLab blog](https://about.gitlab.com/blog/2020/11/23/keep-git-history-clean-with-interactive-rebase/) provides pretty good explanations.
 
 You may find more about both features in [the "Advanced" appendix]({{'/08-advanced' | relative_url }}).
 
diff --git a/07-internals.md b/07-internals.md
index 2024ca8..ba0a212 100644
--- a/07-internals.md
+++ b/07-internals.md
@@ -117,6 +117,6 @@ Also, you can go to your project's page on GitLab, pick a commit, and see every
 
 ----
 
-But wait, there's more! [**Here is more extra stuff thay one could be interested in.**]({{'/08-advanced' | relative_url }}) Advanced branch management, hints for your CI pipelines, a bit of troubleshooting, you name it.
+But wait, there's more! [**Here is more extra stuff that one could be interested in.**]({{'/08-advanced' | relative_url }}) Advanced branch management, hints for your CI pipelines, a bit of troubleshooting, you name it.
 
 You may also go back to the [detailed table of contents]({{'/index#toc' | relative_url }}).
\ No newline at end of file
diff --git a/08-advanced.md b/08-advanced.md
index 20a08ab..e6548b2 100644
--- a/08-advanced.md
+++ b/08-advanced.md
@@ -63,7 +63,7 @@ All hail `git clean`.
 * Add the `-n` option for a dry run, so that you just know what would be removed without it. If you are OK with these changes, you may now run the same command without this option.
 
 {: .box-warning}
-The `-f`, or `--force`, option is here because one of the Git configuration variables might very well prevent you from cleaning enything without forcing. This is one of the rare instances when it is kind of OK to use `-f` in a Git command, because if misused, it will only have an impact on *yourself*. **When using pretty much any Git command other than `git clean`, do not ever write `-f`, unless you are 110% sure that you know what you are doing.**
+The `-f`, or `--force`, option is here because one of the Git configuration variables might very well prevent you from cleaning anything without forcing. This is one of the rare instances when it is kind of OK to use `-f` in a Git command, because if misused, it will only have an impact on *yourself*. **When using pretty much any Git command other than `git clean`, do not ever write `-f`, unless you are 110% sure that you know what you are doing.**
 
 (**Pro Tip:** If you want to play the `-f` card at some point, have your local software engineer do it instead, so that *they* will be held accountable if anything goes wrong.)
 
@@ -207,7 +207,7 @@ The magical command is
 git bisect start HEAD <good_commit>
 ```
 
-This command states that you want to start searching for the forst "bad" commit, and you know that `HEAD` (the current state of your codebase) is "bad" and `<good_commit>` is "good". The search session is initiated with Git pulling a specific commit, namely, the one that is "right in the middle" of the range of commits in which you are searching for the bug. If `<good_commit>` is `HEAD~100`, for instance, Git will pull the commit referenced by `HEAD~50`.
+This command states that you want to start searching for the first "bad" commit, and you know that `HEAD` (the current state of your codebase) is "bad" and `<good_commit>` is "good". The search session is initiated with Git pulling a specific commit, namely, the one that is "right in the middle" of the range of commits in which you are searching for the bug. If `<good_commit>` is `HEAD~100`, for instance, Git will pull the commit referenced by `HEAD~50`.
 
 You can test this version of the codebase and see whether it works or not. If it does, type `git bisect good`; if it doesn't, `git bisect bad`. You just cut the search space roughly in half: Git tells you how many commits are left in the range of commits to assess, and how many more steps of this game are left before you catch the culprit. It also jumps to another commit, right in the middle of the remaining range, so that you can now test this one.
 
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index e9ee8b8..0000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,239 +0,0 @@
-## Unreleased version
-- BREAKING CHANGE: Allow changing the order of the social network links that appear in the footer (#1152)
-- BREAKING CHANGE: `google-scholar` social network link no longer requires the prefix `citations?user=`; if you previously set this parameter, it needs to be updated (#1189)
-- The footer of a page always sticks to the bottom, even on short pages (#576)
-- Added `author` YAML parameter to allow specifying the author(s) of a post (#1220)
-- Fixed bug where hovering over search results showed the text "{desc}" (#1156)
-- Added social network links for GitLab, Bluesky (#1168, #1218)
-- Added instructions and example on how to fix image links in project sites (#1171)
-- Pagination buttons: use nicer arrows, and don't show text on small screens (#1221)
-
-## v6.0.1 (2023-06-08)
-
-This version has been in the works for a few years. It includes several new features that were highly requested, numerous bug fixes, new documentation, and aggresively encourages migrating from the old Google Universal Analytics to the new Analytics 4.
-
-#### Breaking changes
-
-- As of July 2023, Google Universal Analytics is going away and being replaced by Google Analytics 4. Beautiful Jekyll sites that still use the old analytics tag will show a warning to encourage them to move to Analytics 4 (#1096).
-- More control over RSS feed sharing: previously, an RSS feed was *always* generated, and if the config setting `rss-description` was set then there was an RSS icon in the footer. Now, an RSS feed is only generated when the config setting `rss-description` exists, and an RSS footer icon is only shown if `rss: true` is set in the `social-network-links` config settings.
-
-#### New parameters and settings
-
-- Added `navbar-var-length` config setting that allows the navigation menu to be the same length as the longest sub-menu, so that long words in the submenu are not cut off (#765) 
-- Added `post_search` config setting that creates a Search button in the navbar (#770)
-- Added `edit_page_button` config setting that adds a "Edit page" button to the footer (to edit the current page on GitHub) (#1004)
-- Added `footer-hover-col` config setting to customize the hover colour of links in the footer (#848)
-
-#### New features and improvements
-
-- Made the home page feed more accessible for screen readers (#950)
-- Added support for giscus comments (#886) and CommentBox (#960)
-- Added support for Cloudflare Analytics (#797)
-- Added Reddit in share options of posts (#815)
-
-#### Bug fixes
-
-- Fixed page titles, subtitles, and excerpts rendering correctly when there are special characeters in them (#856) 
-- Fixed bug where navbar secondary level dropdown items didn't inherit the same colour as the primary navbar links
-- Fixed bug where the navbar "burger" collapsed button didn't always revert back to a light colour
-- Fixed bug where using an image as a navbar title did not render in GitHub Project pages that did not have a custom domain
-- Fixed bug where image thumbnails on the feed page were always forced into a square rather than maintaining a proper image aspect ratio
-- Fixed bug where special characters in the title led to broken share tags (#744)
-- Fixed bug where staticman didn't work jQuery slim version is used (#766)
-- Fixed very long strings to wrap around the next line rather than go off-screen (#787)
-
-#### Small changes
-
-- Updated staticman from using v2 (public servers) to v3 (private servers) due to the public servers becoming obsolete (#775)
-- Added social network links for Patreon, Medium, Itch.io, Discord, Kaggle, Hackerrank (#783, #788, #907, #961, #978)
-- Slightly reworked margins and position for avatar image to resolve an alignment issue on Safari
-- Changed the width at which the navbar collapses to a higher threshold because most modern non-mobile browsers are >1000px
-
-
-## v5.0.0 (2020-09-15)
-
-One of the major changes in this version is that a lot of time was spent on rethinking the entire SEO and social media sharing model (how a page looks on eg. Google, Twitter, Facebok). It was redesigned to be more simple and customizable. The new documentation has a section dedicated to SEO and social media sharing of a page. Unfortunately some changes that are not backwards-compatible had to be made.
-
-#### Breaking changes
-
-- Renamed `description` YAML parameter to `share-description` to be more clear
-- Renamed `description` config setting to `rss-description` since it was only used in RSS (the FAQ explains the difference between YAML parameters and config settings if you're confused)
-- Removed YAML parameter `use-site-title` (you can now specify the exact title using `share-title`)
-- Removed undocumented YAML parameters `meta-title` and `meta-description`
-- Removed `link-tags` config setting because it wasn't necessary. If you use tags, there will now always be a tags page created; if you don't use tags there won't be a tags page.
-- The YAML parameter `show-avatar` is now true by default. This has always been the case for GitHub Pages users, but not for `remote_theme` users. For consistency, it's now the default for everyone. (#715)
-
-#### New parameters and settings
-
-- Added `full-width` YAML parameter to allow having full-width pages
-- Added `feed_show_excerpt` config setting to show/hide the post excerpts on the feed page
-- Added `feed_show_tags` config setting to show/hide the list of tags on post previews on the feed page
-- Added `share-title` YAML parameter to give control over the search engine/social media title
-- Added `last-updated` YAML parameter to show a "Last Updated on" date for blog posts
-- Added `before-content` and `after-content` YAML parameters that allow you to add some common HTML before the main content of a page (below the title) or after the main content (above the footer). Works in a similar way to `footer-extra`.
-- Added `head-extra` YAML parameter which is similar to `footer-extra` but is used to include custom HTML code in a page's `<head>` tag
-- Added `site-js` config setting to provide JavaScript files that are used on all pages in the site
-
-#### New features and improvements
-
-- Improved the `footer-extra` YAML parameter to support multiple files instead of only a single file
-- Added automatic navbar color detection (#702)
-- When `nav-short` is turned on, the avatar will also be shorter
-- Changed navbar and footer background colour to be slightly darker, for better contrast with the default white page background for accessibility reasons
-- Changed the behaviour of `site-css` to include site-wide CSS file **before** instead of after page-specific files
-- Renamed internal css/js files from "main" to "beautifuljekyll" to make it easier for users to troubleshoot
-- Added alt text to all images for better accessibility
-- Made thumbnail images square instead of circles, as users reported that circles cut off important parts of images
-
-#### Bug fixes
-
-- Fixed rendering issues with `nav-short` parameter that caused the body of the page to start too low
-- Fixed some CSS styles that broke during the bootstrap 4 migration (#716)
-
-#### Library upgrades
-
-- Upgraded kramdown to version 2.3.0 to fix security issues
-- Upgraded jQuery to version 3.5.1 to fix a couple security vulnerabilities with the previous version
-
-## v4.1.0 (2020-08-08)
-
-- Added Open Graph `site_name` meta field to pages automatically
-- Added `text-col` config setting  for main text color (#694)
-- Added `keywords` config setting to set the meta keywords on all pages (for SEO purposes) (#691)
-- Added `mobile-theme-col` config setting to allow a mobile theme colour (#692)
-- Added `site-css` config setting in the config file to provide CSS files that are used on all pages in the site (#695)
-- Added YAML parameter `description`: creates the meta description on a page, intended to provide a brief description of the page for search engines and when the page is shared (#690)
-
-## v4.0.1 (2020-07-13)
-
-- Fixed staticman comments UI that was broken since the migration to bootstrap 4
-
-## v4.0.0 (2020-07-12)
-
-- **BREAKING CHANGE** Replace `image` YAML parameter with `thumbnail-img` to be more clear
-- **MAJOR BEHAVIOUR CHANGE** Don't use the thumbnail as the avatar image
-- Cover image will automatically be used as thumbnail if none is provided
-- Image to share on social media will use the cover image or thumbnail if none is provided
-- All images (social media share, thumbnail, cover) can use either relative or absoluate paths.
-- Fixed issue where if a dropdown menu was the last item in the menu bar, it did not have a proper margin on the right
-- Added social network links: Mastodon (#646), Google Scholar, ORCID (#670)
-- Added support for sharing pages on new social network: VK (#657)
-- Use Open Graph type 'article' for blog posts (#669)
-- Use Twitter's large sumary card (large image) when there is a cover image, thumbnail image, or share image specified (#668)
-- Made post images in the feed page smaller on smaller devices
-- Fixed jQuery version in staticman (#671)
-
-## v3.0.0 (2020-05-07)
-
-- **BREAKING CHANGE** Upgraded from Bootstrap 3.3.2 to 4.4.1. This involved a major rewrite of most components. This shouldn't affect any users unless you have custom HTML/CSS code which the new Bootstrap could have broken.
-- **BREAKING CHANGE** Renamed `bigimg` YAML parameter to `cover-img`
-- **BREAKING CHANGE** Removed `googlefonts` YAML parameter since googlefonts are just CSS so they can be loaded via `ext-css`
-- **BREAKING CHANGE** Upgraded from jQuery 1.11.2 to 3.4.2. This should not affect most people
-- Added `navbar-border-col` setting in the config file
-- Added accessibility features where possible
-- Made the theme completely responsive by rewriting all CSS to use 'rem' instead of 'px'
-- Rewrote and simplified some JavaScript code to use CSS or Bootstrap alternatives that weren't available in 2015
-- Removed most of the sample posts so that users only have two sample posts to learn from
-- Improvements to the README instructions
-
-## v2.3.0 (2020-04-29)
-
-- Added YAML parameter `footer-extra` for including custom content in the footer
-- Fixed issue: linking to a specific part of a page resulted in scrolling too far (#69)
-- Added YAML parameter `nav-short` to have navbar permanently collapsed
-- Added social network link: Calendly
-- Fixed bug where RSS link in footer was showing even when turned off
-
-## v2.2.0 (2020-04-27)
-
-- Added social network link: Telegram (#625) (thanks @mashed-potatoes)
-- Moved the demo site to an independent URL: https://beautifuljekyll.com
-- Major documentation overhaul and cleanup of old files
-- Fixed a few bugs from the remote_theme migration
-
-## v2.0.0 (2020-04-26)
-
-- Beautiful-Jekyll v2.0.0 available as an official Ruby gem
-- Beautifull-Jekyll now supports the `remote_theme` config (#339) (thanks @gpotter2 and @skalee)
-- Consolidated the demo site, the ruby gem, and the master branch into one
-- Added a `home` layout and used it in the index page
-- Added readtime support for the post header (#622) (thanks @MutMatt and @rubyreads)
-- Removed the dependency on `_data` folder since it doesn't get copied when using `remote_theme` (#614)
-- Added support for configuring lang attribute on `html` tag (#608) (thanks @skalee)
-- Added ability to disable round logo (thanks @gpotter2)
-- Added support for Utterances comments (#596) (thanks @colynn)
-- Removed 'just-comments' as it's getting killed at the end of the year
-- Upgraded font-awesome to 5.12.1 (#587) (thanks @cketti)
-
-## Prior to 2020
-
-**2018-12-24** Add support for Staticman comments (#440) (thanks @VincentTam)
-
-**2018-10-19** Move Google Analytics to the head (#419) (thanks @jpvicari)
-
-**2018-06-08** Add support for Facebook comments (#350) (thanks @npes87184)
-
-**2018-02-22** Automatically generate sitemap (#323) (thanks @JosemyDuarte)
-
-**2018-01-18** Add clickable tags to each post and a tags index page, works for GitHub sites (#307) (thanks @OCram85)
-
-**2018-01-14** Redo Dockerfile (#302) (thanks @jennydaman)
-
-**2018-01-06** More color personalization options (#297 and #299) (thanks @jennydaman)
-
-**2018-01-05** Abstract the social networks logic (thanks @OCram85)
-
-**2018-01-03** Avatar image no longer causes a ghost click (thanks @alefi87)
-
-**2017-10-16** Add GitHub buttons to posts (#265) (thanks @yonicd)
-
-**2017-09-04** Ability to change colour/image of navbar/footer/body
-
-**2017-08-17** Add support for notification, error, and warning boxes in markdown (#227) (thanks @OCram85)
-
-**2017-08-12** Add social buttons for twitch, yelp, and steam (#234) (thanks @TheRealBenForce)
-
-**2017-03-30** Make the footer contact links friendly for screen readers (thanks @eugenius1)
-
-**2017-03-30** Started a CHANGELOG file (thanks @eugenius1)
-
-**2017-01-28** Add Subresource Integrity (SRI) support (#164) (thanks @tony-ho)
-
-**2017-01-09** Add Google Tag Manager Integration (#157) (thanks @csarigoz)
-
-**2017-01-06** Add options to configure HTML document title (#154) (thanks @tony-ho)
-
-**2016-12-25** Allow dynamic images on each blog post (#143) (thanks @bbritten)
-
-**2016-12-15** Support `title-img` config param to have image in the navbar instead of text
-
-**2016-12-08** Add support for phone numbers in footer; fix #136
-
-**2016-12-06** Update gemfile (#134) (thanks @stephentuso)
-
-**2016-10-09** Add Docker deployment (#114) (thanks @mangar)
-
-**2016-08-06** Add social share buttons for posts (thanks @rtlee9)
-
-**2016-07-29** Add CSS styling to code chunks
-
-**2016-07-27** Add clickable tags that lead to a tag page (doesn't work for GitHub hosted sites) (thanks @epwalsh)
-
-**2016-07-21** Add support for twitter cards (sharing on Twitter will be better); fixes #70
-
-**2016-03-18** Support full-width images in page headers; fixes #37
-
-**2016-03-18** Support menus in navigation bar
-
-**2016-02-07** Avatar is now conditional (thanks @hristoyankov)
-
-**2016-02-02** Migrate (forced to...) to jekyll 3
-
-**2016-01-22** Make sure not to include JQuery twice, fixes #29
-
-**2015-11-19** Support external links in navigation bar; fixes #3
-
-... Many small changes because the site was in its infancy
-
-**2015-03-12** Beautiful Jekyll version 0.0000001 is released!
-
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 0b6ae57..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2023 Dean Attali
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
index 7f96ae3..d9b05db 100644
--- a/README.md
+++ b/README.md
@@ -1,237 +1,11 @@
-# Beautiful Jekyll
+# Git/GitLab tutorial
 
-[![Gem Version](https://badge.fury.io/rb/beautiful-jekyll-theme.svg)](https://badge.fury.io/rb/beautiful-jekyll-theme)
+A friendly tutorial about Git and Gitlab. Also, jokes. (I apologize.) Hope you enjoy.
 
-> By [Dean Attali](https://deanattali.com) &middot; [Demo](https://beautifuljekyll.com/)
+This whole tutorial is licensed under [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1).
 
-**Beautiful Jekyll** is a ready-to-use template to help you create a beautiful website quickly. Perfect for personal sites, blogs, or simple project websites.  [Check out a demo](https://beautifuljekyll.com) of what you'll get after just two minutes.  You can also look at [my personal website](https://deanattali.com) or [my consulting website](https://attalitech.com) to see it in use, or see [examples of websites](http://beautifuljekyll.com/examples) other people created using this theme.
+My huge thanks to Sébastien Gilles for his careful proofreading and insightful advice.
 
-**If you enjoy Beautiful Jekyll, please consider [supporting me](https://github.com/sponsors/daattali). You'll also gain access to office hours and more features! ❤**
-
-## Table of contents
-
-- [Features](#features)
-- [Sponsors 🏆](#sponsors)
-- [**Build your website in 3 steps**](#build-your-website-in-3-steps)
-- [Plans](#plans)
-- [Add your own content](#add-your-own-content)
-- [Customizing parameters for each page](#customizing-parameters-for-each-page)
-- [Supported parameters](#supported-parameters)
-- [Featured users (success stories!)](#featured-users-success-stories)
-- [Next steps](#next-steps)
-- [Getting help](#getting-help)
-- [Credits and contributions](#contributions)
-
-# Features
-
-__Check out [*What's New?*](https://beautifuljekyll.com/updates/) to see the latest features!__
-
-- **SIMPLE**: The primary goal of Beautiful Jekyll is to allow literally *anyone* to create a website in a few minutes.
-- **Modern**: Uses the latest best practices and technologies to achieve nearly perfect scores on Google Chrome's Audit.
-- **Mobile-first**: Designed to look great on both large-screen and small-screen (mobile) devices.
-- **Highly customizable**: Many personalization settings such as changing the background colour/image, adding a logo.
-- **Flexible usage**: Use Beautiful Jekyll directly on GitHub or via a Ruby gem - choose the best [development method](#build-your-website-in-3-steps) for you.
-- **Battle-tested**: By using Beautiful Jekyll, you'll be joining 50,000+ users enjoying this theme since 2015.
-- **SEO and social media support**: Customize how your site looks on Google and when shared on social media.
-- **Comments support**: Add comments to any page using either [Disqus](https://disqus.com/), [Facebook comments](https://developers.facebook.com/docs/plugins/comments), [Utterances](https://utteranc.es/), [Staticman](https://staticman.net), [giscus](https://giscus.app), or [CommentBox](https://commentbox.io/).
-- **Tags**: Any blog post can be tagged with keywords, and an index page is automatically generated.
-- **Analytics**: Easily integrate Google Analytics, or other analytics platforms, to track visits to your website.
-- **Search**: Let users easily find any page using a Search button in the navigation bar.
-- **Photos support**: Any page can have a full-width cover photo and thumbnail.
-- **RSS**: An RSS feed is automatically created, so you can even host a podcast easily with Beautiful Jekyll.
-
-<h2 id="sponsors">Sponsors 🏆</h2>
-
-Developing and maintaining Beautiful Jekyll takes a lot of time and effort - thank you to anyone who helps fund this effort!
-
-- [DoFollow](https://dofollow.co.uk/)
-- [\_hyp3ri0n](https://hyperiongray.com)
-- [Varna Sri Raman](https://about.me/varna)
-
-**[Become a sponsor for Beautiful Jekyll and unlock new features\!](https://github.com/sponsors/daattali/sponsorships?tier_id=39856)**
-
-# Build your website in 3 steps
-
-There are a few different ways to build a website using Beautiful Jekyll, and this document will go through the simplest one: using a fork on GitHub. For most people (including myself!), this easy method is the recommended one.
-
-Even if you choose to use one of the [advanced installation methods](https://beautifuljekyll.com/getstarted/#install-steps-hard), I still suggest you read through the easy method first.
-
-## The easy way (recommended!)
-
-Getting started is *literally* as easy as 1-2-3 :smile:
-
-Scroll down to see the steps involved, but here is a 30-second video just as a reference as you work through the steps. If you don't already have a [GitHub account](https://github.com), you'll need to sign up.
-
-![Installation steps](https://beautifuljekyll.com/assets/img/install-steps.gif)
-
-### 1. Fork this project
-
-Click on the __*Fork*__ button at the top right corner of this page. Forking means that you're copying this entire project and all its files into your account. Do not click on the __*Create fork*__ button on the next page yet.
-
-### 2. Rename the repository to `YOURUSERNAME.github.io`
-
-You'll see the word "repository" used a lot in GitHub - it simply means "project". Under __*Repository name*__ you should see the name `beautiful-jekyll`, this is where you need to rename your project to `YOURUSERNAME.github.io` (replace `YOURUSERNAME` with your GitHub user name). It's important to use this exact name so that GitHub will recognize it and automatically create a website for this project.   
-
-> Tip: If you want to use a different URL for your website, check out the [FAQ](https://beautifuljekyll.com/faq/#custom-domain)
- 
-### 3. Customize your website settings
-
-Edit the `_config.yml` file to change any settings you want. To edit the file, first click on it to view the file, and on the next page click on the pencil icon to edit it (watch the video tutorial above if you're confused).  The settings in the file are self-explanatory and there are comments inside the file to help you understand what each setting does. Any line that begins with a hashtag (`#`) is a comment, and the other lines are actual settings. After changing the settings, click the green __*Commit changes*__ button to save these edits.
-
-> Note: In the video above, only one setting in the `_config.yml` file is edited, but you should go through the rest of the settings as well.
-
-### 4. Congratulations! You have a website!
-
-If you named your project correctly and made an edit to the config file, your website should be ready in a minute or two at `https://YOURUSERNAME.github.io`. Every time you make a change to any file, your website will get rebuilt and should be updated in about a minute or so. Your website will be initialized with several sample blog posts and a couple other pages.
-
-## The harder way (for advanced users)
-
-The instructions above explain how to use Beautiful Jekyll in the easiest way: by forking on GitHub. There are more [advanced installation methods](https://beautifuljekyll.com/getstarted/#install-steps-hard) that include either using GitHub Pages with remote themes, or using Ruby gems. They provide you with more control, but are only intended for advanced users.
-
-> Note: Beautiful Jekyll was primarily designed to be used as a GitHub theme, so you will not get any support if you use this theme via Ruby gems. 
-
-# Plans
-
-Beautiful Jekyll is, and always will be, free. But if you want to remove the Beautiful Jekyll ad from your website, use a Dark Mode skin, access office hours, or simply support the development efforts, [check out the different plans](https://beautifuljekyll.com/plans).
-
-# Add your own content
-
-To add pages to your site, you can either write a markdown file (`.md`) or you can write an HTML file. It's much easier to write markdown than HTML, so that's the recommended approach ([here's a great tutorial](https://markdowntutorial.com/) if you need to learn markdown in 5 minutes).
-
-To see an example of a markdown file, click on any file that ends in `.md`, for example [`aboutme.md`](./aboutme.md). On that page you can see some nicely formatted text (there's a word in bold, a link, a few bullet points), and if you click on the pencil icon to edit the file, you'll see the markdown code that generated the pretty text. Very easy! 
-
-In contrast, look at [`tags.html`](./tags.html). That's how your write HTML - not as pretty. So stick with markdown if you don't know HTML.
-
-Any markdown or HTML file that you create will be available on your website under `https://<yourusername>.github.io/<pagename>`. For example, if you create a file `about.md` (or `about.html`) then it'll exist at `https://<yourusername>.github.io/about`.
-
-Files you create inside the [`_posts`](./_posts) directory will be treated as blog entries. You can look at the existing files there to get an idea of how to write blog posts. Note the format of the blog post files - they must follow the naming convention of `YEAR-MONTH-DAY-title.md`. After you successfully add your own post, you can delete the existing files inside [`_posts`](./_posts) to remove the sample posts, as those are just demo posts to help you learn.
-
-# Customizing parameters for each page
-
-**One last important thing**: In order to have your new pages use this template and not just be plain HTML pages, **you must add [YAML front matter](https://jekyllrb.com/docs/front-matter/) to the top of each page**:
-
-
-```
----
----
-```
-
-This is where you'll be able to give each page some extra parameters (such as a title, a subtitle, an image, etc - [below is a list of all parameters](#supported-parameters)). Add any parameters you want between these two dashed lines, for example:
-
-```
----
-title: Contact me
-subtitle: Here you'll find all the ways to get in touch with me
----
-```
-
-If you don't want to use any parameters on a page, you still need to use the two dashed lines. If you don't, then your file will be shown as-is without the Beautiful Jekyll template.
-
-You can look at the top of [`aboutme.md`](https://raw.githubusercontent.com/daattali/beautiful-jekyll/master/aboutme.md) as an example.
-
-**Important takeaway: ALWAYS add the YAML front matter, which is two lines of three dashes, to EVERY page. If you have any parameters, they go between the two lines.**
-
-# Supported parameters
-
-Below is a list of the parameters that Beautiful Jekyll supports (any of these can be added to the YAML front matter of any page). Remember to also look in the `_config.yml` file to see additional site-wide settings.
-
-## Main parameters
-
-These are the basic YAML parameters that you are most likely to use on most pages.
-
-Parameter   | Description
------------ | -----------
-title       | Page or blog post title
-subtitle    | Short description of page or blog post that goes under the title
-tags        | List of tags to categorize the post. Separate the tags with commas and place them inside square brackets. Example: `[personal, analysis, finance]`
-cover-img   | Include a large full-width image at the top of the page. You can either provide the path to a single image (eg. `"/path/to/img"`) , or a list of images to cycle through (eg. `["/path/img1", "/path/img2"]`). If you want to add a caption to an image, then you must use the list notation (use `[]` even if you have only one image), and each image should be provided as `"/path/to/img" : "Caption of image"`.
-thumbnail-img | For blog posts, if you want to add a thumbnail that will show up in the feed, use `thumbnail-img: /path/to/image`. If no thumbnail is provided, then `cover-img` will be used as the thumbnail. You can use `thumbnail-img: ""` to disable a thumbnail.
-comments    | If you want do add comments to a specific page, use `comments: true`. Comments only work if you enable one of the comments providers (Facebook, disqus, staticman, utterances, giscus, CommentBox) in `_config.yml` file. Comments are automatically enabled on blog posts but not on other pages; to turn comments off for a specific post, use `comments: false`.
-
-## Parameters for SEO and social media sharing
-
-These parameters let you control what information shows up when a page is shown in a search engine (such as Google) or gets shared on social media (such as Twitter/Facebook).
-
-Parameter   | Description
------------ | -----------
-share-title | A title for the page. If not provided, then `title` will be used, and if that's missing then the site title (from `_config.yml`) is used.
-share-description | A brief description of the page. If not provided, then `subtitle` will be used, and if that's missing then an excerpt from the page content is used.
-share-img   | The image to show. If not provided, then `cover-img` or `thumbnail-img` will be used if one of them is provided.
-
-## Less commonly used parameters
-
-These are parameters that you may not use often, but can come in handy sometimes.
-
-Parameter   | Description
------------ | -----------
-author      | Specify the author of a blog post (useful if a website has multiple authors).
-readtime    | If you want a post to show how many minutes it will take to read it, use `readtime: true`.
-show-avatar | If you have an avatar configured in the `_config.yml` but you want to turn it off on a specific page, use `show-avatar: false`.
-social-share | By default, every blog post has buttons to share the page on social media. If you want to turn this feature off, use `social-share: false`.
-nav-short   | By default, the navigation bar gets shorter after scrolling down the page. If you want the navigation bar to always be short on a certain page, use `nav-short: true`
-gh-repo   | If you want to show GitHub buttons at the top of a post, this sets the GitHub repo name (eg. `daattali/beautiful-jekyll`). You must also use the `gh-badge` parameter to specify what buttons to show.
-gh-badge  | Select which GitHub buttons to display. Available options are: [star, watch, fork, follow]. You must also use the `gh-repo` parameter to specify the GitHub repo.
-last-updated | If you want to show that a blog post was updated after it was originally released, you can specify an "Updated on" date.
-layout      | What type of page this is (default is `post` for blog posts and `page` for other pages). See _Page types_ section below for more information.
-
-## Advanced parameters
-
-These are advanced parameters that are only useful for people who need very fine control over their website.
-
-Parameter   | Description
------------ | -----------
-footer-extra | If you want to include extra content below the social media icons in the footer, create an HTML file in the `_includes/` folder (for example `_includes/myinfo.html`) and set `footer-extra` to the name of the file (for example `footer-extra: myinfo.html`). Accepts a single file or a list of files.
-before-content | Similar to `footer-extra`, but used for including HTML before the main content of the page (below the title).
-after-content | Similar to `footer-extra`, but used for including HTML after the main content of the page (above the footer).
-head-extra   | Similar to `footer-extra`, but used if you have any HTML code that needs to be included in the `<head>` tag of the page.
-language    | HTML language code to be set on the page's &lt;html&gt; element.
-full-width  | By default, page content is constrained to a standard width. Use `full-width: true` to allow the content to span the entire width of the window.
-js          | List of local JavaScript files to include in the page (eg. `/assets/js/mypage.js`)
-ext-js      | List of external JavaScript files to include in the page (eg. `//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.2/underscore-min.js`). External JavaScript files that support [Subresource Integrity (SRI)](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) can be specified using the `href` and `sri` parameters eg.<br/>`href: "//code.jquery.com/jquery-3.1.1.min.js"`<br/>`sri: "sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="`
-css         | List of local CSS files to include in the page
-ext-css      | List of external CSS files to include in the page. External CSS files using SRI (see `ext-js` parameter) are also supported.
-
-## Page types
-
-- **post** - To write a blog post, add a markdown or HTML file in the `_posts` folder. As long as you give it YAML front matter (the two lines of three dashes), it will automatically be rendered like a blog post. Look at the existing blog post files to see examples of how to use YAML parameters in blog posts.
-- **page** - Any page outside the `_posts` folder that uses YAML front matter will have a very similar style to blog posts.
-- **home** - The home layout is meant to act as the homepage of your blog posts - it will display all your blog posts, sorted from newest to oldest. A file using the `home` layout must be named `index.html` (not `index.md` or anything else!).
-- **minimal** - If you want to create a page with minimal styling (ie. without the bulky navigation bar and footer), assign `layout: minimal` to the YAML front matter.
-- If you want to completely bypass the template engine and just write your own HTML page, simply omit the YAML front matter. Only do this if you know how to write HTML!
-
-# Featured users (success stories!)
-
-Visit the [Official website](http://beautifuljekyll.com/examples) to see sample websites using Beautiful Jekyll.
-
-If you'd like to showcase yourself and join this list, [upgrading to the Individual plan](https://github.com/sponsors/daattali/sponsorships?&tier_id=7362) will give you that publicity plus some other rewards!
-
-# Next steps
-
-Congratulations on making it this far! You now have all the tools to easily build a beautiful website for free. 
-
-- After you get comfortable with the basics of writing in markdown, I suggest taking a look at this [sample post](https://beautifuljekyll.com/2020-02-28-sample-markdown/) and [the code that created it](https://raw.githubusercontent.com/daattali/beautiful-jekyll/master/_posts/2020-02-28-sample-markdown.md) to learn some more advanced tips about markdown.
-
-- I highly recommend going over the [*Frequently Asked Questions*](https://beautifuljekyll.com/faq/) to find out answers to questions you may not even know you have. Every few months I suggest checking the [*What's New?*](https://beautifuljekyll.com/updates/) page to see if there are new features, and learn [how to update your site to the newest version](https://beautifuljekyll.com/faq/#updating) when it's time.
-
-- You can also check out the [advanced installation methods](https://beautifuljekyll.com/getstarted/#install-steps-hard) that give you a little more control but are harder to use. Keep in mind that Beautiful Jekyll was primarily designed to be used as a GitHub theme, so you will not get any support if you choose one of the Ruby installation methods. 
-
-# Getting help
-
-Visit the [FAQ page](https://beautifuljekyll.com/faq) for answers to commonly asked questions.
-
-**If you choose to [become a sponsor](https://beautifuljekyll.com/plans/), you'll have access to my [office hours](https://beautifuljekyll.com/officehours/) where you can ask for help.** You can also use the [Discussions](https://github.com/daattali/beautiful-jekyll/discussions) area to try and get help from the community.
-
-Beautiful Jekyll is used by 50,000+ people with wildly varying degrees of web skills, so it's impossible to answer all the questions that may arise. For any question that's not specifically related to Beautiful Jekyll and is more about Jekyll or web development in general, the answer can often be found on Google, in the [Jekyll documentation](https://jekyllrb.com/), or on the [Jekyll support forum](https://talk.jekyllrb.com/).
-
-# Contributions
-
-Thank you to [all past contributors](https://github.com/daattali/beautiful-jekyll/graphs/contributors). If you find any problems or would like to contribute in any way, feel free to create a pull request/open an issue/send me a message.
-
-You can also contribute by becoming an [official sponsor](https://github.com/sponsors/daattali/sponsorships?tier_id=39856) to help keep Beautiful Jekyll well-maintained!
-
-# Credits
-
-This template was not made *entirely* from scratch. I'd like to give special thanks to [Jekyll Now](https://github.com/barryclark/jekyll-now) and [Bootstrap Clean Blog](https://github.com/IronSummitMedia/startbootstrap-clean-blog), from whom I've taken several ideas initially.
-
-I'd also like to thank [Dr. Jekyll's Themes](https://drjekyllthemes.github.io/), [Jekyll Themes](http://jekyllthemes.org/), and another [Jekyll Themes](http://jekyllrc.github.io/jekyllthemes/) for featuring Beautiful Jekyll in their Jekyll theme directories.
+Powered by [Beautiful Jekyll](https://beautifuljekyll.com) by [Dean Attali](https://deanattali.com).
 
+(c) [Mathias Malandain](mailto:mathias.malandain@inria.fr?subject=About your Git(Lab) tutorial), Inria center at Rennes University
\ No newline at end of file
-- 
GitLab


From 5ff552ae963ce2978675951c944428a61d99662e Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Tue, 30 Jul 2024 10:30:23 +0200
Subject: [PATCH 06/20] Fix README

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index d9b05db..d73add1 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,6 @@ This whole tutorial is licensed under [CC BY-SA 4.0](http://creativecommons.org/
 
 My huge thanks to Sébastien Gilles for his careful proofreading and insightful advice.
 
-Powered by [Beautiful Jekyll](https://beautifuljekyll.com) by [Dean Attali](https://deanattali.com).
+Powered by [Beautiful Jekyll](https://beautifuljekyll.com) by [Dean Attali](https://deanattali.com), under the MIT license.
 
-(c) [Mathias Malandain](mailto:mathias.malandain@inria.fr?subject=About your Git(Lab) tutorial), Inria center at Rennes University
\ No newline at end of file
+(c) [Mathias Malandain](mathias.malandain@inria.fr), Inria center at Rennes University
\ No newline at end of file
-- 
GitLab


From e52f26c5ced6f54cc6778aeb2c99cca926f9f07a Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Tue, 30 Jul 2024 10:57:33 +0200
Subject: [PATCH 07/20] Reorder info about fetch --prune + be easier on
 stashing + fix typo

---
 03-linear-git-project.md | 2 +-
 04-branches-issues.md    | 9 +++++++--
 08-advanced.md           | 7 ++-----
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/03-linear-git-project.md b/03-linear-git-project.md
index 55eef77..129436c 100644
--- a/03-linear-git-project.md
+++ b/03-linear-git-project.md
@@ -6,7 +6,7 @@ tags:
 
 I am not one of these old buggers who think that, in order to really understand something, you have to learn it the hard way. I will not be advocating against all these stupid *so-called* "productivity tools" that pre-chew your food, because I learned to write assembly code on vi when I was 12 and do not understand what the fuss is about these "high-level languages" and "IDEs" and stuff.
 
-However, I know for a fact that, without a proper understanding on the basics, you are doomed to make mistakes. Been here, done that.
+However, I know for a fact that, without a proper understanding on the basics, you are doomed to make mistakes. Been there, done that.
 
 What follows is my best attempt, to date, at explaining everything you need to know to use "basic" Git without fear, and nothing more. We will be working on our project "the old-fashioned way", by editing our files with whichever tool we want to use, and directly typing our Git commands from a terminal.
 
diff --git a/04-branches-issues.md b/04-branches-issues.md
index 263ad22..28b69c0 100644
--- a/04-branches-issues.md
+++ b/04-branches-issues.md
@@ -288,8 +288,8 @@ Plus, you probably do not want your changes to be carried over to the main branc
 
 There are two simple ways to avoid carrying uncommitted changes to another branch:
 
-* **Risky solution:**`git stash` and `git stash pop` can be respectively used to store all uncommitted changes "somewhere" and reapply them to your working copy. The workflow in our situation would then be: `git stash` (save all uncommitted changes), `git switch main`, do whatever you want on the main branch, then `git switch add-quantities` to go back to the feature branch, and `git stash pop` to reapply your changes. The main issue here is that the stash is a [stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)): Git will not prevent you from calling `git stash` several times in a row, and if you lose track of what you are doing, you may reapply changes at the wrong place, or call `git stash`3 times, then `git stash pop` only twice, and wonder where your work has gone. I suggest you just keep the word "stash" in a corner of your mind for now.
-* **Risk-free solution:** ...just commit your changes! Duh.
+* `git stash` and `git stash pop` can be respectively used to store all uncommitted changes "somewhere" and reapply them to your working copy. The workflow in our situation would then be: `git stash` (save all uncommitted changes in a fresh stash entry), `git switch main`, do whatever you want on the main branch, then `git switch add-quantities` to go back to the feature branch, and `git stash pop` to reapply your changes. Just be wary of the fact that the stash is a [stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)): Git will not prevent you from calling `git stash` several times in a row, and if you lose track of what you are doing, you may reapply changes at the wrong place, or call `git stash` 3 times, then `git stash pop` only twice, and wonder where your work has gone. You might want to use `git stash save "This is what I have done here"` so as to get the memo later on and know which changes you should apply where. [More on "advanced" stashing here.](https://www.atlassian.com/git/tutorials/saving-changes/git-stash) Stashing is still pretty convenient in a lot of situations, for example if you want every commit to contain code that actually compiles.
+* If you are afraid of stashing, well... just commit your changes. Duh, right? Well, see above: there are changes you do not want to commit yet. The choice is yours, and it will depend on your tastes and on the situation at hand.
 
 We switched from `add-quantities` to `main` with ease; let's just go back to `add-quantities` (still carrying our uncommitted changes with us), commit our changes, and only then, go back to `main`:
 
@@ -384,6 +384,11 @@ This is what my MR could look like at this point:
 
 > Notice that I chose not to use bullet points in the "Related issues" section. The reason is actually pretty sad: `* Closes #2` is currently not handled as it should by GitLab. The word "Close", or "Fix", etc. has to be at the very beginning of a line.
 
+You may also mention other related MRs, here or in issues:
+
+{: .box-success}
+**Mentioning MRs** is made using the `!` character. As for issues, this can be done in any issue or merge request, be it in the description or discussion. Note that issues and MRs have independent numberings: we will be opening MR `!1` here, and we marked it as related to issue `#1`.
+
 Of course, any other information that could help my collaborators understand what is in this MR (which changes are core changes, which pieces of my code could probably be improved and deserve specific attention, which algorithmic choices were made and why...) should be written down. In my case, there is no such need: changes are pretty straaightforward and limited to a single file, with no side effects.
 
 But my work is not over: scrolling down, I notice that there are a few more hoops to jump through before opening the MR.
diff --git a/08-advanced.md b/08-advanced.md
index e6548b2..4e5bbe4 100644
--- a/08-advanced.md
+++ b/08-advanced.md
@@ -41,12 +41,9 @@ The last three lines are more interesting:
 
 Note, however, that `git fetch` may bring you new content, but that it will not delete content that does not exist anymore on the repo.
 
-That is, unless you ask.
+That is, unless you ask. Remember [`git fetch --prune`]({{'/04-branches-issues#clean' | relative_url }})? This command will  delete references that do not exist anymore on the repo before it performs the actual fetching: this includes branches that were deleted from the repo -- hopefully after they were merged to active branches -- but not tags: option `--prune-tags` also has to be provided for deleting tags. (Alternatively, one may edit the `~/.gitconfig` file so that one line reads `fetch.pruneTags=true`: this tells Git to also prune tags when `git fetch --prune` is invoked.)
 
-{: .box-success}
-Command `git fetch --prune` deletes references that do not exist anymore on the repo before it performs the actual fetching. Such references include branches that were deleted from the repo -- hopefully after they were merged to active branches -- but not tags: option `--prune-tags` also has to be provided for deleting tags. (Alternatively, one may edit the `~/.gitconfig` file so that one line reads `fetch.pruneTags=true`: this tells Git to also prune tags when `git fetch --prune` is invoked.)
-
-There is a subtle nuance here that you might have missed: pruning will delete references to branches *that were deleted from the repo*. Branches that never existed on the repo will *not* be subject to pruning, so that, if you are working on a local branch, running `git fetch --prune` will not delete it. Only remote-tracking branches that were deleted on the remote. All in all, running this command should not hurt.
+Once again, do not get too anxious about pruning: local branches that you never pushed to the repo will **not** be pruned. Pinky promise.
 
 # Cleaning up your local copy {#cleanup}
 
-- 
GitLab


From c96b8158824d9e390fcf200757fed9bc12ce4fef Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Tue, 30 Jul 2024 15:03:57 +0200
Subject: [PATCH 08/20] Add information about GitLab instances + better info
 about git config

---
 00-what-why.md        | 10 +++++-----
 01-setup.md           |  3 +++
 04-branches-issues.md |  2 +-
 05-good-practices.md  |  8 +++++---
 08-advanced.md        | 12 ++----------
 5 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/00-what-why.md b/00-what-why.md
index 1824b73..3d2d306 100644
--- a/00-what-why.md
+++ b/00-what-why.md
@@ -33,13 +33,13 @@ A lot of features provided by GitLab are incredibly useful on a day-to-day basis
 * A ***fine handling of permissions and code review***: you can control who can write to each branch of the project, and under which conditions a feature can be merged into the main version of the codebase (which tests should be run, how many people should review and approve the changes, and so on);
 * Easy-to-use ***CI/CD pipelines***: Continuous Integration makes it possible to thoroughly test your code before merging it in the main version, and Continuous Delivery provides you with the possibility to automatically deploy your software for your collaborators to use
 
-A lot of other Git-based development platforms exist (GitHub, Gitea, Bitbucket, to name a few), but it so happens that Inria hosts two instances of GitLab.
-
-{: .box-note}
-Everything on `gitlab.inria.fr` and `gitlab-int.inria.fr` is hosted on Inria's own servers, which guarantees that your code is safe!
+A lot of other Git-based development platforms exist (GitHub, Gitea, Bitbucket, to name a few), but it so happens that Inria hosts two instances of GitLab, at `gitlab.inria.fr` and `gitlab-int.inria.fr`. Everything on these instances is hosted on Inria's own servers, which guarantees that your code is safe.
 
 {: .box-warning}
-In most cases, you should **not** use `gitlab.com` or `github.com` for your software projects. If you are only working with specific collaborators, including a few who do not have an Inria account, the Inria instances of GitLab should still be used: you can very simply [invite external collaborators to `gitlab.inria.fr`](https://external-account.inria.fr). The use of external platforms like `gitlab.com` and `github.com` can be envisioned for open-source software, for which external contributions can be expected (...and in that case, you should also probably discuss the legal aspects with the right people at Inria before making any move), but as long as there is no stringent need, you should keep your codebase safe.
+In most cases, you should **not** use `gitlab.com` or `github.com` for your software projects. If you are only working with specific collaborators, including a few who do not have an Inria account, no need for going on GitHub: you can very simply [invite external collaborators to `gitlab.inria.fr`](https://external-account.inria.fr). The use of external platforms like `gitlab.com` and `github.com` can be envisioned for open-source software, for which external contributions can be expected (...and in that case, you should also probably discuss the legal aspects with the right people at Inria before making any move), but as long as there is no stringent need, you should keep your codebase safe.
+
+{: .box-note}
+Quickly, about `gitlab.inria.fr` and `gitlab-int.inria.fr`: both are hosted on Inria's own servers, but the latter is way more protected, as *one cannot invite external collaborators on it* (only people with Inria accounts and e-mail addresses) and it can only be accessed from the intranet (i.e., from your office network or via VPN). **Confidential projects *must* be hosted on `gitlab-int.inria.fr`.** For non-confidential projects, `gitlab.inria.fr` is the default choice, and it will be used throughout the rest of this tutorial (the other instance works pretty much the same way). More information about Inria's GitLab instances [on this page](https://doc-si.inria.fr/display/SU/Gitlab) (French only at the time of writing).
 
 It is impossible to overstate how the use of GitLab makes collaborating on a software project easier and faster, and you can learn how to use it **one step at a time**.
 
diff --git a/01-setup.md b/01-setup.md
index fbb28d6..380df69 100644
--- a/01-setup.md
+++ b/01-setup.md
@@ -88,6 +88,9 @@ git config --global user.name "Your Name"
 git config --global user.email "youremail@yourdomain.com"
 ```
 
+{: .box-info}
+Once again, [there are a lot more options to uncover](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration), so that you can customize your Git experience. Most of the options are purely local, including, but not limited to, changing the interface colors, telling Git which tool you want to use for merging different versions of the same file (more on that later!), autoconverting newfile characters (useful for collaborations between Mac/Linux and Windows users)... You can either access those by using `git config` commands, or by directly editing a specific file in a given Git project.
+
 Great, you have Git on your computer and it's good to go!
 
 # Connecting to GitLab {#gitlab}
diff --git a/04-branches-issues.md b/04-branches-issues.md
index 28b69c0..3657353 100644
--- a/04-branches-issues.md
+++ b/04-branches-issues.md
@@ -705,7 +705,7 @@ Alright, done, too late for regrets. However, guess who does not know that this
 Of course, your local Git did not get the news: you have to force-feed it. Neither `git pull` nor `git fetch` will help us there, but there is an optional argument to `git fetch` that will.
 
 {: .box-success}
-Command `git fetch --prune` fetches content from the repo (the way `git fetch` does), but also removes all local references that no longer exist on the repo, including branches that were removed.
+Command `git fetch --prune` fetches content from the repo (the way `git fetch` does), but also deletes all local references that no longer exist on the repo, including branches that were removed. Note that branches that never existed on the repo will *not* be subject to pruning: local branches that you did not push yet are safe.
 
 What if I use it right now?
 
diff --git a/05-good-practices.md b/05-good-practices.md
index de2f7cf..f4dc110 100644
--- a/05-good-practices.md
+++ b/05-good-practices.md
@@ -210,7 +210,7 @@ One can also think of personal files that have no reason to be shared. I am not
 
 Finally, maybe even more importantly, your Git repo was probably created for one of several software pieces, which you will compile and run on your computer at some point. By doing this, you will create a lot of files and folders that should not be committed: subfolders like `/build` or `/packages`; compiled code with extensions `.o`, `.byte`, `.pyc` and others; files generated at runtime with extensions `.log`, `.tmp`, `.lock`...
 
-How to prevent these files from being committed? The answer is called `.gitignore`. It is a simple file, at the root of the project, in which you declare which files should remain untracked. Here are several examples:
+How to prevent these files from being committed? The main answer is called `.gitignore`. It is a simple file, at the root of the project, in which you declare which files should remain untracked. Here are several examples:
 
 * In subfolder `src`, you have this file called `source.log` that keeps appearing but no one wants. Well, just write this line in `.gitignore`:
 
@@ -259,8 +259,10 @@ By listing all files, folders and file/folder "name templates" (the exact term i
 {: .box-warning}
 It is actually possible to create several `.gitignore` files in several subfolders of your project, but it makes exclusion rules less clear, clutters your project, and is generally considered bad practice.
 
-{: .box-note}
-On the other hand, one should note that the `.gitignore` file is meant to be pushed to the repo, thus providing rules for which files should be ignored *in every working copy*. You might also want to exclude some of your own files, that you moved in your local copy for convenience but should not push (and yes, this includes your `passwords.txt` file... we definitely have to talk about this). In this case, what you want is exclusion rules that are local to your working copy: [this small appendix is about this]({{'/08-advanced#local-excludes' | relative_url }}).
+On the other hand, one should note that the `.gitignore` file is meant to be pushed to the repo, thus providing rules for which files should be ignored *in every working copy*. Fair warning: this means that your collaborators might have one of their files kept out of the repo because of one of the entries in the `.gitignore` file. You might also want to exclude some of your own files, that you moved in your local copy for convenience but should not push (and yes, this includes your `passwords.txt` file... we definitely have to talk about this). In this case, what you want is exclusion rules that are local to your working copy.
+
+{: .box-success}
+You can use the exact same way of declaring what should be left out of versioning, but write it in your "local exclude file": **`.git/info/exclude`**. (If it does not exist, just create it.) As is the case for the whole `.git` folder, this file will not be pushed to the origin in any case, but it will provide additional instructions to Git on which files/folders from *your* working copy should be ignored (for instance if you `git add` a folder that contains some of them) without setting fixed rules for all developers on your project.
 
 ## MR templates and parameters {#mr}
 
diff --git a/08-advanced.md b/08-advanced.md
index 4e5bbe4..7d7c876 100644
--- a/08-advanced.md
+++ b/08-advanced.md
@@ -41,9 +41,9 @@ The last three lines are more interesting:
 
 Note, however, that `git fetch` may bring you new content, but that it will not delete content that does not exist anymore on the repo.
 
-That is, unless you ask. Remember [`git fetch --prune`]({{'/04-branches-issues#clean' | relative_url }})? This command will  delete references that do not exist anymore on the repo before it performs the actual fetching: this includes branches that were deleted from the repo -- hopefully after they were merged to active branches -- but not tags: option `--prune-tags` also has to be provided for deleting tags. (Alternatively, one may edit the `~/.gitconfig` file so that one line reads `fetch.pruneTags=true`: this tells Git to also prune tags when `git fetch --prune` is invoked.)
+That is, unless you ask. Remember [`git fetch --prune`]({{'/04-branches-issues#clean' | relative_url }})? This command will  delete references that do not exist anymore on the repo before it performs the actual fetching: this includes branches that were deleted from the repo -- hopefully after they were merged to active branches -- but not tags: option `--prune-tags` also has to be provided for deleting tags. (Alternatively, one may edit the `.git/config` file so that one line reads `fetch.pruneTags=true`: this tells Git to also prune tags when `git fetch --prune` is invoked.)
 
-Once again, do not get too anxious about pruning: local branches that you never pushed to the repo will **not** be pruned. Pinky promise.
+Once again, do not get too anxious about pruning: local branches that you never pushed to the repo will **not** be deleted. Pinky promise.
 
 # Cleaning up your local copy {#cleanup}
 
@@ -392,14 +392,6 @@ In order for these hooks to be run, they must be renamed to the name of the hook
 * To alleviate these problems, you should have a look at the [pre-commit framework](https://pre-commit.com/), which will only ask your collaborators to install it (via `pip install pre-commit` for example) and run it (with `pre-commit install`). Despite its name, this framework not only supports the `pre-commit` hook but also 9 other client-side hooks (at the time of writing).
 </div>
 
-## Local exclusion rules {#local-excludes}
-
-We talked about [the `.gitignore` file]({{'/05-good-practices#gitignore' | relative_url }}), a file that you place under version control and that helps prevent files and folders from being committed: build folders, `.tmp` or `.lock` files, VSCode workspace files, and the like.
-
-However, if there are a few files and folders that *you* put in your working copy for convenience but do not want to push, it might be inappropriate to add their paths to the `.gitignore` file for everyone to see (and, hopefully, no one else will ever create this `my-personal-stuff/secret-project-notes.md` document).
-
-In this case, you can use the exact same way of declaring what should be left out of versioning, but write it in your "local exclude file": `.git/info/exclude`. (If it does not exist, just create it.) As is the case for the whole `.git` folder, this file will not be pushed to the origin in any case, but it will provide additional instructions to Git on which files/folders from your working copy should be ignored (for instance if you `git add` a folder that contains some of them).
-
 # CI pipelines: `.gitlab-ci.yml` examples {#gitlab-ci}
 
 Because of how CI pipelines can be configured, **no Git workflow is incompatible with CI**. A few examples are given here, in order to illustrate various use cases.
-- 
GitLab


From 56647c6ad2db2d7455fc8496dc09fa62daba35d2 Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Tue, 30 Jul 2024 15:22:03 +0200
Subject: [PATCH 09/20] Add checkout equivalents of switch commands + add an
 earlier note about forks

---
 04-branches-issues.md | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/04-branches-issues.md b/04-branches-issues.md
index 3657353..e4cb63a 100644
--- a/04-branches-issues.md
+++ b/04-branches-issues.md
@@ -235,11 +235,11 @@ Time for action.
 <div class="box-success" markdown="1">
 **Switching between branches** is performed via the `git switch` command.
 * `git switch branch_name` switches your working copy to the branch named `branch_name`, provided that it exists. The full state of your working copy is changed.
-* `git switch -c branch_name` creates a new branch named `branch_name` (provided that no other branch with the same name already exists) and switches your working copy to this branch.
+* `git switch -c branch_name` **c**reates a new branch named `branch_name` (provided that no other branch with the same name already exists) and switches your working copy to this branch.
 </div>
 
 {: .box-warning}
-A few years ago, command `git checkout` was used for everything, including opening a fresh branch and switching between existing branches. You will definitely find it in a lot of tutorials and Stack Overflow threads. The problem was that `checkout` became a very ambiguous `git` command: `switch` was created to (partially) alleviate this problem, and you should absolutely use it for branch creation and switching.
+A few years ago, command `git checkout` was used for everything, including opening a fresh branch and switching between existing branches. You will definitely find it in a lot of tutorials and Stack Overflow threads. The problem was that `checkout` became a very ambiguous `git` command: `switch` was created to (partially) alleviate this problem, and in my opinion, you should absolutely use it for branch creation and switching. For reference, here are a few `checkout` commands: `git checkout branch_name` is the equivalent of `git switch branch_name`, while `git checkout -b branch_name` is the equivalent of `git switch -c branch_name`.
 
 Here, I will create a branch named `add-quantities` (a pretty fitting and self-explanatory name, should I say). First, let us assume that I forgot about this `-c` thing:
 
@@ -747,6 +747,12 @@ We already know the first half: this make Git aware of which branches were delet
 
 Of course, **use this trick with caution** (but note that it will never do anything to branches that are only local).
 
+# Extra: A note about forks {#fork-note}
+
+I was recently told by a friend of mine that, in the company he is working for, MRs for branches basically do not exist; instead, they rely on MRs for *forks*. It so happens that there is this thing called forks, which essentially amounts to creating an exact copy of an existing project (history, branches and all) while keeping information about where it comes from. This makes it possible to exchange data both ways: the fork can be updated to follow the changes in the source project, and changes made in the fork can be pulled in the original project if they work, make sense, bring interesting features, etc.
+
+This section is already pretty long as it is, and using issues and MRs inside a single project already leads to very efficient collaboration, but existing projects (open-source or not) made forks their *de facto* standard. You can check [this part of the "Advanced" section]({{'/08-advanced#fork' | relative_url }}) to learn more about this other way of managing a collaborative project.
+
 ----
 
 This was a lot of information (and both Git and GitLab offer way more features than what we have seen). With all these tools at our disposal, and the huge degree of freedom that Git actually leaves its users, it is pretty easy to still "do the wrong things". Good practices are required to ensure that our project can live and grow in the best possible way, and [**this is what the next part is about**]({{'/05-good-practices' | relative_url }}).
-- 
GitLab


From f79ac007969cb2f621fe6c24bae813c2d609adb6 Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Fri, 2 Aug 2024 15:31:57 +0200
Subject: [PATCH 10/20] Add warnings about pull/fetch, using the web IDE + fix
 header link

---
 03-linear-git-project.md | 2 +-
 05-good-practices.md     | 2 +-
 06-vscode.md             | 5 ++++-
 _config.yml              | 2 +-
 4 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/03-linear-git-project.md b/03-linear-git-project.md
index 129436c..82e2b59 100644
--- a/03-linear-git-project.md
+++ b/03-linear-git-project.md
@@ -188,7 +188,7 @@ The one question that is important to us right now is the first one: I just fetc
 This means, in particular, that even if you just fetched, `git pull` will call `git fetch` anyway, so that your computer will indeed communicate with the origin once again. (There is a way to merge fetched changes with your local changes without having to call `git fetch` again, but it is way more convoluted, so that Git would rather advise you to just pull.)
 
 {: .box-info}
-There are interesting opinions out there about [why you should not always use `git pull`](http://longair.net/blog/2009/04/16/git-fetch-and-merge/), but for our purposes, using `git pull` should be fine. You should still, at some point, read the article linked in this very paragraph to know more about the differences between "pulling" and "fetching then merging": the more complex your Git project is, the more important it may become. Also, calling `git fetch` with optional arguments will prove pretty useful later on, so even at this stage, it is nice to know that `git pull` is all but an atomic command.
+There are interesting opinions out there about [why you should not always use `git pull`](http://longair.net/blog/2009/04/16/git-fetch-and-merge/), but for our purposes, using `git pull` should be fine. You should still, at some point, read the article linked in this very paragraph to know more about the differences between "pulling" and "fetching then merging": the more complex your Git project is, the more important it may become, and using more advanced commands like [`git rebase`]({{'/02-creating-projects#push-code' | relative_url }}) might essentially require you to fetch instead of pulling. Also, calling `git fetch` with optional arguments will prove pretty useful later on, so even at this stage, it is nice to know that `git pull` is all but an atomic command.
 
 For now, we have to adapt our workflow so that changes on the remote are handled. Let's say that I just have teeny tiny changes to make, and I pulled pretty recently. After I made my changes, but before I push them, I should be pulling again! The part of the workflow that has to be changed is the following:
 
diff --git a/05-good-practices.md b/05-good-practices.md
index f4dc110..2442264 100644
--- a/05-good-practices.md
+++ b/05-good-practices.md
@@ -4,7 +4,7 @@ subtitle: "Where things get less messy."
 tags: 
 ---
 
-Congratulations: you now know basically everything you need to know about the daily use of Git and GitLab 🎉 
+Congratulations: you now know enough about the use of Git and GitLab to manage your first collaborative projects 🎉
 
 However, as a corollary, you may now have an idea of how things may get messy. Here is a "short" list:
 
diff --git a/06-vscode.md b/06-vscode.md
index 6911e61..2d747aa 100644
--- a/06-vscode.md
+++ b/06-vscode.md
@@ -124,7 +124,7 @@ We are still working on a single branch right now, but with changes being made f
 
 ## Using the Web IDE
 
-It's saturday morning, and someone just tested my recipe and told me that there were a few very important and urgent tweaks to apply to the recipe. Not huge changes, but the end result is a total mess without these. My work computer is still in my office, and I really want to commit and push a few changes right now. Time for the Web IDE to shine.
+It's saturday morning, and someone just tested my recipe and told me that there were a few very important and urgent tweaks to apply to the recipe. Not huge changes, but the end result is a total mess without these. My work computer is still in my office, and I really want to commit and push a few changes right now. It might be time for the Web IDE to shine.
 
 I can just log in to GitLab and open the Web IDE to edit our recipe:
 
@@ -149,6 +149,9 @@ Also, there is no committing without pushing. I mean, where would the commit be
 
 And it's over. My changes are on the repo.
 
+{: .box-warning}
+There are cases in which you do **not** want to use the web IDE. Typically, if you have a bunch of tests that you should run before pushing code to the repo (or, even better, have plugged a pre-commit tool that will prevent you from pushing code that fails tests), then you should always work from your local working copy.
+
 ## Fetching and pulling
 
 Alright, fast-forward to monday morning. I am back in my office, and I know changes were made on the repo. Maybe I asked VSCode to fetch on a regular basis, so that it will `git fetch` as soon as I open my working copy. Or maybe I did not, in which case I can just ask nicely by clicking on the three dots:
diff --git a/_config.yml b/_config.yml
index ad9673b..041b3d0 100644
--- a/_config.yml
+++ b/_config.yml
@@ -83,7 +83,7 @@ share-links-active:
   vk: false
 
 # Base URL
-url: https://gitlabpages.inria.fr/tutorial/
+url: https://tutorial.gitlabpages.inria.fr
 baseurl: /git/
 
 # How to display the link to your website in the footer
-- 
GitLab


From 24813457580ffed905a19349f65f5c685da5684e Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Fri, 9 Aug 2024 16:38:40 +0200
Subject: [PATCH 11/20] Add more info about rebasing in Section 5 + commit
 --amend + several fixes

---
 04-branches-issues.md                         |   2 +-
 05-good-practices.md                          |  52 +++++++++++++-----
 07-internals.md                               |  10 ++--
 08-advanced.md                                |   6 +-
 .../img/05-good-practices/merge-vs-rebase.jpg | Bin 0 -> 15686 bytes
 5 files changed, 49 insertions(+), 21 deletions(-)
 create mode 100644 assets/img/05-good-practices/merge-vs-rebase.jpg

diff --git a/04-branches-issues.md b/04-branches-issues.md
index e4cb63a..d39eef5 100644
--- a/04-branches-issues.md
+++ b/04-branches-issues.md
@@ -332,7 +332,7 @@ My new feature is now fully implemented, and should be integrated into the main
 
 * I get a nice clean web interface that makes the process way simpler than having to type the right commands.
 * I can submit my code to collaborators who can review my changes and suggest fixes if needed (which is a very important feature for actual code: maybe I could have used more adapted data structures or algorithms, or the way I wrote my code does not fully comply to the coding standards of the project).
-* Finally, a lot of automatic checks can be performed in order to check that I did not break the software in some way: this is called a CI pipeline, and is an advanced feature that will be briefly presented later on.
+* Finally, a lot of automatic checks can be performed in order to check that I did not break the software in some way: this is called a CI pipeline, and is an advanced feature that will be [introduced later on]({{'/05-good-practices#cicd' | relative_url }})
 
 {: .box-success}
 A **merge request** (or MR) is the mechanism by which a member of a GitLab project proposes that the changes made in a branch be incorporated in another branch. An assignee and a reviewer can (and should!) be picked for a MR; the former will act as a "manager" of sorts for this MR, while the latter will be in charge of checking the actual changes and suggest fixes if necessary.
diff --git a/05-good-practices.md b/05-good-practices.md
index 2442264..45fb8f0 100644
--- a/05-good-practices.md
+++ b/05-good-practices.md
@@ -268,7 +268,7 @@ You can use the exact same way of declaring what should be left out of versionin
 
 Badly written issues were a problem we did not want to face, which is why we created issue templates. For MRs, we want to avoid the exact same problem, and we can use the exact same solution!
 
-#### MR templates
+### MR templates
 
 {: .box-success}
 **MR templates**, just like issue templates, help users write MRs efficiently and enforce a standard format for their descriptions.<br/>To create an issue template, just write it as a Markdown document, save it (as a `.md` file) in the `.gitlab/imerge_request_templates` subfolder of the project, and commit to the default branch (which is `main` if you did not explicitly change it).
@@ -472,9 +472,11 @@ A **CI pipeline** (where CI stands for *Continuous Integration*) is an automated
 
 On the one hand, for most projects, the CD part is basically an FYI (just know that the basic setup for a CD pipeline is very similar to that of a CI pipeline). On the other hand, one should really consider setting up a CI pipeline as soon as possible.
 
-The most basic requirement you should have is pretty simple: the code should compile. However, you should also consider tests, like, *a lot of them*. This is something that you have to plan ahead.
+The most basic requirement you should have is pretty simple: the code should compile. However, you should also consider tests, like, *a lot of them*, and you may very well plug other tools: Python developers are pretty fond of [code formatters](https://github.com/life4/awesome-python-code-formatters), for example.
 
-* Depending on how critical it is that your code works as expected, you may require that unit tests be provided for every new piece of code (in this case, consider writing this in your `CONTRIBUTING.md` and adding a checkbox in your MR template). Practices like [test-driven development](https://en.wikipedia.org/wiki/Test-driven_development) can also be implemented, at least for the core features of your software.
+Let us take a minute to talk a tiny bit more about tests, because this is something that you have to plan ahead.
+
+* Depending on how critical it is that your code works as expected, you may require that unit tests be provided for every new piece of code (in this case, consider writing this in your `CONTRIBUTING.md` and adding a checkbox in your [MR template]({{'/-good-practices#mr' | relative_url }})). Practices like [test-driven development](https://en.wikipedia.org/wiki/Test-driven_development) can also be implemented, at least for the core features of your software.
 * Unit tests are great, but you may also want other kinds of tests, such as integration and acceptance tests. The former check that your modules or classes interact as they should, while the latter check that the requirements of the software are met (if you know the exact output that you should have for a given fixed input, you can use that as a simple acceptance test). [This reply on Stack Exchange](https://stackoverflow.com/a/7672580/21698549) is a short description of the most common types of tests.
 
 Now, considering that you have test suites that you can already run on your machine, how do you set up a CI pipeline that runs these tests? Fortunately, Inria provides you with tools and documentation to help you in your quest. [The Inria tutorial on Gitlab-CI](https://ci.inria.fr/doc/page/gitlab/) is probably where you should start, and you may cherrypick the parts you want to read, so that you just go through the most simple process:
@@ -485,7 +487,9 @@ Now, considering that you have test suites that you can already run on your mach
 * [Register the runner](https://docs.gitlab.com/runner/register/) (you have to explicitly tell `gitlab-runner` which project it should access)
 * [Start working on your CI pipeline](https://docs.gitlab.com/ee/ci/quick_start/index.html#create-a-gitlab-ciyml-file): this is done through a YAML file (the syntax is pretty simple, actually), that has to be called `.gitlab_ci.yml` and put in the root folder of the project, in which you declare the "stages" of your pipeline, and the "jobs" that compose these stages.
 
-Your best sources of information (at least, for starters) include the [official CI/CD pipeline page](https://docs.gitlab.com/ee/ci/pipelines/) on the GitLab docs, the [keyword reference page](https://docs.gitlab.com/ee/ci/yaml/index.html) on the same docs, and the whole [CI Inria portal](https://ci.inria.fr/). A few examples of job declarations for the `.gitlab-ci.yml` file are given [here]({{'/08-advanced#gitlab-ci' | relative_url }}).
+Your best sources of information (at least, for starters) include the [official CI/CD pipeline page](https://docs.gitlab.com/ee/ci/pipelines/) on the GitLab docs, the [keyword reference page](https://docs.gitlab.com/ee/ci/yaml/index.html) on the same docs, and the whole [CI Inria portal](https://ci.inria.fr/).
+
+A few simple examples of job declarations for the `.gitlab-ci.yml` file are given [here]({{'/08-advanced#gitlab-ci' | relative_url }}), but you should *absolutely* have a look at the more numerous (and better!) examples available in the [GitLab CI/CD gallery](https://gitlab.inria.fr/gitlabci_gallery). Made for you, with love.
 
 ### Git workflows
 
@@ -523,7 +527,7 @@ So, here we go: good commit messages, clean history, testing. Let's do this.
 
 ## Writing informative commit messages {#messages}
 
-This goes without saying... which is why the only people on this Earth who never wrote terrible commit messages are those who never used Git in the first place. 
+This goes without saying... which is why the only people on this Earth who never wrote terrible commit messages are those who never used Git in the first place.
 
 {: .box-warning}
 Writing good commit messages is indeed important, as there will come times when you will have to scroll down the repo history to find a specific change.  This especially includes the pretty common occurrence of discovering a bug, having to get to the exact commit that introduced it, and **understanding what this commit was about** so that you can safely fix the bug without breaking something else.
@@ -539,11 +543,6 @@ There are several ways of writing "good" Git commits. A pretty popular one (for
 
 If you can only come up with a message that is longer than a tweet (this is what they were called before Twitter became X) and/or contains three or more action verbs, this can mean two things: either you are still making it too complex by delving into technical details, or you made too many "small" changes that probably could have been contained in several commits. (It is not too late to unstage your changes, then create several "atomic" commits.)
 
-If you **really** want to pile up commits without thinking about their messages too much, you have another (advanced) option: do not push them yet, not even on a feature branch that no one else fetched yet. Once all your changes are done and your local history has become a huge stack of tiny commits with names such as "khsrfjkb" or "please kill me", then use [interactive rebase](https://www.sitepoint.com/git-interactive-rebase-guide/) to reorganize your commits before making them public.
-
-{: .box-note}
-You can use `git rebase -i` , if you are so inclined, for reorganizing your own commits before making them public. **You should never rebase commits that were already pushed.** A local rebase on private commits is basically turning a draft into publishable work. A rebase on public commits is how you mess with every single one of your collaborators.
-
 ## Keeping a clean history {#history}
 
 Pretty advanced users who *really* start having fun with Git, or intermediate users who work on tens of heavily intertwined features at once, might get a bit too excited and run head first into the Git-ar Hero situation:
@@ -561,18 +560,41 @@ If you do so, the "commit message" problem solves itself.
 
 Note that opening subbranches may not even be required in the first place. For example, solving a simple issue by fixing a few typos, writing a single new method, and refactoring before pushing, does not require parallel work by several people for a whole month. In such cases, forget about subbranches: just open a feature branch, do what has to be done, and open a MR.
 
-## If you want to go further {#further}
+## Changing your last commit {#amend}
+
+There is a very simple and safe way to fix a mistake you just did in a commit (like, I don't know, giving it a terrible name, committing something that should not be there or, on the contrary, forgetting a file). Let me introduce you to `git commit --amend`.
+
+You want to change the commit message? Easy: that's `git commit --amend -m "Better message"` for you.
+
+You want to add or remove a few files? Also easy: just `git add` or `git rm` anything you want, and then, instead of creating a new commit with `git commit -m "My message"`, try `git commit --amend --no-edit`. The "no edit" option just means that you do not want to change the commit message.
+
+Of course, if you want to do both at the same time, you can replace the `--no-edit` with `-m "Here is my new commit message"`!
 
-Once you really feel at ease with Git, you may want to have a look at two specific features of Git.
+And as usual, **please do not do this with an already pushed commit**. You would end up in a situation where the origin and your working copy diverge, as the last commit would be different from one to the other. In other words, this is perfect for situations when you commit changes and immediately go "aw crap" (or whatever you actually say out loud when you screw up, Git is curse-word-agnostic).
 
-* **Rebasing:** Frequent rebases is how you guarantee that the branch you are working on is up-to-date with the branch onto which it will be merged at some point, so that you will not have to face major conflicts when merging. The [Atlassian documentation](https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase) on `git rebase` is a pretty good starting point.
-* **Interactive rebasing:** It is pretty hard to grasp the actual relationship with rebasing as we defined it just above, but you may just live with it. Interactive rebasing is how you reorganize the commits on a given branch so that the history of this branch becomes nice and clean. In other words, you can implement things in disorder, make stupid mistakes that you fix five commits later, come back to a task because you forgot to implement unit tests... and, once everything works as expected, "tidy up your room" so that the branch you will actually be pushing has the best possible commits with clear messages. (Yes, this is also a way of turning terrible commit messages into readable and informative ones.) [This article on the GitLab blog](https://about.gitlab.com/blog/2020/11/23/keep-git-history-clean-with-interactive-rebase/) provides pretty good explanations.
+## Going further with rebasing {#further}
 
-You may find more about both features in [the "Advanced" appendix]({{'/08-advanced' | relative_url }}).
+Once you feel at ease with Git, you may want to have a look at a pretty nice feature of Git that may help you with both issues at once: **rebasing**.
+
+Rebasing is the act of taking a sequence of commits and moving them on top of a given branch. It can be, for example, used as an alternative to merging: instead of merging a feature branch to `main`, you can take all commits from the feature branch and move them on top of the `main` branch (with, of course, possible conflicts to resolve, as usual).
+
+![](../assets/img/05-good-practices/merge-vs-rebase.jpg){: .mx-auto.d-block :}
+
+> Merging versus rebasing. Source: [Filiz Senyusluler on `dev.to`](https://dev.to/filizsenyuzluler/git-rebase-vs-merge-1ph0)
+
+This is a nice way of ending up with a linear history instead of one where several branches are opened then merged, and some projects will only allow rebasing for branches. But there is more to that: rebasing a feature branch onto its source branch will basically move your changes on top of the newest content of the source branch... which is probably where you will want to merge your changes at some point! Doing this on a regular basis (especially for long-lived development branches in active projects) is how you guarantee that your feature branch does not fall too far behind the source branch, which means, among others, that you will not have to struggle with a thousand conflicts when it is time to merge. (It also reduces the odds of having several people writing similar functions without even knowing.) The [Atlassian documentation](https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase) is a pretty good starting point on this topic.
+
+Let us go even further. Pretty conveniently, `git rebase` provides you with option `-i`, or `--interactive`, in which you are able to reorder, rename, squash and discard the selected commits before moving them on top of the specified branch. This helps make the repo history clearer, and as long as said commits were still in your working copy only, no one gets hurt.
+
+Now, imagine you use `git rebase -i` for moving commits *where they already are*. Well, this will just let you manage your commits and clean up your history, which can be pretty nice before making your work public, right? In other words, you may very well implement things in disorder, make stupid mistakes that you fix five commits later, come back to a task because you forgot to implement unit tests... and, once everything works as expected, "tidy up your room" so that the branch you will actually be pushing has the best possible commits with clear messages. (Yes, this is also a way of turning terrible commit messages into readable and informative ones.) [This article on the GitLab blog](https://about.gitlab.com/blog/2020/11/23/keep-git-history-clean-with-interactive-rebase/) provides pretty good explanations.
+
+So, yeah, ask your doctor if rebasing is good for you! Which brings us to some important advice:
 
 {: .box-warning}
 **Do not rebase something that was already pushed!** Changing the public history of a project is not only widely considered rude, but also a source of conflicts (between what a branch looks like and what your collaborators' computers think it looks like) that will only result in an even more confusing project history once the immediate problems are solved.<br/>(Advanced: The only exception to this rule is when a project was set up so that merging branches is only allowed in *fast-forward* mode. In this case, a rebase can be performed **just before merging**, and deleting the branch as soon as it is merged is then a good practice.)
 
+You can find more about rebasing (among others) in [the "Advanced" appendix]({{'/08-advanced#juggling' | relative_url }}).
+
 ## Software development practices {#practices}
 
 There are [a lot of good practices](https://opensource.com/article/17/5/30-best-practices-software-development-and-testing) for software development. I could provide you with hundreds of links to pages that agree on a lot of points, contradict each other on some other topics, and sometimes delve into a huge lot of low-level technical details that only the top 5% of developers will understand.
diff --git a/07-internals.md b/07-internals.md
index ba0a212..f47417a 100644
--- a/07-internals.md
+++ b/07-internals.md
@@ -18,7 +18,7 @@ And by "somewhere", I mean "look no further than the hidden objects at the root
 
 ![](../assets/img/07-internals/git-internals-1.jpg){: .mx-auto.d-block :}
 
-This `.git` folder appeared as soon as this folder became a working copy, either when you created it by cloning an existing project, or when you pushed its contents in a repo. It contains quite a lot of stuff, but I have good news: it will make sense in a pretty short time.
+This `.git` folder appeared as soon as this folder became a working copy, either when you created it by cloning an existing project, or when you ran `git init` there. It contains quite a lot of stuff, but I have good news: it will make sense in a pretty short time.
 
 # Git objects {#objects}
 
@@ -26,7 +26,7 @@ Okay, time to start from the low level.
 
 ## Blobs
 
-The basic object stored by Git is a *blob*. A blob stores the contents of a file. It is not the file itself, though. For Git, it makes sense: if a commit changes one file out of the two thousand files of your project, why would you duplicate 1,999 files? Total waste of space.
+The basic object stored by Git is a *blob*. A blob stores the contents of a file (it is not the file itself, though). For Git, it makes sense: if a commit changes one file out of the two thousand files of your project, why would you duplicate 1,999 files? Total waste of space.
 
 What would be the most convenient way to give names to these blobs? A "naive" solution, like taking the whole path of the file in the project, removing special characters and appending an integer that is incremented by 1 in each commit, does not work that well. For instance, what if I just rename a file, or move it to a subfolder, between two commits? Should I duplicate this file?
 
@@ -70,7 +70,7 @@ This is where the `.git/refs` folder shines... but in an incredibly lame way.
 
 ![](../assets/img/07-internals/git-internals-3.jpg){: .mx-auto.d-block :}
 
-Three subfolders: `heads` for the branches you have in your working copy, `remotes` for the one on the repo, `tags` for the tags. Why is the first one called `heads`? Because, in order to switch to a given branch, Git only needs to know the hash of the head of this branch, i.e., the last commit. From the contents of this commit, Git knows the file structure, the contents of the files, and the whole history of the branch.
+Three subfolders: `heads` for the branches you have in your working copy, `remotes` for the ones on the repo, `tags` for the tags. Why is the first one called `heads`? Because, in order to switch to a given branch, Git only needs to know the hash of the head of this branch, i.e., the last commit. From the contents of this commit, Git knows the file structure, the contents of the files, and the whole history of the branch.
 
 Hence, a single file that bears the name of the branch, and only contains a single commit hash, is enough to define a branch and its whole history at this point. The same is true for tags, which are also just pointers to a commit. The whole history of the repo is a handful of 40-bytes long text files.
 
@@ -113,7 +113,9 @@ Note that this is fundamentally not an issue with storage, [as this very good bl
 {: .box-warning}
 As a rule of thumb, **do not store binary files on a Git repo, unless they are reasonably small and not prone to changing often**. A 5-page PDF document that is only regenerated once per release every few months? If you need it, why not. The compiled version of your code, automatically generated with each commit? Please don't. Videos? *Absolutely freaking not.*
 
-Also, you can go to your project's page on GitLab, pick a commit, and see every change that this commit includes. Very informative on text files ("yeah, this `#include` did not serve any purpose anyway"), less so on binary files ("`6fc9a78c6` was replaced with `ae062bb4` and I have no idea whether I should care").
+Also, you can always go to your project's page on GitLab, pick a commit, and see every change that this commit includes. Very informative on text files ("yeah, this `#include` did not serve any purpose anyway"), less so on binary files ("`6fc9a78c6` was replaced with `ae062bb4` and I have no idea whether I should care").
+
+Last but not least, remember that, for all intents and purposes, there is no undo button for the history of a repo. Everything that exists in a pushed commit exists *forever*. In other words, remember that 100MB file you committed and pushed by accident, then removed with a `git revert` a few minutes later? Yep, your repo became 100MB (and change) heavier, and there is nothing you can do about it without taking huge risks of data loss and screwing with every single collaborator on the project.
 
 ----
 
diff --git a/08-advanced.md b/08-advanced.md
index 7d7c876..fb12b4e 100644
--- a/08-advanced.md
+++ b/08-advanced.md
@@ -114,7 +114,11 @@ Oh, also, before we forget: rebasing is great, but for local branches only.
 {: .box-error}
 **Do not rebase a branch that was pushed to the repo:** if you do so, you will then have to force push, that is, to rewrite the public history of the repo, and this is a very bad practice. Not only is it generally deemed disrespectful and unsafe, but it will also cause you a lot of problems when anyone then tries to interact with the branch from their working copy.
 
-A pretty good reference about rebasing is [the Git SCM page about it](https://git-scm.com/book/en/v2/Git-Branching-Rebasing). It features just the right amount of examples, every time along with the basic commands needed in the corresponding situations. It just suffers from two minor issues:
+A notable exception to the above rule is for projects in which a "fast-forward merge only" strategy is enforced, meaning that one just cannot merge a branch if it does not start from the head of the branch onto which it has to be merged. In such cases, though, one will typically work on a branch that was already marked as "ready for merging" (i.e., no more commits to push to this branch) and that will probably be deleted as soon as it is merged, so... No impact whatsoever on your collaborators.
+
+While we're at it, we should at least mention a huge advantage of a workflow in which everything has to be rebased before merging: this will prevent commits from different branches to end up mingled in the main development branch (which may very well happen without it, especially in large and active projects). Commits that were coming from a given branch will always end up being contiguous, which is a blessing both in terms of clarity and for bug fixing. The latter, in particular, is why squashing commits when merging is not a good strategy: go with rebasing instead.
+
+If you are into reading stuff (which you probably are: this is Section 8 already), a pretty good reference about rebasing is [the Git SCM page about it](https://git-scm.com/book/en/v2/Git-Branching-Rebasing). It features just the right amount of examples, every time along with the basic commands needed in the corresponding situations. It just suffers from two minor issues:
 
 * At the time of writing, it still uses the kind of deprecated `git checkout` command instead of `git switch` (this is a pretty common thing we already discussed before).
 * It assumes that both branches are already up-to-date on your computer, which might not be the case: before running the rebase itself, remember to `pull` the changes on the branch you want to rebase into.
diff --git a/assets/img/05-good-practices/merge-vs-rebase.jpg b/assets/img/05-good-practices/merge-vs-rebase.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..86170c6d604044264669c3684013758032cbafde
GIT binary patch
literal 15686
zcmex=<NpH&0WUXCHwH#V1_nk3Mh1rew;5U(*uj8<laqs+hnt66fS-?#UqDhwSV&k%
zQdL}9TwGdQRZ&AxPEkYAT3=IB-`ds6+{!iB%PTlDIkU5K2P0TNJNX9uKg1x&!IZ#U
zz|5$`z$D1XEXer(2!jd8iL4-}GQa>EBNGcNJ2M9(BLfpNBTN)Tv#>HUF|+-@#lXYN
z$iO7PEWp6P@XG}xLnLNQ@6p?nldkcP?~m%$o`mGgRk~rS9ARa~`@eU%eSLp5uPfim
z`MmT8m~kR&*Hly&MedjO{m-ym<mHTWe}(r~d|DFDEICJcdb+2=OA(k#25!T>JJmJ+
z7QHLodOb5&>EfNYSEO>~E-vfk{du{(M9=Nqv2AzvB&2}VGtWG`_wgUy<bR*u<f^z{
z4)*Aub8?Q;rqrp5TW2JuTj^dkw|qLs`YKp00|Nth-iGH^aWkI^{bS8{-)z|)sdV$X
zN9ev^ab_Zu-o1YvzfWjI157O|zn$mx(m6Q_v-Ztg^Eh?sn$3aRCGIU=_0nW=d#lEY
zm*TU}7k)omoVV?z$pM%iG+ONDYo`ThVn|%prDt?5An_R((Nr_@8$hI6j(wluKF@6a
zg^4cTELCqB?rglUo`JzJJxY0k_m}C@U)L;EOJgZ7sy?;wQc)IIOGf#f75CB$vt*}P
zpV^ik{q3Q!@Qx4$=DCTvI|c73@7aIi&CNaaF=Z#&dFIVk0PA2n{n4*}^W)!6`CA?u
z83n66pLlumd5ixH2@H%YZofV!dAVZ$%FA0~zD1S1k#p2j-Ta?nYTZI3u-93q!$S>Z
zlxCo-s}=(TgGfkVpchnzD<nFq3na*}XwmJa+h9?{k{?xzt?T*EtG&(x>4RYwpF2-K
z|9Mn$`~*w{M6>O<5oX)w9kK$%fnd2hNt^vs?oDef5u2K&__6$@ZrQPvfcp**SrF-#
za!ug&x7mA2KAqUqYs<_y0VD{)N<x1Vxo+j};fb_Gaz10e`fHh0s?YcPKfUXot8>vK
z`s$}W^QJFfzGHvp=~|<gZ~bmPn-aWiD#Q#128NH{KHHW4Qh#2*NTKRJU+i_m(#01~
zT3!>;+#9;~#@(Qh`~{Gd3evDNqu6ie=k!YgdsY9*eVO^(;M0da7G<}t%irJ6)dLO^
zP#UdF4}K<?x8_yN^3`T5rn<52TDyDNpMCe1u3o<L<DFuEwyMRhyLT+#>Gkyq$V>(X
z27Y^QgP+%5%%8ijqw#fZW@!7Q?f$!p?oZB3->4OR(|*6w9M4Ym=;)|ba64GF>~em&
zKl{(HM0;=Vq2tGc&tGj@_ja1O+`oOZdfvRAw6wYiYBqP}a_@$Mt(U*fOT1kAwqUXc
z14HEco0q5kxy`*g@yea76q|3ET4o0#u0fr@>9@hp+b{Cx?Q3m(ZQI&DnKAb;ALqpj
z%Ra4ZetuqSZPo4h=W<us9ytM3&al+|?0%1$$6r#*H+~VbvtZRqnh|-{{L1s{?44yd
z!=vY4pZd5K;uPJb-=^JPau*cxOt)LNYqm!DUJHdtF`YhsUf!WH_4xJ`69X6+g3h}M
z^5#2+-?+52w*aDof$?+yMSGiC&e%6bto{8A3?eIz9=sEIdYxV#Us_?o%QIkQ7c;g;
zxOJD#OjO+kN}+7?3s;#$%8AJt+15<i0an4lYU*}U_=tMGJt&b~t&se=A<}RQM2dkc
z#QpoTy;)}9cwq%6b_UiBu`1_f&M$qO)i)8O%<#cS)e_dN)5W0Wf>YYP6h-re>uxhJ
zFtB(>S}tV2muC!82*MS=U3||?j;*xWr42HTy<vUp@^xWq5g<8+;Mrg53gvD`U)!l4
zb$PGLE(Hb#*6jhupZrapQhDF`dj7We&d-}6S(|<S(w02e&-X6`uG@QLRsaJ7SH*7!
zC9iq+7vC#;BwGoMi@p<W%cE8I90r92tCr2WJwXsRMxV2?x9HDZ`#NU&+RS^4Vg(o&
zn5Hi5KV`LF<MY1m^|874+RwFtf`fs9TYoeEyt<~J-(OhRZNB0EDS?4O<oR9hc~@_F
zZl7iQWJRKu1=#HjTw(1ZZ|$xBva?@J;k*~Zz`($jkoNk=x0`);z$S559(RBCaqZT-
z*^|DmDPJ)aR5dMiGuL=^XZg8ba(hds|B|<ngczl>?~GmLFaGD}7d-fNKGFVU0|SHQ
zd#C4H!zSfE>#x+4@alu8W170~^ZE<(ZU1t{zp*{q-p|0mz;w3maQxwYXUZRdl|(PP
zzwwfx>XEa@oby1gs5tV><C4xkVbjTSkdR=AtZhGU@A&8Y7a9J@cj`Y47#P@XU&MS{
zcgc6p#rLYtoPprtkbxm+i(Tn2;ph7oy#Cwfu;C-f_{jA)vVWA{?E3?@iX+~7v&`&M
zrSqQbVPIh3u{j&K^5!e$<H~PjKCcjlR+_pyit{>aD^INe)s2i|Q+9m2mh<8E%Ngd-
zI)hc)`FZ?;eKo(dc3;1vQv-@cvFvYF_hi2{?+04~A(*<lK;aAGxIX#MU?7|3ex&NA
zdG<F31_m}cyVVgcOJyckl|wCMSn6&w|8A`6m3&Z>fUC0FaI&yIG}1suz%iHGlWh`q
z5<#+6RlGYJ7?|!P%gb}CxAgGd3v!1k%G|c!T(&#)z;8_pw<Vw;{Gjvo!vTXQfp1?<
zf~i5G<?5y-e!hOe-tI3u^R;Sjel-T>!{KY3qobnF)_Z>0S0df=0+OB?7@qxAaNo1!
zu)I>6mf?gG3=G@0%GH4a0Le5k6OtgCe}0A~NRg|>w~c2fpU+tT_0p$jGgRPiWnexe
zZ`Kla!)Nb~H^1jcDxF@NwaN%=1_r@8{U$gW{QM##ANfZ8r_qU+Olu3jbhj1TKAzLh
zXs!h%9;hxJztSr@&GyqvYD3soUEiQk9NiUPs;#Ags1%?I!PKVT{PXrTwVhRpk4?Q5
zcV(l^-6Kt_u5F)gauBKFVqoCckIHH~X3fTHdv2Zk>6NGV2d&$lTInR61<ev*v*5&r
zedqP;$}mEQ$y#Z9dz_=%Eay!9w0#pZeeX(?KZ0vQFhm~6I}|RSb@OVjx=<A?B_X64
z7%t>PQ$4aEHa25l;Tv6<6_Y%_7$rkmDcDq@im`4_cs=Lzn*A0$7#=`X2;<4jUh^r-
z``ps^58oGhNxy;#6QG~$&7O4eUa5UOfAy>c<OT#jee9~QW2W_eUite+^_|OXzwjwV
zlCw0Ad@8cN*7^S7d-vwR@-mV<RwiTTbl>9K4?o*(L5p;(s*nY*2>hvYUtuoqS@ZPn
zNmwn2tN;s}Rm(&&I&k?NEK)dyKwS?j0R~1ECPqdU4mKu67A9r}1{OvpW>y9^K?imr
z1498}5k(_o(*Q9A6EnvIQKdj}<-`IN)u6(L|F;-GofAe*hW`wA@_!VD3R;GGJ`4@<
z3@i*6tXH>dn_~U6#8chw&vW6`6FQPZ-0i0v_mvhEJn!oI<@3vbhWlcpem;6M&B!up
zv+3EYqU*)SytR{(=Y4lJDL&TU`>)?7^yR!c%W~7FEMbq*>AkFwEU|G~?tv`@&NA=$
zbA*a!*nEi2c^E3lBeZq)*819uXE~%DmQ8Cq$=i2Hw6H_@ad+9ea68L|t8cn()O@Vt
zW3<V7vXJ7+ZOZWl#d4}`XDnP6T<ni2&SA?rac*I)^lpw>HzXcSj@kU}*Nmk_cPII_
z&YE`8ce~gM3wh&~TWtz6j?c;VT_Uw;hRMX;nPLhPW-jP2?R|R0=z3&MGQ&5giJ>{p
zk*9vxM%V1xUb)Wt<jpA2($=}#xBIW~x8~l^s;ZtRW|@+rbR&v8)4}KPuI|hRsT~r{
z+g?~||J|jN_rQK_=jQgz8r@{2r(3Umym3_dp3UusGZSBOOuc3h$#?T%z1w@8n^zt8
zud#gjFKYjlCHpRvT&&aN$`miG5w_cAVRW%)a{6+2vsWDPTSApK{p{^eTJdi2<CNK}
zt>0=%%-!ABE!lA`kMVoZ?)y9BrwEzpHa(Tu_H~k5%{0?z*=FarGGE(g@=9D>?^fS!
zt&0VlQ?H%fz`HYpso8@$)U0E9;Z=^!b<&Z~g`D(Gcd5TqGCjF#r{b*rSD)snM&07`
z4D!<y&Q0CuyXN{O?y#w<i)$vYF7y0gt(DQd-Rh-!D$ge#)1~oJR})>^zU1!zF)cJO
zVw2Gdu61c!-<P^hnQHar^RKl{)s+XDf|hMulX;lY#HBN*GAWYPxb)SbZpP~EQg35I
zldLRGK3`mKd%sMA<D0-PA*FWjm2EEN1+NVFTPON*NS)0vHcK<gn&@H1EO$uDP2mJr
zwdX2{MGMs2{xft+|LNbZ9UGv0KJ(P^E4`W*XFWR{pu_H!9pScxQSEosmc1duYLTH1
z>*RKn9b~qeC(f}#V(|jQw{{)ULJIRL`d7;x(zt2tw@U0lNn1tB)ds#audY{(a@Blc
zxd$g&HhF!V;5H>AJA$=spX~hAC2!U);M?TxDQ13pb-B&+@+lz?v>F>`RVHR<y5x5E
zx%scWcHVfI+hH#mMH{o@Ka7^QWEp;C+{2#~5$wG(zIayI9?6qZ_S!3*)+XQPR=<+1
zKJ}96LS_a5GmYruU(^>_*1njyai4Gg^lwL9&)I+Vw>($;;<@FQqIoQz-C6u5xrg4l
z9_g-pWcI~##dDr(&iOLuhkmt0*Sd%kZE4>Z*Ds#(a_5)gInV9->aBJPv+Q7)xwMUQ
z^L%&9^W9tD3A`3+l|G)H*|kJS>8kOTQ&*RM`|ix2StBQqa*ccc!f%&bG(va3ogy8(
z#%&YdmF7tmyB~SqvWb84lp(=oYD$y&&iS*qGN0s+&`s(Ny~B9z>x3B}9Nubet2pEI
zc=}eiL&n~<F~83qe{87G#qj-M*V0X!Jh<K(1TJ1vzDf9&PeIj++UC$(hi@*Lnw;OW
zvvA|pz<pvf&HuVws}1seTV_3#H|fA+(I1cF3cRAkH+*YnExKxvGQ0A6`#g<QjlJhu
zjD$G3q{94#Rr8;{wY!>ay7J<t*SG!ldpgG5<WetKBq7mLSvGfZ@bQS02j|!4eZBU9
z>7>f!l7(H8X@x=gRd14)oC=NIVD?Dmk?)1++U!l9@twEYcJ-y}t-Y_Q)1kz+w>s#0
z)H_j+d#jRc8#XR_|Nc)(Zp|zCj45goO<OPKf7v|$jiGkU<j-+pjiHiO&(n9ynr4)_
zP1{<1S9Z2X$VBVF>(wvjblx)hr(#oi@%Pk_#HOHKaTiuRGIIFockzYD5&3<`H@O+U
zjpxq0%Ds2PaxL-AzPh^&zh$fc)wj(`>At0MsjOSOYVo-_Z{<GR-X_YWpWf=5UT7#B
z_N_3>_<@|u!pj{iZ=BsYG0@`A?_8VfAxD|HZhp&)3@usPmso9~a?n5XtiHo-pJh^u
zf)X$F<Q?H{UOIjA-zgb6uMf}vH(ywCi;z+5d`F$z%c7We)$LT35#Ci+@q25`H)*+T
zD{Ow<v^%=9Fzx{V@{IzEvsSN+ne|gE!MM3Ji<i5T<&<*k#!UhfGqz4wdnh$US?by%
z)0ID~eVClT?p)l)U8T*y&oZ6kZ^f+>t8{GJxHkLEPn|o}n4y+a>h0p}%W>P(CSE$h
zcYoa^)~$sTxNn|~Y7962J(u@P*4CvPSE}tOdd1|@5cRrD<;{`>i{*JITKz3`)>zl7
zp<Q@lwa6^)Xx_Gu_fC7e1qv~7Dt@bU`>3<-nTGw@O!>9zbvtf;?XEQ4_a}*a?bNc<
zoC_OH<n*juwl-DR^z-u_yIlk-*6AcITK1noa{cScr*pShB{D8FUHMOA!|Dg$64|>C
zKeqT%I4525c<V7RwYc>^!#pe2Ed5zkTmCb&c3QZE{c2lPu-0S$$5(-&qS1H!fBZSs
zu`gr8qMwV7%_&&>)nm?ohE+$dtMla-TDUw+ey`5wk}soFQhV&<(>s2Z4-?b>Gjtug
zT4Wh~_4m~ZkLdF@%7HeMKNrqhefKzTr_>y!s%f7;e7E>#>m9Xcao~zMzxM`LKHq)3
zU$Q{6?(F$*n{(LN?Eai9I~yx6w=;c{jP690>gGK>otI31t6S#VOb9=(lEt&?p+eRA
zo9c5HANeWUG+DC1DC5`fXS<Xg)xvU~Hxw8ivvKhjn5|GO$lA$#OG22*ZPoG{)8!t&
zUBlHSl%{rZVoaCMV(wzm7&pbMEDH}gxyvURz2SPkb+TRdtlt8?DMFWXwl2KR%Y9!^
z@Vs<N@7<)wv-(`!lM|)%HLgzdd^Yj0NIXl{p5)l~zXcg0xpIy$Jj*_QVw(QEir4FJ
zDKkboN;dY2@cb6ub6I;5|7SBVKTAgM)Av))re=x9wVRd{F)FFY-?BW~Wbm#j@4T<d
ztK)W+6{nY<moT!DVa}OTu9CXJ+R-ODR%FGS=j+PKcN}{Y+HZU_sBE{alG}C5(}IC#
z&V9*qFYel(uyGm7O{t#}rWVZQe`D<1w4TJ56gtWXZnL=k^m^HnIV^f*$zN95^0|aO
z4EV*+`!uxm^|jLVk!}^zk;+;w(M;QTo-I1Aq#yNXqW#66{F=Mh8J{%RG1uVI#vPNR
z0|ZvQS$&h)RO<TbxPHID;Pv%83--Rgxo-dQUmY?1N!Ay<=Un?VQ_y4I(<31vPsLZi
z^?vy{Jx$(cw(!McIvM*a(;XOnAHLC#-nhQ#lyc)OU(S0gRvg#~w$R%0$g5Dp`^+0{
zZ|{1N`LFkgkA??V(k8daSL-{&67H}aD$VH>^kupd{Mg-9y|Q@fxvJw&kN<j?-S}sk
z{=&DepHH^>n>|jQr24Q(bJmw5p|5ra`en19JN<9Ao%)lqg6?S|SDz~_eq<eHVy?5u
z#&*^bb`@6x?hAcM$|~8Df5a`l&%N>9+lPhonG0>XW~Tb6c8kg#*34O%`gQTH)j96k
zNrp;Fnm77-f6R^k&oF1t_dM@L{r?P7_WqJ8K2-%PRrvbv-RWq}-}&SC)_dMp%I3_u
z>O6P4{(pveJN0Letyi{RVT#gD>3JKnFf>)j;hVPB@v249u^U>71y_8jxAQ*r<-Pxx
zGT(Ri#FgW}<f$+3sg`;Ywo~_O<0;okEIHe*2p7CreUrsfus>|~l&7MiRm-0pe0OI$
z!(Ws7>APlXye+p$+7=P6Xnyz5D(fjv#h1O+f5~(1^nMpN^@b<kpUXTfO`LVrGik$>
z=Z&uw^5wo=TlrFwcioLfQ$aB|OPM)~zO4HZ&hwuk_P+8D$<CkR=P!6n5V@MNX3JHT
zR&c=ArgRGWvR!bV(Jj*X^vZ5C`?5znm_F#l&;EHd$<p?v!Ti&On@)0l*eUaNqVd$1
z;^rSt8m->R5<7<>!f8T_)77{dJz)zUvpvp&(JF2)-{;KzC?92fM95-ExyO$G463I^
z9+&xaKiw?-^XiJ7nO>YPR;)Ffc4}70H1?3UD^}g;IpNV)ru?|x@6FB2z55xy_lh^`
zfI?j1d~ayfMv=AO?WL7t<}CVrVg16huAkjDN<ZnCr@T+!sbqEEr<ko>A$O%#oCvH9
zwmkNOyDwSps=Mm84Tf`HDtbx%4)6{0c=GAx-P!58^L$o+?-g3#uJN{hns#byky6xu
zhT_fhs*KLf<1TPdTHbv~P3z;ItG9#-)4m7V>~eKEevRej-s}Y~E+2mQyjvdd=k~<l
zoV>8#&5bpBwp`bCpH&eRt;{pDUYk{7wk@b%MX7JP^R4R*pJt{cMOmC;TXSsNu}Nkk
zZ3n*0?5V0KFAHiE@ok+pIVW_%iTL%Kc1*~v<a)rM&$Pl*sLGpj&FX}CAul<mDs+C*
z3p;nXJ>|tb#r6Zz3zDxdt4fS|8rZVXm|s}1$8CA{ao6-fOIN;xBmNG7Pq;Og-M+AP
zqLQGb{_+imZ!(t|t~lbhs3N@dbgFci`aHIS8PZ3lMcbAgIH4`c$S3sVn~JK3#z%gZ
z!ejS33tp#jDkt_?n)zo3X+ITO_ABG{;)sI`C%hY%xV>lj-Pka3<4%VCY)9Jrh5I(k
z-sV!iwChH;#gh_S>mPY6E-FV~E0y;gUwpCRMQGHFuI@SNH?E&%u@YGG=E^dblW$~m
zN}8|SaZ+`5pU0b#*|y&8#C_JZ4(UfKnh7T1Z<bBwHr=iD<Dt&ZYdw|L&t@xI1$nll
zeP23t+SMmp&vwj`HgH*+t)|4ec$!H~{)ahFvb0t$G^{`KNm(iMndG7*(^Y%fepH5j
z)l|6jtvn;QWAn;j_4yrdX1Vs6@76Xm=Gy#~-{sShPcN>^9J34zouh8gbzEwd)<zr6
z;|={K8w~;%`$=+LZ(0Af%SfqUuJ(pBqeo{>dPFp_tX-6OEN>BO&ex|N-(JuEwsd2Y
z>4$E&4@VB|jbG(6GwQjs^rpPWv#yy6TDZKh_WWg(o_c?Yy6}<mdBVRci~3)8&Oek?
zl6PL;W_HG^hWE)OXG4ku1EU}6d72c~<R{<yraWt}$*&KaL{&bXjSrB`@|j@%VS~^6
zs!m6a0!5F7`7KYfC%5{ibsBjn6+J1~WUm6UL%Vp>`%A)|kF3vg{k7TY`t{hC)qOw0
zb@x|oSNxfC<imG&OCdh7*3fMCmv^6cc3xjUuWa&{u;;1!LGFsT(f;!3srYs2OY8Ix
z?acjsbtnJnH1(F9yM8)Ok@uAr{_%4DY`wDue21D{ZHuQqKKAuv{JW%e{Mz@vy2dru
zeBLsD(RORyzls*~lzu*pUp`%9-;R4z3+qHr=igg<qAuFdMm_EAQ?`IwlN|rY%gXZX
zcS}!Qd16AvrW)<0KSy8G&v~o<V&&Xv|0c}ww->DWu>SJtDe*D+UOV=4J>C93?1{bZ
zjCsPF%RV)0*v&Fi|9IKjT>ftFsUuH3Y9j4K57s4p;ePQ}{l&|<)9WV8@fWQ5u)hH8
zl^1@!_?^&sV!{uo6T<aZD()3zpIZ7hr;20ViMV@#HSQ@Ft8UymdZ4sE#gZd3P}JgO
z>=UGr*<HyG3Yp~)-yj(^U2$WtZf*bW$M^FZFGsgVzPj-);%Z!P;XUtZujcm(D||mJ
zXMQN=?w<Bj{LA_~p`N*a$@$UA59_!;i!Z$OUC?yfarvUdTV>m(CV#tCsK;Bop?Jl{
zJHniXP6a0)-jEbv-d8CWz1qUHFmFBEEoH6Q2`hM)uHE-Iu}nis?W@^k#bg1a60e!Z
z|M6bD=lUw5>Y4GbYg-LhJ}jIqYI3bpd{xxOIEjf)|K{G@@$XGucwHaAn15?Q{EWSP
z_t(F9bBBGKi09Y4yEAXDKCzwWz#FF<iaLcI&Uu}Z`%YYWC}?Bbw9ENWO`y*4n`c;>
z&9=SZ{+6l1P>_8fzr?gSgg1Cm=KVI7X`Xj43Aq%wtuJ0!otkCa{YXARH)E4fNW&c4
zj*XLye}%9AIJ>F5Y}wPG<r@w^I{RTa>(A~BALpcVKU)99^`(B<FW=h0HbK3&t`&;R
zthTjpv)!dsXZE?PYwY7}=iv^#e8Ti>Ws#Z2v$stTCv>m|d9KKf`Z&=sK;-46-S?+U
zY3u3=JXJ|sBVc4#<8HoZPBME=_Nm%CtzQfF{`4>R);;_4`_08+uDWpt3tuJHI=!B_
zD3$5dt&P*-xsE1!{|H$+_ki9N;RUC&tGeSZ#;dOW@<D0$J?~vCd9&QNsad`|q0(1z
zTUq>AW=>F;O8(vOdo%TxuJ>_ivD=e%fJOLbqO7KN;EOM^orenM2`=I(-<9!THA}hj
z;-*}uhN;C%)(bE;b}C89O}m}2a#@zerKPu5=(No!^jo}Zt=I;ORK<1KxB9Yv_!XIo
zhKnpyDq8U~P%+XVSX%h$%(HT7=Y?$dm&Syv`EI`IP`}Ztq)1E6{6M_x+6PyAzON0P
zoYUqxaph%U^_88U^n&fyXYbv$aj&|=3X$EuU1!p=w}uu69Qx`T`>C2`;_5w0QLBYM
zPC6;RdHtT3yBjyIoVQP%<Azd3pbqoK?(gAA%XjNupL=tsQ2p&RLwkFRbv}D;JQ5U>
z5Zg3mb>`j$M<ps+dzCv^UbgL>xazvf--+3iXIpCB(skO_wkyFU{lUWry~!;TT{;YJ
z^7wxE>yr8Yolf9-nT;D<jy_%Ud-I-6x4*A0lAm_Q|IAM1n^M|$UhkdwX;qh4P<DRx
zgvo^yH+FPfTOPLh#dG0b!U(me&xyn+9eb%-I`?AP=W2tsi?2QAl{UH2d(L>*-k>M%
z!`z;$F>XEbaz3Y~$i*{9O7dL)wY=Ba_V?AD_NSYLKUtsGS<AMrHC}n?yyGd_yUwg!
zD!0kx;mT|4v<1(G#O%1LJU3QjHRHD}!R0Ea_I4QGy7qlyrH}s$zE7|M%$94%y3?zF
zXfF=Q>R|lM7`H2xZAU?($D?%lgpfn8*{xJPXJ)Pz622BFwmD5he2ME8?m+KOS?=FA
z&lP{aUYQCj#oE`)eLa14>W1=m(X0%PjgxQno>1uGxHxgE-LaMbPEXtQV;XPhyUEd+
zuJ(1Nt8Po`3yMtimpSWh_@ALBCT6>zdD@eB-5Gr+m#652@69XI^r_#}I;HCR>S7N=
zi6br#cOJi4aWW}oZP?yzzm^1j*4W87ZA$R>6tBG<)@)lvPkec7eZQ)#-X<|BK;^b-
z^U|#HK<VyjSN%7+q_1Cn-Fe;9KjzZk`V4M;>`U5|7M1m+?dufRH8;CCUkYZ(b}T=B
zug$OS>oKkR=X>r|JnyUhdB^A7vchlkjC;bAo-So5(+w}@T(@P>?EO+#-kzDfTQK9~
zP3yq7<@Z!(PE^;g?rPt)&eJs8>0LQ@(7kB!DZg7L9M=w&yPfN&`TG**th<#72cFEm
zUq11~G41KHhP$7hUA6DnqywiO=AWDL^t$T$%X9O7`!YWFT+8t2`a9Vx=WIFlmrY&q
z<IdHS*2*5IO)o_6-!$RAyKJ!Ex;LvN)LVTvHK{pECnwiEJtvU!Zik3R?BA8KhqRvV
zyT0*$^u)-u%X+uIdHzP_dZgX%KU+JGPqWLu#x`Y1U--905ii}R_D1ch{T!=zi{a3v
zuhp|w%?{$~TGE}+kPvq`h^d)->brl}=HFgolCi|&u9BAi^l!J%uQzA=Y51QZch9fS
z1^E-@p(27ritJ9l_El8M{6zon?4zyk-|y`G&+zr{Hr_o#W|Epo>EG5BC%jdf*Rxbq
zGWu4k?`a;#MOU|b{mSN!E_$$Nr_jHB%&zfo&5!t*I$m~~weIrzt5<HHt5&MIn#Cs3
z<GoAL<cFqK>&2Jy&g)rJ=HHsyTOGPCE9;7;O8<WbiC<bPmAcHE)OP#uoVIvSu<}2{
zr}_VnFjxyRFflSSvaoV7b1;L4%o&-O8CV2ag%k}P*@P7g0+ozROdSFe3yX>cj7vn6
zRh)v7k_$vr8o?vs%#4io4Bu}>I!$m@`TR!GDA4J7dFR69l8-ZmjDjZ~7xY{ncT(!a
z21B;}3430%)OzPWw)heJ^7_Wr#!e1_vto@hgWMfX2^k#EW|(vNwy#LGvLe?V>&w9}
zmq}~rP2INb$NJWomqiZScI$5Y^jwRbOH91YQKGeb;siU9UAeEd4O%7`Pu@LMT6-aX
z^i{L-{fGB&+7!KH?%g{aS7bC!-Vb^?oxA9x+upPj?8;?~E4J+J%)NV+@0RDLkV_GF
zJ-2QaJTyuA*#6WVuXbH(Q7hoLns)9H3%`;8FW>9+n|E$&RnHWC6gzQ~kwi%Ox9%%m
zRR=!0h3KoT_^NT?Sj~DhHs{YKv$}LVc7JQ#?B;(Z`=6Up^0{kbH;(>i*pmPD$!mcp
zY>mMd&$im0-F<UOwVNj!L(&cfzF)jScf&ZI2Axp6sr<X~#EQ}qx7H`YQ!}}1%>HP+
z(%58aY`s3{#g2d-x?xYF{ae@>cWpoY&f4;6@GDOh2AwraTsMU1%hXi=)_$DHdmzYp
zM~vVH6H^cV_%@A{8%eh<4|7GoF7FGS<!O`_&cge)Yx|WqLFqFm^IsD_oH5bq*B$4!
z(;E^_aC|O*-kT-<x}<-j_RsuDvlSRW+dVp+EdBBGe}>wZ-~8*#MR!@m?me_VH|o@@
z=(3zC7Am28TdoJpR8p8wbFbvZ$Bp4ZODcZzOgJrOc43{HTQ<AovG;`~8IL13|60Ao
zS?cJ6{|u_GCKv3k<b_<yns8@@_YLPye7ieVnoOBlbz1Y9<6oJho-z{+!-JL-*?#!k
zRw?x|;A`Q>?V^cQ)0R&1nEJThLTb8C(_5cyLFqGl=02Kd-r2Qlg1g?Iu)T@7>1^{p
zth2h|m_L`f+0Ar9s;_}ofqV7E%e_hGU$2|QlO4W4{;^CyH=CPQov7TJ$t%2XggKsU
z7xZ6xxM=B{H2%Nsg`zq}2acvVEq{EEPia^1v&{5=EB+`=^N6uB43jykwm7$Dk@k%P
zbwORbFQv7VPMEh%dB1jy^}EScV*TIj87De998NuI5^-<$@ydm}j;^}3Sw^G4bKOLb
zNw2==^>9s-oig!p!il3EA69Jb-SX<aVr2O7x$&+^3sbhum~j7u+sC_~MK2}KFxh{Z
z@95IMM`!-MJ$GJKd2__&uW>Ang%3~6+O=`V=GvLTPb%fUFWLR3q<-U#@YDy{hNq7g
z2fLj-z3YCw@%-c~Ukz8dXUvVWnsMk`d9(M*JKSZB8(z8Dto`x6%6-4@#r_}Fo|>`8
zE0*856Fz^BTxLpW_{16d43*WaOE<^G9Ay&V-p084xA}%$)9#+oX_u7Uq4R7<U%2B=
zHvh`Q{X4$MN8kK=F;?yC)#ul&s|^0}2mG#mwszU!MA6B|JdKWSE55a9n|QgVU{3m6
zU-?k&WyPC3zMW;i_N~4o+;eYf<yXFYy)UZTZ@>Gay<}hS(z@AO7yUXUwdc#qeVgxP
zZ~Nf9JX2pLYt2WYBYd`77>+&Pd7-v2{X1*P^y}gC!}Hzk55AJ_fBL;n^isUrrF!36
z7i$xF<EldLN4~dmezjNn&AeN6(ccZdRfJR~Zab}c!qn!{ol~h(yA2;zyVp9G+Hkz+
zZ+OhU=cW4MO#9_;Gwy9@f0p(6(z0LYD=*21zPO+A?eeGlxAXGz^scE+{nnDbY3~a4
z>dY{Y?*=PnPP}>EX=(f1qc(hT?c&@1r|T<X;$!Z*@&uiTOp<VXc>Clr+if1|9hw!V
z-tw%plU<x$uz_=yk-!}0_k5+7Vz1ruf4Q5vl4<Rlq^%t>_uf65SZrEdtNXa#C%K7F
z?&C}S#hLcY{v`K##wcl~sWSw0-S+U^`QbbJS;sxPF)^o06(_l!eE)`ZwpibjiSu|L
zhR^c(b}vd$CB0dH$1d*|xBOr3=Z^MVuPS(C=SQ1X&%)fL3%hu1o>clj^m(f+mgH%7
zIDN&PoAVXks+;7ABwhZRxK&cX|F8V1tXHR=o&A>D)8Fy%?Vs0?S9ISm+~DD<rcoAe
z%F(+dQ2C9zakx}Zq4Sl<b*Ji$<<$EA*&X8yo=}i=Jv?Er?<G#9Xa0i0nE^2iXC3lg
zc+U7aS4qW<)hokf9KUY~KArdQagsz(mRM9%$NS`)bwO)m+$Q?G=#zD4`_B-x%6g90
zq}ulj8S>PA`}#lMe&+XW$1k1xP6z*d``PZ>g<7TjO;`R^*PP$GMTzBeO5^Wk%Rk?K
zR{KVB`dN#GpZ_z2*8e}kU=FUE7}z*inb^?kCIdr9VFe>&lYqh^B?qU#Ab}(i=fr~I
zi7LU1!1WRns9yTKSzAm|+~RSp5|dFu<}z0cwOt{{N>_MG%doSni(Y2E%6qnB!HXje
z75UQ=&b@L^pR01}=)nh;7pCc?NA+B6GOD<?D_!#T{z=Y~4s69vsTyl;8~Yly2cGC@
zc5{*WCUxDRa8{&fC&Rn1apqPF5-#?Bc*Srqq1a8Rbo1H9#lm9e*i4(losZvN8!OFI
z-T9xPWW^z;!p+s^X0achYN5JGbAhVI-_`#aW*JPfsCAfCn>X{DOloGL)y)IPiuX^_
zn>g7<d%*+|Yde{XomW<d#;_{?y?jtHVDZP}QieNg+ru9ov~gUKq~YdfVAGxc{avO@
z;5220kRVQF9yYD&AGyl~PjIl5tyJ+8G1{Q;rz7F!!H1CyjdPc6equgPE^5n%mq7<b
zPK3Ge`Y%@7mh^41=-;)67F}8^%(AC-vHg7Iz|%6PBqa>)%dxH5KgW1}-}*QAo`*i3
zILYPB#K26+w{zSpW;~JMZCgB1CE(P7=E(cEPJOaD*q?Hlr%T94#$c&JPxId0@*kh9
zw&xdL{#r#->(#C{`70s2G#@6bE;(lW<CCe}<Y{-C;tmDBIo!Bnc~>c~ber_yu$Z*(
z|0W%lITd<EAS;@?Tg@o)L}}&1)v@X#%NI|rvSe3wc)w=%?f&u?4tXXQr&>luR+=5&
zvy0`xgWBFG%?M@o39t5eDkxqtu&<i!G9|a#Gs^5wW$2XcYtBp;Ob&k~!}sa*R*S!X
zy;n=<9Y3~TTuqu|&HaqSTO=3${>-#?eeSy{61VdopRZ28AM<-xPuJm$H8wG3YjwKr
z{PW<+S8QHnB=fC5q#<)l3fsf9puonHSD)|QeAD*)?ll*g4=1kp+HknCA(Ul;#h;cw
zWv3?vE0zc?+96Z*`JQv$N9DQe3T*bhKD>V+C_omzepxS>`hMZ=?K78T8h_blb$vS9
zHTLO}$F<u0rm55<E6C5;_2K=?usAurebYad*?o4NzU=kf$g<_%ziv6+IQ>HC{I>2}
z=F`@_HF?<QU|X&pYi?dA`&a8s634G!@kejGm0cyXJ?7Qvt@iuZF0<j;*R<x3N!-Of
zTi(B`y<7fXyy%pq*W3k{7Oi05DSf)7DZTe@QNWXYo!`a3cil=paQcPT`9nwFN}u-o
z_x$elx{r0G$|2W|+im%vdL&o+gQ*n91%(IZ(`vsS-@Wedqn}O3I?f!(&9kjxsw=VD
zR!~v+TK9^sVTWA|&%|dkuTF2b-@oGQD$dp2FY{8&z9n1U_*5jCo-DiQpI^n!#~=k;
z?e~A3<kIPF%^F~FaoTgQeM>Ao*u||mS664`F6NYakpKQaLyvEy?g5KO`>VEG+Hn4Z
zU6A9^=o6J!r)SmIzbq}~U6Q(_rncSKllRz^M4bo6IqbP=UkWA%tYTn(lJ}){?~NbR
z`A@b>3B_le?c=%dFFs&(_U-Deydn+%8Jv%w&|Q>qE9S4e(z5i38^?B?vEbUiaZ;qq
z_4derQ=e!sSk%mBaJx7$+)6WYS9F@D!V`-SE5GbA!Fz7*?`5<slczc>v$4<koVoVl
zT(1)gn*CGD6TENP1^?R|_Q_L6>yp~yV)<KPrM_zp@S9&w=}7#~ps`~2)-RuPE$<xs
z7Z~_G`{lD+#XFn-EL!~T`sK4*E~rTq*w50kJM^n^vqo-9eb#@5|3?^X1Q?i@7#UgF
zSXfwCSwKY~BNGF&pb(3qp@XBafs=DUppsESp@4`&BCD}Wkg`faQG=*Sa8l#Mjo?y{
zk%7ye;XgxUu-#4BQ`2Q!WL~YbF{)=}`Ec?}2uq0?lkM>bOpQkloT?B!JEeBvhKLg3
z4DpZGSD8+m*dUU!aeB_X{|p)%3uioC6BI7=D(Cp2bvtywO}m_UuklLHY2MZ%rk-c9
zv4>l8?38tuT`&?l*p%9y8MWz1>Fm&sJO({G&)n;*JSU@`Gg&bojY#Orz1n2SAo=l{
z$^JX;QCWKf3(6(D4H!f6b@dj`fBKeDvhUpKsa&cnA|7TZeiSyFTFv)n&8FKo(l<L!
z)>-!SacndD+z-cCb*<`;DA~?d&HZ34bNYRVdhnu2EGOQaa}U(p7?5~3WP;+RJ?Rf6
zjWd?*mgY`g$Z&k)o1cPgp3^P`cWg+CFU=^prZj1@MrH7gCei*az82pbE?xb@@}c2g
zevrw5!oX(v28%`dpFC%rRjX8DoNaaL(qD;<GEZb2de(*fJ#M~Z@!{oJ_rvd;?_C#`
zzq4(L7DG)6Gw&`5qm@i-Ofy)U?yM`<S;*?lwc@6l?3^i5e8w}%x}6FR$h>zpI&`_&
zFjwKlcWqu4L;g6Hw_n?IF70VaIF!wHd4c3+u6sumg`Ww8Zn+wvJ!9FcY<sEFwz*HN
z5}fOnsqEL1^(kUJ5p-O*h(}YpqvxH4xavm!%mBs2w^~0F^*w(izIDoM-x_+EKcl;m
zKkG5ev1sE-A&-r&CV$RMGB#Q8?0jaxp)-5kwfO{_Iah|aY&?}8aK=O6+bIK{>}@Ib
zQtKtl&V?Q<w`3N69Qe7pS$0lOR+{=e#kIM<hS_>NRX6wL@;DfL%i~LKuwveE@Wx{a
zp=%89PD{MLxlUxYK;n;oNw-f<3p?XiV#shvq?V0``JXVWtE9@&E!qiFzc?^FN=W@K
z*Vms^b3jgJa#Y#0LydZWjyhW@x4*SE3=g{WN<Pziv*gh*ku-HS^QRgzwu_gYO@0}j
zx;<jX!HCeCjtXDSzfQZh<L)JcTlyA`{~0Dp>E65?tvH=`-f`~OxjY-*tPk4Paj?vq
z%jkIV)@1=4{~2c0Ob&dZ=$&b?kzaAa?N8_BCbQ+ndiVZbVA_89yKzviS;I|%tOSL(
zTultGc<vll{%T~q+(Sv|T*HL&8OwItdFbq#a&89O#oE*@4nn(oeQIa;w`^o$cYb@a
zMq_FJ4R0oKjW{Dy&o!?lPMtQ0QQBrMth4RVs%VFEa|70$>Xa-xqCIiv;;nbr^)UWA
ze>k|HXWQ)AI#q`Qmzo+BHg~4+&I)*3?Dl7==L+YWZ~YhTICiyQ38Osgp|Tx6ij5@F
zZEv;Q%)N56BYS_k#v+ZqW{XSH0(&R?Sroi^)%`U$!yX;tJD;;eVYc<f*qPTVX0+`N
z=dx~)JKFhkZEIok!KIq1S0D1$sxtM?IuN9u9(F=2@mr+-lWn)VCncFib1_`nmed%x
zeJb}_>n}xYr-ClU$@&(U)Y$*?F59*CpUl(+m*?_!ZVmd+Fvl!Jl=Dc^)wdPrdSvCE
z<?5JqJFdAl^RDcR^+^tE6J8rIJp9$Wja`B%rmXx%Q__}md}<f#&P<#1#awV^s_9*a
zHxt%ueZ4+aGikv+PN9Q8*FXBZKK+WK;kgqUT!)sPlZt72?VY)Kl4`FW!|#s2`~P}u
z=E*;nyvY8;UB!k2=TuMEo!+uOGp#?_Y|HJgkZrt@?mca9+l!OSc5dS~E4Q>NSS-+H
z{)gxB*H>!G4oqWTo~w6)?bGJ$bq_aZ@+Mr8{x)58x7vldOJ^xFrX3NL=+o`2GCRKI
z)uuz{2@;`egEY&8bM(yi{L%jK*e3CZHgo+-4y8G+O?ob}hmI=g1SvFpYU0?x?}hRE
z4h1&82M%@@D-McCC_TSF;Xi}0U*Xp@b_V5Z5)Z^A&L#fX7Pwr-C#CpcOtM{fTi~wL
zSsVNpy>nIh+wvp2-7Y$P?LHfxM`h=4EtCpx<4KNxawYqi(;Q#FX>94t5^^0G%X)9O
zeM;E8X^qqwt7{AH&iCQ$_26IlCneqEUP5}5#MD=cD*8v<8JQI&SxTQb3JTkA5RB6L
z+h!}YX?y-g`FqT1R~qWKg=KOtxp`gqp)2!+>szmwWc|B;i~qOsivBGQyX3cA<xjtD
zpZ@P&?S$#Ax5I^h$R@Wb{yu8?@`d-USI6vm7#ZarU+CLlmr#(vdSSJEL1KUvb0gEL
z-UG$|EFb@I+P<S@#kcnN;&ylbGkE@Wd1=0Bf^x?BI}$?YGv_<npXHo+g!zSB%Ex~b
zWWF*PYqWGMnAbk{rTvPz><=WI-*<TRR~S`Qv42&naDRF5*`MO$zrKIT+c1I8C5?&U
z-m&!A{}z?}WiWT^2`P<S^5H5o^SLkcudMmd@9<f@e<#cDj>J^C589>dv;HkAkzXQc
z5-G8SGezRL{ffv3vd1j@CFbe9^?%^iUm<wj*}Ujq#XP}ZhdKW<98q=OBl+#wpD*(m
zU+}zLA;WQX(%tF{E=P0@<lF3@r`}SoY=2jBLa8u&+X_kl?Z(el?g*4yKXcce+3#k5
zPPnP>g`l;0ONixsQ}xE`J@SXyr!ea9&U4_Mx9!66JD*PEJYFsRSNe?S{>^bU((kPI
zCrWQ;N#sA}*^n!ysCRr>a@4|x(#)Mx<lac<6?E{dd(<H2<8wFHLFxBy&QMo@-I_9<
zGm1ED);$eMV=j5`w>sXd@eJE$g=cxp^F?DL6oia8W?fs&oDtY!xT<#klS@i_wQgSM
z?wR=BfZ^Sj=wSA>`zw9DPVc>5X~2Jq)#CBWX`!KUhVfzoERGG9?z<it38qfDvt_eD
zMN(|4Y4ge>rwmTKoBJk@qgl;htGG@}LdQ4Wspd*NbJGk=w@r7GNVPeTdQwu}**+)!
zfmOwt6jk0*Ht7>g5z{pi1k@#$Y!*Ad!S>q3)MRIqQ)(waH+~jm$~C)nwDIS%=B<${
z!*4nqcsf<2R84s!OM>hlrNz=Y2h{&FWJvlm@wt~bo)W1|NO9ZH_I`(^L8eY+s!Hkc
z2TT6$-dgy(=LoaJ9hTMM`zD@#wK~0)GxFhgL#H>lEqR2WUQ3Ejyrs*#zRvtm#=1}1
z@4ly3HZL<YFKo7aQj=7%`#s}4<I|7sJeGYStUP_&=Ja!`3V4*aS{7Bz%(d#&5qNCb
zF6$qB_es$_Lz~#|E$1bl{&_l2@ZJyG^keGX`##KkY_osP=0n!^8J-!&ZIzgPiphUL
z#gUKY_k?ZIr+=PS;a>ef=J<@sr{lgaSAQ&g^nQiU$9eJRA|J}WZzz^a^4G1tH)np2
zzj*Bf<71Wemgz0!`xwtucG_%xUsaUqRy<L1tK9F7BkGkFP+QpzpQ(JhzW3#+{5M~p
zPsq-{Wx@K=aN@l1bHZRJ*c_P`^?k3Ua@p0)Lm}$vxBoL}rDyC<W_NgCY;AYpVT4TI
zhlh!8oL(KP)A8lV)^Gmpc57PC+PFhy;Q^IFY#VOOVY5D9GWT=UI?H}T^=W(G`+0v3
zRcA5Gy740Cfx{QI^EW46vo#I*)oow-aU~!7EsGu3!quO)ye-poJMPi=*8Y6sx83Jf
zM^8PZFF94&_Qkp-_s*JzC!CsJc=~6j4fnk-Unj_XaNKj~{moYf=?;>|UQWE5Y{MeE
z@Wa;`f3BXsRlmXUR$$PIAj1PiPyHN^{0!k=SiVACK6Bld@~Esr6V;`y$v0E$PfGlI
z8~pgqak&>|QG7ig&cxPE&eA?qKl!F3_dM2?H)dSnP6-L-`mF(;_8DCB*!Q25sf}Bl
z{87clt6!8!&%I2dq`}}p)u|cNuJ~CUS<BAAW|^|uhS5;&bViLvm&_6tIhOKv;WA^+
zlaDQa?RdMnr@V3gqBBLmr+WTpc%`4ZSxhwKS#sL4-C-TmvfXr^iMec@%D+SQS-I~U
zwV02yfBo7&N4=#yYOUcGVTQodPXwD~%9czExGWku*X4B9^0isV*;rkrcON~&reXJQ
z<8#i3vd0)&ChyqLGEdQmfq%uGhc?PzTLY9c)CElEd}lP7aD<sr-l_6Xh5IYX7mA|I
zjGI?ivB`G|ZfQR7p)uzb|Ao4Od4j*3qc1pVpJCv4V!v_7;pG*l(~Rmb<SqO;{z|QR
zIFXO@91qumger~j?}A(S7PnlwW9s1e^*@7UdP^MxgW^Gp6EpJ^BpYmH1WmSY$+dit
z;Qq~S&%>{5NA9pcII-_gc75^7ghL_Kg#w#;@9${%_3l4I0C)O#j$6e$)?E7cLGZHN
zrd9UEA`iU_UnukTwY|CMU8C}=Bhh4gXuEpD*WLrd@~Qu1HwrCKJeZ`q?Xp9ahRz+&
zY2jO9eqGvX<Joc}i)HfHutyxzFS}jx%(@gI5V`jDYVU1x=S@3Xvi&sEsvZUl##ghO
zrf+|>_o8T7{j)oVl*2cz<a6kZ+B!@0e%(WcO|wm=#j(FyBj&^sF6})@*Z9xBOFnrw
zQnFuupSkV0-t+JFuP(KHJAd__>0I`!`|uLWrH;I?Tg&n{?rav%W<KUur_E+he=f@N
za$4W9rZ;C)uSeD%XAM^jlRJ0tYoM8~UYK-!$F1`_dJawd&mg#`Rkp<McK$7faH$H(
nk1eeKR<Xz_oSh&1=eWa^DeIpEEoKUiZSQ7f_|I_E|Nl(@;^u};

literal 0
HcmV?d00001

-- 
GitLab


From 7496bc13808a32e8843d1a29abc1450b437e5584 Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Fri, 9 Aug 2024 16:41:37 +0200
Subject: [PATCH 12/20] Update TOC

---
 index.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/index.md b/index.md
index faf5cbf..5a7a44f 100644
--- a/index.md
+++ b/index.md
@@ -68,7 +68,8 @@ If you are already somewhat accustomed to Git and GitLab, you may also directly
   * [***Everyday use***]({{'/05-good-practices#everyday' | relative_url }})
     * [Writing informative commit messages]({{'/05-good-practices#messages' | relative_url }})
     * [Keeping a clean history]({{'/05-good-practices#history' | relative_url }})
-    * [If you want to go further]({{'/05-good-practices#further' | relative_url }})
+    * [Changing your last commit]({{'/05-good-practices#amend' | relative_url }})
+    * [Going further with rebasing]({{'/05-good-practices#further' | relative_url }})
     * [Software development practices]({{'/05-good-practices#practices' | relative_url }})
 
 * [**Using Git with VSCode**]({{'/06-vscode' | relative_url }})
-- 
GitLab


From cc370228145405ecf9685714621fb756a8811ec0 Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Mon, 2 Sep 2024 13:22:06 +0200
Subject: [PATCH 13/20] Add REUSE 3.0-compliant licensing information

---
 .reuse/dep5               |  19 +++++
 LICENSES/CC-BY-SA-4.0.txt | 170 ++++++++++++++++++++++++++++++++++++++
 LICENSES/CC0-1.0.txt      | 121 +++++++++++++++++++++++++++
 LICENSES/MIT.txt          |  21 +++++
 screenshot.png            | Bin 61102 -> 0 bytes
 5 files changed, 331 insertions(+)
 create mode 100644 .reuse/dep5
 create mode 100644 LICENSES/CC-BY-SA-4.0.txt
 create mode 100644 LICENSES/CC0-1.0.txt
 create mode 100644 LICENSES/MIT.txt
 delete mode 100644 screenshot.png

diff --git a/.reuse/dep5 b/.reuse/dep5
new file mode 100644
index 0000000..f02327a
--- /dev/null
+++ b/.reuse/dep5
@@ -0,0 +1,19 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: Git/GitLab tutorial
+Upstream-Contact: Mathias Malandain <mathias.malandain@inria.fr>
+Source: https://gitlab.inria.fr/tutorial/git
+
+Files: docs/* assets/img/* *.md android-chrome-*.png apple-touch-icon.png favicon.ico favicon-*.png mstile-*.png 
+Copyright: Mathias Malandain <mathias.malandain@inria.fr>
+License: CC-BY-SA-4.0
+
+Files: .gitignore .gitlab-ci.yml
+Copyright: Mathias Malandain <mathias.malandain@inria.fr>
+License: CC0-1.0
+
+Files: .gitattributes Gemfile *.yml *.html *.css *.js feed.xml *.gemspec safari-pinned-tab.svg browserconfig.xml site.webmanifest 
+Copyright: Dean Attali <daattali@gmail.com>
+License: MIT
+
+
+
diff --git a/LICENSES/CC-BY-SA-4.0.txt b/LICENSES/CC-BY-SA-4.0.txt
new file mode 100644
index 0000000..835a683
--- /dev/null
+++ b/LICENSES/CC-BY-SA-4.0.txt
@@ -0,0 +1,170 @@
+Creative Commons Attribution-ShareAlike 4.0 International
+
+ Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
+
+Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors.
+
+Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described.
+
+Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public.
+
+Creative Commons Attribution-ShareAlike 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
+
+Section 1 – Definitions.
+
+     a.	Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
+
+     b.	Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
+
+     c.	BY-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses, approved by Creative Commons as essentially the equivalent of this Public License.
+
+     d.	Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
+
+     e.	Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
+
+     f.	Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
+
+     g.	License Elements means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike.
+
+     h.	Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
+
+     i.	Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
+
+     j.	Licensor means the individual(s) or entity(ies) granting rights under this Public License.
+
+     k.	Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
+
+     l.	Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
+
+     m.	You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
+
+Section 2 – Scope.
+
+     a.	License grant.
+
+          1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
+
+               A. reproduce and Share the Licensed Material, in whole or in part; and
+
+               B. produce, reproduce, and Share Adapted Material.
+
+          2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
+
+          3. Term. The term of this Public License is specified in Section 6(a).
+
+          4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
+
+          5. Downstream recipients.
+
+               A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
+
+               B. Additional offer from the Licensor – Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply.
+
+               C. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
+
+          6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
+
+     b.	Other rights.
+
+          1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
+
+          2. Patent and trademark rights are not licensed under this Public License.
+
+          3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
+
+Section 3 – License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the following conditions.
+
+     a.	Attribution.
+
+          1. If You Share the Licensed Material (including in modified form), You must:
+
+               A. retain the following if it is supplied by the Licensor with the Licensed Material:
+
+                    i.	identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
+
+                    ii.	a copyright notice;
+
+                    iii. a notice that refers to this Public License;
+
+                    iv.	a notice that refers to the disclaimer of warranties;
+
+                    v.	a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
+
+               B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
+
+               C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
+
+          2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
+
+          3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
+
+     b.	ShareAlike.In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply.
+
+          1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License.
+
+          2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material.
+
+          3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply.
+
+Section 4 – Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
+
+     a.	for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
+
+     b.	if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and
+
+     c.	You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
+For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
+
+Section 5 – Disclaimer of Warranties and Limitation of Liability.
+
+     a.	Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
+
+     b.	To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
+
+     c.	The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
+
+Section 6 – Term and Termination.
+
+     a.	This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
+
+     b.	Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
+
+          1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
+
+          2. upon express reinstatement by the Licensor.
+
+     c.	For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
+
+     d.	For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
+
+     e.	Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
+
+Section 7 – Other Terms and Conditions.
+
+     a.	The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
+
+     b.	Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
+
+Section 8 – Interpretation.
+
+     a.	For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
+
+     b.	To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
+
+     c.	No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
+
+     d.	Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
+
+Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
+
+Creative Commons may be contacted at creativecommons.org.
diff --git a/LICENSES/CC0-1.0.txt b/LICENSES/CC0-1.0.txt
new file mode 100644
index 0000000..0e259d4
--- /dev/null
+++ b/LICENSES/CC0-1.0.txt
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+    HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+  i. the right to reproduce, adapt, distribute, perform, display,
+     communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+     likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+     subject to the limitations in paragraph 4(a), below;
+  v. rights protecting the extraction, dissemination, use and reuse of data
+     in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+     European Parliament and of the Council of 11 March 1996 on the legal
+     protection of databases, and under any national implementation
+     thereof, including any amended or successor version of such
+     directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+     world based on applicable law or treaty, and any national
+     implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+    surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+    warranties of any kind concerning the Work, express, implied,
+    statutory or otherwise, including without limitation warranties of
+    title, merchantability, fitness for a particular purpose, non
+    infringement, or the absence of latent or other defects, accuracy, or
+    the present or absence of errors, whether or not discoverable, all to
+    the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+    that may apply to the Work or any use thereof, including without
+    limitation any person's Copyright and Related Rights in the Work.
+    Further, Affirmer disclaims responsibility for obtaining any necessary
+    consents, permissions or other rights required for any use of the
+    Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+    party to this document and has no duty or obligation with respect to
+    this CC0 or use of the Work.
diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt
new file mode 100644
index 0000000..7416749
--- /dev/null
+++ b/LICENSES/MIT.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Dean Attali
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/screenshot.png b/screenshot.png
deleted file mode 100644
index 0c48110cb69b910d25d4e3198f39285c29320b56..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 61102
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

-- 
GitLab


From 7db0588f6f0bde01f6cf064f59340228c29b047f Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Mon, 2 Sep 2024 13:32:35 +0200
Subject: [PATCH 14/20] Create a new page for forks and workflows

---
 03-linear-git-project.md                      |   2 +-
 04-branches-issues.md                         |   2 +-
 05-good-practices.md                          |  36 +---
 06-forks.md                                   | 171 ++++++++++++++++++
 06-vscode.md => 07-vscode.md                  | 114 ++++++------
 07-internals.md => 08-internals.md            |   8 +-
 08-advanced.md => 09-advanced.md              | 101 +----------
 _config.yml                                   |   7 +-
 _config_dev.yml                               |   7 +-
 .../forks-and-pr => 06-forks}/fork-01.jpg     | Bin
 .../forks-and-pr => 06-forks}/fork-02.jpg     | Bin
 .../forks-and-pr => 06-forks}/fork-03.jpg     | Bin
 .../forks-and-pr => 06-forks}/fork-04.jpg     | Bin
 .../forks-and-pr => 06-forks}/fork-05.jpg     | Bin
 .../forks-and-pr => 06-forks}/fork-06.jpg     | Bin
 .../forks-and-pr => 06-forks}/fork-07.jpg     | Bin
 .../forks-and-pr => 06-forks}/fork-08.jpg     | Bin
 .../forks-and-pr => 06-forks}/fork-update.jpg | Bin
 .../A-open-and-clone/vscode-01.jpg            | Bin
 .../A-open-and-clone/vscode-02.jpg            | Bin
 .../A-open-and-clone/vscode-02bis.jpg         | Bin
 .../A-open-and-clone/vscode-03.jpg            | Bin
 .../A-open-and-clone/vscode-04.jpg            | Bin
 .../A-open-and-clone/vscode-05.jpg            | Bin
 .../A-open-and-clone/vscode-06.jpg            | Bin
 .../A-open-and-clone/vscode-07.jpg            | Bin
 .../A-open-and-clone/vscode-08.jpg            | Bin
 .../A-open-and-clone/vscode-09.jpg            | Bin
 .../B-stage-commit/vscode-stage-01.jpg        | Bin
 .../B-stage-commit/vscode-stage-02.jpg        | Bin
 .../B-stage-commit/vscode-stage-03.jpg        | Bin
 .../B-stage-commit/vscode-stage-04.jpg        | Bin
 .../B-stage-commit/vscode-stage-05.jpg        | Bin
 .../B-stage-commit/vscode-stage-06.jpg        | Bin
 .../B-stage-commit/vscode-stage-07.jpg        | Bin
 .../B-stage-commit/vscode-stage-08.jpg        | Bin
 .../B-stage-commit/vscode-stage-09.jpg        | Bin
 .../B-stage-commit/vscode-stage-10.jpg        | Bin
 .../C-web-ide/vscode-sync-01.jpg              | Bin
 .../C-web-ide/vscode-sync-02.jpg              | Bin
 .../C-web-ide/vscode-sync-03.jpg              | Bin
 .../C-web-ide/vscode-sync-04.jpg              | Bin
 .../D-fetch-pull/vscode-sync-05.jpg           | Bin
 .../D-fetch-pull/vscode-sync-06.jpg           | Bin
 .../D-fetch-pull/vscode-sync-07.jpg           | Bin
 .../D-fetch-pull/vscode-sync-08.jpg           | Bin
 .../E-conflicts/oh-no.jpg                     | Bin
 .../E-conflicts/vscode-conflict-01.jpg        | Bin
 .../E-conflicts/vscode-conflict-02.jpg        | Bin
 .../E-conflicts/vscode-conflict-03.jpg        | Bin
 .../E-conflicts/vscode-conflict-04.jpg        | Bin
 .../E-conflicts/vscode-conflict-05.jpg        | Bin
 .../E-conflicts/vscode-conflict-06.jpg        | Bin
 .../E-conflicts/vscode-conflict-07.jpg        | Bin
 .../E-conflicts/vscode-conflict-08.jpg        | Bin
 .../E-conflicts/vscode-conflict-09.jpg        | Bin
 .../E-conflicts/vscode-conflict-10.jpg        | Bin
 .../E-conflicts/vscode-conflict-11.jpg        | Bin
 .../E-conflicts/vscode-conflict-12.jpg        | Bin
 .../E-conflicts/vscode-conflict-13.jpg        | Bin
 .../F-branch/vscode-branch-01.jpg             | Bin
 .../F-branch/vscode-branch-02.jpg             | Bin
 .../F-branch/vscode-branch-03.jpg             | Bin
 .../F-branch/vscode-branch-04.jpg             | Bin
 .../F-branch/vscode-branch-05.jpg             | Bin
 .../F-branch/vscode-branch-06.jpg             | Bin
 .../F-branch/vscode-branch-07.jpg             | Bin
 .../F-branch/vscode-branch-08.jpg             | Bin
 .../F-branch/vscode-branch-09.jpg             | Bin
 .../F-branch/vscode-branch-10.jpg             | Bin
 .../F-branch/vscode-branch-11.jpg             | Bin
 .../F-branch/vscode-branch-12.jpg             | Bin
 .../F-branch/vscode-branch-13.jpg             | Bin
 .../F-branch/vscode-branch-14.jpg             | Bin
 .../git-internals-1.jpg                       | Bin
 .../git-internals-2.jpg                       | Bin
 .../git-internals-3.jpg                       | Bin
 index.md                                      |  76 ++++----
 78 files changed, 291 insertions(+), 233 deletions(-)
 create mode 100644 06-forks.md
 rename 06-vscode.md => 07-vscode.md (82%)
 rename 07-internals.md => 08-internals.md (98%)
 rename 08-advanced.md => 09-advanced.md (84%)
 rename assets/img/{08-advanced/forks-and-pr => 06-forks}/fork-01.jpg (100%)
 rename assets/img/{08-advanced/forks-and-pr => 06-forks}/fork-02.jpg (100%)
 rename assets/img/{08-advanced/forks-and-pr => 06-forks}/fork-03.jpg (100%)
 rename assets/img/{08-advanced/forks-and-pr => 06-forks}/fork-04.jpg (100%)
 rename assets/img/{08-advanced/forks-and-pr => 06-forks}/fork-05.jpg (100%)
 rename assets/img/{08-advanced/forks-and-pr => 06-forks}/fork-06.jpg (100%)
 rename assets/img/{08-advanced/forks-and-pr => 06-forks}/fork-07.jpg (100%)
 rename assets/img/{08-advanced/forks-and-pr => 06-forks}/fork-08.jpg (100%)
 rename assets/img/{08-advanced/forks-and-pr => 06-forks}/fork-update.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/A-open-and-clone/vscode-01.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/A-open-and-clone/vscode-02.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/A-open-and-clone/vscode-02bis.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/A-open-and-clone/vscode-03.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/A-open-and-clone/vscode-04.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/A-open-and-clone/vscode-05.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/A-open-and-clone/vscode-06.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/A-open-and-clone/vscode-07.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/A-open-and-clone/vscode-08.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/A-open-and-clone/vscode-09.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/B-stage-commit/vscode-stage-01.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/B-stage-commit/vscode-stage-02.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/B-stage-commit/vscode-stage-03.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/B-stage-commit/vscode-stage-04.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/B-stage-commit/vscode-stage-05.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/B-stage-commit/vscode-stage-06.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/B-stage-commit/vscode-stage-07.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/B-stage-commit/vscode-stage-08.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/B-stage-commit/vscode-stage-09.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/B-stage-commit/vscode-stage-10.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/C-web-ide/vscode-sync-01.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/C-web-ide/vscode-sync-02.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/C-web-ide/vscode-sync-03.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/C-web-ide/vscode-sync-04.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/D-fetch-pull/vscode-sync-05.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/D-fetch-pull/vscode-sync-06.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/D-fetch-pull/vscode-sync-07.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/D-fetch-pull/vscode-sync-08.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/oh-no.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-01.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-02.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-03.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-04.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-05.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-06.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-07.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-08.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-09.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-10.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-11.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-12.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/E-conflicts/vscode-conflict-13.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-01.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-02.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-03.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-04.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-05.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-06.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-07.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-08.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-09.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-10.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-11.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-12.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-13.jpg (100%)
 rename assets/img/{06-vscode => 07-vscode}/F-branch/vscode-branch-14.jpg (100%)
 rename assets/img/{07-internals => 08-internals}/git-internals-1.jpg (100%)
 rename assets/img/{07-internals => 08-internals}/git-internals-2.jpg (100%)
 rename assets/img/{07-internals => 08-internals}/git-internals-3.jpg (100%)

diff --git a/03-linear-git-project.md b/03-linear-git-project.md
index 82e2b59..fdf2c86 100644
--- a/03-linear-git-project.md
+++ b/03-linear-git-project.md
@@ -43,7 +43,7 @@ Type your SSH key passphrase when asked, then wait for the cloning operation to
 The `.git` folder is hidden by default (if you do not see it in your working copy, do not worry, you still have it). This is where the magic actually happens, but we are not delving into this before getting the grip of how to use Git. For the moment, you may assume (for convenience) that *there is no reason for you to edit anything in the `.git` folder*. For all intents and purposes, the whole project is a `README.md` file and nothing more.
 
 {: .box-note}
-This is kind of a white lie: there are a few very good, but a bit more advanced, reasons to change the contents of this folder. You may learn more about this in [this additional content]({{'/08-advanced#hooks-excludes' | relative_url }}).
+This is kind of a white lie: there are a few very good, but a bit more advanced, reasons to change the contents of this folder. You may learn more about this in [this additional content]({{'/09-advanced#hooks-excludes' | relative_url }}).
 
 From now on, Git will remember where my folder came from. As long as I am working in the folder (or a subfolder) of the working copy, Git knows to which repository it is linked. I can now, whenever I want, fetch the changes that were submitted by my collaborators, change the code, and decide whether I want to push all or some of my changes back to the repo (thus adding my own brick to the repo's history). Okay, simple enough.
 
diff --git a/04-branches-issues.md b/04-branches-issues.md
index d39eef5..7a71b8a 100644
--- a/04-branches-issues.md
+++ b/04-branches-issues.md
@@ -751,7 +751,7 @@ Of course, **use this trick with caution** (but note that it will never do anyth
 
 I was recently told by a friend of mine that, in the company he is working for, MRs for branches basically do not exist; instead, they rely on MRs for *forks*. It so happens that there is this thing called forks, which essentially amounts to creating an exact copy of an existing project (history, branches and all) while keeping information about where it comes from. This makes it possible to exchange data both ways: the fork can be updated to follow the changes in the source project, and changes made in the fork can be pulled in the original project if they work, make sense, bring interesting features, etc.
 
-This section is already pretty long as it is, and using issues and MRs inside a single project already leads to very efficient collaboration, but existing projects (open-source or not) made forks their *de facto* standard. You can check [this part of the "Advanced" section]({{'/08-advanced#fork' | relative_url }}) to learn more about this other way of managing a collaborative project.
+This section is already pretty long as it is, and using issues and MRs inside a single project already leads to very efficient collaboration, but existing projects (open-source or not) made forks their *de facto* standard. You can check [this part of the "Advanced" section]({{'/09-advanced#fork' | relative_url }}) to learn more about this other way of managing a collaborative project.
 
 ----
 
diff --git a/05-good-practices.md b/05-good-practices.md
index 45fb8f0..42d140e 100644
--- a/05-good-practices.md
+++ b/05-good-practices.md
@@ -450,11 +450,7 @@ At this stage, we may just switch back to the main branch:
 {: .box-success}
 With Git, **commits can be tagged**. There are two types of tags: lightweight tags, created with `git tag <tag_name>`, and annotated tags, created with `git tag -a <tag_name> -m "<tag_message>"`.<br/>Tags are created locally; to push them to the repo, use `git push origin <tag_name>`.<br/>You can delete a tag from your working copy with `git tag -d <tag_name>`; to delete it from the repo, you can either use `git push origin --delete <tag_name>`, or go to Repository → Tags on the GitLab page for your project.
 
-## Advanced: CI/CD pipelines and Git workflows {#cicd}
-
-Okay, time to gain even more trust in our process.
-
-### Configuring a CI/CD pipeline
+## CI/CD pipelines {#cicd}
 
 If you followed every step so far, you now have, among others:
 
@@ -489,31 +485,7 @@ Now, considering that you have test suites that you can already run on your mach
 
 Your best sources of information (at least, for starters) include the [official CI/CD pipeline page](https://docs.gitlab.com/ee/ci/pipelines/) on the GitLab docs, the [keyword reference page](https://docs.gitlab.com/ee/ci/yaml/index.html) on the same docs, and the whole [CI Inria portal](https://ci.inria.fr/).
 
-A few simple examples of job declarations for the `.gitlab-ci.yml` file are given [here]({{'/08-advanced#gitlab-ci' | relative_url }}), but you should *absolutely* have a look at the more numerous (and better!) examples available in the [GitLab CI/CD gallery](https://gitlab.inria.fr/gitlabci_gallery). Made for you, with love.
-
-### Git workflows
-
-There exist several different workflows for Git projects, and which one you actually implement depends on the needs you have. Two main workflows emerged, each with its benefits and drawbacks. Here is a nice summary:
-
-<div class="box-success" markdown="1">
-* The **trunk-based workflow** consists in merging frequent, small updates to the `main` branch (the "trunk" of the repo). This is probably the workflow you will be tempted to use when you start using Git, as it is a very simple and intuitive one.
-    * A trunk-based workflow is particularly efficient for [DevOps](https://www.atlassian.com/devops/what-is-devops), a software engineering practice in which continuous feedback is used for improving the codebase very often (pretty much on a daily basis). It is also a good fit for prototype projects with a small dedicated team of developers.
-    * However, it can hinder long-term research and development efforts; its agile characteristics do not always fit the needs of researchware.
-* The **Gitflow** is somewhat closer to the workflow used in this tutorial, as it can have several (potentially long-lived) feature branches, each of which is typically associated to one or a few issues via the corresponding MRs. However, the main originality of Gitflow is that it typically features at least two "main" branches: a `develop` branch that is the equivalent of the `main` branch we used throughout this tutorial, and a `release` branch on which only release-ready versions of the codebase will be pushed (actually merged from `develop`).
-    * Gitflow provides a clear development workflow for incremental projects with "official" releases, so that collaborative projects with industrial stakes can benefit from such a workflow.
-    * However, merging a feature branch in `develop` requires more effort and caution than in a trunk-based workflow, as there are more commits and larger changes in feature branches (with the risk of having to handle more conflicts along the way). A `hotfix` branch can also be added, which increases complexity and requires even more careful planning.
-</div>
-
-In practice, as a project gets larger, you may very well "reinvent the wheel" one step at a time, by reorganizing your workflow once in a while, so as to address the development management problems when they are encountered, until you reach a workflow that actually looks incredibly similar to Gitflow.
-
-On the other hand, you may converge to a workflow that takes advantage of features from different "conventional" workflows (this is typically the case of a project I am working on, and our workflow became more or less stable after more than three years).
-
-{: .box-note}
-If, after reading tens of different articles on this topic, you reach the conclusion that *one* specific workflow suits your needs for a given project, then you should not only implement this workflow as early as possible, but also **describe this workflow in simple terms in a Markdown file (`CONTRIBUTING.md` is a pretty fitting name) at the root of your project**.
-
-Otherwise, everything is fine as long as:
-* collaborators agree on, and are fine with, the workflow they use;
-* you still keep in mind that a workflow can be adapted, one step at a time, and *should* be adapted whenever efficiency problems arise in your project.
+A few simple examples of job declarations for the `.gitlab-ci.yml` file are given [here]({{'/09-advanced#gitlab-ci' | relative_url }}), but you should *absolutely* have a look at the more numerous (and better!) examples available in the [GitLab CI/CD gallery](https://gitlab.inria.fr/gitlabci_gallery). Made for you, with love.
 
 # Everyday use {#everyday}
 
@@ -593,7 +565,7 @@ So, yeah, ask your doctor if rebasing is good for you! Which brings us to some i
 {: .box-warning}
 **Do not rebase something that was already pushed!** Changing the public history of a project is not only widely considered rude, but also a source of conflicts (between what a branch looks like and what your collaborators' computers think it looks like) that will only result in an even more confusing project history once the immediate problems are solved.<br/>(Advanced: The only exception to this rule is when a project was set up so that merging branches is only allowed in *fast-forward* mode. In this case, a rebase can be performed **just before merging**, and deleting the branch as soon as it is merged is then a good practice.)
 
-You can find more about rebasing (among others) in [the "Advanced" appendix]({{'/08-advanced#juggling' | relative_url }}).
+You can find more about rebasing (among others) in [the "Advanced" appendix]({{'/09-advanced#juggling' | relative_url }}).
 
 ## Software development practices {#practices}
 
@@ -614,6 +586,6 @@ Please allow me to just write a few ones that I think everyone should know and k
 
 ----
 
-We have come quite far in all things related to software development, Git and GitLab. I hope you did not try and read it in a single sitting (if you did, you should really go take a nap). The next part will be way simpler, now that we went through all the tough stuff: it is about [**using Git directly from VSCode**]({{'/06-vscode' | relative_url }}).
+Time to go a bit further on the topic of collaboration. [**The next chapter is about collaborative workflows using Git.**]({{'/06-forks' | relative_url }})
 
 You may also go back to the [detailed table of contents]({{'/index#toc' | relative_url }}).
\ No newline at end of file
diff --git a/06-forks.md b/06-forks.md
new file mode 100644
index 0000000..2f57616
--- /dev/null
+++ b/06-forks.md
@@ -0,0 +1,171 @@
+---
+title: "Forks and workflows"
+subtitle: "Where we have options."
+tags: 
+---
+
+There is a sort of assumption that was taken as granted so far, namely: all collaborators to a project will work on branches that should be merged to the `main` branch at some point. End of story.
+
+This workflow is pretty simple, and will probably be the one you will "instinctively" want to use in your first projects, but ~~people who are way more clever than me~~ the community has come with more refined workflows that leverage even further the capabilities of Git and Git-based tools.
+
+There is even a way of collaborating on a project in which none of the developers will be granted access to the original project!
+
+"Wait," some of you just said, "what the heck?" (Yes, I heard that.) Time to talk about forks.
+
+# Forks and merge requests {#fork}
+
+I was recently told by a friend of mine that, in the company he is working for, MRs for branches basically do not exist; instead, they rely on MRs for *forks*. For experienced users, there are indeed a lot of advantages to this workflow. To explain this in further detail, we first have to know what a fork is.
+
+## Forking {#forking}
+
+{: .box-success}
+A ***fork*** is a fresh repository that contains an exact copy of an already existing repository. This new repository is now yours, in the sense that you have all permissions on it, but GitLab still knows where it comes from.
+
+In other words, forking a repo is a way of getting your own copy of an existing project. You are then free to do whatever you want with it... in a way.
+
+### Legal disclaimer
+
+We should be a bit more precise about this stuff. Just a tiny bit.
+
+{: .box-warning}
+You are free to modify and distribute a forked project ***within the limits of the license of the original project.***
+
+Be very cautious with this! Open source software, in particular, are subject to pretty permissive licenses, either in the "do-whatever-you-want" category (MIT, BSD...) or in the "you-have-to-keep-the-same-licensing" category (aka *copyleft*: GPL, MPL, and others), but a public codebase is **not** open source by default!
+
+Ask your doctor is forking is right for you.
+
+### Forking a GitLab project
+
+This one is tricky.
+
+That is, GitLab-tricky: there is no big blue button on the page on the project you want to fork.
+
+Instead, the button is white:
+
+![](../assets/img/06-forks/fork-01.jpg){: .mx-auto.d-block :}
+
+Yup. Just click on the "Forks" button, and you will have the option to fork to a project, with the name you want to give it, and the place you want to put it in (either your namespace, which is still a bad option in most cases, or a group/subgroup):
+
+![](../assets/img/06-forks/fork-02.jpg){: .mx-auto.d-block :}
+
+This absolutely looks like your standard project creation page, with a bit less options (it would make no sense to give you an "Initialize project with a README" option, after all).
+
+Click.
+
+![](../assets/img/06-forks/fork-03.jpg){: .mx-auto.d-block :}
+
+A few seconds later, you have a project. It is yours (kind of). You can work on it.
+
+## Merge request {#fork-mr}
+
+Remember when I told you that a MR is about bringing the contents of a branch into another branch? Well, here is a nice little detail for you: *these branches do not need to be in the same project*. You can suggest merging contents of a fork into the original project.
+
+This is how it happens for me. I made some changes on my fork, and I really think these changes would be beneficial for other people who use the original project, without breaking any already existing feature.
+
+Well, guess who will help you?
+
+![](../assets/img/06-forks/fork-04.jpg){: .mx-auto.d-block :}
+
+This appeared on the page of the fork (i.e., my "variant" of the project) as soon as I committed some stuff on it. I can totally open an MR in the source project:
+
+![](../assets/img/06-forks/fork-05.jpg){: .mx-auto.d-block :}
+
+I can also, at any point, open an MR from the sidebar, on the webpage of my fork: branches of the original project will appear among the possible target branches.
+
+![](../assets/img/06-forks/fork-06.jpg){: .mx-auto.d-block :}
+
+The form you have to fill to actually create the MR is basically the same, except for this new gizmo at the bottom of the page:
+
+![](../assets/img/06-forks/fork-07.jpg){: .mx-auto.d-block :}
+
+...that's two gizmos. Well. So:
+
+1. If the original project is not a private project, that basically means that you are offering some code to a "public" codebase. It can make sense for the community that developed this codebase in the first place to have their word, and what better way of letting them contribute than directly allowing them to commit?
+2. This "Contribution guidelines" stuff does not come from nowhere. Well... Turns out there is a reason why GitLab suggests you (and so did I) to create a file named `CONTRIBUTING.md` at the root of any project to which other people might contribute. This link is a pointer to the `CONTRIBUTING.md` file of the project you forked. The closer you follow these guidelines, the higher the chances of your MR being accepted.
+
+{: .box-info}
+On the other hand, if you want to work from a given snapshot of a project without contributing to it, you may even remove the "fork relationship", by delving into Settings → Advanced -- at your own risk, though, because you will also be missing out on new features, bug fixes, etc. (Once again, you should still make sure that you are complying with the licence(s) of the original project.)
+
+## Closing remarks {#fork-closing}
+
+**As a forker**, remember that the project you forked will probably evolve while you are working on your own personal copy. In other words, you will sometimes fall behind the original project, which will make things pretty complicated if you want to submit an MR at some point. (Also, maybe some of the commits that were pushed on the original project solve bugs you would have encountered at some point... so, it is also in *your* best interest to stay up to date.)
+
+GitLab will tell you when you are behind the forked project:
+
+![](../assets/img/06-forks/fork-update.jpg){: .mx-auto.d-block :}
+
+...but you have to deal with the consequences (even when you have less commits to pull than here). As a result, you will have to think about your workflow when you work on a fork. Or you may just [read GitLab's page about forkflows](https://docs.gitlab.com/ee/user/project/repository/forking_workflow.html).
+
+**As a forked** (...forkee?), remember that the forks of your project depend on the project itself. For instance, this is the reminder I will get if I want to delete a project that was forked:
+
+![](../assets/img/06-forks/fork-08.jpg){: .mx-auto.d-block :}
+
+This is a nice summary of why your project maybe should not be deleted: the higher the numbers, the more you should think about it. Plus, it could be considered rude.
+
+Regarding forks, there is a simple rule to be remembered: ***If you delete a private project, its forks will be deleted too.*** If you delete a *public* project, one of its forks will be automatically picked as the new "original project" from which all other forks are forked off.
+
+# Git workflows
+
+It is now time to get back to our first concern: which workflow should we use for a project? Indeed, there exist several different workflows for Git projects, and which one you actually implement depends on the needs you have. Let us have a look at the three "main" workflows that emerged, each with its benefits and drawbacks:
+
+## Trunk-based workflow
+
+{: .box-success}
+The **trunk-based workflow** consists in merging frequent, small updates to the `main` branch (the "trunk" of the repo). This is probably the workflow you will be tempted to use when you start using Git, as it is a very simple and intuitive one.
+
+Up to this point, we have been using this workflow without giving it a name. The fact that it is centralized means that, with non-experienced users (very much including people who were accustomed to heavily centralized tools like SVN), it will be very easy to implement.
+
+A trunk-based workflow can be very efficient for [DevOps](https://www.atlassian.com/devops/what-is-devops), a software engineering practice in which continuous feedback is used for improving the codebase very often (pretty much on a daily basis). It is also a good fit for prototype projects with a small dedicated team of developers. However, it can hinder long-term research and development efforts; its agile characteristics do not always fit the needs of researchware. It also does not scale well: as your development team grows larger, the constant merging and conflict resolution will become more of a hindrance.
+
+A small change to this workflow consists in updating a `develop` branch on a regular basis, while the `main` branch will only get updated once in a while, typically when everything is working ("no test should ever fail on the `main` branch"). This approach, sometimes referred to as **feature branching**, is arguably "cleaner" but suffers from the same drawbacks. However, if you push it a bit further, you can get to...
+
+## Gitflow
+
+{: .box-success}
+The **Gitflow** is a strict branching model centered on releases. It typically relies on two "main" branches, namely a `develop` branch and a `main` branch that only receives commits from `develop`, and adds release branches on which only release-ready versions of the codebase will be pushed, and several feature and hotfix branches with clearly-defined roles.
+
+Let us delve a bit further into this branching model:
+
+* The `develop` branch is the one on which new features will be implemented, to be merged at some point into the `main` branch. As was the case with feature branching, this is a way to ensure that the `HEAD` of the `main` branch always points to production-ready code.
+* Feature branches can only be branched off from `develop` and merge back to it. This is where features are developed, issues are handled, and so on. Nothing too fancy for the moment.
+* Release branches can only be branched off from `develop`, and they have to be merged back into both `develop` and `master`.
+    * The basic idea is this: when the code on `develop` is "nearly ready" for a production release, let's say version `0.1` for the sake of illustration, create a branch called `release-0.1`. The code on this branch will only get updates like minor bug fixes and metadata updates. (Meanwhile, the `develop` branch is living its best life, probably incorporating some new features that will be part of version `0.2`!)
+    * When the release is ready, merge it into the `main` branch, where it will be given a tag (`v0.1` for example). Also merge it back to the `develop` branch, so that pre-release bugfixes get into the current working version!
+* Hotfix branches can only be merged off from `main`, and must be merged back into both `main` and `develop`.
+    * Imagine that some bug shows its ugly head just after version 0.1 of your software is released. You can create a branch `hotfix-0.1` (or any other name starting with `hotfix-` indeed) from `main` and get one or several dedicated members of your team working on this branch to work on a fix.
+    * Once the problem is fixed, a new minor version of the software (that would be `0.1.1` in our case) is ready to be released: merge it back into `main` with a nice `v0.1.1` tag, and merge it into `develop` so that the fix is now part of the "main" codebase.
+    * Of course, hotfix branches can be created for any previous release if needed.
+
+There is no "magic trick" in Gitflow, no new commands to master, no new tools to use: once again, this is just a branching model... but it is a very good branching model for incremental projects with official releases. Conceived in 2010 by software engineer Vincent Driessen, who explained it in detail in [this immensely popular blog post](https://nvie.com/posts/a-successful-git-branching-model/), it can benefit, among others, large collaborative projects with industrial stakes.
+
+However, merging a feature branch in `develop` requires more effort and caution than in a trunk-based workflow, as there are more commits and larger changes in feature branches (with the risk of having to handle more conflicts along the way). The `hotfix-*` branches also increase complexity and require even more careful planning. If your software is not explicitly versioned, with several versions (typically, the last X versions) that need to get maintained/patched if needed, Gitflow is likely too heavy for your needs.
+
+## Forkflow
+
+{: .box-success}
+The **forkflow**, more commonly named **forking workflow**, consists in letting any developer or developing team fork a repository and open MRs from the fork to the original project.
+
+Typically, completed feature branches from a fork will be the object of MRs into the original project. It is then up to the maintainers of this project to integrate these new features and deal with releases. As such, the forkflow tends to rely on a branching model similar to Gitflow, except that features are developed in forks instead of new branches in the same project.
+
+The forkflow is an ideal workflow for open-source projects, where possible contributors are basically "trusted third parties" that should be able to propose new features or fixes without being given write access to the project. However, advantages are not limited to the world of FOSS.
+
+In an active project with a lot of contributors, the history of the project will soon get overloaded with development branches. Even when enforcing naming conventions (none of which is a perfect solution) for branches, this can quickly become a mess. This will not happen with forks, so that the important branches of the original project will have a clearer history. As for the CI, it comes packaged with the rest of the project when you fork it! Just set a runner on your fork and you're good to go.
+
+# Personal takes
+
+In practice, as a project gets larger, I believe that you may very well "reinvent the wheel" one step at a time, by reorganizing your workflow once in a while, so as to address the development management problems when they are encountered... until you reach a workflow that actually looks incredibly similar to Gitflow.
+
+Or you may converge to a workflow that takes advantage of features from different "conventional" workflows (this is typically the case of a project I am working on, and our workflow became more or less stable after more than three years).
+
+{: .box-note}
+On the other hand, if, after reading tens of different articles on this topic and/or because of your own experience, you reach the conclusion that *one* specific workflow suits your needs for a given project, then you should not only implement this workflow as early as possible, but also **describe this workflow in simple terms in the `CONTRIBUTING.md` file at the root of your project**.
+
+To me, for most non-industrial projects, everything is fine as long as:
+* collaborators agree on, and are fine with, the workflow they use;
+* you still keep in mind that a workflow can be adapted, one step at a time, and *should* be adapted whenever efficiency problems arise.
+
+----
+
+We have come quite far in all things related to software development, Git and GitLab. I hope you did not try and read it in a single sitting (if you did, you should really go take a nap). The next part will be way simpler, now that we went through all the tough stuff: it is about [**using Git directly from VSCode**]({{'/07-vscode' | relative_url }}).
+
+You may also go back to the [detailed table of contents]({{'/index#toc' | relative_url }}).
\ No newline at end of file
diff --git a/06-vscode.md b/07-vscode.md
similarity index 82%
rename from 06-vscode.md
rename to 07-vscode.md
index 2d747aa..dbe2ec3 100644
--- a/06-vscode.md
+++ b/07-vscode.md
@@ -14,11 +14,11 @@ Yup, it's VSCode time again. I talked about it very briefly [a few centuries ago
 
 We will also be talking about GitLab's very own web IDE, because yes, if you need to, you can directly work on your project via a nice web interface! Just one button to click:
 
-![](../assets/img/06-vscode/A-open-and-clone/vscode-01.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/A-open-and-clone/vscode-01.jpg){: .mx-auto.d-block :}
 
 (There are similar buttons on the pages you reach when exploring the project.) And this is what you get:
 
-![](../assets/img/06-vscode/A-open-and-clone/vscode-02.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/A-open-and-clone/vscode-02.jpg){: .mx-auto.d-block :}
 
 ...oh, well. It's VSCode. **It's always VSCode.** Let's do this.
 
@@ -28,38 +28,38 @@ Everything that we already learned about [cloning a repo]({{'/03-linear-git-proj
 
 Or you may get familiar with the Git menu in VSCode, the third one here:
 
-![](../assets/img/06-vscode/A-open-and-clone/vscode-02bis.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/A-open-and-clone/vscode-02bis.jpg){: .mx-auto.d-block :}
 
 If you just click on it right now, unless you are already in a folder containing a Git project, you should get this:
 
-![](../assets/img/06-vscode/A-open-and-clone/vscode-03.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/A-open-and-clone/vscode-03.jpg){: .mx-auto.d-block :}
 
 To clone a Git repo, you have to get and copy its URL from its GitLab page, still in the same Clone menu as before:
 
-![](../assets/img/06-vscode/A-open-and-clone/vscode-04.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/A-open-and-clone/vscode-04.jpg){: .mx-auto.d-block :}
 > Once again, you should get the SSH link, for future convenience.
 
 Back to VSCode, when you click on the "Clone Repository" button, there is some movement in the top part of the window, near the search bar. This is where VSCode wants you to paste your URL.
 
-![](../assets/img/06-vscode/A-open-and-clone/vscode-05.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/A-open-and-clone/vscode-05.jpg){: .mx-auto.d-block :}
 
 Press Enter, and VSCode will ask you where to clone the project.
 
-![](../assets/img/06-vscode/A-open-and-clone/vscode-06.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/A-open-and-clone/vscode-06.jpg){: .mx-auto.d-block :}
 
 Once again, you should **not** create a folder with the name of the project, as the project will be a fresh folder anyways. If I select a folder `cornbread` in which the project of the same name should be cloned, I will have to navigate to `cornbread/cornbread` to reach the project files.
 
 Last step, of course:
 
-![](../assets/img/06-vscode/A-open-and-clone/vscode-07.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/A-open-and-clone/vscode-07.jpg){: .mx-auto.d-block :}
 
 Once the project is cloned, VSCode asks you if you want to open it right away. Why not?
 
-![](../assets/img/06-vscode/A-open-and-clone/vscode-08.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/A-open-and-clone/vscode-08.jpg){: .mx-auto.d-block :}
 
 And here it is:
 
-![](../assets/img/06-vscode/A-open-and-clone/vscode-09.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/A-open-and-clone/vscode-09.jpg){: .mx-auto.d-block :}
 
 Not a lot of content right now (we only worked on the other one before). Time to change this!
 
@@ -69,11 +69,11 @@ For now, I am going to make changes directly on the `main` branch. You can still
 
 So, changes in the `README.md` file (the only one I have right now), plus a first recipe for our (soon-to-be) delicious cornbread. Time to create a file for that, which I can do with the click of a button.
 
-![](../assets/img/06-vscode/B-stage-commit/vscode-stage-01.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/B-stage-commit/vscode-stage-01.jpg){: .mx-auto.d-block :}
 
 I am asked the name of the file, and bam, I can work on it. A few changes later, let us have a closer look at our sidebar:
 
-![](../assets/img/06-vscode/B-stage-commit/vscode-stage-02.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/B-stage-commit/vscode-stage-02.jpg){: .mx-auto.d-block :}
 
 These colors and letters are not there for nothing:
 
@@ -82,35 +82,35 @@ These colors and letters are not there for nothing:
 
 We basically just have a visual counterpart to `git status`, which is exactly what we need. Also, the small Git logo in the left bar has this small notification bubble with a 2 in it: this is the number of files that differ from the state of the repo, for a reason or another (in our case, one file was changed and one was just created). Let us click this button:
 
-![](../assets/img/06-vscode/B-stage-commit/vscode-stage-03.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/B-stage-commit/vscode-stage-03.jpg){: .mx-auto.d-block :}
 
 Only changed files will appear here, and each of them comes with three buttons, in this order: open the file in the editor, revert changes, stage. Note that the "open file" option is a specific button; if you just click on a filename from here, you will get this view instead:
 
-![](../assets/img/06-vscode/B-stage-commit/vscode-stage-04.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/B-stage-commit/vscode-stage-04.jpg){: .mx-auto.d-block :}
 
 That is a nice diff, indeed. This makes sense: this Git panel is not where you should make changes to your code, but where you should review the changes before committing. I am okay with the changes in `README.md` and ready to stage them: time to click on that `+` button.
 
-![](../assets/img/06-vscode/B-stage-commit/vscode-stage-05.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/B-stage-commit/vscode-stage-05.jpg){: .mx-auto.d-block :}
 
 This will open a new tab "Staged changes". I want a commit that only contains my changes to this file, so that I can just give a message to my commit...
 
-![](../assets/img/06-vscode/B-stage-commit/vscode-stage-06.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/B-stage-commit/vscode-stage-06.jpg){: .mx-auto.d-block :}
 
 ...and click "Commit". The view then becomes this:
 
-![](../assets/img/06-vscode/B-stage-commit/vscode-stage-07.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/B-stage-commit/vscode-stage-07.jpg){: .mx-auto.d-block :}
 
 Everything went fine, and now, only `recipe-v1.txt` is left in my uncommitted changes. I will stage it in the exact same way and provide a message for this new commit, but then, I can click on the small arrow on the right of the "Commit" button, just to see.
 
-![](../assets/img/06-vscode/B-stage-commit/vscode-stage-08.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/B-stage-commit/vscode-stage-08.jpg){: .mx-auto.d-block :}
 
 Yay, we have options! The first one is the default, the second one makes it possible to amend the commit I just created (basically, change its contents and message while I have not pushed it), and I will not be delving into the last one. For now, I would just be content with committing, then pushing all my new commits. Guess what comes next?
 
-![](../assets/img/06-vscode/B-stage-commit/vscode-stage-09.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/B-stage-commit/vscode-stage-09.jpg){: .mx-auto.d-block :}
 
 Yep, I am reaching the repo, so that I have to provide my SSH passphrase. Once this is done, no changes and no upstaged changes remain. Also, if this is my first time doing this, VSCode will ask me if I want it to do more:
 
-![](../assets/img/06-vscode/B-stage-commit/vscode-stage-10.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/B-stage-commit/vscode-stage-10.jpg){: .mx-auto.d-block :}
 
 Remember that `git fetch` will not modify your working copy: it will just update your computer's knowledge of the state of the repo. So, why not? Just remember that `git fetch` and its variants exist if, for a reason or another, you switch back to the editor-and-terminal workflow.
 
@@ -128,11 +128,11 @@ It's saturday morning, and someone just tested my recipe and told me that there
 
 I can just log in to GitLab and open the Web IDE to edit our recipe:
 
-![](../assets/img/06-vscode/C-web-ide/vscode-sync-01.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/C-web-ide/vscode-sync-01.jpg){: .mx-auto.d-block :}
 
 I already told you: **it's always VSCode**. These are pretty familiar grounds, with our good old notification in the sidebar and everything. This time, however, when I switch to the Git panel, there are considerably less options:
 
-![](../assets/img/06-vscode/C-web-ide/vscode-sync-02.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/C-web-ide/vscode-sync-02.jpg){: .mx-auto.d-block :}
 
 In particular, no choosing whether a file should be included to the next commit or not. This makes perfect sense:
 
@@ -141,11 +141,11 @@ Any complex change in the codebase should be made from a working copy, then comm
 
 Also, there is no committing without pushing. I mean, where would the commit be stored? We are on the repo itself, not on a working copy, so there's no "committing now, pushing on the repo later". One click later:
 
-![](../assets/img/06-vscode/C-web-ide/vscode-sync-03.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/C-web-ide/vscode-sync-03.jpg){: .mx-auto.d-block :}
 
 ...yup, one can also create a new branch in a very convenient way from the Web IDE. For now, I just want to push to the main branch. A small pop-up window appears on the bottom-left corner as soon as I click the button:
 
-![](../assets/img/06-vscode/C-web-ide/vscode-sync-04.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/C-web-ide/vscode-sync-04.jpg){: .mx-auto.d-block :}
 
 And it's over. My changes are on the repo.
 
@@ -156,21 +156,21 @@ There are cases in which you do **not** want to use the web IDE. Typically, if y
 
 Alright, fast-forward to monday morning. I am back in my office, and I know changes were made on the repo. Maybe I asked VSCode to fetch on a regular basis, so that it will `git fetch` as soon as I open my working copy. Or maybe I did not, in which case I can just ask nicely by clicking on the three dots:
 
-![](../assets/img/06-vscode/D-fetch-pull/vscode-sync-05.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/D-fetch-pull/vscode-sync-05.jpg){: .mx-auto.d-block :}
 
 I can then click "Fetch", aaaaaaaand...
 
-![](../assets/img/06-vscode/D-fetch-pull/vscode-sync-06.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/D-fetch-pull/vscode-sync-06.jpg){: .mx-auto.d-block :}
 
 ...as usual.
 
 In both cases, my Git panel now has something to tell me:
 
-![](../assets/img/06-vscode/D-fetch-pull/vscode-sync-07.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/D-fetch-pull/vscode-sync-07.jpg){: .mx-auto.d-block :}
 
 Basically, there are changes on the repo, and I should sync with it. The downwards arrow indicates that I should "download" changes, from the repo to my working copy. Alright then. "*click*"
 
-![](../assets/img/06-vscode/D-fetch-pull/vscode-sync-08.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/D-fetch-pull/vscode-sync-08.jpg){: .mx-auto.d-block :}
 
 Actually, in our situation, right now, we will only be pulling, not pushing, but fine, go ahead. (If I am really confident in my knowledge of Git, I may pick the "Don't show again" option. Just remember that "Overconfidence precedes carelessness." Just sayin'.)
 
@@ -178,51 +178,51 @@ Actually, in our situation, right now, we will only be pulling, not pushing, but
 
 A few days later, I am back to work on the project. If I remember correctly, automatic fetching is on, but if I am not sure, I may pull just in case:
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-01.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-01.jpg){: .mx-auto.d-block :}
 
 I then change a few things here and there, and back to the Git panel to prepare my commit.
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-02.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-02.jpg){: .mx-auto.d-block :}
 
 I just want to stage my changes on my file (by just clicking the `+` button), write a nice commit message, then commit **and** push at the same time, because why not?
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-03.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-03.jpg){: .mx-auto.d-block :}
 
 I pulled, like, 10 minutes ago. There is no way any--
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-04.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-04.jpg){: .mx-auto.d-block :}
 
 Hmm, well, let us click the nice blue button as usual, I guess.
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-05.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-05.jpg){: .mx-auto.d-block :}
 
 Okay, someone else was working at the same time on the project. Something was pushed while I was looking away. No problem, I can handle it. However, there is something intriguing in my Git panel:
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-06.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-06.jpg){: .mx-auto.d-block :}
 
 This time, the arrow is pointing up. Am I supposed to push my changes to the repo? Let's see what happens.
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-07.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-07.jpg){: .mx-auto.d-block :}
 
 ...
 
-![](../assets/img/06-vscode/E-conflicts/oh-no.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/oh-no.jpg){: .mx-auto.d-block :}
 
 These red exclamation marks are no good news, right? Is it conflict time again?
 
 Well, yes, but VSCode is really friendly with conflicts. See, this is what is displayed now in the editor, as my `recipe-v1.txt` file:
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-08.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-08.jpg){: .mx-auto.d-block :}
 
 Here, the green block is the "current change", i.e., the one that comes from my working copy, while the blue one is the "incoming change", i.e., the one made on the repo while I was looking away. I can choose whether to keep only one of the changes, or both at the same time.
 
 If none of these options are fine with me, I may also just edit the file by hand, as I did before: this whole part (starting with `<<<<<<<<` and ending with `>>>>>>>>` has been formatted by VSCode, but it is just good old editable code). Or I can do the same thing, but better, with the "Resolve in Merge Editor" option:
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-09.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-09.jpg){: .mx-auto.d-block :}
 
 On this view, I have my version on the left, the incoming version on the right, and the result I want to get on the bottom. As long as I do not type anything in the orange rectangle in the bottom editor, this rectangle will stay here, telling me that there are "no changes accepted". As soon as I edit its contents, whatever the edit actually is, the rectangle will disappear:
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-10.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-10.jpg){: .mx-auto.d-block :}
 
 It is up to me to check that what I type there is exactly what I intended to type. (If this is actual code, it might be a good idea to compile and test my code before I commit and push it.)
 
@@ -231,17 +231,17 @@ When solving conflicts on VSCode, one may start with the ones that only require
 
 Once every conflict was handled, I can "Complete Merge" (VSCode will refuse to cooperate if some of the conflicts are not solved yet), and the status of the conflicting file(s) will change:
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-11.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-11.jpg){: .mx-auto.d-block :}
 
 Depending on your Git settings, it may be impossible for you to edit the title of the commit message:
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-12.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-12.jpg){: .mx-auto.d-block :}
 
 You should still try and give a fresh, clear commit message, and if this warning appears, just Ctrl-Z to get back to the original message.
 
 One commit later:
 
-![](../assets/img/06-vscode/E-conflicts/vscode-conflict-13.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/E-conflicts/vscode-conflict-13.jpg){: .mx-auto.d-block :}
 
 I am now one commit ahead of the repo, and can safely push by clicking on "Sync changes".
 
@@ -253,31 +253,31 @@ Nothing too terribly bad so far, right? I think we are ready to switch to safe c
 
 How to create a branch in VSCode? Well, not that hard, really:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-01.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-01.jpg){: .mx-auto.d-block :}
 
 You will get a prompt asking you for the name of the new branch:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-02.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-02.jpg){: .mx-auto.d-block :}
 
 A `git switch -c <branch_name>` will be done automatically. If you'd rather be careful, just run `git status` in a terminal (...why not the one that is integrated to VSCode?), *et voilà*:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-03.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-03.jpg){: .mx-auto.d-block :}
 
 On this branch `change-recipe-format`, I am going to just turn my `.txt` file into a proper Markdown file, formatting and all. Once this is done, the Git panel tells me what was changed:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-04.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-04.jpg){: .mx-auto.d-block :}
 
 File `recipe-v1.md` is untracked, and `recipe-v1.txt` does not exist anymore. In both cases, though, I can just click on the `+` button. Do not worry, VSCode knows what it is doing: for the `.md` file, a `git add` will be run; for the `.txt` file, a `git rm`. This is made clear once both stages are changed:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-05.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-05.jpg){: .mx-auto.d-block :}
 
 Indeed, the `.md` file is added and the `.txt` file is deleted. Great. I can now commit my changes (with a proper commit message) or, if I like doing two things at once:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-06.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-06.jpg){: .mx-auto.d-block :}
 
 "Hey, this should not work, right?" Indeed: every change so far is local. In particular, no remote branch called `change-recipe-format` exists yet. Should you go back to the terminal for the push and use the `--set-upstream` option? Nope:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-07.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-07.jpg){: .mx-auto.d-block :}
 
 Just click OK and this will be done under the hood.
 
@@ -285,11 +285,11 @@ Just click OK and this will be done under the hood.
 
 Hey, there are merge options in our menu!
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-08.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-08.jpg){: .mx-auto.d-block :}
 
 Let us click on this one, then pick a source branch...
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-09.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-09.jpg){: .mx-auto.d-block :}
 
 ...well, hold on.
 
@@ -307,7 +307,7 @@ Actually, every single user of the project should at least be prevented from pus
 
 So, back to the project page on GitLab. You should get a nice banner here:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-10.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-10.jpg){: .mx-auto.d-block :}
 
 If this is not the case, you can still create your MR from the menu on the left-hand side.
 
@@ -315,7 +315,7 @@ If this is not the case, you can still create your MR from the menu on the left-
 
 Once again, pretty easy, except that it is not called "switching" but "checking out" here:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-11.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-11.jpg){: .mx-auto.d-block :}
 
 It is basically the same thing. Well, in this specific case, it is *exactly* the same thing.
 
@@ -324,20 +324,20 @@ The `git switch` command was added for disambiguation purposes. The historical `
 
 Okay, so, checking out/switching in VSCode. A single click is enough to open a nice list of branches to choose from:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-12.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-12.jpg){: .mx-auto.d-block :}
 
 Back to `main`, my editor tab for `recipe-v1.md` is still open, but clearly indicates that, where I currently am, this file does not exist: VSCode just shows me a buffered file that will disappear as soon as I close the tab.
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-13.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-13.jpg){: .mx-auto.d-block :}
 
 Also note that, in the process, no SSH passphrase was asked. Indeed, no request was sent to the repo: I just switched to my local copy of `main` (this is how `git switch` works). Who knows what happened on the repo while I was working on my branch? If I really want to make sure that I did not miss out on anything:
 
-![](../assets/img/06-vscode/F-branch/vscode-branch-14.jpg){: .mx-auto.d-block :}
+![](../assets/img/07-vscode/F-branch/vscode-branch-14.jpg){: .mx-auto.d-block :}
 
 This illustrates why one should, at least in my opinion, learn to use Git "the hard way" *before* using it through VSCode: the IDE makes your life easier, but only if you know what you are doing and what the buttons mean. Use the Git panel in VSCode without understanding the basics of Git, and you are in for terrible headaches.
 
 ----
 
-If you are interested in how Git works under the hood, [**the next section of this tutorial is for you.**]({{'/07-internals' | relative_url }})
+The "core" of this tutorial is now officially over... but there are still nice things to learn. How about knowing more about [**how Git works under the hood?**]({{'/08-internals' | relative_url }}) ("Wow, this site is a gift that keeps on giving!" I know. Please hold your applause until the end.)
 
 You may also go back to the [detailed table of contents]({{'/index#toc' | relative_url }}).
\ No newline at end of file
diff --git a/07-internals.md b/08-internals.md
similarity index 98%
rename from 07-internals.md
rename to 08-internals.md
index f47417a..a4c5874 100644
--- a/07-internals.md
+++ b/08-internals.md
@@ -16,7 +16,7 @@ Remember that you can switch branches without having to request the repo itself,
 
 And by "somewhere", I mean "look no further than the hidden objects at the root of your working copy":
 
-![](../assets/img/07-internals/git-internals-1.jpg){: .mx-auto.d-block :}
+![](../assets/img/08-internals/git-internals-1.jpg){: .mx-auto.d-block :}
 
 This `.git` folder appeared as soon as this folder became a working copy, either when you created it by cloning an existing project, or when you ran `git init` there. It contains quite a lot of stuff, but I have good news: it will make sense in a pretty short time.
 
@@ -32,7 +32,7 @@ What would be the most convenient way to give names to these blobs? A "naive" so
 
 Instead, Git relies on [hashing](https://en.wikipedia.org/wiki/Hash_function) to compute a nice fixed-size sequence of hexadecimal digits from the contents of the file, which will yield the name of the file. These blobs are in the `.git/objects` folder, separated in subfolders named after the first 2 digits of the hash (for reasons I will not detail here -- efficiency, basically). Here, for instance:
 
-![](../assets/img/07-internals/git-internals-2.jpg){: .mx-auto.d-block :}
+![](../assets/img/08-internals/git-internals-2.jpg){: .mx-auto.d-block :}
 
 the contents of one of my files were hashed and its hash begins with `26d927bb21` (I decided against pasting the remaining 30 characters).
 
@@ -68,7 +68,7 @@ The "direct parent" relationship between commits is already described in the com
 
 This is where the `.git/refs` folder shines... but in an incredibly lame way.
 
-![](../assets/img/07-internals/git-internals-3.jpg){: .mx-auto.d-block :}
+![](../assets/img/08-internals/git-internals-3.jpg){: .mx-auto.d-block :}
 
 Three subfolders: `heads` for the branches you have in your working copy, `remotes` for the ones on the repo, `tags` for the tags. Why is the first one called `heads`? Because, in order to switch to a given branch, Git only needs to know the hash of the head of this branch, i.e., the last commit. From the contents of this commit, Git knows the file structure, the contents of the files, and the whole history of the branch.
 
@@ -119,6 +119,6 @@ Last but not least, remember that, for all intents and purposes, there is no und
 
 ----
 
-But wait, there's more! [**Here is more extra stuff that one could be interested in.**]({{'/08-advanced' | relative_url }}) Advanced branch management, hints for your CI pipelines, a bit of troubleshooting, you name it.
+But wait, there's more! [**Here is more extra stuff that one could be interested in.**]({{'/09-advanced' | relative_url }}) Advanced branch management, hints for your CI pipelines, a bit of troubleshooting, you name it.
 
 You may also go back to the [detailed table of contents]({{'/index#toc' | relative_url }}).
\ No newline at end of file
diff --git a/08-advanced.md b/09-advanced.md
similarity index 84%
rename from 08-advanced.md
rename to 09-advanced.md
index fb12b4e..ee33677 100644
--- a/08-advanced.md
+++ b/09-advanced.md
@@ -219,103 +219,6 @@ Do not forget to type `git bisect reset` once this is over, or if you get tired
 
 For more information and options, [the Git SCM website is there for you](https://git-scm.com/docs/git-bisect).
 
-# Forks and merge requests {#fork}
-
-I was recently told by a friend of mine that, in the company he is working for, MRs for branches basically do not exist; instead, they rely on MRs for *forks*. For advanced and experienced users, there are indeed advantages to this workflow.
-
-More directly, this is what you will be doing if you are contributing to open source projects, either because you believe in FOSS in general, or just because you *had to* implement new features in an existing software, for your personal use, and have nothing against making these features available to other users if they face the same need.
-
-Let us work with this last scenario. There is an open source software that I am using, and it so happens that my life would become way easier if there were a few more features. Maybe this is time-critical and I cannot just request these features to the developers and wait for them; maybe the project has only been the subject of very basic maintenance for the last few years and I cannot expect the original developers to implement new features in the foreseeable future; or maybe I am not sure at all that these features would be useful to anyone else, but I know that they would not be that hard to actually design and implement.
-
-This is where forking happens.
-
-## Forking {#forking}
-
-{: .box-success}
-A ***fork*** is a fresh repository that contains an exact copy of an already existing repository. This new repository is now yours, in the sense that you have all permissions on it, but GitLab still knows where it comes from.
-
-In other words, forking a repo is a way of getting your own copy of an existing project. You are then free to do whatever you want with it... in a way.
-
-### Legal disclaimer
-
-We should be a bit more precise about this stuff. Just a tiny bit.
-
-{: .box-warning}
-You are free to modify and distribute a forked project ***within the limits of the license of the original project.***
-
-Be very cautious with this! Open source software are subject to pretty permissive licenses, either in the "do-whatever-you-want" category (MIT, BSD...) or in the "you-have-to-keep-the-same-licensing" category (aka *copyleft*: GPL, MPL, and others), but a public codebase is **not** open source by default!
-
-Ask your doctor is forking is right for you.
-
-### Forking a GitLab project
-
-This one is tricky.
-
-I mean, tricky in the GitLab sense of the word: there is no big blue button on the page on the project you want to fork.
-
-Instead, the button is white:
-
-![](../assets/img/08-advanced/forks-and-pr/fork-01.jpg){: .mx-auto.d-block :}
-
-Yup. Just click on the "Forks" button, and you will have the option to fork to a project, with the name you want to give it, and the place you want to put it in (either your namespace, which is still a bad option in most cases, or a group/subgroup):
-
-![](../assets/img/08-advanced/forks-and-pr/fork-02.jpg){: .mx-auto.d-block :}
-
-This absolutely looks like your standard project creation page, with a bit less options (it would make no sense to give you an "Initialize project with a README" option, after all).
-
-Click.
-
-![](../assets/img/08-advanced/forks-and-pr/fork-03.jpg){: .mx-auto.d-block :}
-
-A few seconds later, you have a project. It is yours (kind of). You can work on it.
-
-## Merge request {#fork-mr}
-
-Remember when I told you that a MR is about bringing the contents of a branch into another branch? Well, here is a nice little detail for you: *these branches do not need to be in the same project*. You can suggest merging contents of a fork into the original project.
-
-This is how it happens for me. I made some changes on my fork, and I really think these changes would be beneficial for other people who use the original project, without breaking any already existing feature.
-
-Well, guess who will help you?
-
-![](../assets/img/08-advanced/forks-and-pr/fork-04.jpg){: .mx-auto.d-block :}
-
-This appeared on the page of the fork (i.e., my "variant" of the project) as soon as I committed some stuff on it. I can totally open an MR in the source project:
-
-![](../assets/img/08-advanced/forks-and-pr/fork-05.jpg){: .mx-auto.d-block :}
-
-I can also, at any point, open an MR from the sidebar, on the webpage of my fork: branches of the original project will appear among the possible target branches.
-
-![](../assets/img/08-advanced/forks-and-pr/fork-06.jpg){: .mx-auto.d-block :}
-
-The form you have to fill to actually create the MR is basically the same, except for this new gizmo at the bottom of the page:
-
-![](../assets/img/08-advanced/forks-and-pr/fork-07.jpg){: .mx-auto.d-block :}
-
-...that's two gizmos. Well. So:
-
-1. If the original project is not a private project, that basically means that you are offering some code to a "public" codebase. It can make sense for the community that developed this codebase in the first place to have their word, and what better way of letting them contribute than directly allowing them to commit?
-2. This "Contribution guidelines" stuff does not come from nowhere. Well... Turns out there is a reason why GitLab suggests you (and so did I) to create a file named `CONTRIBUTING.md` at the root of any project to which other people might contribute. This link is a pointer to the `CONTRIBUTING.md` file of the project you forked. The closer you follow these guidelines, the higher the chances of your MR being accepted.
-
-## Closing remarks {#fork-closing}
-
-**As a forker**, remember that the project you forked will probably evolve while you are working on your own personal copy. In other words, you will sometimes fall behind the original project, which will make things pretty complicated if you want to submit an MR at some point. (Also, maybe some of the commits that were pushed on the original project solve bugs you would have encountered at some point... so, it is also in *your* best interest to stay up to date.)
-
-GitLab will tell you when you are behind the forked project:
-
-![](../assets/img/08-advanced/forks-and-pr/fork-update.jpg){: .mx-auto.d-block :}
-
-...but you have to deal with the consequences (even when you have less commits to pull than here). As a result, you will have to think about your workflow when you work on a fork. Or you may just [read GitLab's page about forkflows](https://docs.gitlab.com/ee/user/project/repository/forking_workflow.html).
-
-Also note that you can remove the fork relationship if you know where to look. (Spoilers: this should be Settings → Advanced).
-
-**As a forked** (...forkee?), remember that the forks of your project depend on the project itself. For instance, this is the reminder I will get if I want to delete a project that was forked:
-
-![](../assets/img/08-advanced/forks-and-pr/fork-08.jpg){: .mx-auto.d-block :}
-
-This is a nice summary of why your project maybe should not be deleted: the higher the numbers, the more you should think about it.
-
-Regarding forks, there is a simple rule to be remembered: ***If you delete a private project, its forks will be deleted too.*** If you delete a *public* project, one of its forks will be automatically picked as the new "original project" from which all other forks are forked off.
-
 # About the `.git` folder {#hooks-excludes}
 
 [Earlier on in this tutorial]({{'/03-linear-git-project#clone' | relative_url }}), I told you that you might just pretend that there is no reason to touch anything in the `.git` folder that is automatically created when you initialize or clone a project.
@@ -509,11 +412,11 @@ Not all occurrences require the exact same solution, in particular because of th
 This is the nice use case: you made your commit to the wrong branch, but it only lives on your computer. Nothing has been pushed yet.
 
 {: .box-note}
-This is one of the many reasons why `git commit` and `git push` should not always be used together: you can create several commits without pushing any of them, so that you can safely review your work and local history before pushing anything. Other reasons include the possibility to [rebase on a regular basis]({{'/08-advanced#rebase' | relative_url }}) so as to make the development and merging process more streamlined, and/or [reorganize your branch before pushing it]({{'/08-advanced#irebase' | relative_url }}).
+This is one of the many reasons why `git commit` and `git push` should not always be used together: you can create several commits without pushing any of them, so that you can safely review your work and local history before pushing anything. Other reasons include the possibility to [rebase on a regular basis]({{'/09-advanced#rebase' | relative_url }}) so as to make the development and merging process more streamlined, and/or [reorganize your branch before pushing it]({{'/09-advanced#irebase' | relative_url }}).
 
 Here is our use case (just change branch names for your use case): the last commit I created is on branch `main`, but it was actually intended for branch `feature`. (Oh, BTW, if `main` is protected, [which it should definitely be]({{'/05-good-practices#protect' | relative_url }}), Git will prevent you from pushing this commit, which will help you realize that you made a mistake and avoid making the situation worse.)
 
-First, copy the hash of your commit: you will need it for what follows. Then, the process is basically in two steps: [cherrypick]({{'/08-advanced#cherrypick' | relative_url }}) the commit to the `feature` branch, and delete it from the `main` branch.
+First, copy the hash of your commit: you will need it for what follows. Then, the process is basically in two steps: [cherrypick]({{'/09-advanced#cherrypick' | relative_url }}) the commit to the `feature` branch, and delete it from the `main` branch.
 
 * Step 1: `git switch feature` (switch to the branch on which the commit should go), `git cherry-pick <commit_hash>` (create a new commit that applies the same changes on `feature` as your misplaced commit did on `main`);
 * Step 2: `git switch main` (switch back to the branch where you wrongly committed in the first place), then `git reset --hard HEAD~1` (reset branch to its state one commit ago, which actually deletes the last commit).
diff --git a/_config.yml b/_config.yml
index 041b3d0..26dc4c2 100644
--- a/_config.yml
+++ b/_config.yml
@@ -27,9 +27,10 @@ navbar-links:
     - Working on a linear project: "./03-linear-git-project"
     - Branches and issues: "./04-branches-issues"
     - Good practices: "./05-good-practices"
-    - Using VSCode: "./06-vscode"
-    - Git internals: "./07-internals"
-    - Advanced: "./08-advanced"
+    - Workflows: "./06-forks"
+    - Using VSCode: "./07-vscode"
+    - Git internals: "./09-advanced"
+    - Advanced: "./09-advanced"
   Resources:
     - Git (official): "https://git-scm.com/"
     - Git Internals: "https://github.com/pluralsight/git-internals-pdf"
diff --git a/_config_dev.yml b/_config_dev.yml
index 9cd6416..cb28d1e 100644
--- a/_config_dev.yml
+++ b/_config_dev.yml
@@ -27,9 +27,10 @@ navbar-links:
     - Working on a linear project: "./03-linear-git-project"
     - Branches and issues: "./04-branches-issues"
     - Good practices: "./05-good-practices"
-    - Using VSCode: "./06-vscode"
-    - Git internals: "./07-internals"
-    - Advanced: "./08-advanced"
+    - Workflows: "./06-forks"
+    - Using VSCode: "./07-vscode"
+    - Git internals: "./08-internals"
+    - Advanced: "./09-advanced"
   Resources:
     - Git (official): "https://git-scm.com/"
     - Git Internals: "https://github.com/pluralsight/git-internals-pdf"
diff --git a/assets/img/08-advanced/forks-and-pr/fork-01.jpg b/assets/img/06-forks/fork-01.jpg
similarity index 100%
rename from assets/img/08-advanced/forks-and-pr/fork-01.jpg
rename to assets/img/06-forks/fork-01.jpg
diff --git a/assets/img/08-advanced/forks-and-pr/fork-02.jpg b/assets/img/06-forks/fork-02.jpg
similarity index 100%
rename from assets/img/08-advanced/forks-and-pr/fork-02.jpg
rename to assets/img/06-forks/fork-02.jpg
diff --git a/assets/img/08-advanced/forks-and-pr/fork-03.jpg b/assets/img/06-forks/fork-03.jpg
similarity index 100%
rename from assets/img/08-advanced/forks-and-pr/fork-03.jpg
rename to assets/img/06-forks/fork-03.jpg
diff --git a/assets/img/08-advanced/forks-and-pr/fork-04.jpg b/assets/img/06-forks/fork-04.jpg
similarity index 100%
rename from assets/img/08-advanced/forks-and-pr/fork-04.jpg
rename to assets/img/06-forks/fork-04.jpg
diff --git a/assets/img/08-advanced/forks-and-pr/fork-05.jpg b/assets/img/06-forks/fork-05.jpg
similarity index 100%
rename from assets/img/08-advanced/forks-and-pr/fork-05.jpg
rename to assets/img/06-forks/fork-05.jpg
diff --git a/assets/img/08-advanced/forks-and-pr/fork-06.jpg b/assets/img/06-forks/fork-06.jpg
similarity index 100%
rename from assets/img/08-advanced/forks-and-pr/fork-06.jpg
rename to assets/img/06-forks/fork-06.jpg
diff --git a/assets/img/08-advanced/forks-and-pr/fork-07.jpg b/assets/img/06-forks/fork-07.jpg
similarity index 100%
rename from assets/img/08-advanced/forks-and-pr/fork-07.jpg
rename to assets/img/06-forks/fork-07.jpg
diff --git a/assets/img/08-advanced/forks-and-pr/fork-08.jpg b/assets/img/06-forks/fork-08.jpg
similarity index 100%
rename from assets/img/08-advanced/forks-and-pr/fork-08.jpg
rename to assets/img/06-forks/fork-08.jpg
diff --git a/assets/img/08-advanced/forks-and-pr/fork-update.jpg b/assets/img/06-forks/fork-update.jpg
similarity index 100%
rename from assets/img/08-advanced/forks-and-pr/fork-update.jpg
rename to assets/img/06-forks/fork-update.jpg
diff --git a/assets/img/06-vscode/A-open-and-clone/vscode-01.jpg b/assets/img/07-vscode/A-open-and-clone/vscode-01.jpg
similarity index 100%
rename from assets/img/06-vscode/A-open-and-clone/vscode-01.jpg
rename to assets/img/07-vscode/A-open-and-clone/vscode-01.jpg
diff --git a/assets/img/06-vscode/A-open-and-clone/vscode-02.jpg b/assets/img/07-vscode/A-open-and-clone/vscode-02.jpg
similarity index 100%
rename from assets/img/06-vscode/A-open-and-clone/vscode-02.jpg
rename to assets/img/07-vscode/A-open-and-clone/vscode-02.jpg
diff --git a/assets/img/06-vscode/A-open-and-clone/vscode-02bis.jpg b/assets/img/07-vscode/A-open-and-clone/vscode-02bis.jpg
similarity index 100%
rename from assets/img/06-vscode/A-open-and-clone/vscode-02bis.jpg
rename to assets/img/07-vscode/A-open-and-clone/vscode-02bis.jpg
diff --git a/assets/img/06-vscode/A-open-and-clone/vscode-03.jpg b/assets/img/07-vscode/A-open-and-clone/vscode-03.jpg
similarity index 100%
rename from assets/img/06-vscode/A-open-and-clone/vscode-03.jpg
rename to assets/img/07-vscode/A-open-and-clone/vscode-03.jpg
diff --git a/assets/img/06-vscode/A-open-and-clone/vscode-04.jpg b/assets/img/07-vscode/A-open-and-clone/vscode-04.jpg
similarity index 100%
rename from assets/img/06-vscode/A-open-and-clone/vscode-04.jpg
rename to assets/img/07-vscode/A-open-and-clone/vscode-04.jpg
diff --git a/assets/img/06-vscode/A-open-and-clone/vscode-05.jpg b/assets/img/07-vscode/A-open-and-clone/vscode-05.jpg
similarity index 100%
rename from assets/img/06-vscode/A-open-and-clone/vscode-05.jpg
rename to assets/img/07-vscode/A-open-and-clone/vscode-05.jpg
diff --git a/assets/img/06-vscode/A-open-and-clone/vscode-06.jpg b/assets/img/07-vscode/A-open-and-clone/vscode-06.jpg
similarity index 100%
rename from assets/img/06-vscode/A-open-and-clone/vscode-06.jpg
rename to assets/img/07-vscode/A-open-and-clone/vscode-06.jpg
diff --git a/assets/img/06-vscode/A-open-and-clone/vscode-07.jpg b/assets/img/07-vscode/A-open-and-clone/vscode-07.jpg
similarity index 100%
rename from assets/img/06-vscode/A-open-and-clone/vscode-07.jpg
rename to assets/img/07-vscode/A-open-and-clone/vscode-07.jpg
diff --git a/assets/img/06-vscode/A-open-and-clone/vscode-08.jpg b/assets/img/07-vscode/A-open-and-clone/vscode-08.jpg
similarity index 100%
rename from assets/img/06-vscode/A-open-and-clone/vscode-08.jpg
rename to assets/img/07-vscode/A-open-and-clone/vscode-08.jpg
diff --git a/assets/img/06-vscode/A-open-and-clone/vscode-09.jpg b/assets/img/07-vscode/A-open-and-clone/vscode-09.jpg
similarity index 100%
rename from assets/img/06-vscode/A-open-and-clone/vscode-09.jpg
rename to assets/img/07-vscode/A-open-and-clone/vscode-09.jpg
diff --git a/assets/img/06-vscode/B-stage-commit/vscode-stage-01.jpg b/assets/img/07-vscode/B-stage-commit/vscode-stage-01.jpg
similarity index 100%
rename from assets/img/06-vscode/B-stage-commit/vscode-stage-01.jpg
rename to assets/img/07-vscode/B-stage-commit/vscode-stage-01.jpg
diff --git a/assets/img/06-vscode/B-stage-commit/vscode-stage-02.jpg b/assets/img/07-vscode/B-stage-commit/vscode-stage-02.jpg
similarity index 100%
rename from assets/img/06-vscode/B-stage-commit/vscode-stage-02.jpg
rename to assets/img/07-vscode/B-stage-commit/vscode-stage-02.jpg
diff --git a/assets/img/06-vscode/B-stage-commit/vscode-stage-03.jpg b/assets/img/07-vscode/B-stage-commit/vscode-stage-03.jpg
similarity index 100%
rename from assets/img/06-vscode/B-stage-commit/vscode-stage-03.jpg
rename to assets/img/07-vscode/B-stage-commit/vscode-stage-03.jpg
diff --git a/assets/img/06-vscode/B-stage-commit/vscode-stage-04.jpg b/assets/img/07-vscode/B-stage-commit/vscode-stage-04.jpg
similarity index 100%
rename from assets/img/06-vscode/B-stage-commit/vscode-stage-04.jpg
rename to assets/img/07-vscode/B-stage-commit/vscode-stage-04.jpg
diff --git a/assets/img/06-vscode/B-stage-commit/vscode-stage-05.jpg b/assets/img/07-vscode/B-stage-commit/vscode-stage-05.jpg
similarity index 100%
rename from assets/img/06-vscode/B-stage-commit/vscode-stage-05.jpg
rename to assets/img/07-vscode/B-stage-commit/vscode-stage-05.jpg
diff --git a/assets/img/06-vscode/B-stage-commit/vscode-stage-06.jpg b/assets/img/07-vscode/B-stage-commit/vscode-stage-06.jpg
similarity index 100%
rename from assets/img/06-vscode/B-stage-commit/vscode-stage-06.jpg
rename to assets/img/07-vscode/B-stage-commit/vscode-stage-06.jpg
diff --git a/assets/img/06-vscode/B-stage-commit/vscode-stage-07.jpg b/assets/img/07-vscode/B-stage-commit/vscode-stage-07.jpg
similarity index 100%
rename from assets/img/06-vscode/B-stage-commit/vscode-stage-07.jpg
rename to assets/img/07-vscode/B-stage-commit/vscode-stage-07.jpg
diff --git a/assets/img/06-vscode/B-stage-commit/vscode-stage-08.jpg b/assets/img/07-vscode/B-stage-commit/vscode-stage-08.jpg
similarity index 100%
rename from assets/img/06-vscode/B-stage-commit/vscode-stage-08.jpg
rename to assets/img/07-vscode/B-stage-commit/vscode-stage-08.jpg
diff --git a/assets/img/06-vscode/B-stage-commit/vscode-stage-09.jpg b/assets/img/07-vscode/B-stage-commit/vscode-stage-09.jpg
similarity index 100%
rename from assets/img/06-vscode/B-stage-commit/vscode-stage-09.jpg
rename to assets/img/07-vscode/B-stage-commit/vscode-stage-09.jpg
diff --git a/assets/img/06-vscode/B-stage-commit/vscode-stage-10.jpg b/assets/img/07-vscode/B-stage-commit/vscode-stage-10.jpg
similarity index 100%
rename from assets/img/06-vscode/B-stage-commit/vscode-stage-10.jpg
rename to assets/img/07-vscode/B-stage-commit/vscode-stage-10.jpg
diff --git a/assets/img/06-vscode/C-web-ide/vscode-sync-01.jpg b/assets/img/07-vscode/C-web-ide/vscode-sync-01.jpg
similarity index 100%
rename from assets/img/06-vscode/C-web-ide/vscode-sync-01.jpg
rename to assets/img/07-vscode/C-web-ide/vscode-sync-01.jpg
diff --git a/assets/img/06-vscode/C-web-ide/vscode-sync-02.jpg b/assets/img/07-vscode/C-web-ide/vscode-sync-02.jpg
similarity index 100%
rename from assets/img/06-vscode/C-web-ide/vscode-sync-02.jpg
rename to assets/img/07-vscode/C-web-ide/vscode-sync-02.jpg
diff --git a/assets/img/06-vscode/C-web-ide/vscode-sync-03.jpg b/assets/img/07-vscode/C-web-ide/vscode-sync-03.jpg
similarity index 100%
rename from assets/img/06-vscode/C-web-ide/vscode-sync-03.jpg
rename to assets/img/07-vscode/C-web-ide/vscode-sync-03.jpg
diff --git a/assets/img/06-vscode/C-web-ide/vscode-sync-04.jpg b/assets/img/07-vscode/C-web-ide/vscode-sync-04.jpg
similarity index 100%
rename from assets/img/06-vscode/C-web-ide/vscode-sync-04.jpg
rename to assets/img/07-vscode/C-web-ide/vscode-sync-04.jpg
diff --git a/assets/img/06-vscode/D-fetch-pull/vscode-sync-05.jpg b/assets/img/07-vscode/D-fetch-pull/vscode-sync-05.jpg
similarity index 100%
rename from assets/img/06-vscode/D-fetch-pull/vscode-sync-05.jpg
rename to assets/img/07-vscode/D-fetch-pull/vscode-sync-05.jpg
diff --git a/assets/img/06-vscode/D-fetch-pull/vscode-sync-06.jpg b/assets/img/07-vscode/D-fetch-pull/vscode-sync-06.jpg
similarity index 100%
rename from assets/img/06-vscode/D-fetch-pull/vscode-sync-06.jpg
rename to assets/img/07-vscode/D-fetch-pull/vscode-sync-06.jpg
diff --git a/assets/img/06-vscode/D-fetch-pull/vscode-sync-07.jpg b/assets/img/07-vscode/D-fetch-pull/vscode-sync-07.jpg
similarity index 100%
rename from assets/img/06-vscode/D-fetch-pull/vscode-sync-07.jpg
rename to assets/img/07-vscode/D-fetch-pull/vscode-sync-07.jpg
diff --git a/assets/img/06-vscode/D-fetch-pull/vscode-sync-08.jpg b/assets/img/07-vscode/D-fetch-pull/vscode-sync-08.jpg
similarity index 100%
rename from assets/img/06-vscode/D-fetch-pull/vscode-sync-08.jpg
rename to assets/img/07-vscode/D-fetch-pull/vscode-sync-08.jpg
diff --git a/assets/img/06-vscode/E-conflicts/oh-no.jpg b/assets/img/07-vscode/E-conflicts/oh-no.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/oh-no.jpg
rename to assets/img/07-vscode/E-conflicts/oh-no.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-01.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-01.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-01.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-01.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-02.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-02.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-02.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-02.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-03.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-03.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-03.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-03.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-04.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-04.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-04.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-04.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-05.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-05.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-05.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-05.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-06.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-06.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-06.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-06.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-07.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-07.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-07.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-07.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-08.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-08.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-08.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-08.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-09.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-09.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-09.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-09.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-10.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-10.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-10.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-10.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-11.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-11.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-11.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-11.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-12.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-12.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-12.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-12.jpg
diff --git a/assets/img/06-vscode/E-conflicts/vscode-conflict-13.jpg b/assets/img/07-vscode/E-conflicts/vscode-conflict-13.jpg
similarity index 100%
rename from assets/img/06-vscode/E-conflicts/vscode-conflict-13.jpg
rename to assets/img/07-vscode/E-conflicts/vscode-conflict-13.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-01.jpg b/assets/img/07-vscode/F-branch/vscode-branch-01.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-01.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-01.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-02.jpg b/assets/img/07-vscode/F-branch/vscode-branch-02.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-02.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-02.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-03.jpg b/assets/img/07-vscode/F-branch/vscode-branch-03.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-03.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-03.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-04.jpg b/assets/img/07-vscode/F-branch/vscode-branch-04.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-04.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-04.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-05.jpg b/assets/img/07-vscode/F-branch/vscode-branch-05.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-05.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-05.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-06.jpg b/assets/img/07-vscode/F-branch/vscode-branch-06.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-06.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-06.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-07.jpg b/assets/img/07-vscode/F-branch/vscode-branch-07.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-07.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-07.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-08.jpg b/assets/img/07-vscode/F-branch/vscode-branch-08.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-08.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-08.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-09.jpg b/assets/img/07-vscode/F-branch/vscode-branch-09.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-09.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-09.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-10.jpg b/assets/img/07-vscode/F-branch/vscode-branch-10.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-10.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-10.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-11.jpg b/assets/img/07-vscode/F-branch/vscode-branch-11.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-11.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-11.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-12.jpg b/assets/img/07-vscode/F-branch/vscode-branch-12.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-12.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-12.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-13.jpg b/assets/img/07-vscode/F-branch/vscode-branch-13.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-13.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-13.jpg
diff --git a/assets/img/06-vscode/F-branch/vscode-branch-14.jpg b/assets/img/07-vscode/F-branch/vscode-branch-14.jpg
similarity index 100%
rename from assets/img/06-vscode/F-branch/vscode-branch-14.jpg
rename to assets/img/07-vscode/F-branch/vscode-branch-14.jpg
diff --git a/assets/img/07-internals/git-internals-1.jpg b/assets/img/08-internals/git-internals-1.jpg
similarity index 100%
rename from assets/img/07-internals/git-internals-1.jpg
rename to assets/img/08-internals/git-internals-1.jpg
diff --git a/assets/img/07-internals/git-internals-2.jpg b/assets/img/08-internals/git-internals-2.jpg
similarity index 100%
rename from assets/img/07-internals/git-internals-2.jpg
rename to assets/img/08-internals/git-internals-2.jpg
diff --git a/assets/img/07-internals/git-internals-3.jpg b/assets/img/08-internals/git-internals-3.jpg
similarity index 100%
rename from assets/img/07-internals/git-internals-3.jpg
rename to assets/img/08-internals/git-internals-3.jpg
diff --git a/index.md b/index.md
index 5a7a44f..8a946ad 100644
--- a/index.md
+++ b/index.md
@@ -64,7 +64,7 @@ If you are already somewhat accustomed to Git and GitLab, you may also directly
     * [MR templates and parameters]({{'/05-good-practices#mr' | relative_url }})
     * [Protecting branches]({{'/05-good-practices#protect' | relative_url }})
     * [Tags]({{'/05-good-practices#tags' | relative_url }})
-    * [Advanced: CI/CD pipelines and Git workflows]({{'/05-good-practices#cicd' | relative_url }})
+    * [CI/CD pipelines]({{'/05-good-practices#cicd' | relative_url }})
   * [***Everyday use***]({{'/05-good-practices#everyday' | relative_url }})
     * [Writing informative commit messages]({{'/05-good-practices#messages' | relative_url }})
     * [Keeping a clean history]({{'/05-good-practices#history' | relative_url }})
@@ -72,38 +72,48 @@ If you are already somewhat accustomed to Git and GitLab, you may also directly
     * [Going further with rebasing]({{'/05-good-practices#further' | relative_url }})
     * [Software development practices]({{'/05-good-practices#practices' | relative_url }})
 
-* [**Using Git with VSCode**]({{'/06-vscode' | relative_url }})
-    * [Clone a repo]({{'/06-vscode#clone' | relative_url }})
-    * [Stage and commit]({{'/06-vscode#stage' | relative_url }})
-    * [Collaborative development]({{'/06-vscode#collab' | relative_url }})
-    * [Branching and MRs]({{'/06-vscode#branch' | relative_url }})
-
-* [**Extra: basic Git internals**]({{'/07-internals' | relative_url }})
-  * [What's on my computer?]({{'/07-internals#computer' | relative_url }})
-  * [Git objects]({{'/07-internals#objects' | relative_url }})
-  * [History]({{'/07-internals#history' | relative_url }})
-  * [Deltas]({{'/07-internals#deltas' | relative_url }})
-  * [Consequences]({{'/07-internals#consequences' | relative_url }})
-
-* [**Extra: Advanced Git commands and troubleshooting hints**]({{'/08-advanced' | relative_url }})
-  * [Branch management: `git fetch` and `git fetch --prune`]({{'/08-advanced#git-fetch' | relative_url }})
-  * [Cleaning up your local copy]({{'/08-advanced#cleanup' | relative_url }})
-  * [Juggling with branches]({{'/08-advanced#juggling' | relative_url }})
-    * [Rebasing (how to keep up with a source branch)]({{'/08-advanced#rebase' | relative_url }})
-    * [Interactive rebasing (how to clean up your mess before pushing)]({{'/08-advanced#irebase' | relative_url }})
-    * [Cherrypicking (how to move commits around)]({{'/08-advanced#cherrypick' | relative_url }})
-  * [Searching for bugs with `git-bisect`]({{'/08-advanced#git-bisect' | relative_url }})
-  * [Forks and merge requests]({{'/08-advanced#fork' | relative_url }})
-    * [Forking]({{'/08-advanced#forking' | relative_url }})
-    * [Merge request]({{'/08-advanced#fork-mr' | relative_url }})
-    * [Closing remarks]({{'/08-advanced#fork-closing' | relative_url }})
-  * [About the `.git` folder]({{'/08-advanced#hooks-excludes' | relative_url }})
-    * [Git hooks]({{'/08-advanced#git-hooks' | relative_url }})
-    * [Local exclusion rules]({{'/08-advanced#local-excludes' | relative_url }})
-  * [CI pipelines: `.gitlab-ci.yml` examples]({{'/08-advanced#gitlab-ci' | relative_url }})
-  * [How to fix a commit to the wrong branch?]({{'/08-advanced#wrong-branch' | relative_url }})
-      * [Moving local commits around]({{'/08-advanced#wrong-branch-local' | relative_url }})
-      * [Moving pushed commits around]({{'/08-advanced#wrong-branch-pushed' | relative_url }})
+* [**Forks and workflows**]({{'/06-forks' | relative_url }})
+  * [***Forks and merge requests***]({{'/06-forks#fork' | relative_url }})
+    * [Forking]({{'/06-forks#forking' | relative_url }})
+    * [Merge request]({{'/06-forks#fork-mr' | relative_url }})
+    * [Closing remarks]({{'/06-forks#fork-closing' | relative_url }})
+  * [***Git workflows***]({{'/06-forks#workflows' | relative_url }})
+    * [Trunk-based workflow]({{'/06-forks#trunk-wf' | relative_url }})
+    * [Gitflow]({{'/06-forks#gitflow' | relative_url }})
+    * [Forkflow]({{'/06-forks#fork-wf' | relative_url }})
+    * [Personal takes]({{'/06-forks#personal-wf' | relative_url }})
+
+* [**Using Git with VSCode**]({{'/07-vscode' | relative_url }})
+    * [Clone a repo]({{'/07-vscode#clone' | relative_url }})
+    * [Stage and commit]({{'/07-vscode#stage' | relative_url }})
+    * [Collaborative development]({{'/07-vscode#collab' | relative_url }})
+    * [Branching and MRs]({{'/07-vscode#branch' | relative_url }})
+
+* [**Extra: basic Git internals**]({{'/08-internals' | relative_url }})
+  * [What's on my computer?]({{'/08-internals#computer' | relative_url }})
+  * [Git objects]({{'/08-internals#objects' | relative_url }})
+  * [History]({{'/08-internals#history' | relative_url }})
+  * [Deltas]({{'/08-internals#deltas' | relative_url }})
+  * [Consequences]({{'/08-internals#consequences' | relative_url }})
+
+* [**Extra: Advanced Git commands and troubleshooting hints**]({{'/09-advanced' | relative_url }})
+  * [Branch management: `git fetch` and `git fetch --prune`]({{'/09-advanced#git-fetch' | relative_url }})
+  * [Cleaning up your local copy]({{'/09-advanced#cleanup' | relative_url }})
+  * [Juggling with branches]({{'/09-advanced#juggling' | relative_url }})
+    * [Rebasing (how to keep up with a source branch)]({{'/09-advanced#rebase' | relative_url }})
+    * [Interactive rebasing (how to clean up your mess before pushing)]({{'/09-advanced#irebase' | relative_url }})
+    * [Cherrypicking (how to move commits around)]({{'/09-advanced#cherrypick' | relative_url }})
+  * [Searching for bugs with `git-bisect`]({{'/09-advanced#git-bisect' | relative_url }})
+    * [Forking]({{'/09-advanced#forking' | relative_url }})
+    * [Merge request]({{'/09-advanced#fork-mr' | relative_url }})
+    * [Closing remarks]({{'/09-advanced#fork-closing' | relative_url }})
+  * [About the `.git` folder]({{'/09-advanced#hooks-excludes' | relative_url }})
+    * [Git hooks]({{'/09-advanced#git-hooks' | relative_url }})
+    * [Local exclusion rules]({{'/09-advanced#local-excludes' | relative_url }})
+  * [CI pipelines: `.gitlab-ci.yml` examples]({{'/09-advanced#gitlab-ci' | relative_url }})
+  * [How to fix a commit to the wrong branch?]({{'/09-advanced#wrong-branch' | relative_url }})
+      * [Moving local commits around]({{'/09-advanced#wrong-branch-local' | relative_url }})
+      * [Moving pushed commits around]({{'/09-advanced#wrong-branch-pushed' | relative_url }})
 
 In any case, [please do not hesitate to contact me](mailto:mathias.malandain@inria.fr) for any (constructive) criticism, requests or suggestions you may have. Enjoy!
 
-- 
GitLab


From c22a448167de945ae90c43d6f1fa58335b2ac84b Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Mon, 2 Sep 2024 13:32:56 +0200
Subject: [PATCH 15/20] Make a few small fixes

---
 .gitignore           | 1 +
 docs/LocalServing.md | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index e065359..4aab0fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ _site
 .DS_Store
 Thumbs.db
 ehthumbs.db
+*.backup
 
 Gemfile.lock
 
diff --git a/docs/LocalServing.md b/docs/LocalServing.md
index d993d45..9873938 100644
--- a/docs/LocalServing.md
+++ b/docs/LocalServing.md
@@ -21,7 +21,7 @@ sudo gem install jekyll bundler
 
 ## Install the website dependencies
 
-Just `cd` into the directory where `Gemfile` is located, then:
+Just `cd` into the root directory of the project (where `Gemfile` is located), then:
 
 ```shell
 bundle install
-- 
GitLab


From 04dbc51f762ba2ef67aaecabbd13ead22024edc4 Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Mon, 2 Sep 2024 13:33:05 +0200
Subject: [PATCH 16/20] Update README

---
 README.md | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index d73add1..70fcefc 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,33 @@
 # Git/GitLab tutorial
 
-A friendly tutorial about Git and Gitlab. Also, jokes. (I apologize.) Hope you enjoy.
+A friendly tutorial about Git and Gitlab. Also, jokes. (I apologize.)
 
-This whole tutorial is licensed under [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1).
+## Why another one?
 
-My huge thanks to Sébastien Gilles for his careful proofreading and insightful advice.
+I definitely know that the Internet is filled to the brim with tutorials on Git and GitLab. I have read, at least partially, tens of them, some incredibly insightful, other ones... not so much. So, why write another one?
+
+The answer is pretty simple, actually: the first sentence here was a white lie. There are not a lot of tutorials on Git and GitLab. Instead, there are a lot of tutorials on Git, *and* a lot of tutorials on GitLab.
+
+I spent way too much time learning Git "the hard way", from the terminal only, then learning GitLab by delving through its official documentation, then experimenting (and making terrible mistakes) until I finally got hold of the whole package.
+
+As I started collaborating with people who did not have the time and/or patience to take on the same journey, the idea of writing a Git **and** GitLab tutorial became self-evident. This is the current state of the result. Hope you enjoy!
+
+## How can I contribute?
+
+Please do not hesitate to contact me via [e-mail](mailto:mathias.malandain@inria.fr) if you have questions and/or constructive criticism. You may also open an issue on the project, and I will be happy to have a chat with you!
+
+For convenience, I will not be accepting MRs that are not related to any open issue. Other MRs are welcomed, with the simplest solution being submitting them from a fork (please grant me writing permissions).
+
+To validate your changes before opening an MR, please follow the instructions provided in the [Local Deployment readme file](docs/LocalServing.md).
+
+## Acknowledgements
+
+My huge, huge, ***HUGE*** thanks to Sébastien Gilles for his careful proofreading and insightful advice.
 
 Powered by [Beautiful Jekyll](https://beautifuljekyll.com) by [Dean Attali](https://deanattali.com), under the MIT license.
 
+## Legal
+
+This whole tutorial is licensed under [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/).
+
 (c) [Mathias Malandain](mathias.malandain@inria.fr), Inria center at Rennes University
\ No newline at end of file
-- 
GitLab


From 7e77a6e8fe880fac4e09a1579ed9d4bf84a1076a Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Mon, 2 Sep 2024 13:37:17 +0200
Subject: [PATCH 17/20] Add section labels in Chapter 6

---
 06-forks.md | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/06-forks.md b/06-forks.md
index 2f57616..1107e5b 100644
--- a/06-forks.md
+++ b/06-forks.md
@@ -104,11 +104,11 @@ This is a nice summary of why your project maybe should not be deleted: the high
 
 Regarding forks, there is a simple rule to be remembered: ***If you delete a private project, its forks will be deleted too.*** If you delete a *public* project, one of its forks will be automatically picked as the new "original project" from which all other forks are forked off.
 
-# Git workflows
+# Git workflows {#workflows}
 
 It is now time to get back to our first concern: which workflow should we use for a project? Indeed, there exist several different workflows for Git projects, and which one you actually implement depends on the needs you have. Let us have a look at the three "main" workflows that emerged, each with its benefits and drawbacks:
 
-## Trunk-based workflow
+## Trunk-based workflow {#trunk-wf}
 
 {: .box-success}
 The **trunk-based workflow** consists in merging frequent, small updates to the `main` branch (the "trunk" of the repo). This is probably the workflow you will be tempted to use when you start using Git, as it is a very simple and intuitive one.
@@ -119,7 +119,7 @@ A trunk-based workflow can be very efficient for [DevOps](https://www.atlassian.
 
 A small change to this workflow consists in updating a `develop` branch on a regular basis, while the `main` branch will only get updated once in a while, typically when everything is working ("no test should ever fail on the `main` branch"). This approach, sometimes referred to as **feature branching**, is arguably "cleaner" but suffers from the same drawbacks. However, if you push it a bit further, you can get to...
 
-## Gitflow
+## Gitflow {#gitflow}
 
 {: .box-success}
 The **Gitflow** is a strict branching model centered on releases. It typically relies on two "main" branches, namely a `develop` branch and a `main` branch that only receives commits from `develop`, and adds release branches on which only release-ready versions of the codebase will be pushed, and several feature and hotfix branches with clearly-defined roles.
@@ -140,7 +140,7 @@ There is no "magic trick" in Gitflow, no new commands to master, no new tools to
 
 However, merging a feature branch in `develop` requires more effort and caution than in a trunk-based workflow, as there are more commits and larger changes in feature branches (with the risk of having to handle more conflicts along the way). The `hotfix-*` branches also increase complexity and require even more careful planning. If your software is not explicitly versioned, with several versions (typically, the last X versions) that need to get maintained/patched if needed, Gitflow is likely too heavy for your needs.
 
-## Forkflow
+## Forkflow {#fork-wf}
 
 {: .box-success}
 The **forkflow**, more commonly named **forking workflow**, consists in letting any developer or developing team fork a repository and open MRs from the fork to the original project.
@@ -151,7 +151,7 @@ The forkflow is an ideal workflow for open-source projects, where possible contr
 
 In an active project with a lot of contributors, the history of the project will soon get overloaded with development branches. Even when enforcing naming conventions (none of which is a perfect solution) for branches, this can quickly become a mess. This will not happen with forks, so that the important branches of the original project will have a clearer history. As for the CI, it comes packaged with the rest of the project when you fork it! Just set a runner on your fork and you're good to go.
 
-# Personal takes
+# Personal takes {#personal-wf}
 
 In practice, as a project gets larger, I believe that you may very well "reinvent the wheel" one step at a time, by reorganizing your workflow once in a while, so as to address the development management problems when they are encountered... until you reach a workflow that actually looks incredibly similar to Gitflow.
 
-- 
GitLab


From 4634cded0e346d400c1954b3c122821b1f4b067c Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Mon, 2 Sep 2024 13:46:05 +0200
Subject: [PATCH 18/20] Add small piece of info about personal namespaces

---
 02-creating-projects.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/02-creating-projects.md b/02-creating-projects.md
index ee66750..324f2d0 100644
--- a/02-creating-projects.md
+++ b/02-creating-projects.md
@@ -104,6 +104,8 @@ Remember the analogy with folders and subfolders? Yup, here we go again:
 
 In other words, you can create huge tree-shaped architectures of projects. I do not know of any limit for the number of possible subgroups in a group; if you happen to reach it, please (i) tell me, and (ii) sort your life out, this is way too many subgroups, *what are you doing*--
 
+(FYI, there is no creating subgroups in your personal namespace.)
+
 As for access, roles and visibility settings, you probably already guessed where we are going. Access can be granted to groups, subgroups or individual projects, and the rules for inheritance are as stated above. Let us highlight this:
 
 {: .box-success}
-- 
GitLab


From c7203ea509dff8d8dbbca3af56e4131fdbd15f81 Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Thu, 5 Sep 2024 16:04:04 +0200
Subject: [PATCH 19/20] Fix a lot of details up to (and incl.) Section 5

---
 00-what-why.md           |   6 +-
 01-setup.md              |  24 ++---
 02-creating-projects.md  |  34 ++++---
 03-linear-git-project.md |  44 ++++-----
 04-branches-issues.md    | 190 ++++++++++++++++++++++-----------------
 05-good-practices.md     |  76 +++++++++-------
 06-forks.md              |   2 +-
 09-advanced.md           |   6 +-
 index.md                 |  15 ++++
 9 files changed, 220 insertions(+), 177 deletions(-)

diff --git a/00-what-why.md b/00-what-why.md
index 3d2d306..ae6a78e 100644
--- a/00-what-why.md
+++ b/00-what-why.md
@@ -19,7 +19,7 @@ Among its advantages, you should remember that Git:
 This might look like complete overkill for the development of researchware, but it is very useful in this context for several reasons:
 
 * It makes it possible to ***control what is merged in the main version of the codebase*** (and ensure that this main version always works, as we shall see).
-* It provides a very convenient ***tagging system***, so that the exact version of the codebase that was used for providing numerical results in scientific articles can be easily retrieved (and you may even go further by providing stable exxecution environments...).
+* It provides a very convenient ***tagging system***, so that the exact version of the codebase that was used for providing numerical results in scientific articles can be easily retrieved (and you may even go further by providing stable execution environments...).
 * The use of ***Git tools*** such as GitLab makes it possible to ensure long-term backups of codes developed by permanent and non-permanent members alike.
 
 # GitLab {#gitlab}
@@ -29,9 +29,9 @@ GitLab is a **software development platform** that relies on Git for providing h
 
 A lot of features provided by GitLab are incredibly useful on a day-to-day basis, among others:
 
-* A very convenient ***issue and bug tracking*** for clear and efficient communication and collaboration;
+* A very convenient ***issue and bug tracking*** system for clear and efficient communication and collaboration;
 * A ***fine handling of permissions and code review***: you can control who can write to each branch of the project, and under which conditions a feature can be merged into the main version of the codebase (which tests should be run, how many people should review and approve the changes, and so on);
-* Easy-to-use ***CI/CD pipelines***: Continuous Integration makes it possible to thoroughly test your code before merging it in the main version, and Continuous Delivery provides you with the possibility to automatically deploy your software for your collaborators to use
+* Easy-to-use ***CI/CD pipelines***: Continuous Integration makes it possible to thoroughly test your code before merging it in the main version, and Continuous Delivery provides you with the possibility to automatically deploy your software for your collaborators to use.
 
 A lot of other Git-based development platforms exist (GitHub, Gitea, Bitbucket, to name a few), but it so happens that Inria hosts two instances of GitLab, at `gitlab.inria.fr` and `gitlab-int.inria.fr`. Everything on these instances is hosted on Inria's own servers, which guarantees that your code is safe.
 
diff --git a/01-setup.md b/01-setup.md
index 380df69..b4bef74 100644
--- a/01-setup.md
+++ b/01-setup.md
@@ -64,7 +64,7 @@ sudo port install git
 
 If you really love your standalone installers, both 32-bit and 64-bit installers are provided [here](https://git-scm.com/download/win).
 
-There is another option that I would warmly recommend, as it will likely save you several other times in the future: [Scoop](https://scoop.sh/#/) is a package manager that you can very easily install and run from the PowerShell, and it installs packages without requiring specific permissions (i.e., no permission popup windows and no inputting passwords every minute). The website provides you with simple instructions for installation; basically just input these two commands in a PowerShell terminal:
+There is another option that I would warmly recommend, as it will likely save your life a couple more times in the future: [Scoop](https://scoop.sh/#/) is a package manager that you can very easily install and run from the PowerShell, and it installs packages without requiring specific permissions (i.e., no permission popup windows and no inputting passwords every minute). The website provides you with simple instructions for installation; basically just input these two commands in a PowerShell terminal:
 
 ```shell
 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
@@ -79,7 +79,7 @@ scoop install git
 
 ## Local configuration {#git-config}
 
-Once Git is installed, you may configure it as you want. There are [a lot of options](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration), most of which will not make sense before we delve further into Git. The only thing that is necessary is telling Git your name and e-mail address; this information will not be spread on the Internet and/or sold to companies (this is not Honey!), it will just be written in the metadata of your *commits* (we will be talking about these [later on]({{'/03-linear-git-project#repo' | relative_url }})) so that your collaborators know who contributed which piece of code.
+Once Git is installed, you may configure it as you want. There are [a lot of options](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration), most of which will not make sense before we delve further into Git. The only thing that is required is telling Git your name and e-mail address; this information will not be spread on the Internet and/or sold to companies (this is not [Honey](https://www.joinhoney.com/fr/)!), it will just be written in the metadata of your *commits* (we will be talking about these [later on]({{'/03-linear-git-project#repo' | relative_url }})) so that your collaborators know who contributed which piece of code.
 
 Only two commands are needed from the terminal (or the PowerShell terminal for Windows users):
 
@@ -88,8 +88,8 @@ git config --global user.name "Your Name"
 git config --global user.email "youremail@yourdomain.com"
 ```
 
-{: .box-info}
-Once again, [there are a lot more options to uncover](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration), so that you can customize your Git experience. Most of the options are purely local, including, but not limited to, changing the interface colors, telling Git which tool you want to use for merging different versions of the same file (more on that later!), autoconverting newfile characters (useful for collaborations between Mac/Linux and Windows users)... You can either access those by using `git config` commands, or by directly editing a specific file in a given Git project.
+{: .box-note}
+Once again, [there are a lot more options to uncover](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration), so that you can customize your Git experience. Most of the options are purely local, including, but not limited to, changing the interface colors, telling Git which tool you want to use for merging different versions of the same file ([more on that later]({{'/03-linear-git-project#conflict' | relative_url }})), autoconverting newfile characters (useful for collaborations between Mac/Linux and Windows users)... You can either access those by using `git config` commands, or by directly editing a specific file in a given Git project.
 
 Great, you have Git on your computer and it's good to go!
 
@@ -103,7 +103,7 @@ From now on, every use of the word "GitLab" refers to the `gitlab.inria.fr` inst
 This one is easy:
 
 * Go to `gitlab.inria.fr` with your favorite Web browser (even if it is Safari, Chrome or Microsoft Edge, we will let it slide).
-* Connect with ILDAP, using your usual CAS username-password pair.
+* Connect with iLDAP, using your usual CAS username-password pair.
 * Well, that's it. Welcome to GitLab. You should be welcomed with the list of projects hosted on GitLab that you have access to, and you can filter out the ones you did not create yourself by clicking on "Personal". We shall explore the interface pretty soon.
 
 But now, there is a technical hurdle that we should be dealing with. You see, you do not need to log on to the website every time you want to work on a project hosted on GitLab (if this were the case, no one would bother using it). Instead, you "pull" a local copy, on your computer, that you can edit as you wish, and when you are satisfied with your changes, you can "push" the results back. Not everyone can pull a project to their computer, and even less people can push their changes. So, when your computer asks GitLab to pull or push some code, how does GitLab check that you are allowed to do this?
@@ -126,11 +126,11 @@ If you already have an SSH key that you want to use, you can (of course) skip th
 
 * If you're on Windows: Go to `Settings > App > Optional features` and check that the OpenSSH Client is installed. If it is not, click the `Add a feature` / `+` button, scroll down to OpenSSH Client, and click `Install`. (If you're on Linux or MacOS, you already have it installed.)
 
-* From the Terminal (Linux/MacOS) or the PowerShell (Windows), run either `ssh-keygen -t ed25519` or `ssh-keygen -t rsa -b 4096` (Ed25519 and RSA are two different cryptosystems: Ed25519 is considered safer, but the additional parameter in the second command tells the tool to create a 4096-bit key, which is basically [unbreakable in the foreseeable future](https://security.stackexchange.com/questions/90077/ssh-key-ed25519-vs-rsa)).
+* From the Terminal (Linux/MacOS) or the PowerShell (Windows), run either `ssh-keygen -t ed25519` or `ssh-keygen -t rsa -b 4096` (Ed25519 and RSA are two different cryptosystems: Ed25519 is considered safer, but the additional parameter in the second command tells the tool to create a 4096-bit RSA key, which is basically [unbreakable in the foreseeable future](https://security.stackexchange.com/questions/90077/ssh-key-ed25519-vs-rsa)).
 
     * When asked for the full path of the file in which the key should be saved, just press Enter to keep the default path.
-    * When prompted, enter (twice) a passphrase for your key. You technically can just press Enter so as not to set any passphrase, but this additional layer of security is strongly recommended. (By default, you will have to type this passphrase every time a command such as `git fetch`, `git pull`, `git push`... is run. However, there is a way to alleviate this: see below.)
-    * Done! You are told where you public and private keys are, plus a long string of seemingly random characters and a weird abstract ASCII art. You may totally ignore these last two things.
+    * When prompted, enter (twice) a passphrase for your key. You technically can just press Enter so as not to set any passphrase, but this additional layer of security is strongly recommended. (By default, you will have to type this passphrase every time a command such as `git fetch`, `git pull`, `git push`... is run. However, there is a way to alleviate this, as we shall see in a few seconds.)
+    * Done! You are told where your public and private keys are, plus a long string of seemingly random characters and a weird abstract ASCII art. You may totally ignore these last two things.
     * If you are afraid about this "having-to-type-your-huge-passphrase-100-times-a-day" thing, good news are coming your way. What if you were only asked your passphrase once per session? Pretty simple: just type `ssh-add ~/.ssh/<name-of-the-private-key>` (where the name of the private key should be either `id_rsa` or `id_ed25519`). This will definitely make your life easier. You may now say "good night" to your private key: this should be the last time you explicitly use it.
 
 ### Giving your public key to GitLab
@@ -138,9 +138,9 @@ If you already have an SSH key that you want to use, you can (of course) skip th
 * Check the contents of your public key (the filename ends with `.pub`, and the whole path to this file is in the output of `ssh-keygen`): you may browse the folder in which it was saved and open the file with any text editor, or display it in your terminal/shell using a command like `more`, or `less`, or `cat`. The key should begin with `ssh-rsa` or `ssh-ed25519` and end with something like `<your_username>@<the_name_of_your_computer>`. Copy the whole think. (The example shown below is an SSH key that I never used and has been erased, for safety reasons.)
 
 ![](../assets/img/01-setup/ssh-keygen.jpg){: .mx-auto.d-block :}
-> Folder `/Users/mmalanda` is my home folder, also known as `~` by the terminal. 
+> Folder `/Users/mmalanda` is my home folder, also known as `~` by the terminal. My public key is the whole line that starts with `ssh-ed25519` and ends with `mmalanda@sparemac-az`.
 
-* Log on to GitLab (that's still `gitlab.inria.fr`), click on the round picture on the upper-right corner of the window, then "Edit profile".
+* Log on to GitLab (that's still `gitlab.inria.fr`), click on the round picture on the upper-left corner, then "Edit profile".
 
 ![](../assets/img/01-setup/ssh-key-1.jpg){: .mx-auto.d-block :}
 
@@ -154,7 +154,7 @@ If you already have an SSH key that you want to use, you can (of course) skip th
 
 * Click "Add key", *et voilà*.
 
-* Later on, you will just have to "tell" GitLab that SSH authentication is what you want, instead of HTTPS authentication: this is done when you initialize a fresh Git project or when you clone an already existing project. We will come back to it.
+* Later on, you will just have to "tell" GitLab that SSH authentication is what you want, instead of HTTPS authentication: as we shall see pretty soon, this is done when you [initialize a fresh Git project]({{'/02-creating-projects' | relative_url }}) or when you [clone an existing project]({{'/03-linear-git-project#clone' | relative_url }}). We will come back to it.
 
 For the moment, everything is set up. Breathe in. Take a few seconds to appreciate how far you have gone and reconnect with your senses.
 
@@ -165,7 +165,7 @@ Breathe out.
 {: .box-success}
 **VSCode** is a very good code editor with thousands of extensions, including parsers and linters for pretty much every programming language you can think of. It offers a lot of features with a pretty simple and readable interface.
 
-VSCode is by far the most used developer environment tool, with nearly three quarters of respondents to the 2023 Stack Overflow Developer Survey declaring that they use it. Later on, this tutorial will show you how to use Git from VSCode.
+VSCode is by far the most used developer environment tool, with nearly three quarters of respondents to the [2024 Stack Overflow Developer Survey](https://survey.stackoverflow.co/2024/technology#1-integrated-development-environment) declaring that they use it. Later on, this tutorial will show you [how to use Git from VSCode]({{'/07-vscode' | relative_url }}).
 
 For the moment, let us configure VSCode for the use of Git... or maybe not: **VSCode knows Git**.
 
diff --git a/02-creating-projects.md b/02-creating-projects.md
index 324f2d0..54f6672 100644
--- a/02-creating-projects.md
+++ b/02-creating-projects.md
@@ -16,7 +16,7 @@ We will be going through both options, and see various (essentially equivalent)
 {: .box-success}
 A **project** is pretty much what you think it is. All relevant files for a given software development project (as a first approximation, the contents of the main folder in which you have all the relevant files) are handled together in a project.
 
-As a result, the different versions that will be "remembered" by Git are all snapshots of the entire project. (The way Git actually handles them is way smarter than just storing complete copies of the whole project, so do not worry about storage space. We shall talk about this later on.)
+As a result, the different versions that will be "remembered" by Git are all snapshots of the entire project. (The way Git actually handles them is [way smarter]({{'/08-internals#deltas' | relative_url }}) than just storing complete copies of the whole project, so do not worry about storage space.)
 
 Creating a project on GitLab is as simple as clicking a button:
 
@@ -39,7 +39,7 @@ There are a few things to unpack there:
 {: .box-note}
 **Spoiler alert:** The vast majority of projects are created as private projects. When in doubt, make your project private.
 
-* **Initialize repository with a README:** I would advise ***never*** unchecking this box. All it does is create a `README.md` file at the root of the project, and this file will be displayed in all its rendered glory on the corresponding web page. As soon as the project will be accessed by anyone other than yourself, you will want to write some stuff in this file: basic description first, but then, maybe, setup instructions, a short tutorial/example, links to documentation, copyright information, etc. Common practices include adding a few more Markdown files alongside this one:
+* **Initialize repository with a README:** When creating a fresh empty project, I would advise never unchecking this box. All it does is create a `README.md` file at the root of the project, and this file will be displayed in all its rendered glory on the corresponding web page. As soon as the project will be accessed by anyone other than yourself, you will want to write some stuff in this file: basic description first, but then, maybe, setup instructions, a short tutorial/example, links to documentation, copyright information, etc. Common practices include adding a few more Markdown files alongside this one:
 
     * `LICENSE.md` where the complete text of the software license is pasted,
     * `CHANGELOG.md` where, huh, the change log is provided, and
@@ -53,7 +53,7 @@ But wait! Before we reach this page, we need to know **where** to create the pro
 
 # Groups {#groups}
 
-GitLab provides you with a *personal namespace*, based on your username. It is the most obvious solution when you want to create a project, but the fact that it is *personal* probably means that it is not the best idea to put everything in here. Plus, well... it would not be a great idea either to put every project in the same place anyways, would it? There are also a lot of limitations on what you can do there, including a strict limit on the number of projects you can create inside it.
+GitLab provides you with a *personal namespace*, based on your username. It is the most obvious solution when you want to create a project, but the fact that it is *personal* probably means that it is not the best idea to put everything in here. Also, well... it would not be a great idea either to put every project in the same place anyways, would it? There are also a lot of limitations on what you can do there, including a strict limit on the number of projects you can create inside it.
 
 So... What are our alternatives?
 
@@ -64,19 +64,17 @@ Yeah, exactly.
 {: .box-success}
 **Groups** are exactly what it says on the label. If you have (or *will* have in the foreseeable future) several related projects, you should create a group for them. You can think of a group as a folder for projects... with a sophisticated lock.
 
-"Hey!", you say, "There was this thing about members of the group having automatic access to all projects in the group, right? Why would I want to do that?"
-
-Glad you asked. See, it is true that all members to a group have access to every project in this group: this is what [the GitLab documentation](https://docs.gitlab.com/ee/user/project/members/) calls "inherited membership". With inherited membership, you cannot choose to remove access to a single project: you have to remove the member from the whole group.
+You can then invite new members to a group, and they will automatically get access to every project in this group: this is what [the GitLab documentation](https://docs.gitlab.com/ee/user/project/members/) calls "inherited membership". With inherited membership, you cannot choose to remove access to a single project: you have to remove the member from the whole group.
 
 However, you can also add members to individual projects without adding them to the whole group! This is a pretty convenient solution in several contexts, actually:
 
 * For dealing with all pieces of software that are developed in the context of a **large collaborative project**, create a group with a few members (the coordinator(s) + one or two admins sworn to secrecy), then grant access to individual projects as required and carefully set roles for every project (more on that later).
-* For gathering all **building bricks of a software suite**, just create each "brick" as a project, all inside the same group with the same members: for each project, each member inherits the role they have in the group itself, so that you only have to deal with who does what *once and for all*.
+* For gathering all **building bricks of a software suite** that is developed and maintained as a whole by the same people, just create each "brick" as a project, all inside the same group with the same members: for each project, each member inherits the role they have in the group itself, so that you only have to deal with who does what *once and for all*.
 
 Time for a short summary in a nice green box, don't you think?
 
 {: .box-success}
-**Group members** will be given the same role (or permissions, if you will) in all projects in the group. The administrator of the group can then add **project members**: they will be added to projects independently, possibly with different roles in different projects, and they will not be able to see the remaining projects in the group.
+**Group members** will be given the same role (or permissions, if you will) in all projects in the group. The administrator can then add **project members**: they will be added to projects independently, possibly with different roles in different projects, and they will not be able to see the remaining private projects in the group.
 
 "Talking about seeing stuff", you say, "what about project visibility? Is group visibility inherited by all projects?" That's a solid question, and the answer is no, thank Gosh! What if you are collaborating with other people for writing both open-source *and* proprietary code? In such cases, the benefits of creating groups would just collapse.
 
@@ -89,7 +87,7 @@ Remember that there are three visibility levels: *private*, *internal* and *publ
 
 As a corollary, if at least one of the projects has to be public, you have to create a public group, but other projects can be set to internal, or even private. (People with no access to your private projects will not even be able to know they exist in the first place.)
 
-To sum up, as you go down the chain (from groups to projects), objects can only have their visibility reduced, and members can only have their permissions raised. If you only remember one thing about visibility and permissions, there it is.
+To sum up, **as you go down the chain (from groups to projects), objects can only have their visibility reduced, and members can only have their permissions raised**. If you only remember one thing about visibility and permissions, there it is.
 
 And it will be our guideline for the next step, because... Well, what if I work on a huge project, with 100+ pieces of software developed by various members? A single group containing a bazillion projects will not be convenient for anyone.
 
@@ -104,9 +102,9 @@ Remember the analogy with folders and subfolders? Yup, here we go again:
 
 In other words, you can create huge tree-shaped architectures of projects. I do not know of any limit for the number of possible subgroups in a group; if you happen to reach it, please (i) tell me, and (ii) sort your life out, this is way too many subgroups, *what are you doing*--
 
-(FYI, there is no creating subgroups in your personal namespace.)
+(FYI, there is no creating subgroups in your personal namespace: if you need any sort of hierarchical structure for your projects, even if they are personal, your personal namespace is not fit, and you should create a private group instead.)
 
-As for access, roles and visibility settings, you probably already guessed where we are going. Access can be granted to groups, subgroups or individual projects, and the rules for inheritance are as stated above. Let us highlight this:
+As for access, roles and visibility settings, you probably already guessed where we are going. Access can be granted to groups, subgroups or individual projects, and the rules for inheritance are as stated above. Let us highlight this once again:
 
 {: .box-success}
 As you go down the hierarchical tree (from group to subgroups to projects), **objects can only have their visibility reduced, and members can only have their role raised**.
@@ -119,9 +117,9 @@ Sounds pretty abstract, right? Well, let us talk about roles.
 
 This is the part where I lie to your face: **There are 5 different member roles on GitLab.** `</lie>`, I promise.
 
-This is a lie, because a 6th role was added, called "Minimal Access". However, this role cannot be granted at any level and, at the time of writing, [has been buggy for more than two years](https://gitlab.com/gitlab-org/gitlab/-/issues/267996). So, for all intents and purposes, there are 5 different member roles on GitLab. I will try my best to tell you, in less than 500 words, what each of those means. Just scroll down to the next green box if this is too much information for you at this stage, no offence taken.
+This is a lie, because a 6th role was added, called "Minimal Access". However, this role cannot be granted at any level and, at the time of writing, [has been buggy for more than three years](https://gitlab.com/gitlab-org/gitlab/-/issues/267996) (the official documentation even provides workarounds now!). So, for all intents and purposes, there are 5 different member roles on GitLab. I will try my best to tell you, in less than 500 words, what each of those means. Just scroll down to the next green box if this is too much information for you at this stage, no offence taken.
 
-* **Guest:** On instances other than `gitlab.com`, a guest on a private project cannot see or download the code. They can basically leave comments, open issues (which is the intended way to report a bug/incident *or request a feature*, so, yeah, kind of a misnomer), and view some very basic metrics. For all intents and purposes, guests are users that can offer feedback. (The guest role does not exist for public projects, because everyone with the right URL has these rights on a public project.)
+* **Guest:** On instances other than `gitlab.com`, a guest on a private project cannot see or download the code. They can basically leave comments, [open issues]({{'/04-branches-issues#issues' | relative_url }}) (which is the intended way to report a bug/incident *or request a feature*, so, yeah, kind of a misnomer), and view some very basic metrics. For all intents and purposes, guests are users that can offer feedback. (The guest role does not exist for public projects, because everyone with the right URL has these rights on a public project.)
 * **Reporter:** A reporter has all guest permissions, access to the codebase and the project metrics that are provided by GitLab, plus a few permissions related to issues. This list of permissions, along with the name itself, makes me think that reporters are typically non-developers whose main job is to extract basic information about project activity and turn it into colorful graphs to be shown to suit-and-tie executives during bimonthly project follow-up meetings.
 * **Developer:** The label here is pretty clear, right? Project developers are the people who write and review code. The "blood, sweat and energy drinks" tier. The larger the project, the more members with this role. (Group developers can also create fresh projects in the group.) However, developers have to play by the rules that are set by the maintainers. To make it clearer, let us see what maintainers can do that developers cannot.
 * **Maintainer:** Not only do maintainers have all the permissions that developers have, but they also choose who the developers are, and they draw the line between what any developer can do and what only *they* can do. Adding or removing project members? Their job. (Group members? Nope, only the owner of a group can manage its members.) Specific conditions for code changes to be propagated into some branches? They decide, they enforce. Setting up a robust pipeline for automatic code testing? Their duty. Has the time come for a new release? I don't know, ask *them*. But, you know the saying about great powers and responsibilities. (Was that Jesus Christ or Ulysses S. Grant?) Maintainers are the ones responsible for releasing software that works, for managing issues and incidents, and sometimes for applying ten independent patches to the same codebase in a single day without opening a black hole somewhere in Nevada.
@@ -195,15 +193,15 @@ I am gonna keep my multigrain baguette recipe private for the moment (visibility
 
 # Pushing existing code on GitLab {#push-code}
 
-There is an alternative to creating empty project, and that is taking existing code that you have on your computer and turning it into a GitLab project. There are many cases that lead to turning local folders into shared projects, a vast majority of which are actually cases of "we should have done it before". Once again, even if you are working by yourself on a piece of code, making it a GitLab project is a good idea for several reasons (backups, complete change history, archiving...).
+There is an alternative to creating an empty project, and that is taking existing code that you have on your computer and turning it into a GitLab project. There are many cases that lead to turning local folders into shared projects, a vast majority of which are actually cases of "we should have done it before". Once again, even if you are working by yourself on a piece of code, making it a GitLab project is a good idea for several reasons (backups, complete change history, archiving...).
 
-Assume that, somewhere (**anywhere**) on your computer, you have some folder, let's say a folder called `cornbread` (why not?), that you want to turn into a GitLab project.
+Assume that, somewhere (**anywhere**) on your computer, you have some folder, let's say a folder called `cornbread` (why not?), only containing a `README.md` for now, that you want to turn into a GitLab project.
 
 We would indeed like to have this project alongside `multigrain-baguette` on GitLab, that is, in the same subgroup `bread`. Counter-intuitively, we will first have to create an empty project `cornbread`:
 
 ![](../assets/img/02-creating-projects/project-from-local-2.jpg){: .mx-auto.d-block :}
 
-Blue button again, and pick the settings you want... but, for convenience, uncheck the "Initialize repository with a README" option this time:
+Blue button again, and pick the settings you want... but, for convenience, **uncheck** the "Initialize repository with a README" option this time:
 
 ![](../assets/img/02-creating-projects/project-from-local-3.jpg){: .mx-auto.d-block :}
 
@@ -217,7 +215,7 @@ This is exactly what you want! *If you want to push **all** the contents of the
 **Think about cleaning up your project before pushing it:** you should not push temporary files, local configuration files, and so on. If there are specific files or subfolders that you do not want to push (the `build` or `_build` folders are typical examples), you can choose what you actually want to push. Just replace command `git add .` with several commands of the form `git add path/to/subfolder` or `git add path/to/file`. While the former tells Git to push the whole directory (this is what `.` means), the latter specifies which subfolders and files should be tracked. We will see later on how to [prevent specific files from being added]({{'/05-good-practices#gitignore' | relative_url }}).
 
 {: .box-warning}
-If the `-initial-branch` option is not recognized, you have a version of Git that is too old (maybe you installed it a few years ago and forgot to update it). Just update your Git installation and retry.
+If the `-initial-branch` option is not recognized, you have a version of Git that is too old (maybe you installed it a few years ago and forgot to update it). Just update your Git installation (the same steps that are used for [a fresh install]({{'/01-setup#git' | relative_url }}) should work) and retry.
 
 Understanding these lines requires knowledge about how Git works, including some dirty details about what Git does behind the curtains. No delving into it right now, but if you're curious:
 
@@ -225,7 +223,7 @@ Understanding these lines requires knowledge about how Git works, including some
 In short, the Git commands given here basically amount to the following:
 * setup the current directory so that it is "Git-ready", and ensure that the name of the default branch is the right one (older projects might have `master` as the name of their default branch, but this was changed in 2020);
 * tell Git that this local directory should be linked to the one at the given address (it is exactly the one that is provided to you by *Clone → Clone with SSH* on the project page; **do not use the `https` address instead**: this would require you to use HTTPS authentication on this project, which is way more cumbersome);
-* take all the current contents of your local folder (read the box below before continuing) and push them to the GitLab project (plus, the `-u` option tells Git that the remote project to which you just pushed will indeed be the default remote).
+* take all the current contents of your local folder (or parts of the contents if you are using one or several `git add some/path` commands instead) and push them to the GitLab project (plus, the `-u` option tells Git that the remote project to which you just pushed will indeed be the default remote).
 </div>
 
 Done! Refresh the webpage for your project, and this is what you will see:
diff --git a/03-linear-git-project.md b/03-linear-git-project.md
index fdf2c86..f814131 100644
--- a/03-linear-git-project.md
+++ b/03-linear-git-project.md
@@ -10,18 +10,18 @@ However, I know for a fact that, without a proper understanding on the basics, y
 
 What follows is my best attempt, to date, at explaining everything you need to know to use "basic" Git without fear, and nothing more. We will be working on our project "the old-fashioned way", by editing our files with whichever tool we want to use, and directly typing our Git commands from a terminal.
 
-Later on, once we know how Git works, we shall see how the "version control" panel in VSCode can help us. (Other tools exist that can help you with Git; I chose to only show you VSCode because (i) it is an IDE that knows Git, meaning that you can edit your local copy *and* handle version control with a single software, and (ii) it is the most widespread development environment by far, arguably for a lot of good reasons.)
+Later on, once we know how Git works, we shall see [how the "version control" panel in VSCode can help us]({{'/07-vscode' | relative_url }}). (Other tools exist that can help you with Git; I chose to only show you VSCode because (i) it is an IDE that knows Git, meaning that you can edit your local copy *and* handle version control with a single software, and (ii) it is the most widespread development environment by far, arguably for a lot of good reasons.)
 
 # Preamble {#preamble}
 
-The nice thing about Git is that **you will spend 95% of your time working on a Git project as if it was just a folder on your machine**. In a way, it is *your* code, and you can edit it like you would any document or code that you are keeping to yourself. You will be working on a local copy, with all files and folders of the project on your own computer.
+The nice thing about Git is that **you will spend 95% of your time working on a Git project as if it were just a folder on your machine**. In a way, it is *your* code, and you can edit it like you would any document or code that you are keeping to yourself. You will be working on a local copy, with all files and folders of the project on your own computer. This page is mainly about how to exchange data with the project on the server (pushing your own changes to the project, pulling changes in your working copy, handling conflicts between the codebase on your computer and the one on the server, and so on).
 
 {: .box-success}
 In the Git terminology, the project (on the server) is called the **repository** (or **repo** for short), and the local copy is called the **working copy**.
 
 # Cloning a project {#clone}
 
-The first thing I have to do, before working on the code, is to **clone** the repo (unless, of course, I created the project by [uploading local files]({{'/02-creating-projects#push-code' | relative_url }}). In a nutshell:
+The first thing I have to do, before working on the code, is to **clone** the repo (unless, of course, I created the project by [uploading local files]({{'/02-creating-projects#push-code' | relative_url }})). In a nutshell:
 
 {: .box-success}
 **Cloning a repo** is the act of creating a working copy of this repo on your machine. The corresponding command is `git clone`.
@@ -30,7 +30,7 @@ Of course, just typing `git clone` in your terminal will give you an error: "Wha
 
 ![](../assets/img/03-linear-git-project/A-cloning/project-clone.jpg){: .mx-auto.d-block :}
 
-We went through the (reasonable) hassle of configuring SSH authentication for GitLab, why wouldn't we reap the benefits? The contents of the text box below "Clone with SSH" (it will always start with `git@`) is our missing argument for `git clone`. Open a terminal, `cd` into the folder you want to clone into, and put the pieces together; in this case, the full command would be
+We went through the (reasonable) hassle of [configuring SSH authentication for GitLab]({{'/01-setup#gitlab' | relative_url }}), why wouldn't we reap the benefits? The contents of the text box below "Clone with SSH" (it will always start with `git@`) is our missing argument for `git clone`. Open a terminal, `cd` into the folder you want to clone into, and put the pieces together; in this case, the full command would be
 
 ```shell
 git clone git@gitlab.inria.fr:bakery/bread/multigrain-baguette.git
@@ -40,23 +40,23 @@ Type your SSH key passphrase when asked, then wait for the cloning operation to
 
 ![](../assets/img/03-linear-git-project/A-cloning/local-1.jpg){: .mx-auto.d-block :}
 
-The `.git` folder is hidden by default (if you do not see it in your working copy, do not worry, you still have it). This is where the magic actually happens, but we are not delving into this before getting the grip of how to use Git. For the moment, you may assume (for convenience) that *there is no reason for you to edit anything in the `.git` folder*. For all intents and purposes, the whole project is a `README.md` file and nothing more.
+The `.git` folder is hidden by default (if you do not see it in your working copy, do not worry, you still have it). [This is where the magic actually happens]({{'/08-internals' | relative_url }}), but we are not delving into this before getting a grip on how to use Git. For the moment, you may assume (for convenience) that *there is no reason for you to edit anything in the `.git` folder*. For all intents and purposes, the whole project is a `README.md` file and nothing more.
 
 {: .box-note}
 This is kind of a white lie: there are a few very good, but a bit more advanced, reasons to change the contents of this folder. You may learn more about this in [this additional content]({{'/09-advanced#hooks-excludes' | relative_url }}).
 
 From now on, Git will remember where my folder came from. As long as I am working in the folder (or a subfolder) of the working copy, Git knows to which repository it is linked. I can now, whenever I want, fetch the changes that were submitted by my collaborators, change the code, and decide whether I want to push all or some of my changes back to the repo (thus adding my own brick to the repo's history). Okay, simple enough.
 
-However, this basic description is already lacking something. Something that you may not be told from day 1, and that will prevent you from understanding anything from the online documentation when you will (inevitably) have to check it. Let's jump on the stage.
+However, this basic description is already lacking something. Something that you may not be told from day 1, and that will prevent you from understanding anything from the online documentation when you will (inevitably) have to check it. Let's jump on stage.
 
 # Repository, staging area, working copy {#repo}
 
-Assume that you are working on a nice and simple project, that evolves incrementally. People kind of take turns making changes to the code, and the history of the project, as Git sees it, is just a nice straight line from one version to the next. (Enjoy living in this ideal world: this will not last.)
+Assume that you are working on a nice and simple project, that evolves incrementally. People kind of take turns making changes to the code, and the history of the project, as Git sees it, is just a nice straight line from one version to the next. (Enjoy living in this ideal world: [this will not last]({{'/03-linear-git-project#fetch-pull' | relative_url }}).
 
 Today, it is your turn to make changes to the code. This is what you do:
 
 * You **fetch** (or **pull**) the most recent version of the codebase on your computer, from the server.
-* You work on the code, 100% locally: you change the contents of some files, create one or two fresh files for new features (or just because some of your modules became bloated and you wanted to refactor a bit), maybe remove a few files here and there, all of this on your working copy. You use your favorite editor or IDE to get work done, save your changes regularly (with Ctrl-S or `:w` or whatever floats your boat), without a care in the world.
+* You work on the code, 100% locally: you change the contents of some files, create one or two fresh files for new features (or just because [some of your modules became bloated]({{'/05-good-practices#practices' | relative_url }}) and you wanted to refactor a bit), maybe remove a few files here and there, all of this on your working copy. You use your favorite editor or IDE to get work done, save your changes regularly (with Ctrl-S or `:w` or whatever floats your boat), without a care in the world.
 * Finally, you check that everything you did actually works, clean up a bit, and **push** your work to the server.
 
 Pretty simple, right? Actually, the last step is a bit more involved. See, there is the possibility that you worked on two different things in the same code today, and maybe you want to make it clear in the public history of the repository. Hence, you want to pick part of your changes and bundle them together, then pick the remaining changes and bundle *them* together, and, finally, push these two nice boxes, wrapped in beautiful wrapping paper, to the repo, where everyone can see (and take) them.
@@ -73,8 +73,8 @@ After my work session, I will ask for information about the **status** of the pr
 
 ![](../assets/img/03-linear-git-project/A-cloning/local-2.jpg){: .mx-auto.d-block :}
 
-* For now, there is only one branch, called `main`: it is the one created by default (it used to be called `master`, and a lot of online tutorials were not updated, so be cautious). We shall see later how to deal with more than one branch.
-* Also, my local branch seems to be up to date with the `main` branch on `origin`, that is, the version of the server. I have no commit that the server is unaware of, and no commit was pushed to the repo while I was looking away... presumably (we will get back to this).
+* For now, there is only one branch, called `main`: it is the one created by default (it used to be called `master`, and a lot of online tutorials were not updated, so be cautious). We shall see later how to deal with [more than one branch]({{'/04-branches-issues' | relative_url }}).
+* Also, my local branch seems to be up to date with the `main` branch on `origin`, that is, the version of the server. I have no commit that the server is unaware of, and no commit was pushed to the repo while I was looking away... presumably ([we will get back to this]({{'/03-linear-git-project#fetch-pull' | relative_url }})).
 * I have changed the contents of the `README.md` file (I could use `git diff README.md` to see what my changes are), and added a new file `recipe-v1.txt`).
 * Finally, I am not preparing any commit.
 
@@ -101,7 +101,7 @@ git commit -m "Add a first version of the recipe"
 
 (Of course, I could have added other files/changes to the same commit, just by using the commands `git add` and `git rm` several times before committing, and/or by listing several files in my `git add`, something like `git add file.txt myfolder/otherfile.csv`.)
 
-The result of `git status` are now pretty obvious: no more changes to commit, empty staging area (the exact words should be *"Nothing to commit, working tree clean"*), and I am 2 commits ahead of `origin/main`. Time for a `git push`, during which I will be asked my SSH passphrase. I did not have to type it earlier, because **this is the first time since cloning that I actually interact with the server**. In our ideal setup, this is not an issue, but we'll get back to this.
+The output of `git status` at this stage (no pun intended) should be pretty obvious: no more changes to commit, empty staging area (the exact words should be *"Nothing to commit, working tree clean"*), and I am 2 commits ahead of `origin/main`. Time for a `git push`, during which I will be asked my SSH passphrase. I did not have to type it earlier, because **this is the first time since cloning that I actually interact with the server**. In our ideal setup, this is not an issue, but [we'll get back to this]({{'/03-linear-git-project#fetch-pull' | relative_url }}).
 
 Going back to the project's page on GitLab, I can see that some changes occurred recently:
 
@@ -136,12 +136,12 @@ As an illustration, this is a basic flowchart of every operation we performed so
 The fact that nearly all Git commands are local has important implications. Let us start with the bad news:
 
 {: .box-warning}
-**`git status` will lie to you**. Okay, it will not actually lie to your face, but its mission is to compare the current state of your working copy with *the last known state of the repo*. If you haven't used any fetching command in the last year, `git status` will not know anything about the repo's activity in the meantime, and this may lead to *conflicts*, that we will learn how to solve and how to alleviate in a few screens.
+**`git status` will lie to you**. Okay, it will not actually lie to your face, but its mission is to compare the current state of your working copy with *the last known state of the repo*. If you haven't used any fetching command in the last year, `git status` will not know anything about the repo's activity in the meantime, and this may lead to *conflicts*, that we will learn how to solve and how to alleviate [in a few screens]({{'/03-linear-git-project#conflict' | relative_url }}).
 
 Okay, now, the good news:
 
 {: .box-note}
-**As long as you do not push, all your changes and commits are invisible to everyone but you, and you can undo anything**. We will not be going through the bazillion commands that can help you undo changes, reorganize your commits, erase all evidence of your mistakes, but know that they exist.<br/>This implies that **pushing after every commit is not always the best move**. It can be more convenient for "real-time collaboration", especially as inexperienced Git users, but as you grow familiar with it, you will realize this and think to yourself "Wait, he told me, why didn't I listen?" (Been there, done that. It is part of the learning process.)
+**As long as you do not push, all your changes and commits are invisible to everyone but you, and you can undo anything**. We will not be going (yet) through the bazillion commands that can help you undo changes, [reorganize your commits](({{'/09-advanced#irebase' | relative_url }})), erase all evidence of your mistakes, but know that they exist.<br/>This implies that **pushing after every commit is not always the best move**. It can be more convenient for "real-time collaboration", especially as inexperienced Git users, but as you grow familiar with it, you will realize this and think to yourself "Wait, he told me, why didn't I listen?" (Been there, done that. It is part of the learning process.)
 
 # Fetching vs. pulling {#fetch-pull}
 
@@ -154,7 +154,7 @@ What you want to do instead is to check, at the right times, whether your change
 If you want Git to be aware of changes that were made on the origin, you will have to fetch or pull at some point. We have been using these terms interchangeably so far: it is time to know what they actually mean.
 
 {: .box-success}
-**Fetching** amounts to synchronizing the state of your local copy of the repo with the current state of the actual repo. The command `git fetch` is how you ask Git to update its knowledge of the state of the project on the origin (i.e., the remote server).
+**Fetching** amounts to synchronizing the state of your local copy with the current state of the actual repo. The command `git fetch` is how you ask Git to update its knowledge of the state of the project on the origin (i.e., the remote server).
 
 In order to illustrate this, I asked my doppelganger to change a few things in my recipe, from the online IDE on GitLab. A new commit was created and pushed. I will now run `git status` from my computer:
 
@@ -162,7 +162,7 @@ In order to illustrate this, I asked my doppelganger to change a few things in m
 
 "What do you mean, up to date?", you think. "I happen to know this is not real. Stop lying to me."
 
-Well, as I already said, `git status` is not lying to you: he just chose the wrong words. You see, your branch is in sync with *the last version of origin/main it knows*. However, if you want Git to update its knowledge, you have to run `git fetch` (and, of course, you will be asked your passphrase):
+Well, as I already said, `git status` is not lying to you: he just chose the wrong words. You see, your branch is in sync with *the last version of `origin/main` it knows*. However, if you want Git to update its knowledge, you have to run `git fetch` (and, of course, you will be asked your passphrase):
 
 ![](../assets/img/03-linear-git-project/B-fetching-pulling/git-fetch-2.jpg){: .mx-auto.d-block :}
 
@@ -170,7 +170,7 @@ Something happened, right? Let's now run `git status` again:
 
 ![](../assets/img/03-linear-git-project/B-fetching-pulling/git-fetch-3.jpg){: .mx-auto.d-block :}
 
-See, `git status` was not lying! Now that it got the latest news about the origin, you are told that you are one commit behind, and that you can "fast-forward", whatever that means! We indeed have to talk about a few other things before coming back to fast-forwarding. The only thing you have to know is that the situation is still pretty simple to handle: you did not change anything to your working copy, you just happen to be one commit behind. Git suggests that you update your working copy with `git pull`: why not?
+See, `git status` was not lying! Now that it got the latest news about the origin, you are told that you are one commit behind, and that you can "fast-forward", [whatever that means]({{'/09-advanced#rebase' | relative_url }})! We indeed have to talk about a few other things before coming back to fast-forwarding. The only thing you have to know is that the situation is still pretty simple to handle: you did not change anything to your working copy, you just happen to be one commit behind. Git suggests that you update your working copy with `git pull`: why not?
 
 ![](../assets/img/03-linear-git-project/B-fetching-pulling/git-fetch-4.jpg){: .mx-auto.d-block :}
 
@@ -178,17 +178,17 @@ Great! Now, my dopperganger's changes appear in my working copy. A few things do
 
 I will not answer question 2 in this tutorial, because (i) we are only here for the "basics", and (ii) because of the default configuration of Git, you may not even see this specific message when pulling.
 
-The answer to question 3 will come in a few screens, when we take a look at how Git handles all this data internally.
+The answer to question 3 will come later, when we take a look at [how Git handles all this data internally]({{'/08-internals#objects' | relative_url }}).
 
-The one question that is important to us right now is the first one: I just fetched, so why must I type my passphrase again for pulling? The answer is pretty simple:
+The one question that is important to us right now is the first one: I just fetched, so why must I type my passphrase again for pulling? The answer is twofold. First, [you did not use `ssh-add`]({{'/01-setup#gitlab' | relative_url }}), otherwise you would only be asked your passphrase once per session. Second, and this is more relevant right now:
 
 {: .box-success}
 **Pulling** is a two-stage process: first, changes are *fetched* from the origin; second, the changes that were done on the origin are *merged* with the changes that were already made in the working copy.
 
 This means, in particular, that even if you just fetched, `git pull` will call `git fetch` anyway, so that your computer will indeed communicate with the origin once again. (There is a way to merge fetched changes with your local changes without having to call `git fetch` again, but it is way more convoluted, so that Git would rather advise you to just pull.)
 
-{: .box-info}
-There are interesting opinions out there about [why you should not always use `git pull`](http://longair.net/blog/2009/04/16/git-fetch-and-merge/), but for our purposes, using `git pull` should be fine. You should still, at some point, read the article linked in this very paragraph to know more about the differences between "pulling" and "fetching then merging": the more complex your Git project is, the more important it may become, and using more advanced commands like [`git rebase`]({{'/02-creating-projects#push-code' | relative_url }}) might essentially require you to fetch instead of pulling. Also, calling `git fetch` with optional arguments will prove pretty useful later on, so even at this stage, it is nice to know that `git pull` is all but an atomic command.
+{: .box-note}
+There are interesting opinions out there about [why you should not always use `git pull`](http://longair.net/blog/2009/04/16/git-fetch-and-merge/), but for our purposes, using `git pull` should be fine. You should still, at some point, read the article linked above to know more about the differences between "pulling" and "fetching then merging": the more complex your Git project is, the more important it may become, and using more advanced commands like [`git rebase`]({{'/09-advanced#rebase' | relative_url }}) might essentially require you to fetch instead of pulling. Also, calling `git fetch` with optional arguments will prove pretty useful later on, so even at this stage, it is nice to know that `git pull` is all but an atomic command.
 
 For now, we have to adapt our workflow so that changes on the remote are handled. Let's say that I just have teeny tiny changes to make, and I pulled pretty recently. After I made my changes, but before I push them, I should be pulling again! The part of the workflow that has to be changed is the following:
 
@@ -203,9 +203,9 @@ This results in the following updated and safer workflow:
 
 ![](../assets/img/03-linear-git-project/B-fetching-pulling/sequence-02.jpg){: .mx-auto.d-block :}
 
-(Notice that I chose to describe `git pull` as a command acting on the staging area, which is a white lie: it actually acts on the working copy. However, I think it helps visualizing the fact that your commit and the possible commits that are pulled will be interacting in some way.)
+> I chose to describe `git pull` as a command acting on the staging area, which is a white lie: it actually acts on the working copy. However, I think it helps visualizing the fact that your commit and the possible commits that are pulled will be interacting in some way.
 
-To be perfectly honest, you should probably pull as often as possible. If you are afraid that the merging stage of a pull might go terribly wrong and force you to redo your work, [`git stash` might be what you need](https://stackoverflow.com/questions/18529206/when-do-i-need-to-do-git-pull-before-or-after-git-add-git-commit). (This is a powerful command, but I do not want to give you too much information at once. Click at your own risk.)
+To be perfectly honest, you should probably pull as often as possible. If you are afraid that the merging stage of a pull might go terribly wrong and force you to redo your work, [`git stash` might be what you need](https://stackoverflow.com/questions/18529206/when-do-i-need-to-do-git-pull-before-or-after-git-add-git-commit). (This is a powerful command, but I do not want to give you too much information at once. [We will talk about it in the next chapter.]({{'/04-branches-issues#switch' | relative_url }}))
 
 "Excuse me, sir", you gently interrupt. "You already implied twice that merging might go wrong. How so?"
 
diff --git a/04-branches-issues.md b/04-branches-issues.md
index 7a71b8a..71addf7 100644
--- a/04-branches-issues.md
+++ b/04-branches-issues.md
@@ -22,13 +22,13 @@ Let us make this less abstract.
 
 # What you should not do {#not-do}
 
-Imagine that you have been working with other people on a project, and your team managed to create a first working version. However, you really feel that this experimental feature you have been thinking about for months would be incredibly valuable for the software as a whole.
+Imagine that you have been working with other people on a project, and your team managed to create a first working version. However, you really feel like this experimental feature you have been thinking about for months would be incredibly valuable for the software as a whole.
 
-Knowing nothing about branches and issues, or maybe just deciding that you do not need them at all, you start developing your new feature on your working copy. You know that, once it finally works, you will just have to go through the usual "commit-and-push" ritual.
+Knowing nothing about branches and issues, or maybe just deciding that you do not really care, you start developing your new feature on your working copy. You know that, once it finally works, you will just have to go through the usual "commit-and-push" ritual.
 
 Well, here are some drawbacks of your method:
 
-* You are working on a collaborative project, yet ***no one will be able to work with you on this new feature***, because your work is purely local. This is, most probably, an absolute waste of resources.
+* You are working on a collaborative project, yet ***no one will be able to work with you on this new feature***, because your work is purely local. This is likely an absolute waste of resources.
 * Once you start making changes to your working copy, you have to *only* work on your new feature, either until it is ready to commit and push, or (this unfortunately happens) until you have to scrap the idea and dismiss everything you have done. ***What if you have to go back to the `main` branch***, in its current "shared" state, for helping fix an urgent issue, or collaborating on another specific development, or just because there are other features on which you would like to work once in a while? The workarounds would involve a lot of copy-pasting files and creating temporary folders, not to mention that it would be incredibly risk-prone. (For instance, delete the wrong folder and all your local work is lost.)
 * Let's assume that you managed to design the entire feature by yourself, and are ready to push it. When it is finally pushed, ***not a single collaborator got an opportunity to tell you whether your work is well-done, but everyone now has to deal with it***, as it becomes **the** current version of the codebase. For all you know, maybe it does not even work properly on their computers, or maybe there are some glaring issues that you did not notice, or no one actually wants/needs this new feature.
 
@@ -51,7 +51,7 @@ To make this clearer, we will create a few issues on our dumb bread project.
 
 ## Bug report
 
-Mike, one of the members of the project, has tried making his bread using our incredible recipe, and it flat out did not work. The dough just would not raise. Of course, he wants to warn everyone that there is a problem, but he will not just send e-mails to everyone: first, he does not have the e-mail addresses of everyone involved, and second, he knows this:
+Mike, one of the members of the project, has tried making his bread using our incredible recipe, and it flat out (pun not intended) did not work, as the dough just would not raise. Of course, he wants to warn everyone that there is a problem, but he will not just send e-mails to everyone: first, he does not have the e-mail addresses of everyone involved, and second, he knows this:
 
 {: .box-success}
 **Pretty much everything related to a GitLab project should be discussed on GitLab.**
@@ -84,11 +84,24 @@ Pretty clear. The "Type" dropdown only gives two options: "Issue" and "Incident"
 {: .box-note}
 **Incidents** are a specific type of issues designed to handle service disruptions or outages. Once an incident is open, actions can be tracked and timed, and subtasks can be created. This is likely not a feature you will need to use. Just remember that **a bug is not an incident**. Incidents are for very urgent matters, to which researchware is often immune by nature.
 
-The description of the issue can use Markdown, which can be a very nice touch: this will make the issue more readable.
+The description of the issue can use Markdown, which can be a very nice touch: this will make the issue more readable. Mike writes something like this:
+
+```
+## How it occurred
+
+I followed to the letter the recipe provided by file `recipe-v1.txt` in the root folder. However, [this step](https://gitlab.inria.fr/bakery/bread/multigrain-baguette/-/blob/main/recipe-v1.txt#L7) did not succeed: after more than an hour, the dough still had its original size.
+
+## Possible fixes
+
+* No quantities are mentioned in the recipe. I may not have used enough yeast (1 tbsp for 1 oz flour).
+* I live in a very cold place and the heater in my kitchen broke. Maybe the dough was below "room temperature"?
+```
+
+He then scrolls down:
 
 ![](../assets/img/04-branches-issues/A-bug-report/bug-report-5.jpg){: .mx-auto.d-block :}
 
-Not sure about what stands below, he decides not to touch anything else and posts his issue.
+Not sure about what stands there, he decides not to touch anything else and posts his issue.
 
 ![](../assets/img/04-branches-issues/A-bug-report/bug-report-6.jpg){: .mx-auto.d-block :}
 > Please do not hesitate to contact me for any Photoshop-related requests.
@@ -116,13 +129,13 @@ Of course, going back to the issue list...
 ...it is not empty anymore. I can click the "Open", "Closed" and "All" buttons to filter out the list of issues; when I open the issue list, only open issues are displayed. I will now create a new issue, mentioning the one opened by Mike as related (this pointer might be convenient later).
 
 {: .box-success}
-**Mentioning issues** is made using the `#` character. This can be done in any issue or merge request (which we will see later), be it in the description or discussion.
+**Mentioning issues** is made using the `#` character. This can be done in any issue or *merge request* ([which we will see later]({{'/04-branches-issues#mr' | relative_url }})), be it in the description or discussion.
 
 As a matter of fact, as soon as I type a `#`, a small dropdown appears:
 
 ![](../assets/img/04-branches-issues/B-interact-with-issues/issue-handling-4.jpg){: .mx-auto.d-block :}
 
-By default, a list of the 5 latest open issues is displayed (unless there are less, of course). Just clicking on the one you want to reference is enough, and I can then go on writing the issue description. (If the issue you aree searching for is not in the dropdown list, just type its number.) I can also mention Mike here:
+By default, a list of the 5 latest open issues is displayed (unless there are less, of course). Just clicking on the one I want to reference is enough, and I can then go on writing the issue description. (If the issue you are searching for is not in the dropdown list, just type its number.) I can also mention Mike here:
 
 {: .box-success}
 **Mentioning projects or project members** is done using the `@` character.
@@ -131,21 +144,21 @@ If I type one or several letters after the `@` character, the items in the dropd
 
 ![](../assets/img/04-branches-issues/B-interact-with-issues/issue-handling-5.jpg){: .mx-auto.d-block :}
 
-Mentioning other project members can be done in the description of any issue or merge request, as well as in every comment or thread below. Mentioned members will get notified, which is extremely convenient when you want to get specific input from collaborators, or even general opinions. Like on tools such as Discord or Mattermost, an `@all` tag exists, to be used only in case of stringent need.
+Mentioning other project members can be done in the description of any issue or merge request, as well as in every comment or thread below. Mentioned members will get notified, which is extremely convenient when you want to get specific input from collaborators, or even general opinions. As is also the case on tools such as Discord or Mattermost, an `@all` tag exists, to be used only in case of stringent need.
 
 As a project maintainer, I am also interested in the options below the description box:
 
 ![](../assets/img/04-branches-issues/B-interact-with-issues/issue-handling-6.jpg){: .mx-auto.d-block :}
 
-* By checking the small box, I can make my issue **confidential**, so that guests (i.e., simple users) will not be able to see it. Issues directly related to code internals (algorithmic details, refactoring tasks...) may very well fall into this category, while no feature proposal should ever be made confidential.
+* By checking the small box, I can make my issue **confidential**, so that guests (i.e., simple users -- [click here]({{'/02-creating-projects#roles' | relative_url }}) if you need a refresher) will not be able to see it. Issues directly related to code internals (algorithmic details, refactoring tasks...) may very well fall into this category, while no feature proposal should ever be made confidential.
 * The **assignee** will be the collaborator in charge of handling the issue. Said issue will appear in his to-do list, one of three buttons on the upper left part of the GitLab window:
 
 ![](../assets/img/04-branches-issues/B-interact-with-issues/gitlab-notif-buttons.jpg){: .mx-auto.d-block :}
 
-> From left to right: open issues that are assigned to the current user, merge requests assigned to the current user and/or to be reviewed by them (more on that later), to-do list (automated alerts, notifications, etc. that are not part of the first two categories).
+> From left to right: open issues that are assigned to the current user, [merge requests]({{'/04-branches-issues#mr' | relative_url }}) assigned to the current user and/or to be reviewed by them (more on that later), to-do list (automated alerts, notifications, etc. that are not part of the first two categories).
 
-* **Milestones** are a convenient feature for more mature projects. Issues and merge requests can be grouped under a milestone, so that the advancement of the set of all tasks required to reach a given objective (a new feature being fully implemented, a release-ready version...) can be tracked. This will not be discussed here, as it is out of the scope of a 101 course, but it is a very convenient and pretty easy feature to use.
-* **Labels** are maintainer-defined strings that can be used in order to sort out the issues. The use of labels makes it easier for managers to distinguish between urgent and low-priority issues, and for developers to directly reach issues on which they might be most helpful. Frequently used labels include `doc`, `bug`, `feature_request`... but the "best" set of labels is indeed project-dependent. (Labels arealso important if your team wants to use an **issue board** for easier project management: think of it as [an automated Kanban or Scrum board](https://docs.gitlab.com/ee/user/project/issue_board.html).)
+* **Milestones** are a convenient feature for more mature projects. Issues and merge requests can be grouped under a milestone, so that the advancement of the set of all tasks required to reach a given objective (a new feature being fully implemented, a release-ready version...) can be tracked. This will not be discussed here, but it is a very convenient and pretty easy feature to use.
+* **Labels** are maintainer-defined strings that can be used in order to sort out the issues. The use of labels makes it easier for managers to distinguish between urgent and low-priority issues, and for developers to directly reach issues on which they might be most helpful. Frequently used labels include `doc`, `bug`, `feature_request`... but the "best" set of labels is indeed project-dependent. (Labels are also important if your team wants to use an **issue board** for easier project management: think of it as [an automated Kanban or Scrum board](https://docs.gitlab.com/ee/user/project/issue_board.html).)
 * **Due date** is exactly what it says on the (metaphorical) label. Reminders will be sent automatically to people involved with the issue when its due date is closing in.
 
 For illustration purposes, this in an example of what an issue list can look like on an active project:
@@ -160,9 +173,9 @@ You do not have to use all of these features from the get-go, but as a project g
 In general, assigning issues tends to be a good practice, but assigning an issue to someone who is not even aware of it leans on dictatorial management, which you want to avoid at all costs.
 
 {: .box-success}
-More often than not, someone will assign an issue to themself as a way of telling everyone **"I am taking charge of this task and starting working on it"**. Issues that are currently not being addressed should not be assigned, and an issue should never be assigned to someone without their approval.
+More often than not, someone will assign an issue to themself as a way of telling everyone **"I am taking charge of this task and starting working on it"**. Issues that are currently not being addressed should not be assigned, and an issue should not be assigned to someone without their approval.
 
-This is, in a nutshell, why assigning a task to yourself just requires clicking a button: in most cases, you are the person to which you will be assigning tasks. Only when the matter has been discussed before, and one of your collaborators is explicitly willing to be assigned to an issue, should you ever open the "Assignee" dropdown menu.
+This is, in a nutshell, why assigning a task to yourself just requires clicking a button: in most cases, you are the person to which you will be assigning tasks. Only when the matter has been discussed before, and one of your collaborators is explicitly willing to be assigned to an issue, should you open the "Assignee" dropdown menu.
 
 As for our "quantities" task, well... I am ready to take charge of it. A simple click and it's done. Here is our fresh task, simply called `#2`:
 
@@ -188,12 +201,12 @@ And if I go back to the page for issue `#1`:
 
 How beautiful.
 
-Before jumping the next hoop, let me state once again the importance of issues (last time, pinky promise):
+Before jumping through the next hoop, let me state once again the importance of issues (last time, pinky promise):
 
 {: .box-warning}
 If you are not using issues, you definitely will lose track of what needs to be fixed or improved, you will get several people working at the same time on the same thing, problems in your codebase will be left unchecked for months (or until the app crashes and no one has any idea why)... Basically, issues **are** how you manage your GitLab project. If you do not use them, you will lose efficiency and accumulate technical debt, even if you are working solo.
 
-Okay, nice. I know have an issue assigned to myself. Time to work on it!
+Okay, nice. I now have an issue assigned to myself. Time to work on it!
 
 # Working on a feature branch {#feature}
 
@@ -202,14 +215,14 @@ Let us start with the basics:
 {: .box-success}
 A **branch** is a line of development that can evolve independently.
 
-This is a pretty basic and abstract definition, for a pretty good reason: a more explicit (and valid) definition of branches would require delving into the internals of Git. Telling you that a branch is a *lightweight movable pointer to a commit* will not help you understand how you are supposed to use them, right?
+This is a pretty basic and abstract definition, for a pretty good reason: a more explicit (and valid) definition of branches would require delving into [the internals of Git]({{'/08-internals' | relative_url }}). Telling you that a branch is a *lightweight movable pointer to a commit* will not help you understand how you are supposed to use them, right?
 
 But still, this high-level "independent line of development" non-definition probably does not help you either. What does it mean in practice? Why is branching ***the*** feature of Git? Here is another non-definition that will hopefully make it clearer:
 
 {: .box-success}
 By creating a **branch**, you can start working on brand new (sometimes experimental) features with the guarantee that you will not mess with the work on the main line(s) of development. If the features developed on this branch end up working, they can be merged into the main codebase. Otherwise, the branch may just be discarded without posing any threat to the codebase.
 
-*(Branching exists in a lot of modern version control software. However, and this is where Git truly shines, creating a new branch with Git is an incredibly fast operation: no duplicating files, no weird shenanigans, your branch can be created in the blink of an eye... and merging branches is pretty fast and comfortable too, as we shall see.)*
+*(Branching exists in a lot of modern version control software. However, and this is where Git truly shines, creating a new branch with Git is an incredibly fast operation: no duplicating files, no weird shenanigans, your branch can be created in the blink of an eye... and merging branches is pretty fast and comfortable too, [as we shall see]({{'/04-branches-issues#mr' | relative_url }}).)*
 
 "Okay", you say, "so... It wasn't difficult enough yet, so we have to add a new layer of complexity, is it what you're saying?"
 
@@ -228,14 +241,14 @@ This simple sentence solves pretty much every potential problem that was address
 * When you work on an issue on a dedicated branch, your WIP has no impact whatsoever on the versions of the codebase that live on other branches, including the main branch.
 * The branch is created locally, but you can push it to the repo at any moment so that other people can collaborate on the task.
 * Switching between branches is very easy, and Git has a lot of mechanisms in place to ensure that you will not lose work in the process.
-* When your feature is fully implemented on a branch, you can initiate the process of merging your contents with the contents of the main branch, and require that your changes be reviewed by one or several collaborators. (It is even possible to run automated tests on the merged code before pushing the changes to the target branch, but this is a story for another time.)
+* When your feature is fully implemented on a branch, you can initiate the process of merging your contents with the contents of the main branch, and require that your changes be reviewed by one or several collaborators. (It is even possible to run automated tests on the merged code before pushing the changes to the target branch, but this is a story for [another time]({{'/05-good-practices#cicd' | relative_url }}).)
 
 Time for action.
 
 <div class="box-success" markdown="1">
 **Switching between branches** is performed via the `git switch` command.
-* `git switch branch_name` switches your working copy to the branch named `branch_name`, provided that it exists. The full state of your working copy is changed.
-* `git switch -c branch_name` **c**reates a new branch named `branch_name` (provided that no other branch with the same name already exists) and switches your working copy to this branch.
+* `git switch branch_name` switches your working copy to the branch named `branch_name`, provided that it exists. The full state of your working copy is changed accordingly.
+* `git switch -c branch_name` ***c***reates a new branch named `branch_name` (provided that no other branch with the same name already exists) and switches your working copy to this branch.
 </div>
 
 {: .box-warning}
@@ -245,7 +258,7 @@ Here, I will create a branch named `add-quantities` (a pretty fitting and self-e
 
 ![](../assets/img/04-branches-issues/C-feature-branch/feature-branch-1.jpg){: .mx-auto.d-block :}
 
-Well, that makes sense: `add-quantities` does not exist yet. But hey, there's another thing: I'd rather make sure that my branch is created from an up-to-date version of the project! Given that I already encountered conflicts while working on a single branch, who knows what could happen with several branches?
+Well, that makes sense: `add-quantities` does not exist yet. But hey, there's another thing: I'd rather make sure that my branch is created from an up-to-date version of the project! Given that I already encountered conflicts [while working on a single branch]({{'/03-linear-git-project#conflict' | relative_url }}), who knows what could happen with several branches?
 
 ![](../assets/img/04-branches-issues/C-feature-branch/feature-branch-2.jpg){: .mx-auto.d-block :}
 
@@ -268,7 +281,7 @@ A lot of things happened here, but most of the contents of this log can be skipp
 
 # Switching branches {#switch}
 
-I have been working on my feature branch for quite some time now, but I am not quite finished yet. However, a colleague asks me to go back to the `main` branch for a quick fix: the `README` of the project now includes a draft copyright notice that does not look quite right.
+I have been working on my feature branch for some time now, but I am not quite finished yet. However, a colleague asks me to go back to the `main` branch for a quick fix: the `README` of the project now includes a draft copyright notice that does not look quite right.
 
 ![](../assets/img/04-branches-issues/D-switch-branch/switch-1.jpg){: .mx-auto.d-block :}
 
@@ -284,11 +297,13 @@ Git lets you switch to `main`, but tells you that you have changes (that's the `
 
 However, you are still taking risks. There are still a few words hinting at this in the paragraph above: *"that Git knows of"*. Maybe there were changes made on the `origin/main` branch that you have not pulled yet, and if you try and pull them, you may have to solve a conflict.
 
-Plus, you probably do not want your changes to be carried over to the main branch: they were to remain on the feature branch for the moment, and you do not want to push them on the main branch by mistake!
+Plus, you probably do not want your changes to be carried over to `main`: they were to remain on the feature branch for the moment, and you do not want to push them on the main branch by mistake!
 
 There are two simple ways to avoid carrying uncommitted changes to another branch:
 
-* `git stash` and `git stash pop` can be respectively used to store all uncommitted changes "somewhere" and reapply them to your working copy. The workflow in our situation would then be: `git stash` (save all uncommitted changes in a fresh stash entry), `git switch main`, do whatever you want on the main branch, then `git switch add-quantities` to go back to the feature branch, and `git stash pop` to reapply your changes. Just be wary of the fact that the stash is a [stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)): Git will not prevent you from calling `git stash` several times in a row, and if you lose track of what you are doing, you may reapply changes at the wrong place, or call `git stash` 3 times, then `git stash pop` only twice, and wonder where your work has gone. You might want to use `git stash save "This is what I have done here"` so as to get the memo later on and know which changes you should apply where. [More on "advanced" stashing here.](https://www.atlassian.com/git/tutorials/saving-changes/git-stash) Stashing is still pretty convenient in a lot of situations, for example if you want every commit to contain code that actually compiles.
+* `git stash` and `git stash pop` can be respectively used to store all uncommitted changes "somewhere" and reapply them to your working copy. The workflow in our situation would then be: `git stash` (save all uncommitted changes in a fresh stash entry), `git switch main`, do whatever you want on the main branch, then `git switch add-quantities` to go back to the feature branch, and `git stash pop` to reapply your changes.
+  * Just be wary of the fact that the stash is a [stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)): Git will not prevent you from calling `git stash` several times in a row, and if you lose track of what you are doing, you may reapply changes at the wrong place, or call `git stash` 3 times, then `git stash pop` only twice, and wonder where some of your work has gone.
+  * You might want to use `git stash save "This is what I have done here"` so as to get the memo later on and know which changes you should apply where. [More on "advanced" stashing here.](https://www.atlassian.com/git/tutorials/saving-changes/git-stash) Stashing is still pretty convenient in a lot of situations, for example if you want every commit to contain code that actually compiles.
 * If you are afraid of stashing, well... just commit your changes. Duh, right? Well, see above: there are changes you do not want to commit yet. The choice is yours, and it will depend on your tastes and on the situation at hand.
 
 We switched from `add-quantities` to `main` with ease; let's just go back to `add-quantities` (still carrying our uncommitted changes with us), commit our changes, and only then, go back to `main`:
@@ -305,7 +320,7 @@ I can now, as usual, make my changes with whichever editor I enjoy using, commit
 
 ![](../assets/img/04-branches-issues/D-switch-branch/git-diff.jpg){: .mx-auto.d-block :}
 
-There are uncommitted changes in `README.md`, so `git diff README.md` shows me what I changed in this file since the last commit. In red, what disappeared. In green, what appeared. (This is a simple line-by-line diff; there are tools that make an ever better job at this, but this one is quick and simple.)
+There are uncommitted changes in `README.md`, so `git diff README.md` shows me what I changed in this file since the last commit. In red, what disappeared. In green, what appeared. (This is a simple line-by-line diff; there are tools that make a better job, but this one is quick and simple.)
 
 Basically, `git status` and `git diff <path_to_file>` are two great commands when you want to know where you're at, and make sure that you commit exactly what you want to.
 
@@ -316,9 +331,9 @@ Now that I know everything is fine, I can commit and push my changes to `main`,
 This is where a green box is probably needed:
 
 {: .box-success}
-As a general rule, **you do not want to switch to another branch when there is uncommitted work in the current branch**. There are two ways of avoiding this situation; the recommended one is the most simple: commit your changes before switching!
+As a general rule, **you do not want to switch to another branch when there is uncommitted work in the current branch**. There are two ways of avoiding this situation: committing your changes before switching, or stashing your uncommitted changes.
 
-As long as you follow this advice, you will always be working on a branch "as if it were the only branch", like what we did when only the `main` branch existed.
+In particular, when using the former strategy, you will always be working on a branch "as if it were the only branch", like what we did when only the `main` branch existed.
 
 ...expect, of course, when you **decide** that it is time to merge branches.
 
@@ -332,18 +347,21 @@ My new feature is now fully implemented, and should be integrated into the main
 
 * I get a nice clean web interface that makes the process way simpler than having to type the right commands.
 * I can submit my code to collaborators who can review my changes and suggest fixes if needed (which is a very important feature for actual code: maybe I could have used more adapted data structures or algorithms, or the way I wrote my code does not fully comply to the coding standards of the project).
-* Finally, a lot of automatic checks can be performed in order to check that I did not break the software in some way: this is called a CI pipeline, and is an advanced feature that will be [introduced later on]({{'/05-good-practices#cicd' | relative_url }})
+* Finally, a lot of automatic checks can be performed so as to ensure that I did not break the software in some way: this is called a CI pipeline, and is an advanced feature that will be [introduced later on]({{'/05-good-practices#cicd' | relative_url }}).
 
 {: .box-success}
 A **merge request** (or MR) is the mechanism by which a member of a GitLab project proposes that the changes made in a branch be incorporated in another branch. An assignee and a reviewer can (and should!) be picked for a MR; the former will act as a "manager" of sorts for this MR, while the latter will be in charge of checking the actual changes and suggest fixes if necessary.
 
+{: .box-note}
+On GitHub, this is called a Pull Request, or PR for short. Do not let it confuse you: these are essentially the same thing.
+
 ## Opening a MR
 
-As the whole merging process will be carried out on the server site, the most recent version of my works must be sent to the repo (otherwise, how would GitLab be able to see it?): time for pushing.
+As the whole merging process will be carried out on the server side, the most recent version of my works must be sent to the repo (otherwise, how would GitLab be able to see it?): time for pushing.
 
 ![](../assets/img/04-branches-issues/E-merge-requests/merge-2.jpg){: .mx-auto.d-block :}
 
-As I push, I get once again a URL that I can just copy-paste in my browser to get on the right page, but I could also go to the page of the project, click on "Merge requests" in the left-hand menu...
+As I push, I get once again a URL that I can just copy-paste in my browser to get on the right page. I can also go to the page of the project, click on "Merge requests" in the left-hand menu...
 
 ![](../assets/img/04-branches-issues/E-merge-requests/merge-3.jpg){: .mx-auto.d-block :}
 > ...the one in "Code", **not the one in "Pinned"!** Once again, "Pinned" is for all projects, the rest is for the current project only.
@@ -361,8 +379,8 @@ From here, I just have to pick `add-quantities` as the source branch and `main`
 ![](../assets/img/04-branches-issues/E-merge-requests/merge-6.jpg){: .mx-auto.d-block :}
 
 * I can write a more descriptive title than the one proposed by GitLab (usually, the name of the commit if there is a single commit on the branch, or a slightly more readable version of the name of the branch itself), and I definitely should.
-* If there is still some work to be done on the branch, I can mark the MR as draft, which will prevent its merging for now. I can then mark it as ready, so that merging becomes possible again. 
-* I should add a description (once again, in Markdown format) in order to explain what I did: typically, what the purpose is, what are the main changes, which issues it solves or may solve...
+* If there is still some work to be done on the branch, I can mark the MR as draft, which will prevent its merging for now. At some point in the future, I will mark it as ready, so that merging will be possible. 
+* I should add a description (once again, in Markdown format) in order to explain what I did: typically, what the purpose is, what the main changes are, which issues it solves or may solve...
 
 In the description, I should absolutely mention issues `#1` and `#2`, as the actual merging will resolve `#2` and probably help with `#1`. We will say that it will **close** `#2` and is **related to** `#1`. And, once again, GitLab can help me with this:
 
@@ -376,7 +394,7 @@ This is not a magic trick, but a GitLab feature that is enabled by default. Inde
 Unless somebody (with the rights to do so) unchecked this box, this is the default behaviour:
 
 {: .box-success}
-When an MR has the default branch as target, **all issues that are mentioned in the description of this MR using `Close #xx`, `Fix #xx`, `Resolve #xx`, `Implement #xx`, or [variations on these keywords](https://archives.docs.gitlab.com/15.11/ee/user/project/issues/managing_issues.html#default-closing-pattern) will be automatically closed when the MR is closed**, i.e., when merging is performed. (By default, the `main` branch, which is the only branch that exists in a fresh project, is the default branch.)
+When an MR has the default branch as target, **all issues that are mentioned in the description of this MR using `Close #xx`, `Fix #xx`, `Resolve #xx`, `Implement #xx`, or [variations on these keywords](https://archives.docs.gitlab.com/15.11/ee/user/project/issues/managing_issues.html#default-closing-pattern) will be automatically closed when the MR is closed**, i.e., when merging is performed. (Without specific action from the maintainers, the `main` branch, being the only branch created in a fresh project, is the default branch.)
 
 This is what my MR could look like at this point:
 
@@ -389,20 +407,21 @@ You may also mention other related MRs, here or in issues:
 {: .box-success}
 **Mentioning MRs** is made using the `!` character. As for issues, this can be done in any issue or merge request, be it in the description or discussion. Note that issues and MRs have independent numberings: we will be opening MR `!1` here, and we marked it as related to issue `#1`.
 
-Of course, any other information that could help my collaborators understand what is in this MR (which changes are core changes, which pieces of my code could probably be improved and deserve specific attention, which algorithmic choices were made and why...) should be written down. In my case, there is no such need: changes are pretty straaightforward and limited to a single file, with no side effects.
+Of course, any other information that could help my collaborators understand what is in this MR (which changes are core changes, which pieces of my code could probably be improved and deserve specific attention, which algorithmic choices were made and why...) should be written down. In my case, there is no such need: changes are pretty straightforward and limited to a single file, with no side effects.
 
 But my work is not over: scrolling down, I notice that there are a few more hoops to jump through before opening the MR.
 
 ![](../assets/img/04-branches-issues/E-merge-requests/merge-9.jpg){: .mx-auto.d-block :}
 
-* The **assignee** is the one person who will manage this MR, check that everything goes right and, most likely, be the one to finally click the "Merge" button. Depending on the project, it can make perfect sense to assign "your" MR to someone other than yourself. Here, I will assign here to myself.
-* The **reviewer** will get a notification, asking them to, well, review the code. They should be either an expert on the specific topics addressed by the changes to be merged, or a maintainer who knows the whole codebase like the back of their hand -- better yet: both at the same time. The reviewer of a MR should never be someone who actively contributed to it. Here, I will be asking my evil doppelganger to review the code. (When you are working on a solo project, it can make sense to do so, as the review request will then be part of your GitLab to-do: you can then come back to it a few hours/days/weeks later and give your changes a fresh look.)
-* **Milestones** and **labels** serve the exact same purpose as for issues, and there are no distinct sets of milestones/labels for issues and MRs.
-* You can choose to automatically delete the branch after merging it, which makes sense when you created it specifically for developing a feature to be integrated to the main branch. Still, for future purposes, I will uncheck this box for now. (Deleting a branch that was merged is very easy from the GitLab web interface.)
+* The **assignee** is the one person who will manage this MR, check that everything goes right and, most likely, be the one to finally click the "Merge" button. Depending on the project, it can make perfect sense to assign "your" MR to someone other than yourself. Here, I will just assign it to myself.
+* The **reviewer** will get a notification, asking them to, well, review the code. They should be either an expert on the specific topics addressed by the changes to be merged, or a maintainer who knows the whole codebase like the back of their hand -- better yet: both at the same time. The reviewer of a MR should never be someone who actively contributed to it. Here, I will be asking my evil doppelganger to review the code.
+  * Even when you are working on a solo project, it can make sense to pick yourself as reviewer, as the review request will then be part of your GitLab to-do: you can then come back to it a few hours/days/weeks later and give your changes a fresh look.
+* **Milestones** and **labels** serve the exact same purpose as for issues, and the milestones/labels at your disposal for MRs are the same as for issues.
+* You can choose to automatically **delete the branch after merging it**, which makes sense when you created it specifically for developing a feature to be integrated to the main branch. Still, for future purposes, I will uncheck this box for now. (Deleting a branch that was merged is very easy from the GitLab web interface anyways, so that we can deal with this later.)
 * You may want to **squash commits**, that is, turn all the commits you made on the feature branch into a single one. This makes perfect sense in my case, because my changes would have nicely fit into a single commit (the only reason I have two is that I had to switch back to the main branch at some point and wanted to make sure that I would not lose some work or make some mistake in the process). Let us check this box.
 
 {: .box-success}
-If important changes were made in several files, squashing commits is probably a bad idea, as it will make it way harder to point to a specific change if you need to do so in the future (which happens more than you would hope). However, cluttering the history of the project with tens of tiny commits is also a terrible idea.
+If important changes were made in several files, squashing commits is probably a bad idea, as it will make it way harder to point to a specific change if you need to do so in the future (which happens more than you would hope). However, cluttering the history of the project with tens of tiny commits is also a terrible idea. (If you worked alone on a branch, there is a way to reorganize all commits on the branch *before* pushing it and opening a MR, which [we will see later]({{'/09-advanced#irebase' | relative_url }}).)
 
 {: .box-note}
 All of this is related to the core idea that **commits should be atomic**: ideally, each commit would accomplish a clear, well-delimited, easily explainable task or subtask.<br/>On the one hand, a commit that adds several unrelated functions, possibly in different files, at the same time, should probably have been split (and if it also makes some of those accessible from the API of the software and changes the layout of the user interface in irreversible ways, well... good luck with that if anything goes wrong in the future).<br/>On the other hand, creating one commit in which you define the template of a new method, one in which you half-implement it, a third one in which you define unit tests for it, and a fourth one where you implement the corner cases, will just clutter the history of the project.
@@ -415,7 +434,7 @@ One click later, here it is: our first MR, in all its unfathomable glory! A pinn
 
 Did you think that pull conflicts would be the only conflicts we would encounter? Time for **merge conflicts**. In this case, changes were made on the main branch that conflict with our own.
 
-GitLab gives you a choice between "Resolve locally" and "Resolve conflicts". The former option basically amounts to GitLab opening a small window with instructions about what you should do, on your computer, to resolve things. This is the hard way of fixing conflicts. We want to avoid that. Let us click on "Resolve conflicts" instead and hope that GitLab will hold our hand:
+GitLab gives you a choice between "Resolve locally" and "Resolve conflicts". The former option basically amounts to GitLab opening a small window with instructions about what you should do, on your computer, to resolve things. This is made easier when using [an IDE like VSCode]({{'/07-vscode#branch' | relative_url }}), but for the moment, we will avoid that. Let us click on "Resolve conflicts" instead and hope that GitLab will hold our hand:
 
 ![](../assets/img/04-branches-issues/F-merge-conflicts/merge-conflict-1.jpg){: .mx-auto.d-block :}
 
@@ -425,11 +444,11 @@ However, I would like to keep my version, but with the Fahrenheit-to-Celsius bit
 
 ![](../assets/img/04-branches-issues/F-merge-conflicts/merge-conflict-2.jpg){: .mx-auto.d-block :}
 
-Alright, now we're talking! I can now edit this the old-fashioned way, like I did when I go that pull conflict earlier:
+Alright, now we're talking! I can now edit this the old-fashioned way, like I did [when I got that pull conflict earlier]({{'/03-linear-git-project#conflict' | relative_url }}):
 
 ![](../assets/img/04-branches-issues/F-merge-conflicts/merge-conflict-3.jpg){: .mx-auto.d-block :}
 
-(At this stage, GitLab will not let me go back to the interactive mode, because that would discard the changes I just made. As a rule of thumb, if every conflict can be solved by picking one of the two conflicting versions, you should go full interactive mode for efficiency. Otherwise, you will have to solve every conflict "by hand" in the inline edition mode.)
+> At this stage, GitLab will not let me go back to the interactive mode, because that would discard the changes I just made. As a rule of thumb, if every conflict can be solved by picking one of the two conflicting versions, you should go full interactive mode for efficiency. Otherwise, you will have to solve every conflict "by hand" in the inline edition mode.
 
 At the bottom of the page, I just have to edit the commit message if I want to, then commit.
 
@@ -445,7 +464,7 @@ Enter... the reviewer.
 
 ## Reviewing a MR
 
-A while ago, I showed you three buttons that appear on the upper-right corner of the GitLab webpage, for the issues, MR and other to-do list items that have to be handled. Well, our reviewer has them too, and if they click on the small arrow right next to the MR button, this is what they get:
+A while ago, I showed you three buttons that appear on the upper-right corner of the GitLab webpage, for the issues, MRs and other to-do list items that have to be handled, respectively. Well, our reviewer has them too:
 
 ![](../assets/img/04-branches-issues/G-merge-review/review-1.jpg){: .mx-auto.d-block :}
 
@@ -453,9 +472,9 @@ And of course, among the review requests, they have this:
 
 ![](../assets/img/04-branches-issues/G-merge-review/review-2.jpg){: .mx-auto.d-block :}
 
-(They may also access it from the "Code" category on the project page, of course.)
+> They may also access it from the "Code" category on the project page, of course.)
 
-Clicking on the link will just send them to the MR page itself, but what they can do to start the review process is just go to the Changes tab, just below the title and basic information:
+Clicking on the link will just send them to the MR page itself, but what they can do to start the review process is just go to the Changes tab, below the title and basic information:
 
 ![](../assets/img/04-branches-issues/G-merge-review/review-3.jpg){: .mx-auto.d-block :}
 
@@ -469,22 +488,22 @@ We haven't talked about this yet, but there are indeed three different tabs on a
 
 A few remarks here:
 
-* The number displayed aside the name of the tab is the number of files that were changed in one way or another (added, deleted, or modified contents). The number of actual red and/or green blocks that have to be read tends to be way greater, asChanges are all displayed below one another on the same page. For the reader's convenience:
-
-* If there are two or more changed files, they are displayed in a hierarchical way in a sidebar.
-* If there are more than 6 unchanged lines between two changes in the same file, only 3 lines around each change are shown for basic context, and clickable arrows make it possible to display more unchanged lines in case of need. Just below is an example taken from another project (it is okay if you have no idea what the actual code is about). Clicking the arrow just below "101" on the left, or below "104" on the right, would show me around 20 more lines (lines 102-122 for the file displayed on the left, which are the exact same lines as lines 105-125 on the right).
+* The number displayed aside the name of the tab is the number of files that were changed in one way or another (added, deleted, or modified contents). The number of actual red and/or green blocks that have to be read tends to be way greater, as there might be several changes in a single file, of course.
+* Changes are all displayed below one another on the same page. For the reader's convenience:
+  * If there are two or more changed files, they are displayed in a hierarchical way in a sidebar on the left-hand side of the window.
+  * If there are more than 6 unchanged lines between two changes in the same file, only 3 lines around each change are shown for basic context, and clickable arrows make it possible to display more unchanged lines in case of need.
 
 ![](../assets/img/04-branches-issues/G-merge-review/review-5.jpg){: .mx-auto.d-block :}
+> Here is an example taken from another project (it is okay if you have no idea what the actual code is about). Clicking the arrow just below "101" on the left, or below "104" on the right, would show me around 20 more lines (lines 102-122 for the file displayed on the left, which are the exact same lines as lines 105-125 on the right).
 
-There are useful for navigating the source code, but then, when you actually want to review the MR, there is basically one thing you have to know: a button will appear when you move your cursor in one of the columns that display line numbers.
+These are useful for navigating the source code, but then, when you actually want to review the MR, there is basically one thing you have to know: a button will appear when you move your cursor in one of the columns that display line numbers.
 
 ![](../assets/img/04-branches-issues/G-merge-review/review-6.jpg){: .mx-auto.d-block :}
 
 By clicking it, you will be able to type a comment about the specific line you picked. For instance, if you want to ask a simple question about this change from "warm" to "lukewarm" on line 1, just click on the button that appears when you hover over line 1 in the right column: this will open a text box for you to type your question.
 
 ![](../assets/img/04-branches-issues/G-merge-review/review-7.jpg){: .mx-auto.d-block :}
-
-> The buttons above the text box itself are mainly for formatting. One of them is not for formatting,
+> The buttons above the text box itself are for tex formatting, except one that we will learn more about in a few seconds.
 
 This question will be the first item in your code review, so just click the "Start a review" button, *et voilà*:
 
@@ -522,63 +541,66 @@ You can provide a summary comment if you want, or maybe approve the MR. By defau
 
 ![](../assets/img/04-branches-issues/G-merge-review/review-15.jpg){: .mx-auto.d-block :}
 
+{: .box-note}
+If you want more information about what should and should not be done in the context of a code review, I highly recommend [this article by Simon Tatham](https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/code-review-antipatterns/), a software engineer whose website is a huge collection of great stuff.
+
 One click later, our review is submitted, and our job is done! What does it look like from the outside?
 
 ## Fixing and accepting a MR
 
-Okay, someone reviewed my MR, **what a surprise**. So, back to the MR page, I already have some information:
+Okay, someone reviewed my MR, **what a surprise**. So, back to the MR page, I already have some information that appeared on the upper-right corner: there are two *unresolved threads*.
 
 ![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-1.jpg){: .mx-auto.d-block :}
 
 {: .box-success}
-**Threads** are a way of discussing specific points in an issue or MR. A thread can be opened by posting a comment and specifying that it has to open a thread, and each comment that is part of a review opens a thread. The page of an issue or MR always indicates the number of unresolved threads, if any.
+**Threads** are a way of discussing specific points in an issue or MR. A thread can be opened by posting a comment and specifying that it has to open a thread, and ***each comment that is part of a review opens a thread***. The page of an issue or MR always indicates the number of unresolved threads, if any.
 
-Threads can also make our workflow more secure. Let me explain: noticed how our current MR is still marked as "Ready to merge", despite the threads that were opened by the reviewer and are not resolved yet? If you want to avoid this (and this is probably what you should do, no matter what), go to the MR part of the project settings:
+> Threads can also make our workflow more secure. Let me explain: noticed how our current MR is still marked as "Ready to merge", despite the threads that were opened by the reviewer and are not resolved yet? If you want to avoid this (and this is probably what you should do, no matter what), go to the MR part of the project settings:
 
 ![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-parameters-1.jpg){: .mx-auto.d-block :}
 
-then find and check this box:
+> then find and check this box:
 
 ![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-parameters-2.jpg){: .mx-auto.d-block :}
 
-It does exactly what it says: merging is prohibited as long as threads are open, so that, in particular, every part of the review has to be taken into account!
+> It does exactly what it says: merging is prohibited as long as threads are open, so that, in particular, every part of the review has to be taken into account!
 
-Okay, let us scroll down a bit:
+Okay, back to our reviewing task. Let us scroll down a bit:
 
 ![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-2.jpg){: .mx-auto.d-block :}
 
 This is just a simple question, and I am sure of the answer. I shall just answer "yes, indeed" and mark the thread as resolved.
 
-![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-3.jpg){: .mx-auto.d-block :}
+![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-5.jpg){: .mx-auto.d-block :}
 
-A simple click on "Add comment now", and I am done with this one:
+A simple click on "Add comment now", and I am done with this one (as the "Resolve thread" box is checked):
 
-![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-4.jpg){: .mx-auto.d-block :}
+![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-6.jpg){: .mx-auto.d-block :}
 
 Anyone will be able to unresolve this thread if there is any concern about this specific point.
 
 Scrolling down again, the next item in the review is a bit more involved:
 
-![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-5.jpg){: .mx-auto.d-block :}
+![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-3.jpg){: .mx-auto.d-block :}
 
 I could be worried, but this "Apply suggestion" button is pretty good news! Let us scroll down a bit:
 
-![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-6.jpg){: .mx-auto.d-block :}
+![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-4.jpg){: .mx-auto.d-block :}
 
-Remember this suggestion thing? This is how it helps collaborators: changes that are suggested by reviewers can be directly applied, as one or several commits, and the corresponding threads are automatically closed! And this is why, as a reviewer, you should always consider this option. By doing this, you are not forcing anyone to accept your suggestion: they could still discuss it with you in order to reach a compromise or improvement, or they could still make their own changes, commit and push them, then request a second review from you.
+Remember this suggestion thing? This is how it helps collaborators: changes that are suggested by reviewers can be directly applied, as one or several commits, and the corresponding threads are automatically closed! And this is why, as a reviewer, you should always consider this option. By doing this, you are not forcing anyone to accept your suggestion: they can still discuss it with you, in the dedicated thread, in order to reach a compromise or improvement... or they can make their own changes, commit and push them, then request a second review from you.
 
 <div class="box-note" markdown="1">
 Note that the green and red colors in the two images above do not represent the same thing.
 
-* On the top image, the code block represents the part of the MR that the thread is about: it shows the difference between the source branch and the target branch (before the suggestion was made).
-* On the bottom image, the code block is all about the suggestion made by the reviewer: it shows the additional changes that are suggested (i.e., the code from the target branch does not appear here).
+* On the top part, the code block represents the part of the MR that the thread is about: it shows the difference between the source branch and the target branch (before the suggestion was made).
+* On the bottom part, the code block is all about the suggestion made by the reviewer: it shows the additional changes that are suggested on the target branch (i.e., the code from the source branch does not appear here).
 </div>
 
 I completely agree with this suggestion, so that I just have to click the "Apply suggestion" button:
 
 ![](../assets/img/04-branches-issues/H-accept-mr-and-threads/mr-threads-7.jpg){: .mx-auto.d-block :}
 
-> Instead of clicking the button, you may click the arrow on the right of this button and choose option "Add suggestion to batch". Doing so with other suggestions makes it possible to group these suggestions into a single commit.
+> Instead of clicking the button itself, you may choose to click the arrow on the right of it and choose option "Add suggestion to batch". Doing so with other suggestions makes it possible to group these suggestions into a single commit.
 
 A fresh commit is created from this suggestion, ready to be pushed. It just needs a proper "name":
 
@@ -594,15 +616,15 @@ The thread was automatically closed, and a new commit named "Replace teaspoon wi
 
 Also notice the "All threads resolved!" thingy. As I basically agreed with everything my reviewer had to say, and no other problem or possible improvement or disagreement was identified (otherwise, at least one thread would still be open!), I may choose to merge right now. Depending on your actual workflow, you may also request a review from another collaborator, or change your project settings so that one or several approvals are necessary before merging, or... This is pretty much up to you, at this point! But you should, **at least**, always request a review before merging anything to the main line of development.
 
-Time to merge!
+For now, time to merge!
 
 ![](../assets/img/04-branches-issues/H-accept-mr-and-threads/apply-merge-1.jpg){: .mx-auto.d-block :}
 
-What I have decided so far: I will squash my commits, and I will not delete source branch. I may as well check the "Edit commit message" box at this stage:
+What I have decided so far: I will squash my commits (they are all about a single "feature" and do not change a large number of lines and/or files), and I will not delete the source branch (...just in case). I may as well check the "Edit commit message" box at this stage:
 
 ![](../assets/img/04-branches-issues/H-accept-mr-and-threads/apply-merge-2.jpg){: .mx-auto.d-block :}
 
-The contents of these text boxes are the messages that GitLab would have applied. If I am OK with those, I can just go on without a care. Otherwise, I can of course change them.
+The contents of these text boxes are the messages that GitLab wants to use. If I am OK with those, I can just go on without a care. Otherwise, I can of course change them.
 
 Note that, despise the absence of a final "s" in "Edit commit message", two commits will actually appear. Alright, I guess, as long as the final result is the one we expect. Also, issue `#2` will be automatically closed (nice), and our MR will still be mentioned in issue `#1`.
 
@@ -622,7 +644,7 @@ Our first closed issue, and we did not click a single "Close" button. Depending
 
 # Commit graph {#graph}
 
-If you can visualize what our project now looks like and how branches interact with each order, congratulations! Otherwise, do not worry: Git knows, and GitLab will ask Git and give you even better drawings.
+If you can visualize what our project now looks like and how branches interact with each order, congratulations! Otherwise, do not worry: Git knows, and GitLab will ask Git and provide you with even nicer drawings.
 
 ## Getting the graph from Git
 
@@ -631,7 +653,7 @@ First, let us have a look from our personal computer:
 {: .box-success}
 The **history**, or even the **graph**, of a Git project can be displayed in a terminal by using variants of the `git log` command. A common (and convenient) command is `git log --graph --oneline`.
 
-There would be a lot to unpack here, but in a nutshell: `git log` is how you ask for the commit history, option `--graph` asks Git to draw a basic graph with this information, and `--oneline` specifies that each commit should be displayed on a single line. (Basically, `git log --graph` without the `--oneline` option is pretty hard to read.)
+There would be a lot to unpack here, but in a nutshell: `git log` is how you ask for the history (as seen from the branch you are currently on), option `--graph` asks Git to draw a basic graph with this information, and `--oneline` specifies that each commit should be displayed on a single line. (Honestly, `git log --graph` without the `--oneline` option yields something that is pretty hard to read.)
 
 <div class="box-note" markdown="1">
 A good practice, if you want to get a nice commit history by typing a command in your terminal, would be:
@@ -639,14 +661,14 @@ A good practice, if you want to get a nice commit history by typing a command in
 1. Playing with the `git log` command and its many options ([here is a nice reference](https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History)), until you find the format that suits you most.
 2. Creating an alias for the whole (probably pretty long) `git log`-based command that you enjoy. If you stumble upon somebody typing a Git command that you never heard about (most probably `git hist` or a variation of it) and getting a commit graph in return, this is exactly what they did. [Click here to see how to set Git aliases](https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases).
 
-On my computer, I typed something like `git config --global alias.hist 'log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short'`, so that I can use `git hist` as an alias for this Gosh-awful command, and `--global` means that I can use this alias on all my projects.
+On my computer, I used a command that looked like `git config --global alias.hist 'log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short'`, so that I can use `git hist` as an alias for this Gosh-awful command (and the `--global` option means that I can use this alias on all my projects).
 </div>
 
 Alright, so, for now, `git log --graph --oneline` it is:
 
 ![](../assets/img/04-branches-issues/I-graph/graph-1.jpg){: .mx-auto.d-block :}
 
-> These 7-character strings are automatically assigned commit identifiers. It is actually very nice to have them when you want to use more advanced features.
+> These 7-character strings at the beginning of each line are **commit hashes** -- for all intents and purposes, automatically assigned commit identifiers. It is actually very nice to have them when you want to use more advanced features, like [interactive rebasing]({{'/09-advanced#irebase' | relative_url }}) or [cherrypicking]({{'/09-advanced#cherrypick' | relative_url }}).
 
 I know, it has been a long time since we left our working copy, but we were still on branch `add-quantities` indeed! Let us switch to the main branch, use our log command again, and see how it goes. (Ten more points if you already guessed that something would be wrong *again*.)
 
@@ -660,13 +682,13 @@ At last! We can now see the feature branch, but also how it got squashed into a
 
 "Hey", you ask, "why do we have this triangle thing at the top?" Because that is exactly what we asked for: all commits replaced with a single one in our feature branch, and then, this branch being merged into the main branch.
 
-We could have made this history perfectly linear: our `cfc35aa` commit would then be on top of all others, in a nice straight line, with no additional merge commit. This would be called a "fast-forward merge", and honestly, this 101 tutorial has already delved into 201 territory several times 😉 More on that in the extra contents for those of you who *have* to know.
+We could have made this history perfectly linear: our `cfc35aa` commit would then be on top of all others, in a nice straight line, with no additional merge commit. This would be called a "fast-forward merge", and honestly, this 101 tutorial has already delved into 201 territory several times 😉 More on that [in the extra contents]({{'/09-advanced#rebase' | relative_url }}) for those of you who *have* to know.
 
 This was how you get commit graphs from your terminal. Let us now have a look at the graph given by GitLab.
 
 ## Getting the graph from GitLab
 
-Just go to the left-hand menu, from any page of the project, and go to `Code > Repository graph`:
+Just go to the left-hand menu, from any page of the project, and go to *Code > Repository graph*:
 
 ![](../assets/img/04-branches-issues/I-graph/graph-4.jpg){: .mx-auto.d-block :}
 
@@ -690,7 +712,7 @@ See that "Branches" button? Yup. That's the one.
 
 ![](../assets/img/04-branches-issues/J-cleaning-up/branch-cleanup-2.jpg){: .mx-auto.d-block :}
 
-There is a button to delete merged branches, which can be pretty surprising, but once we delve a bit into the internals of Git, you should be able to understand why it is basically a risk-free and incredibly cheap operation. For the moment, we want to delete branch `add-quantities`, and there is this trash can icon on the right. How tempting is *that*?
+There is a button to delete merged branches, which can be pretty surprising, but (trust me) when you know more about [the internals of Git]({{'/08-internals' | relative_url }}), you understand why this is basically a risk-free and incredibly cheap operation. For the moment, we want to delete branch `add-quantities`, and there is this trash can icon on the right. How tempting is *that*?
 
 ![](../assets/img/04-branches-issues/J-cleaning-up/branch-cleanup-3.jpg){: .mx-auto.d-block :}
 
@@ -727,7 +749,7 @@ If you need it at some point, there is a way of getting a list of existing branc
 git branch -vv
 ```
 
-For each branch in your working copy, you can see whether it is only local, linked to a branch in the repo, or linked to a branch that *used to* exist on the repo but is now gone. This is a simple output you may have:
+For each branch in your working copy, you can see whether it is only local, linked to a branch in the repo, or linked to a branch that *used to* exist on the repo but is now gone. This is a simplified output I got for a project I work on, shown here for illustrative purposes:
 
 ```raw
   fix-time-shift       4092ee0 [origin/fix-time-shift: gone] Check Internet connection
@@ -743,15 +765,15 @@ git fetch --prune
 git branch -vv | grep ': gone]'|  grep -v "\*" | awk '{ print $1; }' | xargs -r git branch -d
 ```
 
-We already know the first half: this make Git aware of which branches were deleted from the `origin`. What the second one does is using `git branch -vv` to get the same information as above, keep only the lines for branches whose `origin` counterpart is gone and that do not contain an asterisk (like the line for the branch you are currently on), fetch the corresponding branch names and call `git branch -d` on these.
+We already know the first half: make Git aware of which branches were deleted from the `origin`. What the second one does is using `git branch -vv` to get the same information as above, keep only the lines for branches whose `origin` counterpart is gone and that do not contain an asterisk (like the line for the branch you are currently on), fetch the corresponding branch names and call `git branch -d` on these.
 
 Of course, **use this trick with caution** (but note that it will never do anything to branches that are only local).
 
-# Extra: A note about forks {#fork-note}
+# Extra: a note about forks {#fork-note}
 
-I was recently told by a friend of mine that, in the company he is working for, MRs for branches basically do not exist; instead, they rely on MRs for *forks*. It so happens that there is this thing called forks, which essentially amounts to creating an exact copy of an existing project (history, branches and all) while keeping information about where it comes from. This makes it possible to exchange data both ways: the fork can be updated to follow the changes in the source project, and changes made in the fork can be pulled in the original project if they work, make sense, bring interesting features, etc.
+Just so you know, there is this thing called *forking*, which essentially amounts to creating an exact copy of an existing project (history, branches and all) while keeping information about where it comes from. This makes it possible to exchange data both ways: the fork can be updated to follow the changes in the source project, and changes made in the fork can be pulled in the original project if they work, make sense, bring interesting features, etc.
 
-This section is already pretty long as it is, and using issues and MRs inside a single project already leads to very efficient collaboration, but existing projects (open-source or not) made forks their *de facto* standard. You can check [this part of the "Advanced" section]({{'/09-advanced#fork' | relative_url }}) to learn more about this other way of managing a collaborative project.
+This section is already pretty long as it is, but you should know that, even though using issues and MRs inside a single project already leads to efficient collaboration, fork-based collaboration can be incredibly powerful, especially for large projects. There is [a full page about forks and Git workflows]({{'/06-forks' | relative_url }}) to learn more about all of this... when time comes. If you already heard about forks, be reassured: I did not forget about them!
 
 ----
 
diff --git a/05-good-practices.md b/05-good-practices.md
index 42d140e..73fbf89 100644
--- a/05-good-practices.md
+++ b/05-good-practices.md
@@ -33,9 +33,9 @@ At this stage, you probably got the message, but to reiterate, using issues is t
 * You can communicate efficiently, in a single place, about bugs, feature proposals, and so on.
 * The fact that issues can be explicitly assigned alleviates the risk of several people working on the same thing without knowing it.
 * You can choose which ones should be closed before the next milestone (typically, the next release), and GitLab provides you with simple tools for easy monitoring. (Milestones are not addressed in this tutorial, but they are very simple to use and pretty convenient. You may try as soon as your project actually approaches a milestone -- for preparing the release of your v0.1 for instance!)
-* Once issues are solved (e.g., bug were solved, features were implemented...), every piece of information about them is archived at the same place, for future reference.
+* Once issues are solved (e.g., bugs were solved, features were implemented...), every piece of information about them is archived at the same place, for future reference.
 
-However, if issues are written in haste and left to rot in a heap, all these efforts amount to nothing. To solve these problems, let us see how to use templates and how to tag issues with labels.
+However, if issues are hastily written and left to rot in a heap, all these efforts amount to nothing. To solve these problems, let us see how to use *templates* and how to tag issues with *labels*.
 
 {: .box-warning}
 I would argue that **templates are the most important feature to set up early in your project**. You may leave tags for later, but remember that they will be very useful as soon as your project starts to grow in size, age, and/or number of collaborators.
@@ -48,7 +48,7 @@ If you try to open a new issue in your project, have a look at the small message
 
 You even have a nice link to click, bringing you to a page on which you are explained how to [create an issue template](https://archives.docs.gitlab.com/15.11/ee/user/project/description_templates.html#create-an-issue-template). It is basically just a Markdown file, with the default contents you want to see on some issues, that you will commit to the main branch. That's it.
 
-But wait, there's more! You can have several issue templates, which is very convenient if you want to help your collaborators write informative issues for bugs, features proposals, refactoring, or anything else!
+Or is that? You can have several issue templates, which is very convenient if you want to help your collaborators write informative issues for bugs, features proposals, refactoring tasks, or anything else!
 
 Here is a simple example of a template for a feature request:
 
@@ -114,7 +114,7 @@ Great, I am already on the default branch and I just have to add the `.gitlab` f
 
 ![](../assets/img/05-good-practices/A-issue-template/issue-templates-3.jpg){: .mx-auto.d-block :}
 
-Oh no. I am on Mac OS (...shameful, I know), which creates a lot of `.DS_Store` files everywhere, and I do not want them on the repo, do I? Fortunately, Git tells me what to do to unstage a file. Let's follow the instructions, and remember that we would *really* like some files like this one to be left out of the repo by default (who knows, maybe we will do something about it pretty soon).
+Oh no. I am on Mac OS (...shameful, I know), which creates a lot of `.DS_Store` files everywhere, and I do not want them on the repo, do I? Fortunately, Git tells me what to do to unstage a file. Let's follow the instructions (that's `git restore --staged <file>`), and remember that we would *really* like some files like this one to be left out of the repo by default (who knows, maybe we will do something about it [pretty soon]({{'/05-good-practices#gitignore' | relative_url }})).
 
 ![](../assets/img/05-good-practices/A-issue-template/issue-templates-4.jpg){: .mx-auto.d-block :}
 
@@ -130,14 +130,14 @@ Let us preview it:
 
 ![](../assets/img/05-good-practices/A-issue-template/issue-templates-7.jpg){: .mx-auto.d-block :}
 
-How nice. I can now just go to the Write tab and replace what I have to replace, and... done!
+How nice. I can now just go back to the Write tab and replace what I have to replace, and... done!
 
-The better the templates, the better the issue descriptions: a good template should be clearly organized (use titles and subtitles -- the `#` character is your best friend in Markdown) and ask the right questions in the right order, so as to ensure that the person opening the issue will provide everyone will all needed information and/or explanations.
+The better the templates, the better the issue descriptions: a good template should be clearly organized (use titles and subtitles -- the `#` character is your best friend in Markdown) and ask the right questions in the right order, so as to ensure that the person opening the issue will provide everyone with all needed information and/or explanations.
 
 Green box time:
 
 {: .box-success}
-**Issue templates** are simple templates that anyone who opens an issue can choose from. They help users write issues efficiently, enforces a standard format for issue descriptions, and help distinguish between various types of issues (bugs, feature proposals, improvements, etc.)<br/>To create an issue template, just write it as a Markdown document, save it (as a `.md` file) in the `.gitlab/issue_templates` subfolder of the project, and commit to the default branch (which is `main` if you did not explicitly change it).
+**Issue templates** are simple templates that anyone who opens an issue can choose from. They help users write issues efficiently, enforce a standard format for issue descriptions, and help distinguish between various types of issues (bugs, feature proposals, improvements, etc.)<br/>To create an issue template, just write it as a Markdown document, save it (as a `.md` file) in the `.gitlab/issue_templates` subfolder of the project, and commit to the default branch (which is `main` if you did not explicitly change it).
 
 ### Labels
 
@@ -146,7 +146,7 @@ Our issues can also be tagged, which is a very convenient feature of GitLab (amo
 The most common use of tags is to state which parts of the software and/or its life cycle an issue refers to. These can be pretty generic tags like:
 
 * `backend` / `frontend` / `doc`;
-* `feature proposal` / `bug` / `performance` / `memory usage` / `CI/CD` (more on this last one later on);
+* `feature proposal` / `bug` / `performance` / `memory usage` / `CI/CD` (more on this last one [later on]({{'/05-good-practices#cicd' | relative_url }}));
 * a pointer to the most simple and quick tasks;
 * tags precisely identifying parts/features of the specific software you are working on, like module names, or steps in the particular data flow the software implements...
 
@@ -156,9 +156,12 @@ Your project, your rules! Just remember a few basics about issue tags:
 * When you create a tag, you will be able to choose a color for it. Think about a simple color code that will be easy to parse. For instance, red should only be used for bugs and/or urgent issues. Also, maybe you want to use the same "non-hostile" color for all tags that describe which parts of the software an issue is about.
 
 {: .box-warning}
-I have seen projects in which `todo`,`doing` and `done` tags were created, but one could argue that these are supposed to be the statuses of open issues with no assignee, open issues with an assignee, and closed issues, respectively.<br/>However, if you want to use [GitLab Issue Boards](https://docs.gitlab.com/ee/user/project/issue_board.html) (which give you a [Kanban](https://www.atlassian.com/agile/kanban/boards)-ish view of project issues), tags like `In dev` and `In review` can be used. The Issue Board can then be set up so that four columns are displayed: the Backlog (with all unassigned open issues), the "In dev" and "In review" columns (with all open issues with the corresponding tags), and the "Closed" column.
+I have seen projects in which `todo`,`doing` and `done` tags were created, but one could argue that these are supposed to be the statuses of open issues with no assignee, open issues with an assignee, and closed issues, respectively.
 
-In practice, creating and using tags is very simple. To create and manage tags, from the menu on the left side on your project page, go to Manage → Labels:
+{: .box-note}
+If you want to use [GitLab Issue Boards](https://docs.gitlab.com/ee/user/project/issue_board.html) (which give you a [Kanban](https://www.atlassian.com/agile/kanban/boards)-ish view of project issues), tags like `In dev` and `In review` can be used. The Issue Board can then be set up so that four columns are displayed: the Backlog (with all unassigned open issues), the "In dev" and "In review" columns (with all open issues with the corresponding tags), and the "Closed" column.
+
+In practice, creating and using tags is very simple. To create and manage tags, from the menu on the left side on your project page, go to *Manage > Labels*:
 
 ![](../assets/img/05-good-practices/B-issue-labels/issue-label-1.jpg){: .mx-auto.d-block :}
 
@@ -208,7 +211,7 @@ Okay, while we're at it... Remember this pesky `.DS_Store` file? These automatic
 
 One can also think of personal files that have no reason to be shared. I am not talking about your `passwords.txt` file. (Even though we will have to talk about it at some point, I mean... Dude.) But stuff like `.workspace` files, for all the VSCode users out there, should be yours and only yours.
 
-Finally, maybe even more importantly, your Git repo was probably created for one of several software pieces, which you will compile and run on your computer at some point. By doing this, you will create a lot of files and folders that should not be committed: subfolders like `/build` or `/packages`; compiled code with extensions `.o`, `.byte`, `.pyc` and others; files generated at runtime with extensions `.log`, `.tmp`, `.lock`...
+Finally, maybe even more importantly, your Git repo was probably created for one or several software pieces, which you will compile and run on your computer at some point. By doing this, you will create a lot of files and folders that should not be committed: subfolders like `/build` or `/packages`; compiled code with extensions `.o`, `.byte`, `.pyc` and others; files generated at runtime with extensions `.log`, `.tmp`, `.lock`...
 
 How to prevent these files from being committed? The main answer is called `.gitignore`. It is a simple file, at the root of the project, in which you declare which files should remain untracked. Here are several examples:
 
@@ -230,7 +233,7 @@ How to prevent these files from being committed? The main answer is called `.git
 .DS_Store
 ```
 
-* An option I really enjoy is that you can exclude all files with a specific name, *except* for a few specific ones, using `!`. For example, if you want to be able to commit and push file `/tests/initial_campaign.log` but exclude all other `.log` files:
+* An option I really enjoy is that you can exclude all files with a specific name, *except* for a few specific ones, using `!`. For example, if you want to update file `/tests/initial_campaign.log` on a regular basis, while excluding all other `.log` files:
 
 ```sh
 *.log
@@ -239,7 +242,7 @@ How to prevent these files from being committed? The main answer is called `.git
 
 Other possibilities (if you happen to ever need more options) are provided in [this nice page](https://www.atlassian.com/fr/git/tutorials/saving-changes/gitignore).
 
-Once your `.gitignore` file contains what you want it to contain (no worry though, you can change it anytime you have to), just commit and push it so that it is available to everyone.
+Once your `.gitignore` file contains what you want it to contain (no worry though, you can change it anytime you have to), just commit and push it to the main branch, so that it is available to everyone.
 
 This is now what happens if I try to stage a `.DS_Store` file:
 
@@ -306,9 +309,9 @@ The item list at the very end does not rely on basic Markdown syntax, but I reco
 
 ### MR options
 
-Maybe, one day, it will be possible to prevent a MR from being merged before all boxes are ticked. (At least, [the issue about this on GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/19830) gets frequent updates. It is something that can be done on GitHub, GitLab's main competitor, and a feature that many users, including premium ones, have been asking for years.) As it is, it still serves as a useful reminder for developers, which is why I decided to include general but useful things in my template, from the very obvious ("only code that compiles") to the easily forgettable ("update all documentation").
+Maybe, one day, it will be possible to prevent a MR from being merged before all boxes are ticked. (At least, [the issue about this on GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/19830) gets frequent updates. It is something that can be done on GitHub and a feature that many users, including premium ones, have been asking for years.) As it is, it still serves as a useful reminder for developers, which is why I decided to include general but useful things in my template, from the very obvious ("only code that compiles") to the easily forgettable ("update all documentation").
 
-Still, there are already a few (too few?) GitLab options that make it possible to enforce specific guardrails, so that you can decide under which conditions a MR can or cannot be merged. Let us click on the Settings → Merge Requests option of the project page:
+Still, there are already a few (too few?) GitLab options that make it possible to enforce specific guardrails, so that you can decide under which conditions a MR can or cannot be merged. Let us click on the *Settings > Merge Requests* option of the project page:
 
 ![](../assets/img/05-good-practices/D-mr-templates-and-options/thread-lock-1.jpg){: .mx-auto.d-block :}
 
@@ -333,7 +336,9 @@ Other options are made available to premium users. For now, we unfortunately hav
 
 ## Protecting branches {#protect}
 
-There is still a huge glaring problem that we want to solve: anyone can push *anything* to the `main` branch. Thus, why would anyone go through the hassle of creating a MR, instead of just pushing their changes? They know it *should* work fine, I guess. Hopefully. ...yeah, this is how catastrophes are born.
+There is still a huge glaring problem that we want to solve: anyone can push *anything* to the `main` branch. Thus, why would anyone go through the hassle of creating a MR, instead of just pushing their changes? They know it *should* work fine, I guess. Hopefully.
+
+...yeah, this is how catastrophes are born.
 
 Let us solve this problem by protecting the main branch.
 
@@ -343,8 +348,8 @@ A **protected branch** is a branch on which no direct push can be performed: the
 <div class="box-note" markdown="1">
 **For most projects, protecting the `main` branch is a necessity.** These are a few ways this will help:
 * By preventing direct pushes on `main` and only enabling MRs to impact this branch, it ensures that **the branch- and issue-based workflow will be enforced**. This helps with project tracking, thanks to all the tools available in GitLab, and prevents developers from fixing problems/bugs that were never documented.
-* **Project tracking is also made easier** by the fact that commits on the `main` branch come in batches, each batch coming from a MR that was created to solve a specific issue. On an unprotected branch, commits related to different bugs/features may be intertwined, which makes the history of the project opaque.
-* Coupled with testing (including automated testing via [CI pipelines]({{'/05-good-practices#cicd' | relative_url }})), it ensures that **every version of the software that reaches the `main` branch works as expected**. Of course, no test suite is 100% complete, but the code on `main` should at least meet basic requirements, which cannot be enforced on an unprotected branch.
+* **Project tracking is also made easier** by the fact that commits on `main` come in batches, each batch coming from a MR that was created to solve a specific issue. On an unprotected branch, commits related to different bugs/features may be intertwined, which makes the history of the project opaque.
+* Coupled with testing, it ensures that **every version of the software that reaches the `main` branch works as expected**. Of course, no test suite is 100% complete, but the code on `main` should at least meet basic requirements, which cannot be enforced on an unprotected branch.
 </div>
 
 To protect a branch, just go to the "Repository" settings from the page of your project, then expand the "Protected branches" section:
@@ -366,19 +371,19 @@ Now, no one *at all* can push on `main`. The only way to "push" changes on `main
 You may think this is a waste, but it is actually quite the opposite. If every change in the codebase is reviewed by at least one person, then there will be less undetected bugs and less "malpractices" (such as bad indentation, obscure names for methods or variables, methods that are not declared in the right class, overly long methods that should have been split, bad separation of concerns...). This results in reduced debugging efforts and lower technical debt, so that, overall, **you are actually wasting less time and effort by adding (the right) hoops to jump through**.
 
 {: .box-warning}
-If there are very few people working on a project, they are physically working from the same place and interact on a daily basis, the development process is very linear, *and* the software has no users yet, then you *might* want to skip this step, so as to keep your workflow as simple as possible. **In any other case, you should *absolutely* protect `main` from any direct push.**
+If there are very few people working on a project, physically working from the same place and interacting on a daily basis, with a very linear development process, for a software that has no users yet, then you *might* want to skip this step, so as to keep your workflow as simple as possible. **In any other case, you should *absolutely* protect `main` from any direct push.**
 
 To impact the `main` branch of every project in a group, you can go to the settings from the page of the group. In the "Repository" settings, expand the "Default branch" section:
 
 ![](../assets/img/05-good-practices/D-mr-templates-and-options/settings-protect-4.jpg){: .mx-auto.d-block :}
 
-You can choose another name for your initial branch (although choosing a name other than `main` only makes sense for specific Git workflows that are not addressed here), and pick default protection options for every project in this group -- these options can be overridden for any individual project, and are just the "default" options that are applied to a project when it is created in this group or one of its subgroups.
+You can choose another name for your initial branch (choosing a name other than `main` can make sense for [some Git workflows]({{'/06-forks#workflows' | relative_url }})), and pick default protection options for every project in this group -- these options can be overridden for any individual project, and are just the "default" options that are applied to a project when it is created in this group or one of its subgroups.
 
 However, notice that even the strongest level of protection proposed here is the one that I insisted was *not strong enough* for our needs: maintainers can push on `main`! If you want to prevent anyone from pushing to `main`, you will have to change the settings of every individual project. Sorry about that. Still strongly recommended, and it's just a few clicks for each project, so why not?
 
 ## Tags {#tags}
 
-In the life cycle of any software, there will be some versions that are, in a way, more important than others -- "milestones" of the project, if you will. If your software is deployed on a server somewhere and is used by people outside your team, these include the versions that are actually released. For pure researchware, the versions that are used for filling up the "Experimental results" section of an article are definitely important.
+In the life cycle of any software, there will be some versions that are, in a way, more important than others -- "milestones" of the project, if you will. If your software is deployed on a server somewhere and is used by people outside your team, these include the versions that are actually released. For pure researchware, the versions that are used for filling up the "Experimental results" sections of published articles are definitely important.
 
 So, it makes sense that you would want to tag these versions somehow and, then, be able to efficiently retrieve them. Git knows. And Git provides. Let us come back to our dummy (...yummy?) project. After a `git status` to check that we have nothing waiting to be committed, let us have a look at the graph of the project:
 
@@ -390,7 +395,7 @@ In the first case, I may use what is called a **lightweight tag**. It is, basica
 
 ![](../assets/img/05-good-practices/E-tags/git-tag-2.jpg){: .mx-auto.d-block :}
 
-I was not asked my SSH passphrase, and by now, I know what that means: this tag only exists in my working copy. I could have created a commit, tagged it, and then pushed, right? Well, yes, but the situation would be the same: tags are not pushed by default by `git push`. We will have to explicitly push our tag to the repo (aka `origin`):
+I was not asked my SSH passphrase, and by now, I know what that means: this tag only exists in my working copy. I could have created a commit, tagged it, and then pushed, right? Well, yes, but the situation would be the same: tags are not pushed by default by `git push`. We will have to explicitly push our tag to the repo:
 
 ![](../assets/img/05-good-practices/E-tags/git-tag-3.jpg){: .mx-auto.d-block :}
 
@@ -400,7 +405,7 @@ Deleting a tag? Easy peasy: just add `-d` (yup, `d` for **d**elete) to your `git
 
 ![](../assets/img/05-good-practices/E-tags/git-tag-4.jpg){: .mx-auto.d-block :}
 
-However, if you check Code → Tags on the project page...
+However, if you check *Code > Tags* on the project page...
 
 ![](../assets/img/05-good-practices/E-tags/git-tag-5.jpg){: .mx-auto.d-block :}
 
@@ -408,7 +413,7 @@ However, if you check Code → Tags on the project page...
 
 ![](../assets/img/05-good-practices/E-tags/git-tag-5bis.jpg){: .mx-auto.d-block :}
 
-The tag was deleted from the working copy, but still exists on the remote. You can delete it from the Tags webpage, using the small wastebin icon on the far right, or you can do this locally:
+The tag was deleted from the working copy, but still exists on the remote. You can delete it from the *Tags* webpage, using the small wastebin icon on the far right, or you can do this locally:
 
 ![](../assets/img/05-good-practices/E-tags/git-tag-6.jpg){: .mx-auto.d-block :}
 
@@ -428,7 +433,7 @@ Branch `main` can still grow: you made sure that this specific version of our co
 
 The question of what "detached HEAD" means is one that pops up *a lot* in discussions around Git. If you just want some very pragmatic recap, here it is:
 
-* You can basically "just have a look" at the tagged version of the code (or any commit for that matter, as checking out a commit using its hash is possible but will get you in a "detached HEAD" state.
+* You can basically "just have a look" at the tagged version of the code (or any commit for that matter, as checking out a commit using its hash -- the hexadecimal thingy associated with it -- is possible but will get you in a "detached HEAD" state).
 * However, *changes you commit in a "detached HEAD" state will **not** be saved when you switch back to a branch, unless you create a new branch or tag that references your commit*.
 
 If you want more information, the following info box is for you. You may skip it if you want. No hard feelings.
@@ -480,20 +485,20 @@ Now, considering that you have test suites that you can already run on your mach
 * [Enable CI/CD for your project](https://ci.inria.fr/doc/page/gitlab/#enabling-ci-on-a-gitlab-project) (somewhere in its settings, of course);
 * [Create a runner dedicated to your project](https://ci.inria.fr/doc/page/web_portal_tutorial/#getting-started) (basically, a virtual machine on which all tests will run), or [to the group itself](https://docs.gitlab.com/ee/ci/runners/runners_scope.html#group-runners) (it is shared between all projects in this group)... or do not create a runner, and just [use one that is shared by the whole `gitlab.inria.fr` instance](https://ci.inria.fr/doc/page/gitlab/#using-shared-runners-linux-only) (typically, if you know that you will only launch short jobs once in a while and can wait a bit more for the results);
 * [Install `gitlab-runner` on your runner](https://ci.inria.fr/doc/page/gitlab/#installing-runners-linux-windows-or-mac-os): this is the software that will be able to connect to the GitLab project, fetch the sources, run the tests and send the results back to GitLab;
-* [Register the runner](https://docs.gitlab.com/runner/register/) (you have to explicitly tell `gitlab-runner` which project it should access)
+* [Register the runner](https://docs.gitlab.com/runner/register/) (you have to explicitly tell `gitlab-runner` which project it should access);
 * [Start working on your CI pipeline](https://docs.gitlab.com/ee/ci/quick_start/index.html#create-a-gitlab-ciyml-file): this is done through a YAML file (the syntax is pretty simple, actually), that has to be called `.gitlab_ci.yml` and put in the root folder of the project, in which you declare the "stages" of your pipeline, and the "jobs" that compose these stages.
 
 Your best sources of information (at least, for starters) include the [official CI/CD pipeline page](https://docs.gitlab.com/ee/ci/pipelines/) on the GitLab docs, the [keyword reference page](https://docs.gitlab.com/ee/ci/yaml/index.html) on the same docs, and the whole [CI Inria portal](https://ci.inria.fr/).
 
-A few simple examples of job declarations for the `.gitlab-ci.yml` file are given [here]({{'/09-advanced#gitlab-ci' | relative_url }}), but you should *absolutely* have a look at the more numerous (and better!) examples available in the [GitLab CI/CD gallery](https://gitlab.inria.fr/gitlabci_gallery). Made for you, with love.
+A few simple examples of job declarations for the `.gitlab-ci.yml` file are given [near the end of this very tutorial]({{'/09-advanced#gitlab-ci' | relative_url }}), but you should *absolutely* have a look at the more numerous (and better!) examples available in the [GitLab CI/CD gallery](https://gitlab.inria.fr/gitlabci_gallery). Made for you, with love.
 
 # Everyday use {#everyday}
 
 Let us assume that we basically set everything above. What a beautiful, nearly professional project we have. However, this does not mean that we can now do whatever we want and everything will be fine in the long run, because magic does not exist (at least, not in the world of Git and GitLab):
 
-* Issue and MR templates are very helpful, but even if you use them, you have to think about what you will write to fill in the blanks, how you will write it so that everyone gets on the same page... and **this is even worse for commits**: there is nothing that can be put in place in order to ensure that commit messages are "informative enough", or "clear enough".
+* Issue and MR templates are very helpful, but even if you use them, you have to think about what you will write to fill in the blanks, how you will write it so that everyone gets on the same page... and **this is even worse for commits**: there is nothing (except sophisticated [pre-commit hooks]({{'/09-advanced#git-hooks' | relative_url }}), but hey) that can be put in place in order to ensure that commit messages are "informative enough", or "clear enough".
 * The most important branches of the project are protected, but you may still be able to do whatever you want everywhere else, including **absolutely messing up with the history of your feature branches**. Depending on your project setup, this may not be very risky (because of main branch protection and automated testing), but this will increase the rate at which you will have to solve conflicts and make them way harder to solve. In other words, you will be wasting time and resources on preventable problems.
-* You have a functioning CI pipeline? Great! Just remember that **tests do not write/update themselves**. If you forget this simple fact, your CI pipeline will end up testing a past version of your code, which will help no one.
+* You have a functioning CI pipeline? Great! Just remember that **tests do not write/update themselves**. If you forget this simple fact, your CI pipeline will end up testing a past, probably way simpler, version of your code, which will help no one.
 
 So, here we go: good commit messages, clean history, testing. Let's do this.
 
@@ -511,7 +516,7 @@ This also proves pretty difficult sometimes: commits might get terrible messages
 Please do not do this. If anything goes wrong in the future and these commits need to be inspected, someone (probably yourself) will hate you. So, once you reached a stage when you think your changes should be committed, take a few seconds to close your eyes, breathe deeply, appreciate the fact that you are making progress even if you are not realizing yet, maybe burn some incense (if you are working from home), and reflect on the changes you made. How could you describe them, clear as day, to someone other than yourself? This is what you should write after `git commit -m`.
 
 {: .box-success}
-There are several ways of writing "good" Git commits. A pretty popular one (for good reasons, in my opinion) is to think about how you would explain your commit in a single sentence starting with ***"Once applied, the changes in this commit will..."***. This forces you to use action verbs, which is an effective way of describing the changes in terms of what their direct impact on the code is.
+There are several ways of writing "good" Git commits. A pretty popular one (for good reasons, in my opinion) is to think about how you would explain your commit in a single sentence starting with ***"Once applied, the changes in this commit will..."***. This forces you to use action verbs, which is an effective way of describing the changes in terms of what their direct impact on the code and/or app is.
 
 If you can only come up with a message that is longer than a tweet (this is what they were called before Twitter became X) and/or contains three or more action verbs, this can mean two things: either you are still making it too complex by delving into technical details, or you made too many "small" changes that probably could have been contained in several commits. (It is not too late to unstage your changes, then create several "atomic" commits.)
 
@@ -528,7 +533,7 @@ The basic principle would be: **keep branching simple**. You probably do not nee
 {: .box-success}
 **The clearer your development process is, the simpler your branching will be.** Basically, for implementing a specific feature, you should be able to partition the global effort into a small number of tasks (implementing prerequisites, then subfeatures), and split those tasks into simple ("atomic") subtasks. You may open short-lived subbranches for the tasks, and the commits in each subbranch should match the subtasks.
 
-If you do so, the "commit message" problem solves itself.
+If you do so, the "commit message" problem also solves itself.
 
 Note that opening subbranches may not even be required in the first place. For example, solving a simple issue by fixing a few typos, writing a single new method, and refactoring before pushing, does not require parallel work by several people for a whole month. In such cases, forget about subbranches: just open a feature branch, do what has to be done, and open a MR.
 
@@ -542,7 +547,10 @@ You want to add or remove a few files? Also easy: just `git add` or `git rm` any
 
 Of course, if you want to do both at the same time, you can replace the `--no-edit` with `-m "Here is my new commit message"`!
 
-And as usual, **please do not do this with an already pushed commit**. You would end up in a situation where the origin and your working copy diverge, as the last commit would be different from one to the other. In other words, this is perfect for situations when you commit changes and immediately go "aw crap" (or whatever you actually say out loud when you screw up, Git is curse-word-agnostic).
+{: .box-warning}
+As usual, **please do not do this with an already pushed commit**. You would end up in a situation where the origin and your working copy diverge, as the last commit would be different from one to the other.
+
+In other words, this is perfect for situations when you commit changes and immediately go "aw crap" (or whatever you actually say out loud when you screw up, Git is curse-word-agnostic).
 
 ## Going further with rebasing {#further}
 
@@ -558,9 +566,9 @@ This is a nice way of ending up with a linear history instead of one where sever
 
 Let us go even further. Pretty conveniently, `git rebase` provides you with option `-i`, or `--interactive`, in which you are able to reorder, rename, squash and discard the selected commits before moving them on top of the specified branch. This helps make the repo history clearer, and as long as said commits were still in your working copy only, no one gets hurt.
 
-Now, imagine you use `git rebase -i` for moving commits *where they already are*. Well, this will just let you manage your commits and clean up your history, which can be pretty nice before making your work public, right? In other words, you may very well implement things in disorder, make stupid mistakes that you fix five commits later, come back to a task because you forgot to implement unit tests... and, once everything works as expected, "tidy up your room" so that the branch you will actually be pushing has the best possible commits with clear messages. (Yes, this is also a way of turning terrible commit messages into readable and informative ones.) [This article on the GitLab blog](https://about.gitlab.com/blog/2020/11/23/keep-git-history-clean-with-interactive-rebase/) provides pretty good explanations.
+Now, imagine you use `git rebase -i` for moving commits *where they already are*. Well, this will just let you manage your commits and clean up your history, which can be pretty nice before making your work public, right? In other words, you may very well implement things in disorder, make stupid mistakes that you fix five commits later, come back to a task because you forgot to implement unit tests... and, once everything works as expected, "tidy up your room" so that the branch you will actually be pushing has the best possible commits with clear messages. [This article on the GitLab blog](https://about.gitlab.com/blog/2020/11/23/keep-git-history-clean-with-interactive-rebase/) provides pretty good explanations. (And, before you ask, yes, this is also a way of turning terrible commit messages into readable and informative ones.) 
 
-So, yeah, ask your doctor if rebasing is good for you! Which brings us to some important advice:
+Ask your doctor if rebasing is good for you! Which brings us to some important advice:
 
 {: .box-warning}
 **Do not rebase something that was already pushed!** Changing the public history of a project is not only widely considered rude, but also a source of conflicts (between what a branch looks like and what your collaborators' computers think it looks like) that will only result in an even more confusing project history once the immediate problems are solved.<br/>(Advanced: The only exception to this rule is when a project was set up so that merging branches is only allowed in *fast-forward* mode. In this case, a rebase can be performed **just before merging**, and deleting the branch as soon as it is merged is then a good practice.)
diff --git a/06-forks.md b/06-forks.md
index 1107e5b..15ffd81 100644
--- a/06-forks.md
+++ b/06-forks.md
@@ -83,7 +83,7 @@ The form you have to fill to actually create the MR is basically the same, excep
 1. If the original project is not a private project, that basically means that you are offering some code to a "public" codebase. It can make sense for the community that developed this codebase in the first place to have their word, and what better way of letting them contribute than directly allowing them to commit?
 2. This "Contribution guidelines" stuff does not come from nowhere. Well... Turns out there is a reason why GitLab suggests you (and so did I) to create a file named `CONTRIBUTING.md` at the root of any project to which other people might contribute. This link is a pointer to the `CONTRIBUTING.md` file of the project you forked. The closer you follow these guidelines, the higher the chances of your MR being accepted.
 
-{: .box-info}
+{: .box-note}
 On the other hand, if you want to work from a given snapshot of a project without contributing to it, you may even remove the "fork relationship", by delving into Settings → Advanced -- at your own risk, though, because you will also be missing out on new features, bug fixes, etc. (Once again, you should still make sure that you are complying with the licence(s) of the original project.)
 
 ## Closing remarks {#fork-closing}
diff --git a/09-advanced.md b/09-advanced.md
index ee33677..f7ae8f3 100644
--- a/09-advanced.md
+++ b/09-advanced.md
@@ -36,7 +36,7 @@ The last three lines are more interesting:
 * In particular, a branch that I did not know of, called `readme-structure-change`, now exists. This branch now exists in my working copy: a `git switch` to this branch will be lightning fast, because my computer holds all necessary data to switch to this branch.
 * In a similar fashion, my computer did not know about tag `checkpoint`; now it does.
 
-{: .box-info}
+{: .box-note}
 "New content fetched from the repo? Well," you may ask, "where else could it come from? Duh!" First, please do not duh me, thank you, and second, a Git project may very well have several remotes associated to it. Our current use (with GitLab, Github and others) relies on a central repo, but nothing technically prevents you from collaborating on a Git project with several people in a decentralized network... apart from the fact that it is pretty difficult, messy, and no one does that anymore.
 
 Note, however, that `git fetch` may bring you new content, but that it will not delete content that does not exist anymore on the repo.
@@ -83,7 +83,7 @@ The title of this section is admittedly vague, so let us have a brief look at wh
 
 There are already a lot of very good resources about `git rebase`, probably because it is a command that seems pretty frightening at first, but is actually a very powerful and beautiful command. This is why I will only get to the "why" and the 101 here, before providing you a few links. Also, this is kind of a "pure Git" command, which is not exactly the scope of this tutorial.
 
-{: .box-info}
+{: .box-note}
 **Rebasing** consists in taking a sequence of commits and moving them somewhere else in the graph of the project.
 
 ...okay, well, that's... pretty vague. Could I provide an example? Yeah, sure. Here is the most common use of rebasing:
@@ -432,7 +432,7 @@ Step 1 remains basically unchanged: cherrypick the commit on the branch to which
 
 Some nice people on Stack Overflow would then advise you to force-push: `git push --force` would overwrite `origin/main` with the contents of your local `main` branch, thus effectively erasing the last commit from public history... You may already know why this is terrible advice in most cases, right? If one or several of your collaborators already pulled the branch as it was seconds ago, with your "wrong" commit on it, then you just made the situation worse for everyone. Once again (for the last time, pinky promise): **Do not rewrite public history unless absolutely necessary.**
 
-{: .box-info}
+{: .box-note}
 By "absolutely necessary", I basically mean "one of the public commits contains sensitive, private information", and even then, you will have to carefully agree with all members of the project on a specific date at which public history will be rewritten, explicitly tell them what commands they will have to use, make sure that absolutely everyone understands and agrees... Yeah, basically, try and avoid such a terrible situation.
 
 "Okay, so, I cannot just delete my commit, because it is already public. What do I do?" Well, pretty simple: you *revert* it.
diff --git a/index.md b/index.md
index 8a946ad..0184acb 100644
--- a/index.md
+++ b/index.md
@@ -119,6 +119,21 @@ In any case, [please do not hesitate to contact me](mailto:mathias.malandain@inr
 
 ----
 
+# Changelog
+
+## September 3rd, 2024
+
+A lot of changes! Thanks to the careful proofreading and insightful advice of Sébastien Gilles, this site got way better.
+
+* New section ["Forks and workflows"]({{'/06-forks' | relative_url }}) gathers information about the three most common Git workflows and how they may or may not fit your projects.
+* A lot of small changes and fixes here and there. If you are driven by FOMO, I guess you should reread the whole thing. Sorry about that.
+
+## January 16th, 2024
+
+The first complete version is online!
+
+----
+
 # Future improvements
 
 For any suggestion you may have, please do not hesitate to [send me an e-mail](mailto:mathias.malandain@inria.fr?subject=About%20your%20Git(Lab)%20tutorial).
\ No newline at end of file
-- 
GitLab


From 28819023d16476c51234413d3c886405352c5796 Mon Sep 17 00:00:00 2001
From: Mathias Malandain <mathias.malandain@inria.fr>
Date: Mon, 9 Sep 2024 10:56:28 +0200
Subject: [PATCH 20/20] Fix sections 6 to 9: proofreading + missing paragraph
 on local excludes

---
 06-forks.md     |  39 ++++++++++--------
 07-vscode.md    |  24 ++++++------
 08-internals.md |  12 +++---
 09-advanced.md  | 102 ++++++++++++++++++++++++++++++++++++------------
 4 files changed, 116 insertions(+), 61 deletions(-)

diff --git a/06-forks.md b/06-forks.md
index 15ffd81..f2d8e02 100644
--- a/06-forks.md
+++ b/06-forks.md
@@ -14,7 +14,7 @@ There is even a way of collaborating on a project in which none of the developer
 
 # Forks and merge requests {#fork}
 
-I was recently told by a friend of mine that, in the company he is working for, MRs for branches basically do not exist; instead, they rely on MRs for *forks*. For experienced users, there are indeed a lot of advantages to this workflow. To explain this in further detail, we first have to know what a fork is.
+I was recently told by a friend of mine that, in the company he used to work for, MRs for branches basically do not exist; instead, they rely on MRs for *forks*. For experienced users, there are indeed a lot of advantages to this workflow. To explain this in further detail, we first have to know what a fork is.
 
 ## Forking {#forking}
 
@@ -44,7 +44,7 @@ Instead, the button is white:
 
 ![](../assets/img/06-forks/fork-01.jpg){: .mx-auto.d-block :}
 
-Yup. Just click on the "Forks" button, and you will have the option to fork to a project, with the name you want to give it, and the place you want to put it in (either your namespace, which is still a bad option in most cases, or a group/subgroup):
+Yup. Just click on the "Forks" button, and you will have the option to fork the project. You will be asked the name you want to give your fork and where you want to put it (either your namespace, which is [still a bad option in most cases]({{'/02-creating-projects#groups' | relative_url }}), or a group/subgroup):
 
 ![](../assets/img/06-forks/fork-02.jpg){: .mx-auto.d-block :}
 
@@ -66,7 +66,7 @@ Well, guess who will help you?
 
 ![](../assets/img/06-forks/fork-04.jpg){: .mx-auto.d-block :}
 
-This appeared on the page of the fork (i.e., my "variant" of the project) as soon as I committed some stuff on it. I can totally open an MR in the source project:
+This appeared on the page of my fork as soon as I committed some stuff on it. I can totally open an MR into the source project:
 
 ![](../assets/img/06-forks/fork-05.jpg){: .mx-auto.d-block :}
 
@@ -74,17 +74,17 @@ I can also, at any point, open an MR from the sidebar, on the webpage of my fork
 
 ![](../assets/img/06-forks/fork-06.jpg){: .mx-auto.d-block :}
 
-The form you have to fill to actually create the MR is basically the same, except for this new gizmo at the bottom of the page:
+The form you have to fill to actually create the MR is basically [the same as with "local" MRs]({{'/04-branches-issues#mr' | relative_url }}), except for this new gizmo at the bottom of the page:
 
 ![](../assets/img/06-forks/fork-07.jpg){: .mx-auto.d-block :}
 
 ...that's two gizmos. Well. So:
 
 1. If the original project is not a private project, that basically means that you are offering some code to a "public" codebase. It can make sense for the community that developed this codebase in the first place to have their word, and what better way of letting them contribute than directly allowing them to commit?
-2. This "Contribution guidelines" stuff does not come from nowhere. Well... Turns out there is a reason why GitLab suggests you (and so did I) to create a file named `CONTRIBUTING.md` at the root of any project to which other people might contribute. This link is a pointer to the `CONTRIBUTING.md` file of the project you forked. The closer you follow these guidelines, the higher the chances of your MR being accepted.
+2. This "Contribution guidelines" stuff does not come from nowhere. Well... Turns out there is a reason why GitLab suggests (and [so did I]({{'/05-good-practices#cicd' | relative_url }})) to create a file named `CONTRIBUTING.md` at the root of any project to which other people might contribute. This link is a pointer to the `CONTRIBUTING.md` file of the project you forked. The closer you follow these guidelines, the higher the chances of your MR being accepted.
 
 {: .box-note}
-On the other hand, if you want to work from a given snapshot of a project without contributing to it, you may even remove the "fork relationship", by delving into Settings → Advanced -- at your own risk, though, because you will also be missing out on new features, bug fixes, etc. (Once again, you should still make sure that you are complying with the licence(s) of the original project.)
+On the other hand, if you want to work from a given snapshot of a project without contributing to it, you may even remove the "fork relationship", by delving into *Settings > Advanced* -- at your own risk, though, because you will also be missing out on new features, bug fixes, etc. (Once again, you should still make sure that you are complying with the licence(s) of the original project.)
 
 ## Closing remarks {#fork-closing}
 
@@ -94,19 +94,22 @@ GitLab will tell you when you are behind the forked project:
 
 ![](../assets/img/06-forks/fork-update.jpg){: .mx-auto.d-block :}
 
-...but you have to deal with the consequences (even when you have less commits to pull than here). As a result, you will have to think about your workflow when you work on a fork. Or you may just [read GitLab's page about forkflows](https://docs.gitlab.com/ee/user/project/repository/forking_workflow.html).
+...but you have to deal with the consequences (even when you have less commits to pull than here). As a result, you will have to think about your workflow when you work on a fork (more on that below).
 
-**As a forked** (...forkee?), remember that the forks of your project depend on the project itself. For instance, this is the reminder I will get if I want to delete a project that was forked:
+**As a forked** (...forkee?), remember that the forks of a project depend on the project itself. For instance, this is the reminder I will get if I want to delete a project that was forked:
 
 ![](../assets/img/06-forks/fork-08.jpg){: .mx-auto.d-block :}
 
 This is a nice summary of why your project maybe should not be deleted: the higher the numbers, the more you should think about it. Plus, it could be considered rude.
 
-Regarding forks, there is a simple rule to be remembered: ***If you delete a private project, its forks will be deleted too.*** If you delete a *public* project, one of its forks will be automatically picked as the new "original project" from which all other forks are forked off.
+Regarding forks, there is a simple rule to be remembered:
+
+{: .box-warning}
+***If you delete a private project, its forks will be deleted too.*** If you delete a *public* project, one of its forks will be automatically picked as the new "original project" from which all other forks are forked off.
 
 # Git workflows {#workflows}
 
-It is now time to get back to our first concern: which workflow should we use for a project? Indeed, there exist several different workflows for Git projects, and which one you actually implement depends on the needs you have. Let us have a look at the three "main" workflows that emerged, each with its benefits and drawbacks:
+It is now time to get back to our first concern: which workflow should we use for a project? Indeed, there exist several different workflows for Git projects, and which one you actually implement depends on the needs you have. Let us have a look at the three "main" workflows that emerged, each with its benefits and drawbacks.
 
 ## Trunk-based workflow {#trunk-wf}
 
@@ -117,12 +120,12 @@ Up to this point, we have been using this workflow without giving it a name. The
 
 A trunk-based workflow can be very efficient for [DevOps](https://www.atlassian.com/devops/what-is-devops), a software engineering practice in which continuous feedback is used for improving the codebase very often (pretty much on a daily basis). It is also a good fit for prototype projects with a small dedicated team of developers. However, it can hinder long-term research and development efforts; its agile characteristics do not always fit the needs of researchware. It also does not scale well: as your development team grows larger, the constant merging and conflict resolution will become more of a hindrance.
 
-A small change to this workflow consists in updating a `develop` branch on a regular basis, while the `main` branch will only get updated once in a while, typically when everything is working ("no test should ever fail on the `main` branch"). This approach, sometimes referred to as **feature branching**, is arguably "cleaner" but suffers from the same drawbacks. However, if you push it a bit further, you can get to...
+A small change to this workflow consists in updating a `develop` branch on a regular basis, while the `main` branch will only get updated once in a while, typically when everything is working ("no test should fail on the `main` branch"). This approach, sometimes referred to as **feature branching**, is arguably "cleaner" but suffers from the same drawbacks. However, if you push it a bit further, you can get to...
 
 ## Gitflow {#gitflow}
 
 {: .box-success}
-The **Gitflow** is a strict branching model centered on releases. It typically relies on two "main" branches, namely a `develop` branch and a `main` branch that only receives commits from `develop`, and adds release branches on which only release-ready versions of the codebase will be pushed, and several feature and hotfix branches with clearly-defined roles.
+**Gitflow** is a strict branching model centered on releases. It typically relies on two "main" branches, namely a `develop` branch and a `main` branch that only receives commits from `develop`, and adds release branches on which only release-ready versions of the codebase will be pushed, and several feature and hotfix branches with clearly-defined roles.
 
 Let us delve a bit further into this branching model:
 
@@ -130,9 +133,9 @@ Let us delve a bit further into this branching model:
 * Feature branches can only be branched off from `develop` and merge back to it. This is where features are developed, issues are handled, and so on. Nothing too fancy for the moment.
 * Release branches can only be branched off from `develop`, and they have to be merged back into both `develop` and `master`.
     * The basic idea is this: when the code on `develop` is "nearly ready" for a production release, let's say version `0.1` for the sake of illustration, create a branch called `release-0.1`. The code on this branch will only get updates like minor bug fixes and metadata updates. (Meanwhile, the `develop` branch is living its best life, probably incorporating some new features that will be part of version `0.2`!)
-    * When the release is ready, merge it into the `main` branch, where it will be given a tag (`v0.1` for example). Also merge it back to the `develop` branch, so that pre-release bugfixes get into the current working version!
+    * When the release is ready, merge it into the `main` branch, where it will be given a tag (`v0.1` for example). Also merge it back to the `develop` branch, so that pre-release bugfixes get into the current working version.
 * Hotfix branches can only be merged off from `main`, and must be merged back into both `main` and `develop`.
-    * Imagine that some bug shows its ugly head just after version 0.1 of your software is released. You can create a branch `hotfix-0.1` (or any other name starting with `hotfix-` indeed) from `main` and get one or several dedicated members of your team working on this branch to work on a fix.
+    * Imagine that some bug shows its ugly head just after version 0.1 is released. You can create a branch `hotfix-0.1` (or any other name starting with `hotfix-` indeed) from `main` and get one or several dedicated members of your team working on this branch to work on a fix.
     * Once the problem is fixed, a new minor version of the software (that would be `0.1.1` in our case) is ready to be released: merge it back into `main` with a nice `v0.1.1` tag, and merge it into `develop` so that the fix is now part of the "main" codebase.
     * Of course, hotfix branches can be created for any previous release if needed.
 
@@ -147,10 +150,14 @@ The **forkflow**, more commonly named **forking workflow**, consists in letting
 
 Typically, completed feature branches from a fork will be the object of MRs into the original project. It is then up to the maintainers of this project to integrate these new features and deal with releases. As such, the forkflow tends to rely on a branching model similar to Gitflow, except that features are developed in forks instead of new branches in the same project.
 
+Note that, as a forker, you will have to pull the changes from the original project on a regular basis while working on a feature: you do not want to rewrite some piece of code that was recently added by other contributors, and you want to be able to open a MR that is *merge-ready*, i.e., not too far behind the destination branch. You may [read GitLab's page about forkflows](https://docs.gitlab.com/ee/user/project/repository/forking_workflow.html) for further info.
+
 The forkflow is an ideal workflow for open-source projects, where possible contributors are basically "trusted third parties" that should be able to propose new features or fixes without being given write access to the project. However, advantages are not limited to the world of FOSS.
 
 In an active project with a lot of contributors, the history of the project will soon get overloaded with development branches. Even when enforcing naming conventions (none of which is a perfect solution) for branches, this can quickly become a mess. This will not happen with forks, so that the important branches of the original project will have a clearer history. As for the CI, it comes packaged with the rest of the project when you fork it! Just set a runner on your fork and you're good to go.
 
+
+
 # Personal takes {#personal-wf}
 
 In practice, as a project gets larger, I believe that you may very well "reinvent the wheel" one step at a time, by reorganizing your workflow once in a while, so as to address the development management problems when they are encountered... until you reach a workflow that actually looks incredibly similar to Gitflow.
@@ -160,9 +167,9 @@ Or you may converge to a workflow that takes advantage of features from differen
 {: .box-note}
 On the other hand, if, after reading tens of different articles on this topic and/or because of your own experience, you reach the conclusion that *one* specific workflow suits your needs for a given project, then you should not only implement this workflow as early as possible, but also **describe this workflow in simple terms in the `CONTRIBUTING.md` file at the root of your project**.
 
-To me, for most non-industrial projects, everything is fine as long as:
+To me, for most non-industrial projects, pretty much anything is fine as long as:
 * collaborators agree on, and are fine with, the workflow they use;
-* you still keep in mind that a workflow can be adapted, one step at a time, and *should* be adapted whenever efficiency problems arise.
+* you still keep in mind that a workflow can and *should* be improved or changed whenever efficiency problems arise.
 
 ----
 
diff --git a/07-vscode.md b/07-vscode.md
index dbe2ec3..3621326 100644
--- a/07-vscode.md
+++ b/07-vscode.md
@@ -26,7 +26,7 @@ We will also be talking about GitLab's very own web IDE, because yes, if you nee
 
 Everything that we already learned about [cloning a repo]({{'/03-linear-git-project#clone' | relative_url }}) still works. You may very well open a terminal in your VSCode window and proceed as before.
 
-Or you may get familiar with the Git menu in VSCode, the third one here:
+Or you may get familiar with the Git menu in VSCode. That's the third icon on the left:
 
 ![](../assets/img/07-vscode/A-open-and-clone/vscode-02bis.jpg){: .mx-auto.d-block :}
 
@@ -34,7 +34,7 @@ If you just click on it right now, unless you are already in a folder containing
 
 ![](../assets/img/07-vscode/A-open-and-clone/vscode-03.jpg){: .mx-auto.d-block :}
 
-To clone a Git repo, you have to get and copy its URL from its GitLab page, still in the same Clone menu as before:
+To clone a Git repo, you have to get and copy its URL from its GitLab page, still in the same *Clone* menu as before:
 
 ![](../assets/img/07-vscode/A-open-and-clone/vscode-04.jpg){: .mx-auto.d-block :}
 > Once again, you should get the SSH link, for future convenience.
@@ -75,7 +75,7 @@ I am asked the name of the file, and bam, I can work on it. A few changes later,
 
 ![](../assets/img/07-vscode/B-stage-commit/vscode-stage-02.jpg){: .mx-auto.d-block :}
 
-These colors and letters are not there for nothing:
+These colors and letters are not here for nothing:
 
 * **M** means *modified*: the contents of this file have changed since the last time the sources were fetched.
 * **U** means *untracked*: this is a file that the repo does not know of. (We just created it in our working copy, so... of course.)
@@ -104,7 +104,7 @@ Everything went fine, and now, only `recipe-v1.txt` is left in my uncommitted ch
 
 ![](../assets/img/07-vscode/B-stage-commit/vscode-stage-08.jpg){: .mx-auto.d-block :}
 
-Yay, we have options! The first one is the default, the second one makes it possible to amend the commit I just created (basically, change its contents and message while I have not pushed it), and I will not be delving into the last one. For now, I would just be content with committing, then pushing all my new commits. Guess what comes next?
+Yay, we have options! The first one is the default, the second one makes it possible to [amend the commit I just created]({{'/05-good-practices#amend' | relative_url }}) (which is okay, as I have not pushed it yet), "Commit & Push" does exactly what it says on the label, and "Commit & Sync" will actually commit, then pull, then push. For now, I would just be content with committing, then pushing all my new commits. Guess what comes next?
 
 ![](../assets/img/07-vscode/B-stage-commit/vscode-stage-09.jpg){: .mx-auto.d-block :}
 
@@ -114,17 +114,15 @@ Yep, I am reaching the repo, so that I have to provide my SSH passphrase. Once t
 
 Remember that `git fetch` will not modify your working copy: it will just update your computer's knowledge of the state of the repo. So, why not? Just remember that `git fetch` and its variants exist if, for a reason or another, you switch back to the editor-and-terminal workflow.
 
-Of course, if you clicked "No", everything is fine:
-
 # Collaborative development {#collab}
 
-We are still working on a single branch right now, but with changes being made from several places. Will VSCode still help us?
+We are still working on a single branch right now, but with changes being made from several places, will VSCode still help us?
 
 ...you bet it will.
 
 ## Using the Web IDE
 
-It's saturday morning, and someone just tested my recipe and told me that there were a few very important and urgent tweaks to apply to the recipe. Not huge changes, but the end result is a total mess without these. My work computer is still in my office, and I really want to commit and push a few changes right now. It might be time for the Web IDE to shine.
+It's saturday morning, and someone just tested my recipe and told me that there were a few very important and urgent tweaks to apply to the recipe. No huge changes, but the end result is a total mess without these. My work computer is still in my office, and I really want to commit and push a few changes right now. It might be time for the Web IDE to shine.
 
 I can just log in to GitLab and open the Web IDE to edit our recipe:
 
@@ -150,7 +148,7 @@ Also, there is no committing without pushing. I mean, where would the commit be
 And it's over. My changes are on the repo.
 
 {: .box-warning}
-There are cases in which you do **not** want to use the web IDE. Typically, if you have a bunch of tests that you should run before pushing code to the repo (or, even better, have plugged a pre-commit tool that will prevent you from pushing code that fails tests), then you should always work from your local working copy.
+There are cases in which you do **not** want to use the web IDE. Typically, if you have a bunch of tests that you should run before pushing code to the repo (or, even better, have plugged a [pre-commit hook]({{'/09-advanced#git-hooks' | relative_url }}) that will prevent you from pushing code that fails tests), then you should always work from your local working copy.
 
 ## Fetching and pulling
 
@@ -168,7 +166,7 @@ In both cases, my Git panel now has something to tell me:
 
 ![](../assets/img/07-vscode/D-fetch-pull/vscode-sync-07.jpg){: .mx-auto.d-block :}
 
-Basically, there are changes on the repo, and I should sync with it. The downwards arrow indicates that I should "download" changes, from the repo to my working copy. Alright then. "*click*"
+Basically, there are changes on the repo, hence I should sync with it. The downwards arrow indicates that I should "download" changes, from the repo to my working copy. Alright then. "*click*"
 
 ![](../assets/img/07-vscode/D-fetch-pull/vscode-sync-08.jpg){: .mx-auto.d-block :}
 
@@ -216,7 +214,7 @@ Well, yes, but VSCode is really friendly with conflicts. See, this is what is di
 
 Here, the green block is the "current change", i.e., the one that comes from my working copy, while the blue one is the "incoming change", i.e., the one made on the repo while I was looking away. I can choose whether to keep only one of the changes, or both at the same time.
 
-If none of these options are fine with me, I may also just edit the file by hand, as I did before: this whole part (starting with `<<<<<<<<` and ending with `>>>>>>>>` has been formatted by VSCode, but it is just good old editable code). Or I can do the same thing, but better, with the "Resolve in Merge Editor" option:
+If none of these options are fine with me, I can also just edit the file by hand, as I did before: this whole part (starting with `<<<<<<<<` and ending with `>>>>>>>>`) has been formatted by VSCode, but it is just good old editable code. Or I can do the same thing, but better, with the "Resolve in Merge Editor" option:
 
 ![](../assets/img/07-vscode/E-conflicts/vscode-conflict-09.jpg){: .mx-auto.d-block :}
 
@@ -295,7 +293,7 @@ Let us click on this one, then pick a source branch...
 
 This is not right, is it?
 
-There is something at play here: merging branches is something that Git can do by itself, but every nice option that is provided by GitLab (picking reviewers, discussing changes, running tests on a branch before it can be merged...) is forgotten here. Plain old Git merging in a pure unsafe and selfish way. You do **not** want to do this.
+There is something at play here: merging branches is something that Git can do by itself, but every nice option that is provided by GitLab (picking reviewers, discussing changes, running tests on a branch before it can be merged...) is forgotten here. This is just plain old Git merging, in a pure unsafe and selfish way. You do **not** want to do this.
 
 Let us make this absolutely clear:
 
@@ -317,7 +315,7 @@ Once again, pretty easy, except that it is not called "switching" but "checking
 
 ![](../assets/img/07-vscode/F-branch/vscode-branch-11.jpg){: .mx-auto.d-block :}
 
-It is basically the same thing. Well, in this specific case, it is *exactly* the same thing.
+It is basically the same thing. Well, in this specific case, it is *exactly* the same thing. [We went through part of this before]({{'/04-branches-issues#feature' | relative_url }}), but here are more details:
 
 {: .box-note}
 The `git switch` command was added for disambiguation purposes. The historical `checkout` command can be used in [several different ways](https://stackoverflow.com/a/57266005/21698549) (change branches, create a new branch, inspect a specific commit, remove fresh changes to specific files, ~~bring coffee and toasts, trigger the end of the universe as we know it~~ and, above all, make inexperienced Git users utterly confused). Now, there is `switch` for changing branches, `restore` to remove untracked changes from one or several files, and `checkout` for old-school masochists and IDEs. However, `git switch <branch>` and `git checkout <branch>` are equivalent, and `checkout` should not be deprecated in the foreseeable future.
diff --git a/08-internals.md b/08-internals.md
index a4c5874..8dc2c08 100644
--- a/08-internals.md
+++ b/08-internals.md
@@ -30,11 +30,11 @@ The basic object stored by Git is a *blob*. A blob stores the contents of a file
 
 What would be the most convenient way to give names to these blobs? A "naive" solution, like taking the whole path of the file in the project, removing special characters and appending an integer that is incremented by 1 in each commit, does not work that well. For instance, what if I just rename a file, or move it to a subfolder, between two commits? Should I duplicate this file?
 
-Instead, Git relies on [hashing](https://en.wikipedia.org/wiki/Hash_function) to compute a nice fixed-size sequence of hexadecimal digits from the contents of the file, which will yield the name of the file. These blobs are in the `.git/objects` folder, separated in subfolders named after the first 2 digits of the hash (for reasons I will not detail here -- efficiency, basically). Here, for instance:
+Instead, Git relies on [hashing](https://en.wikipedia.org/wiki/Hash_function) to compute a nice fixed-size sequence of hexadecimal digits from the contents of the file, which will yield the name of the file. These blobs are in the `.git/objects` folder, separated in subfolders named after the first 2 digits of the hash (for reasons I will not detail here -- efficiency, basically). Here is one of those files in my working copy:
 
 ![](../assets/img/08-internals/git-internals-2.jpg){: .mx-auto.d-block :}
 
-the contents of one of my files were hashed and its hash begins with `26d927bb21` (I decided against pasting the remaining 30 characters).
+The contents of one of my files were hashed and its hash begins with `26d927bb21` (I decided against pasting the remaining 30 characters -- you can thank me later).
 
 ## Trees
 
@@ -76,7 +76,7 @@ Hence, a single file that bears the name of the branch, and only contains a sing
 
 # Deltas {#deltas}
 
-There is still a huge aspect of Git that was not addressed yet. Imagine that you make one tiny change in a 1 MB file. From what we have seen so far, we would imagine that Git would take the new contents of the file, compare them to the blobs it already has in store (using their hashes), notice that these are indeed new contents, and... create a new blob weighing 1 MB to store the new contents? Come on, Git is more clever than this, isn't it?
+There is still a huge aspect of Git that was not addressed yet. Imagine that you make one tiny change in a 1 MB file. From what we have seen so far, we would imagine that Git would take the new contents of the file, compare them to the blobs it already has in store (using their hashes, for efficiency), notice that these are indeed new contents, and... create a new blob weighing 1 MB to store the new contents? Come on, Git is more clever than this, isn't it?
 
 Indeed it is. In such cases, Git will compute a delta, that is, the difference between the previous and current contents (pretty much like `diff` does with any pair of files in your standard Linux terminal), and store this delta instead of the whole file contents.
 
@@ -92,13 +92,13 @@ There are two main consequences of everything we just said. One of them is why G
 
 ## Git is unreasonably efficient
 
-To put it simply, I never stumbled upon a single occurrence of Git duplicating a file, and this is not even the most impressing thing about Git.
+To put it simply, I never stumbled upon a single occurrence of Git duplicating a file, and this is not even the most impressive thing about Git.
 
-Story time. The most atrocious commit I ever created on a project was when I reorganized all source files in a 4-year-old software project: I renamed a few files, sorted everything in fresh subfolders, used this new file structure to plug in a new build system, added/deleted several files, and changed a few things here and there in some of the source files themselves so that the build could be successful. It was (and still is) a mess of a commit. Close to 400 files were moved, some of them had parts of their contents changed, new files were created... I was even more worried as a few changes had been committed in the meantime, which meant that (because of the project settings) I would also have to rebase. I had pretty vivid nightmares the night before. How did it go?
+Story time. The most atrocious commit I ever created on a project was when I reorganized all source files in a 4-year-old software project: I renamed a few files, sorted everything in fresh subfolders, used this new file structure to plug in a new build system, added/deleted several files, and changed a few things here and there in some of the source files themselves so that the build could be successful. It was (and still is) a mess of a commit. Close to 400 files were moved, some of them had parts of their contents changed, new files were created... I was even more worried as a few changes had been committed in the meantime, which meant that (because of the project settings) I would also have to [rebase]({{'/09-advanced#rebase' | relative_url }}). I had pretty vivid nightmares the night before. How did it go?
 
 ...well, the whole thing took me 10 minutes. I had not used `git mv` once in the whole process, but Git was able to know which files were moved where, including the ones whose contents had been changed. A single conflict occurred in the whole rebasing stage, and it was a very simple one that I could solve in a handful of seconds. **This is how unreasonably good Git is.**
 
-And this all makes sense from how it handles all this stuff. Git has no difficulty detecting files that were merely moved or renamed, and it can then use sophisticated heuristics to minimize the total size of the deltas for the remaining files (typically, those that were moved *and* changed). It turns out that, when changes in files are not too extensive, Git identifies in the blink of an eye which file was moved where, *even when you also created and deleted files*. Nothing short of amazing, if you ask me.
+And this all makes sense from how it handles all this stuff. Git has no difficulty detecting files that were merely moved or renamed (because of hashes), and it can then use sophisticated heuristics to minimize the total size of the deltas for the remaining files (typically, those that were moved *and* changed). It turns out that, when changes in files are not too extensive, Git identifies in the blink of an eye which file was moved where, *even when you also created and deleted files*. Nothing short of amazing, if you ask me.
 
 But...
 
diff --git a/09-advanced.md b/09-advanced.md
index f7ae8f3..b77dbc2 100644
--- a/09-advanced.md
+++ b/09-advanced.md
@@ -15,7 +15,7 @@ Note, however, that `git fetch`, used by itself, will do more than just fetch th
 {: .box-success}
 Command `git fetch` is used to fetch the contents of the repo (or *remote*), including branches and tags previously unknown by your computer.
 
-This is an example of the output of `git fetch`:
+This is an example of an output of `git fetch`:
 
 ```
 remote: Enumerating objects: 6, done.
@@ -41,13 +41,13 @@ The last three lines are more interesting:
 
 Note, however, that `git fetch` may bring you new content, but that it will not delete content that does not exist anymore on the repo.
 
-That is, unless you ask. Remember [`git fetch --prune`]({{'/04-branches-issues#clean' | relative_url }})? This command will  delete references that do not exist anymore on the repo before it performs the actual fetching: this includes branches that were deleted from the repo -- hopefully after they were merged to active branches -- but not tags: option `--prune-tags` also has to be provided for deleting tags. (Alternatively, one may edit the `.git/config` file so that one line reads `fetch.pruneTags=true`: this tells Git to also prune tags when `git fetch --prune` is invoked.)
+That is, unless you ask. Remember [`git fetch --prune`]({{'/04-branches-issues#clean' | relative_url }})? This command will delete references that do not exist anymore on the repo before it performs the actual fetching: this includes branches that were deleted from the repo -- hopefully after they were merged to active branches -- but not tags: option `--prune-tags` also has to be provided for deleting tags. (Alternatively, one may edit the `.git/config` file so that one line reads `fetch.pruneTags=true`: this tells Git to also prune tags when `git fetch --prune` is invoked.)
 
 Once again, do not get too anxious about pruning: local branches that you never pushed to the repo will **not** be deleted. Pinky promise.
 
 # Cleaning up your local copy {#cleanup}
 
-Your Git repo was probably created for one of several software pieces, which you will compile and run on your computer at some point. By doing this, you will create files and folders that should not be committed: subfolders like -- hey, am I just repeating myself now?
+Your Git repo was probably created for one of several software pieces, which you will compile and run on your computer at some point. By doing this, you will create a lot of files and folders that should not be committed: subfolders like -- hey, [am I just repeating myself now?]({{'/05-good-practices#gitignore' | relative_url }})
 
 This is the thing: one might want to remove all untracked files (i.e., all files in their *local* working copy that are unknown by Git), or, more probably, to only remove the files that are ignored by Git (typically, those pesky compilation/runtime junk files -- and you know that one of those caches preprocessor variables and messes with your CMake, but you do not know which one it is and it has already been an hour, Gosh).
 
@@ -55,8 +55,8 @@ All hail `git clean`.
 
 * Use `git clean -f` to remove all untracked files from the current folder.
 * Add the `-d` option to do this recursively: all subfolders of the current folders will be cleaned up as well.
-* Add the `-X` option (uppercase `X`) to only remove files ignored by Git.
-* The lowercase `x` has a different meaning: `-x` will remove every untracked file, ignored or not. Say goodbye to any local file that you were holding dear.
+* Add the `-X` option (that's an uppercase `X`) to only remove files ignored by Git.
+* Lowercase `x` has a different meaning: `-x` will remove every untracked file, ignored or not. Say goodbye to any local file that you were holding dear.
 * Add the `-n` option for a dry run, so that you just know what would be removed without it. If you are OK with these changes, you may now run the same command without this option.
 
 {: .box-warning}
@@ -81,9 +81,9 @@ The title of this section is admittedly vague, so let us have a brief look at wh
 
 ## Rebasing (how to keep up with a source branch) {#rebase}
 
-There are already a lot of very good resources about `git rebase`, probably because it is a command that seems pretty frightening at first, but is actually a very powerful and beautiful command. This is why I will only get to the "why" and the 101 here, before providing you a few links. Also, this is kind of a "pure Git" command, which is not exactly the scope of this tutorial.
+There are already a lot of very good resources about `git rebase`, probably because it is a command that seems pretty frightening at first, but is actually a very powerful and beautiful command. This is why I will only get to the "why" and the 101 here, before providing you with a few links. Also, this is kind of a "pure Git" command, which is not exactly the scope of this tutorial.
 
-{: .box-note}
+{: .box-success}
 **Rebasing** consists in taking a sequence of commits and moving them somewhere else in the graph of the project.
 
 ...okay, well, that's... pretty vague. Could I provide an example? Yeah, sure. Here is the most common use of rebasing:
@@ -91,6 +91,7 @@ There are already a lot of very good resources about `git rebase`, probably beca
 * You created a local `feature` branch from a source branch (let's say `main`), and pushed a few commits on it.
 * Meanwhile, other commits were pushed to the `main` branch. Some of these commits probably change files that you also modified on the `feature` branch.
 * You know that you will go on working on `feature`, and that other people will go on pushing stuff on `main`. The longer it goes, the harder merging your branch in `main` will be.
+* What if you moved all your fresh commits to the latest commit on `main`? This is what rebasing your `feature` branch onto `main` will do.
 
 <div class="box-success" markdown="1">
 By rebasing, you can have your local branch "look like" it originates from the latest commit on the source branch, and during this rebasing process, you will be able to fix conflicts directly on your local branch. This means two things:
@@ -116,14 +117,14 @@ Oh, also, before we forget: rebasing is great, but for local branches only.
 
 A notable exception to the above rule is for projects in which a "fast-forward merge only" strategy is enforced, meaning that one just cannot merge a branch if it does not start from the head of the branch onto which it has to be merged. In such cases, though, one will typically work on a branch that was already marked as "ready for merging" (i.e., no more commits to push to this branch) and that will probably be deleted as soon as it is merged, so... No impact whatsoever on your collaborators.
 
-While we're at it, we should at least mention a huge advantage of a workflow in which everything has to be rebased before merging: this will prevent commits from different branches to end up mingled in the main development branch (which may very well happen without it, especially in large and active projects). Commits that were coming from a given branch will always end up being contiguous, which is a blessing both in terms of clarity and for bug fixing. The latter, in particular, is why squashing commits when merging is not a good strategy: go with rebasing instead.
+While we're at it, we should at least mention a huge advantage of a workflow in which everything has to be rebased before merging: this will prevent commits from different branches to end up mingled in the main development branch (which may very well happen without it, especially in large and active projects). Commits that were coming from a given branch will always end up being contiguous, which is a blessing both in terms of clarity and for bug fixing. The latter, in particular, is why squashing commits when merging is not a good strategy: in most cases, you should go with rebasing instead.
 
-If you are into reading stuff (which you probably are: this is Section 8 already), a pretty good reference about rebasing is [the Git SCM page about it](https://git-scm.com/book/en/v2/Git-Branching-Rebasing). It features just the right amount of examples, every time along with the basic commands needed in the corresponding situations. It just suffers from two minor issues:
+If you are into reading stuff (which you probably are, as you are currently reading Section 642279 of this thing), a pretty good reference about rebasing is [the Git SCM page about it](https://git-scm.com/book/en/v2/Git-Branching-Rebasing). It features just the right amount of examples, every time along with the basic commands needed in the corresponding situations. It just suffers from two minor issues:
 
-* At the time of writing, it still uses the kind of deprecated `git checkout` command instead of `git switch` (this is a pretty common thing we already discussed before).
+* At the time of writing, it still uses the kind of deprecated `git checkout` command instead of `git switch` (this is a pretty common thing [we already discussed before]({{'/04-branches-issues#feature' | relative_url }})).
 * It assumes that both branches are already up-to-date on your computer, which might not be the case: before running the rebase itself, remember to `pull` the changes on the branch you want to rebase into.
 
-If you want to understand the difference, in a nutshell, between rebasing and merging, there's [a nice page on the Atlassian website](https://www.atlassian.com/git/tutorials/merging-vs-rebasing) about this, as well as countless questions on Stack Overflow, some of which are [very short and to the point](https://stackoverflow.com/questions/804115/when-do-you-use-git-rebase-instead-of-git-merge), others [way more detailed](https://stackoverflow.com/questions/457927/git-workflow-and-rebase-vs-merge-questions).
+If you want to understand the difference, in a nutshell, between rebasing and merging, there's [a nice page on the Atlassian website](https://www.atlassian.com/git/tutorials/merging-vs-rebasing) about this, as well as countless questions and answers on Stack Overflow, some of which are [very short and to the point](https://stackoverflow.com/questions/804115/when-do-you-use-git-rebase-instead-of-git-merge), others [way more detailed](https://stackoverflow.com/questions/457927/git-workflow-and-rebase-vs-merge-questions).
 
 On the Atlassian page, there is also something about... *interactive* rebasing? What the heck is this? Well, glad you asked.
 
@@ -141,15 +142,51 @@ But what about filling two needs with one deed? (Not the most common idiom, but
 Speaking of which, of course:
 
 {: .box-error}
-Just like good ol' rebasing, interactive rebasing rewrites history. Hence, **do NOT use interactive rebasing on a branch that was already pushed on the remote**.
+Just like good ol' rebasing, interactive rebasing rewrites history. Hence, **do NOT use interactive rebasing on a branch that was already pushed to the origin**.
 
 The basic course of action is as follows:
-* See where you want to start rebasing: you can get, with commands such as `git log`, the short hash of the commit *just before* the sequence of commits you want to change (e.g., `4f29ed1`), or count the number of commits you want to take into account, in which case the `HEAD~<number_of_commits>` shortcut will come in handy (e.g., `HEAD~5` if you want to change the last 5 commits), or even manipulate the whole branch by using the name of the branch it was branched off (e.g., `main`).
-  * In the latter case, **make sure that you just rebased!** Otherwise, you will be trying to do two things at the same time (integrating fresh changes from `main` into your branch *and* manipulating your local history), and I absolutely do not recommend trying this.
+* See where you want to start rebasing: you can get, with [commands such as `git log`]({{'/04-branches-issues#graph' | relative_url }}), the short hash of the commit *just before* the sequence of commits you want to change (e.g., `4f29ed1`), or count the number of commits you want to take into account, in which case the `HEAD~<number_of_commits>` shortcut will come in handy (e.g., `HEAD~5` if you want to change the last 5 commits), or even manipulate the whole branch by using the name of the branch it was branched off (e.g., `main`).
+  * In the latter case, **make sure that you just rebased!** Otherwise, you will be trying to do two things at the same time (integrating fresh changes from `main` into your branch *and* manipulating your local history), and I do not recommend trying this. Safety first.
 * Launch the interactive rebase session (`git rebase -i 4f29ed1` or `git rebase -i HEAD~5` or `git rebase -i main` in our examples).
 * A text file appears, listing the commits and prefixing them with a short description of the operation to be performed on each commit. Every commit is initially prefixed with keyword `pick` (basically, keep the commit exactly as it is). Below this list is a long comment telling you what keywords can be used. Change the file as you want (you can also move lines up and down to reorder commits).
 * Save and exit (hopefully).
 
+Here is an illustration of what the text file might look like when you start rebasing:
+
+```
+pick 1fc6c95 Patch A
+pick 6b2481b Patch B
+pick c619268 A fix for Patch B
+pick fa39187 something to adddd to patch A
+pick 7b36971 something to move before patch B
+
+# Rebase 4f29ed1..7b36971 onto 4f29ed1
+#
+# Commands:
+#  p, pick = use commit
+#  r, reword = use commit, but edit the commit message
+#  e, edit = use commit, but stop for amending
+#  s, squash = use commit, but meld into previous commit
+#  f, fixup = like "squash", but discard this commit's log message
+#  x, exec = run command (the rest of the line) using shell
+#
+# If you remove a line here THAT COMMIT WILL BE LOST.
+# However, if you remove everything, the rebase will be aborted.
+#
+```
+
+Note that `git rebase -i` lists the commits in the opposite order of `git log`, i.e., in the standard chronological order, with the most recent being at the bottom. This makes things clearer to our poor monkey brains.
+
+This is what the same file might look like after you work on it (of course, you may or may not remove the commented lines):
+
+```
+pick 1fc6c95 Patch A
+fixup fa39187 something to adddd to patch A
+reword 7b36971 Prepare for Batch B
+pick 6b2481b Patch B
+fixup c619268 A fix for Patch B
+```
+
 I found [this very nice article by Blake DeBoer](https://dev.to/blakedeboer/beginners-guide-to-interactive-rebasing-1ob) about interactive rebasing, based on a not-that-simple example, and 100% performed from the terminal. It is, in my opinion, a way better introduction than the thousands of pages showing you the basics ("I want to rename a commit") and leaving you with that. I hope you enjoy.
 
 Also, you should definitely play with `git rebase -i` on a dummy project. You might very well realize that it is actually pretty simple to use, while also proving incredibly powerful in a lot of cases. This is how you gain confidence in your Git skills, and this is how, in a few weeks or months, your collaborators may thank you for providing them with very clear and organized branches in your MRs.
@@ -162,7 +199,7 @@ Well, yes and no. Here is a good use-case of cherrypicking: a hotfix was applied
 
 Here is another one: someone just fixed a bug on the development branch and I want to use the corresponding commit to patch the latest release of the project. However, a bunch of other stuff has been changed on `main` since then, so that I just cannot merge `main` into the release branch.
 
-Finally, to make things clear, this is a case in which cherrypicking is actually a bad idea: a feature that you are currently developing in a fresh branch (that was, say, branched off `main`) was already fully implemented by someone else, in several commits, on another branch `feature`. Even if you cherrypick all these commits at once, this will very likely yield merge conflicts, because cherrypicking is actually merging! What you probably want to do instead is go back on `main`, create a fresh branch from there, and merge `feature` in there.
+Finally, to make things clear, here is a case in which cherrypicking is actually a bad idea: a feature that you are currently developing in a fresh branch (that was, say, branched off `main`) was already fully implemented by someone else, in several commits, on another branch `feature`. Even if you cherrypick all these commits at once, this will very likely yield merge conflicts, because cherrypicking is actually merging! What you probably want to do instead is go back on `main`, create a fresh branch from there, and merge `feature` in there.
 
 Now, for more practical information:
 
@@ -189,9 +226,9 @@ Okay, let us delve into some pretty depressing scenarios.
 
 * Imagine that you just implemented a new test for your software, and it fails miserably. The problem is that this test focuses on a feature that was introduced a long time ago.
 * Or maybe you already had this test but forgot to run it for a pretty long time (...maybe you should think about implementing a [CI pipeline]({{'/05-good-practices#cicd' | relative_url }})). Like, you think you remember it passed last time you ran the whole test suite, in March of last year maybe?
-* Or this test only runs on the versions that are tagged for release, so that you know that this test passed on the latest release, but fails on the one you are currently preparing.
+* Or this test only runs on the versions that were tagged for release, so that you know that this test passed on the latest release, but fails on the one you are currently preparing.
 
-In any case, the current version of the codebase is "bad", the last "good" version was a bazillion commits ago, and these commits introduced changes in thousands of lines of code across tens of files.
+In any case, the current version of the codebase is "bad", the last known "good" version was a bazillion commits ago, and these commits introduced changes in thousands of lines of code across tens of files.
 
 You try and use your favorite debugger for fixing the issue, but you just end up trying to understand the logics of tens or hundreds of methods that you either did not write, or wrote eons ago. The situation looks dire.
 
@@ -200,7 +237,7 @@ Well, what if I told you that you may be able to restrict the scope of your inve
 {: .box-success}
 **`git bisect`** is a simple implementation of binary search (in Baguette: "recherche par dichotomie") that helps you pinpoint the commit that introduced a bug.
 
-It is actually pretty simple to use. In our case, we first want to save our test outside of our working copy. Once this is done, find a commit hash, a tag, anything that can identify a commit that you know did not "feature" the bug (maybe the one just before the first implementation of the method that your failing test focuses on, or maybe an old version in which the test actually passes if you are dealing with regression): let us denote it by `<good_commit>` (it could be something like `v2.1`, or `HEAD~100`, for instance`).
+It is actually pretty simple to use. In our case, we first want to save our test outside of our working copy. Once this is done, find a commit hash, a tag, anything that can identify a commit that you know did not "feature" the bug (maybe the one just before the first implementation of the method that your failing test focuses on, or maybe an old version in which the test actually passes if you are dealing with regression): let us denote it by `<good_commit>` (it could be something like `v2.1`, or `HEAD~100`, for instance).
 
 The magical command is
 
@@ -221,7 +258,7 @@ For more information and options, [the Git SCM website is there for you](https:/
 
 # About the `.git` folder {#hooks-excludes}
 
-[Earlier on in this tutorial]({{'/03-linear-git-project#clone' | relative_url }}), I told you that you might just pretend that there is no reason to touch anything in the `.git` folder that is automatically created when you initialize or clone a project.
+[Earlier in this tutorial]({{'/03-linear-git-project#clone' | relative_url }}), I told you that you might just pretend that there is no reason to touch anything in the `.git` folder, you know, the one that is [automatically created]({{'/08-internals#computer' | relative_url }}) when you initialize or clone a project.
 
 *Well, actually*, there are a few neat tricks that you can use there. Let us have a look at two of them: Git hooks, and local excludes.
 
@@ -297,8 +334,19 @@ In order for these hooks to be run, they must be renamed to the name of the hook
 
 * One solution is to provide hooks in another folder of the project and to give clear installation instructions to the developers, but the process might be made difficult for them by dependencies.
 * To alleviate these problems, you should have a look at the [pre-commit framework](https://pre-commit.com/), which will only ask your collaborators to install it (via `pip install pre-commit` for example) and run it (with `pre-commit install`). Despite its name, this framework not only supports the `pre-commit` hook but also 9 other client-side hooks (at the time of writing).
+
+In both cases, write down some clear information about how to setup and run these hooks in your `CONTRIBUTING.md` file.
 </div>
 
+## Local exclusion rules {#local-excludes}
+
+We already talked about this one [a few million words ago]({{'/05-good-practices#gitignore' | relative_url }}), but let us state the basics again:
+
+{: .box-success}
+File **`.git/info/exclude`** can be used for defining local exclusion rules. It will provide additional instructions to Git on which files/folders from *your* working copy should be ignored, without setting fixed rules for all developers on your project.
+
+There can be a lot of reasons why you would have some files in your working copy that you do not want to push to the origin. (And no, I am not talking about this `passwords.txt` file again, though... Come on.) Whatever those reasons are, there is no way you change the contents of the `.gitignore` file, a file that is pushed to the origin, hence shared with every collaborator on the project, for a couple files that no one else has in their working copy. Just edit the `.git/info/exclude` file instead, using the exact same syntax as in the `.gitignore` file.
+
 # CI pipelines: `.gitlab-ci.yml` examples {#gitlab-ci}
 
 Because of how CI pipelines can be configured, **no Git workflow is incompatible with CI**. A few examples are given here, in order to illustrate various use cases.
@@ -369,6 +417,8 @@ In a workflow where tags are only used (and pushed on the repo) for releases, it
       when: never
 ```
 
+If you have several jobs that should be triggered under the exact same conditions, you should absolutely define such rules... and then:
+
 * **Use a previously defined rule**
 
 ```yaml
@@ -384,12 +434,12 @@ ut:
     - for file in $(ls *.byte); do ./$file 2>&1 | tee unittests.log; done
     - make clean
   rules:
-    - !reference [.exclude_merge_request_rules, rules]
+    - !reference [.merge_request_only_rules, rules]
   artifacts:
     paths: ["tests/mr_tests/unittests.log"]
 ```
 
-The `rules` section may contain references to several previously defined rules, possibly alternating with other custom rules:
+By the way, a `rules` section may also contain references to several previously defined rules, possibly alternating with other custom rules:
 
 ```yaml
   rules:
@@ -414,12 +464,12 @@ This is the nice use case: you made your commit to the wrong branch, but it only
 {: .box-note}
 This is one of the many reasons why `git commit` and `git push` should not always be used together: you can create several commits without pushing any of them, so that you can safely review your work and local history before pushing anything. Other reasons include the possibility to [rebase on a regular basis]({{'/09-advanced#rebase' | relative_url }}) so as to make the development and merging process more streamlined, and/or [reorganize your branch before pushing it]({{'/09-advanced#irebase' | relative_url }}).
 
-Here is our use case (just change branch names for your use case): the last commit I created is on branch `main`, but it was actually intended for branch `feature`. (Oh, BTW, if `main` is protected, [which it should definitely be]({{'/05-good-practices#protect' | relative_url }}), Git will prevent you from pushing this commit, which will help you realize that you made a mistake and avoid making the situation worse.)
+Here is our use case (just change branch names depending on the mix-up you currently want to fix): the last commit I created is on branch `main`, but it was actually intended for branch `feature`. (Oh, BTW, if `main` is protected, [which it should definitely be]({{'/05-good-practices#protect' | relative_url }}), Git will prevent you from pushing this commit, which will help you realize that you made a mistake and avoid making the situation worse.)
 
-First, copy the hash of your commit: you will need it for what follows. Then, the process is basically in two steps: [cherrypick]({{'/09-advanced#cherrypick' | relative_url }}) the commit to the `feature` branch, and delete it from the `main` branch.
+First, copy the hash of your commit (a simple `git log` will do). Then, the process is basically in two steps: [cherrypick]({{'/09-advanced#cherrypick' | relative_url }}) the commit to the `feature` branch, and delete it from the `main` branch.
 
 * Step 1: `git switch feature` (switch to the branch on which the commit should go), `git cherry-pick <commit_hash>` (create a new commit that applies the same changes on `feature` as your misplaced commit did on `main`);
-* Step 2: `git switch main` (switch back to the branch where you wrongly committed in the first place), then `git reset --hard HEAD~1` (reset branch to its state one commit ago, which actually deletes the last commit).
+* Step 2: `git switch main` (switch back to the branch where you wrongly committed in the first place), `git reset --hard HEAD~1` (reset the branch to its state one commit ago, which actually deletes the last commit).
 
 {: .box-warning}
 Remember that `git reset --hard HEAD~1` will undo and delete the changes from the last commit, while `git reset --soft HEAD~1` would just "uncommit" them but keep them in your working copy as untracked changes. We can safely use option `--hard` here, because the changes in question were just applied to another branch *and* have absolutely nothing to do on the current branch: this is one of the rare instances where using `git reset --hard` is "safe".
@@ -444,11 +494,11 @@ This will work, because you do not have to rewrite public history: instead, you
 
 Of course, this means that the history of the branch will now contain two commits that basically cancel each other, the second one bearing the message `Revert "<message of the original commit>"`. There is now evidence that you screwed up at some point. Your collaborators *know*. Your credibility is lost. Nothing will ever be the same again.
 
-...just kidding. Maybe one or two of them will notice, and they will be like "eh, happens to the best of us", or "wait, how do you revert a commit? I didn't know this existed", depending on who you work with.
+...just kidding. Maybe one or two of them will notice, and they will be like "eh, happens to the best of us", or "wait, how do you revert a commit? I didn't know this existed", depending on whom you work with.
 
 So, to sum up:
 
-* Step 1: `git switch feature` (switch to the branch on which the commit should go), then `git cherry-pick <commit_hash>` (create a new commit that applies the same changes on `feature` as your misplaced commit did on `main`);
+* Step 1: `git switch feature` (switch to the branch on which the commit should go), `git cherry-pick <commit_hash>` (create a new commit that applies the same changes on `feature` as your misplaced commit did on `main`);
 * Step 2: `git switch main` (switch back to the branch where you wrongly committed in the first place), `git revert <commit_hash>` (create a fresh commit that undoes the changes introduced by your misplaced commit), `git push` ("undo" your mistake on the origin).
 
 ----
-- 
GitLab