diff --git a/content/tutorials/git_rewrite_history/.gitignore b/content/tutorials/git_rewrite_history/.gitignore
new file mode 100644
index 000000000..c64a71a52
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/.gitignore
@@ -0,0 +1,2 @@
+/.quarto/
+output
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/_extension.yml b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/_extension.yml
new file mode 100644
index 000000000..52a98aa15
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/_extension.yml
@@ -0,0 +1,62 @@
+title: Reveal.js quarto extension with corporate identity of the Flemish government
+author: Thierry Onkelinx
+version: 0.0.1
+contributes:
+ knitr:
+ opts_chunk:
+ echo: false
+ message: false
+ warning: false
+ fig-height: 5.7
+ fig-width: 12
+ formats:
+ revealjs:
+ theme: [default, slides.scss]
+ css: entity.css
+ transition: convex
+ width: 1244
+ height: 700
+ navigation-mode: vertical
+ controls-layout: bottom-right
+ controls-tutorial: true
+ slide-number: c/t
+ show-slide-number: all
+ slide-level: 2
+ email-obfuscation: javascript
+ embed-resources: true
+ chalkboard: false
+ preview-links: true
+ output-file: index.html
+ df-print: kable
+ progress: true
+ csl: research-institute-for-nature-and-forest.csl
+ template: partials/template.html
+ template-partials:
+ - partials/title-slide.html
+ format-resources:
+ - research-institute-for-nature-and-forest.csl
+ - css/entity.css
+ - fonts/FlandersArtSans-Bold.ttf
+ - fonts/FlandersArtSans-Light.ttf
+ - fonts/FlandersArtSans-Medium.ttf
+ - fonts/FlandersArtSans-Regular.ttf
+ - fonts/Inconsolata-Bold.ttf
+ - fonts/Inconsolata-Light.ttf
+ - fonts/Inconsolata-Medium.ttf
+ - fonts/Inconsolata-Regular.ttf
+ - img/flanders-en-intermediate.png
+ - img/flanders-en-slide.png
+ - img/flanders-en-title.png
+ - img/flanders-nl-intermediate.jpg
+ - img/flanders-nl-slide.jpg
+ - img/flanders-nl-transparent.png
+ - img/flanders-nl-title.png
+ - img/inbo-en-black.jpg
+ - img/inbo-en-title.png
+ - img/inbo-en-white.png
+ - img/inbo-nl-black.png
+ - img/inbo-nl-title.png
+ - img/inbo-nl-white.png
+ filters:
+ - filters/translations.lua
+ - filters/url.lua
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/css/entity.css b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/css/entity.css
new file mode 100644
index 000000000..913c5ec77
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/css/entity.css
@@ -0,0 +1,107 @@
+.trapezium {
+ background: var(--flandersqmd-level1-trapezium);
+}
+
+.reveal h1, .reveal h1 code {
+ color: var(--flandersqmd-level1-colour);
+}
+
+.reveal h2, .reveal h2 code {
+ color: var(--flandersqmd-level2-colour);
+}
+
+.reveal .title, .reveal .title code {
+ color: var(--flandersqmd-title-colour);
+}
+
+.sidebar {
+ background-color: var(--flandersqmd-sidebar-bg);
+}
+
+.sidebar-tussen {
+ background-color: var(--flandersqmd-level1-bg);
+}
+
+.sidebar-url {
+ color: var(--flandersqmd-sidebar-colour);
+}
+
+.sidebar-url-tussen {
+ color: var(--flandersqmd-sidebar-tussen-colour);
+}
+
+.title-entity {
+ color: var(--flandersqmd-title-border);
+}
+
+caption {
+ color: var(--flandersqmd-level2-colour);
+}
+
+figcaption {
+ color: var(--flandersqmd-level2-colour);
+}
+
+.reveal .slide aside, .reveal .slide div.aside {
+ color: var(--flandersqmd-footnote);
+}
+
+.panel-tabset [role=tablist] {
+ border-bottom-color: var(--flandersqmd-border);
+}
+
+.panel-tabset [role=tab] {
+ border-top-color: var(--flandersqmd-border);
+ border-left-color: var(--flandersqmd-border);
+ border-right-color: var(--flandersqmd-border);
+}
+
+.panel-tabset [role=tab][aria-selected=true] {
+ border-top-color: var(--flandersqmd-border);
+ border-left-color: var(--flandersqmd-border);
+ border-right-color: var(--flandersqmd-border);
+}
+
+.reveal div.callout.callout-note {
+ border-left-color: var(--flandersqmd-callout-note-border);
+}
+
+.reveal div.callout.callout-note.callout-style-default .callout-title{
+ background-color: var(--flandersqmd-callout-note-bg);
+}
+
+.reveal div.callout.callout-tip {
+ border-left-color: var(--flandersqmd-callout-tip-border);
+}
+
+.reveal div.callout.callout-tip.callout-style-default .callout-title{
+ background-color: var(--flandersqmd-callout-tip-bg);
+}
+
+.reveal div.callout.callout-caution {
+ border-left-color: var(--flandersqmd-callout-caution-border);
+}
+
+.reveal div.callout.callout-caution.callout-style-default .callout-title{
+ background-color: var(--flandersqmd-callout-caution-bg);
+}
+
+.reveal div.callout.callout-warning {
+ border-left-color: var(--flandersqmd-callout-warning-border);
+}
+
+.reveal div.callout.callout-note.warning-style-default .callout-title{
+ background-color: var(--flandersqmd-callout-warning-bg);
+}
+
+.reveal div.callout.callout-important {
+ border-left-color: var(--flandersqmd-callout-important-border);
+}
+
+.reveal div.callout.callout-important.callout-style-default .callout-title{
+ background-color: var(--flandersqmd-callout-important-bg);
+}
+
+.photographer {
+ color: var(--flandersqmd-title-colour);
+}
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/filters/translations.lua b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/filters/translations.lua
new file mode 100644
index 000000000..0fbc02d75
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/filters/translations.lua
@@ -0,0 +1,225 @@
+function is_empty(s)
+ return s == nil or s == ''
+end
+
+function entity_en(entity, level)
+ local result
+ if (entity == "INBO") then
+ result = {
+ url = "https://www.vlaanderen.be/inbo/en",
+ entity_name = "Research Institute for Nature and Forest (INBO)",
+ }
+ if is_empty(level) or tonumber(pandoc.utils.stringify(level)) < 2 then
+ result.entity_title_logo = "inbo-en-black.jpg"
+ else
+ result.entity_title_logo = "inbo-en-white.png"
+ end
+ else
+ result = {
+ url = "invalid `flandersqmd.entity`"
+ }
+ end
+ result.flanders_title_logo = "flanders-en-title.png"
+ result.flanders_alt = "Flanders, state of the art"
+ result.title_logo_style = "max-width: 205px;"
+ return result
+end
+
+function entity_nl(entity, level)
+ local result
+ if (entity == "INBO") then
+ result = {
+ url = "https://www.vlaanderen.be/inbo",
+ entity_name = "Instituut voor Natuur- en Bosonderzoek (INBO)",
+ flanders_alt = "Vlaanderen is wetenschap"
+ }
+ if is_empty(level) or tonumber(pandoc.utils.stringify(level)) < 2 then
+ result.flanders_title_logo = "flanders-nl-intermediate.jpg"
+ result.entity_title_logo = "inbo-nl-black.png"
+ result.title_logo_style = "max-width: 245px;"
+ else
+ result.flanders_title_logo = "flanders-nl-transparent.png"
+ result.entity_title_logo = "inbo-nl-white.png"
+ result.title_logo_style = "max-width: 250px;"
+ end
+ else
+ result = {
+ url = "invalid `flandersqmd.entity`"
+ }
+ end
+ return result
+end
+
+function translation(lang, entity, level)
+ if (lang == "nl-BE") then
+ result = entity_nl(entity, level)
+ else
+ result = entity_en(entity, level)
+ end
+ return result
+end
+
+function display_person (person, i)
+ res = ""
+ if is_empty(person.name) then
+ res = '
!!! flandersqmd.authors element ' .. i .. ' has no name element!!!
'
+ return res
+ end
+ if is_empty(person.name.given) then
+ res = '!!! flandersqmd.authors element ' .. i .. ' has no given element under name!!!
'
+ return res
+ end
+ if is_empty(person.name.family) then
+ res = '!!! flandersqmd.authors element ' .. i .. ' has no given element under name!!!
'
+ return res
+ end
+ if is_empty(person.email) then
+ res = pandoc.utils.stringify(person.name.given) .. ' ' .. pandoc.utils.stringify(person.name.family)
+ else
+ res = res .. '' .. pandoc.utils.stringify(person.name.given) .. ' ' .. pandoc.utils.stringify(person.name.family) .. ''
+ end
+ if (is_empty(person.orcid)) then
+ return res
+ end
+ res = res .. '
'
+ return res
+end
+
+function title_author(author)
+ if is_empty(author) then
+ return '!!! Missing flandersqmd.author !!!'
+ end
+ z =''
+ for i, person in pairs(author) do
+ z = z .. display_person(person, i) .. ' '
+ end
+ return pandoc.RawInline('html', z)
+end
+
+function levelcss (entity)
+ local css
+ css = ':root {\n'
+ css = css .. ' --flanders-white: #FFFFFF;\n'
+ css = css .. ' --inbo-darkblue: #282A72;\n'
+ css = css .. ' --inbo-darkblue-40: #282A7266;\n'
+ css = css .. ' --inbo-darkgreen: #006635;\n'
+ css = css .. ' --inbo-darkgreen-40: #00663566;\n'
+ css = css .. ' --inbo-orange: #EF972C;\n'
+ css = css .. ' --inbo-orange-40: #EF972C66;\n'
+ css = css .. ' --inbo-yellow: #FFCD34;\n'
+ css = css .. ' --inbo-yellow-40: #FFCD3466;\n'
+ css = css .. ' --inbo-red: #BE3254;\n'
+ css = css .. ' --inbo-red-40: #BE325466;\n'
+ if (entity == "inbo") then
+ css = css .. ' --inbo-black: #000000;\n'
+ css = css .. ' --inbo-gray: #8E9DA7;\n'
+ css = css .. ' --inbo-fushia: #C04384;\n'
+ css = css .. ' --inbo-blue: #356196;\n'
+ css = css .. ' --inbo-lightblue: #BDDDD7;\n'
+
+ css = css .. ' --flandersqmd-border: var(--inbo-fushia);\n'
+ css = css .. ' --flandersqmd-callout-note-border: var(--inbo-darkblue);\n'
+ css = css .. ' --flandersqmd-callout-note-bg: var(--inbo-darkblue-40);\n'
+ css = css .. ' --flandersqmd-callout-tip-border: var(--inbo-darkgreen);\n'
+ css = css .. ' --flandersqmd-callout-tip-bg: var(--inbo-darkgreen-40);\n'
+ css = css .. ' --flandersqmd-callout-caution-border: var(--inbo-orange);\n'
+ css = css .. ' --flandersqmd-callout-caution-bg: var(--inbo-orange-40);\n'
+ css = css .. ' --flandersqmd-callout-warning-border: var(--inbo-yellow);\n'
+ css = css .. ' --flandersqmd-callout-warning-bg: var(--inbo-yellow-40);\n'
+ css = css .. ' --flandersqmd-callout-important-border: var(--inbo-red);\n'
+ css = css .. ' --flandersqmd-callout-important-bg: var(--inbo-red-40);\n'
+ css = css .. ' --flandersqmd-footnote: var(--inbo-gray);\n'
+ css = css .. ' --flandersqmd-level1-colour: var(--flanders-white);\n'
+ css = css .. ' --flandersqmd-level1-trapezium: var(--inbo-fushia);\n'
+ css = css .. ' --flandersqmd-level2-colour: var(--inbo-fushia);\n'
+ css = css .. ' --flandersqmd-link-colour: var(--inbo-blue);\n'
+ css = css .. ' --flandersqmd-sidebar-bg: var(--inbo-fushia);\n'
+ css = css .. ' --flandersqmd-sidebar-colour: var(--flanders-white);\n'
+ css = css .. ' --flandersqmd-sidebar-tussen-colour: var(--inbo-fushia);\n'
+ css = css .. ' --quarto-hl-fu-color: var(--inbo-black);\n'
+ css = css .. ' --r-link-color: var(--inbo-blue);\n'
+ css = css .. ' --r-link-color-hover: var(----inbo-lightblue);\n'
+ css = css .. ' --r-main-color: var(--inbo-black);\n'
+ else
+ css = css .. ' --flanders-canary-yellow: #FFED00;\n'
+ css = css .. ' --flanders-dark-yellow: #F0D70F;\n'
+ css = css .. ' --flanders-black: #3C3D3C;\n'
+ css = css .. ' --flanders-gray: #D5D5D5;\n'
+ css = css .. ' --flanders-dark-blue: #215E9E;\n'
+ css = css .. ' --flanders-light-blue: #32B2E9;\n'
+
+ css = css .. ' --flandersqmd-border: var(--flanders-dark-yellow);\n'
+ css = css .. ' --flandersqmd-footnote: var(--flanders-gray);\n'
+ css = css .. ' --flandersqmd-level1-trapezium: var(--flanders-canary-yellow);\n'
+ css = css .. ' --flandersqmd-level1-colour: var(--flanders-black);\n'
+ css = css .. ' --flandersqmd-level2-colour: var(--flanders-dark-yellow);\n'
+ css = css .. ' --flandersqmd-link-colour: var(--flanders-dark-blue);\n'
+ css = css .. ' --flandersqmd-sidebar-bg: var(--flanders-canary-yellow);\n'
+ css = css .. ' --flandersqmd-sidebar-colour: var(--flanders-black);\n'
+ css = css .. ' --flandersqmd-sidebar-tussen-colour: var(--flanders-black);\n'
+ css = css .. ' --quarto-hl-fu-color: var(--flanders-black);\n'
+ css = css .. ' --r-link-color: var(--flanders-dark-blue);\n'
+ css = css .. ' --r-link-color-hover: var(--flanders-dark-blue);\n'
+ css = css .. ' --r-main-color: var(--flanders-black);\n'
+ end
+ css = css .. ' --flandersqmd-callout-note-border: var(--inbo-darkblue);\n'
+ css = css .. ' --flandersqmd-callout-note-bg: var(--inbo-darkblue-40);\n'
+ css = css .. ' --flandersqmd-callout-tip-border: var(--inbo-darkgreen);\n'
+ css = css .. ' --flandersqmd-callout-tip-bg: var(--inbo-darkgreen-40);\n'
+ css = css .. ' --flandersqmd-callout-caution-border: var(--inbo-orange);\n'
+ css = css .. ' --flandersqmd-callout-caution-bg: var(--inbo-orange-40);\n'
+ css = css .. ' --flandersqmd-callout-warning-border: var(--inbo-yellow);\n'
+ css = css .. ' --flandersqmd-callout-warning-bg: var(--inbo-yellow-40);\n'
+ css = css .. ' --flandersqmd-callout-important-border: var(--inbo-red);\n'
+ css = css .. ' --flandersqmd-callout-important-bg: var(--inbo-red-40);\n'
+ css = css .. ' --flandersqmd-title-colour: var(--flanders-white);\n'
+ css = css .. ' --flandersqmd-title-border: var(--flanders-white);\n'
+ css = css .. ' --flandersqmd-level1-bg: var(--flanders-white);\n'
+ css = css .. ' --r-main-font: flanders_art_sanslight, Calibri, Source Sans Pro, Helvetica, sans-serif;\n'
+ css = css .. ' --r-heading-font-weight: 400;\n'
+ css = css .. '}\n'
+ return css
+end
+
+return {
+ {
+ Meta = function(meta)
+ if is_empty(meta.flandersqmd) then
+ meta.title = "No `flandersqmd` entry found in yaml"
+ meta.entitycolours = 'flanders'
+ meta.translation = translation(
+ pandoc.utils.stringify(meta.lang), "INBO"
+ )
+ else
+ if is_empty(meta.flandersqmd.entity) then
+ meta.translation = translation(
+ pandoc.utils.stringify(meta.lang), "INBO", meta.flandersqmd.level
+ )
+ else
+ meta.translation = translation(
+ pandoc.utils.stringify(meta.lang),
+ pandoc.utils.stringify(meta.flandersqmd.entity),
+ meta.flandersqmd.level
+ )
+ end
+ if is_empty(meta.flandersqmd.title) then
+ meta.title = "missing `flandersqmd:title`"
+ else
+ meta.title = pandoc.utils.stringify(meta.flandersqmd.title)
+ end
+ if is_empty(meta.flandersqmd.level) or tonumber(pandoc.utils.stringify(meta.flandersqmd.level)) < 2 then
+ meta.entitycolours = 'flanders'
+ else
+ if is_empty(meta.flandersqmd.entity) then
+ meta.entitycolours = 'inbo'
+ else
+ meta.entitycolours = pandoc.text.lower(pandoc.utils.stringify(meta.flandersqmd.entity))
+ end
+ end
+ meta.title_author = title_author(meta.flandersqmd.author)
+ end
+ meta.entitycss = levelcss(meta.entitycolours)
+ return meta
+ end,
+ }
+}
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/filters/url.lua b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/filters/url.lua
new file mode 100644
index 000000000..eb30855d2
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/filters/url.lua
@@ -0,0 +1,62 @@
+this_url = nil
+this_lang = nil
+entitycolours = nil
+
+function is_empty(s)
+ return s == nil or s == ''
+end
+
+function Meta(meta)
+ this_url = pandoc.utils.stringify(meta.translation.url)
+ this_lang = pandoc.utils.stringify(meta.lang)
+ entitycolours = meta.entitycolours
+end
+
+function Header(elem)
+ if not is_empty(this_lang) and elem.level == 1 and this_url then
+ local url_div = pandoc.Div({pandoc.Para({pandoc.Str(this_url)})}, pandoc.Attr("", {"sidebar-url-tussen"}))
+ ent_logo = pandoc.Div("", { class = "entity-tussen" })
+ if (this_lang == "nl-BE") then
+ if (entitycolours == "inbo") then
+ vl_logo = pandoc.Image("Vlaanderen is wetenschap", "flanders-nl-transparent.png")
+ ent_logo = pandoc.Image("Instituut voor Natuur- en Bosonderzoek", "inbo-nl-white.png")
+ ent_logo.attr = {class = "entity-tussen"}
+ else
+ vl_logo = pandoc.Image("Vlaanderen, verbeelding werkt", "flanders-nl-intermediate.jpg")
+ end
+ vl_logo.attr = {class = "vl-tussen"}
+ else
+ if (entitycolours == "inbo") then
+ ent_logo = pandoc.Image("Instituut voor Natuur- en Bosonderzoek", "inbo-en-white.png")
+ ent_logo.attr = {class = "entity-tussen-vert"}
+ end
+ vl_logo = pandoc.Image("Flanders, state of the art", "flanders-en-intermediate.png")
+ vl_logo.attr = {class = "vl-tussen-vert"}
+ end
+ return {
+ elem, pandoc.Div("", { class = "trapezium" }),
+ pandoc.Div("", { class = "sidebar-tussen" }), vl_logo, ent_logo, url_div
+ }
+ elseif not is_empty(this_lang) and elem.level == 2 then
+ if (this_lang == "nl-BE") then
+ if (entitycolours == "inbo") then
+ vl_logo = pandoc.Image("Vlaanderen is wetenschap", "flanders-nl-title.png")
+ else
+ vl_logo = pandoc.Image("Vlaanderen is wetenschap", "flanders-nl-slide.jpg")
+ end
+ else
+ vl_logo = pandoc.Image("Vlaanderen is wetenschap", "flanders-en-slide.png")
+ end
+ vl_logo.attr = {class = "vl-slide"}
+ return {elem, vl_logo}
+ end
+ return elem
+end
+
+function Pandoc(doc)
+ Meta(doc.meta)
+ doc.blocks = pandoc.walk_block(pandoc.Div(doc.blocks), {
+ Header = Header
+ }).content
+ return doc
+end
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Bold.ttf b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Bold.ttf
new file mode 100644
index 000000000..ade426637
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Bold.ttf differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Light.ttf b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Light.ttf
new file mode 100644
index 000000000..577a2a07a
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Light.ttf differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Medium.ttf b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Medium.ttf
new file mode 100644
index 000000000..1deb44983
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Medium.ttf differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Regular.ttf b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Regular.ttf
new file mode 100644
index 000000000..a7b8d23b3
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/FlandersArtSans-Regular.ttf differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Bold.ttf b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Bold.ttf
new file mode 100644
index 000000000..9f9272588
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Bold.ttf differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Light.ttf b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Light.ttf
new file mode 100644
index 000000000..2ce184299
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Light.ttf differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Medium.ttf b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Medium.ttf
new file mode 100644
index 000000000..364328355
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Medium.ttf differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Regular.ttf b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Regular.ttf
new file mode 100644
index 000000000..457d262cf
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/fonts/Inconsolata-Regular.ttf differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-en-intermediate.png b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-en-intermediate.png
new file mode 100644
index 000000000..5ff476ae4
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-en-intermediate.png differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-en-slide.png b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-en-slide.png
new file mode 100644
index 000000000..8a15aa752
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-en-slide.png differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-en-title.png b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-en-title.png
new file mode 100644
index 000000000..6e567f250
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-en-title.png differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-intermediate.jpg b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-intermediate.jpg
new file mode 100644
index 000000000..55f6c3dd7
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-intermediate.jpg differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-slide.jpg b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-slide.jpg
new file mode 100644
index 000000000..61a47d52d
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-slide.jpg differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-title.png b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-title.png
new file mode 100755
index 000000000..66cd77495
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-title.png differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-transparent.png b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-transparent.png
new file mode 100755
index 000000000..fb9cfaabe
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/flanders-nl-transparent.png differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-en-black.jpg b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-en-black.jpg
new file mode 100644
index 000000000..55cca1103
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-en-black.jpg differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-en-title.png b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-en-title.png
new file mode 100644
index 000000000..c437ebaca
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-en-title.png differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-en-white.png b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-en-white.png
new file mode 100644
index 000000000..dff148d79
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-en-white.png differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-nl-black.png b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-nl-black.png
new file mode 100644
index 000000000..f7b010d14
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-nl-black.png differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-nl-title.png b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-nl-title.png
new file mode 100755
index 000000000..d9de57120
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-nl-title.png differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-nl-white.png b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-nl-white.png
new file mode 100755
index 000000000..cb0b0ce35
Binary files /dev/null and b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/img/inbo-nl-white.png differ
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/research-institute-for-nature-and-forest.csl b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/research-institute-for-nature-and-forest.csl
new file mode 100644
index 000000000..bad203bb5
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/research-institute-for-nature-and-forest.csl
@@ -0,0 +1,298 @@
+
+
diff --git a/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/slides.scss b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/slides.scss
new file mode 100644
index 000000000..9699789f2
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/_extensions/inbo/flandersqmd/slides.scss
@@ -0,0 +1,271 @@
+/*-- scss:defaults --*/
+
+// Fonts
+
+$font-family-sans-serif: flanders_art_sans, Calibri, Source Sans Pro, Helvetica, sans-serif;
+$font-family-monospace: inconsolata, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
+
+@font-face {
+ font-family: flanders_art_sanslight;
+ src: url("../../../../../FlandersArtSans-Light.ttf") format("truetype");
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: flanders_art_sansmedium;
+ src: url("../../../../../FlandersArtSans-Medium.ttf") format("truetype");
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: flanders_art_sansregular;
+ src: url("../../../../../FlandersArtSans-Regular.ttf") format("truetype");
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: flanders_art_sansbold;
+ src: url("../../../../../FlandersArtSans-Bold.ttf") format("truetype");
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: flanders_art_sans;
+ src: url("../../../../../FlandersArtSans-Light.ttf") format("truetype");
+ font-weight: 300;
+ font-style: normal;
+}
+@font-face {
+ font-family: flanders_art_sans;
+ src: url("../../../../../FlandersArtSans-Medium.ttf") format("truetype");
+ font-weight: 400;
+ font-style: normal;
+}
+@font-face {
+ font-family: flanders_art_sans;
+ src: url("../../../../../FlandersArtSans-Regular.ttf") format("truetype");
+ font-weight: 500;
+ font-style: normal;
+}
+@font-face {
+ font-family: flanders_art_sans;
+ src: url("../../../../../FlandersArtSans-Bold.ttf") format("truetype");
+ font-weight: 700;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: inconsolata;
+ src: url("../../../../../Inconsolata-Light.ttf") format("truetype");
+ font-weight: 300;
+ font-style: normal;
+}
+@font-face {
+ font-family: inconsolata;
+ src: url("../../../../../Inconsolata-Medium.ttf") format("truetype");
+ font-weight: 400;
+ font-style: normal;
+}
+@font-face {
+ font-family: inconsolata;
+ src: url("../../../../../Inconsolata-Regular.ttf") format("truetype");
+ font-weight: 500;
+ font-style: normal;
+}
+@font-face {
+ font-family: inconsolata;
+ src: url("../../../../../Inconsolata-Bold.ttf") format("truetype");
+ font-weight: 700;
+ font-style: normal;
+}
+
+/*-- scss:rules --*/
+
+.reveal h1 {
+ margin: 30% 10% 0% 10%;
+}
+
+.subtitle {
+ font-size: 1.5em;
+ font-weight: bold;
+}
+
+.date {
+ font-size: 1.5em;
+}
+
+.reveal h1.title {
+ margin: 0% 0% 0% 0%;
+ font-size: 2em;
+}
+
+#title-slide {
+ text-align: left;
+}
+
+.reveal[data-navigation-mode="linear"] .title-slide h1 {
+ font-size: 2em;
+}
+
+.title-logo {
+ position: fixed;
+ right: 0;
+ top: -120px;
+ height: 110px;
+ border: 0px;
+ padding: 0px;
+ margin: 0px;
+ text-align: center;
+ line-height: 1;
+}
+
+.title-logo-img {
+ text-align: center;
+ margin: 2px !important;
+ max-width: 100% !important;
+}
+
+.vl-tussen {
+ position: absolute;
+ left: 15px;
+ top: 5px;
+ width: 200px;
+}
+
+.vl-tussen-vert {
+ position: absolute;
+ left: 15px;
+ top: 5px;
+ height: 200px;
+}
+
+.entity-tussen {
+ position: absolute;
+ left: 15px;
+ top: 100px;
+ width: 200px;
+}
+
+.entity-tussen-vert {
+ position: absolute;
+ left: 15px;
+ top: 210px;
+ width: 200px;
+}
+
+.vl-slide {
+ position: absolute;
+ left: 0%;
+ bottom: -5%;
+ width: 200px;
+ z-index: -1;
+}
+
+.coop-slide {
+ position: absolute;
+ right: 0%;
+ bottom: -5%;
+ width: 200px;
+ z-index: -1;
+}
+
+.photographer {
+ font-size: 0.5em;
+ position: fixed;
+ bottom: 0px;
+ right: 0px;
+}
+
+.sidebar {
+ position: fixed;
+ left: -70px;
+ bottom: -40px;
+ width: 50px;
+ height: 800px;
+}
+
+.sidebar-tussen {
+ position: fixed;
+ left: -71px;
+ bottom: -40px;
+ width: 53px;
+ height: 800px;
+}
+
+.sidebar-url {
+ font-size: 0.5em;
+ position: fixed;
+ writing-mode: vertical-rl;
+ transform: rotate(180deg);
+ display: inline-block;
+ left: -55px;
+ bottom: 0px;
+ width: 30px;
+ height: 700px;
+}
+
+.sidebar-url-tussen {
+ font-size: 0.5em;
+ position: fixed;
+ writing-mode: vertical-rl;
+ transform: rotate(180deg);
+ display: inline-block;
+ left: -55px;
+ bottom: 0px;
+ width: 30px;
+ height: 700px;
+}
+
+.fontsize-0-5 {
+ font-size: 0.5em;
+}
+
+.fontsize-0-6 {
+ font-size: 0.6em;
+}
+
+.fontsize-0-7 {
+ font-size: 0.7em;
+}
+
+.fontsize-0-8 {
+ font-size: 0.8em;
+}
+
+.fontsize-0-9 {
+ font-size: 0.9em;
+}
+
+.trapezium {
+ z-index: -100;
+ position: absolute;
+ left: 0%;
+ top: 0%;
+ clip-path: polygon(0% 0%, 80% 0%, 100% 100%, 0% 100%);
+ width: 100%;
+ height: 700px;
+}
+
+caption {
+ text-align: center;
+}
+
+figcaption {
+ text-align: center;
+}
+
+.dataTables_wrapper .dataTables_paginate {
+ font-size: 35%;
+}
+
+.reveal .slide aside, .reveal .slide div.aside {
+ bottom: 50px;
+}
+
+.reveal pre {
+ font-size: inherit;
+}
+
+.reveal code {
+ font-size: inherit;
+}
diff --git a/content/tutorials/git_rewrite_history/_quarto.yml b/content/tutorials/git_rewrite_history/_quarto.yml
new file mode 100644
index 000000000..a020f833d
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/_quarto.yml
@@ -0,0 +1,28 @@
+project:
+ type: default
+ preview:
+ port: 4201
+ browser: true
+ render:
+ - presentation.qmd
+ output-dir: output
+ post-render: post_render.R
+
+lang: en-GB
+
+format: flandersqmd-revealjs
+
+flandersqmd:
+ entity: INBO
+ level: 2
+ title: Rewriting git history
+ author:
+ - name:
+ given: Thierry
+ family: Onkelinx
+ email: thierry.onkelinx@inbo.be
+ orcid: 0000-0001-8804-4216
+ affiliation:
+ - Research Institute for Nature and Forest (INBO)
+ date: '2026-03-05'
+ cover: pexels-erfin-ekarana-494408160-28216541.jpg
diff --git a/content/tutorials/git_rewrite_history/index.md b/content/tutorials/git_rewrite_history/index.md
new file mode 100644
index 000000000..704230503
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/index.md
@@ -0,0 +1,17 @@
+---
+title: "Rewriting git history"
+description: "A presentation on rewriting git history"
+authors: [thierryo]
+date: 2026-03-05
+categories: ["version control"]
+tags: ["version control", "git", "github"]
+output:
+ md_document:
+ preserve_yaml: true
+ variant: gfm+footnotes
+---
+
+This [presentation](presentation.html) gives some basic instructions on rewriting git history.
+Use the `F11` function key to display the presentation full screen.
+Use the spacebar and arrow keys to navigate in the presentation.
+Use the `F5` function key to refresh the page when the labels in the graphics are missing or misplaced.
\ No newline at end of file
diff --git a/content/tutorials/git_rewrite_history/pexels-erfin-ekarana-494408160-28216541.jpg b/content/tutorials/git_rewrite_history/pexels-erfin-ekarana-494408160-28216541.jpg
new file mode 100644
index 000000000..4348fb517
Binary files /dev/null and b/content/tutorials/git_rewrite_history/pexels-erfin-ekarana-494408160-28216541.jpg differ
diff --git a/content/tutorials/git_rewrite_history/post_render.R b/content/tutorials/git_rewrite_history/post_render.R
new file mode 100644
index 000000000..00a001e65
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/post_render.R
@@ -0,0 +1,16 @@
+library(yaml)
+list.files(
+ "_extensions",
+ pattern = "_extension.yml",
+ full.names = TRUE,
+ recursive = TRUE
+) |>
+ grepv(pattern = "flandersqmd") |>
+ read_yaml() -> resources
+resources$contributes$format$revealjs[["format-resources"]] |>
+ basename() |>
+ file.remove() -> hide
+file.copy("output/index.html", "presentation.html", overwrite = TRUE) -> hide
+list.files("output", recursive = TRUE, full.names = TRUE) |>
+ file.remove() -> hide
+rm(hide)
\ No newline at end of file
diff --git a/content/tutorials/git_rewrite_history/presentation.html b/content/tutorials/git_rewrite_history/presentation.html
new file mode 100644
index 000000000..3cd78491f
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/presentation.html
@@ -0,0 +1,4792 @@
+
+
+
+
+
+
+
+
+
+
+
+ presentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Refresher on git basics
+
+
+
+
+
+
+
+
+
+The commit
+
+
+
+
+
+
+- which files to change
+- how to change the files
+- when (timestamp)
+- by whom (author)
+- description (message)
+- previous commit
+
+
+
+
+
+
+
+
+
+- sha1 digest of content
+- references the commit
+
+
+
+
+
+
+Commands
+
+git add README.md
+
+- select
README.md to be added to the next commit
+
+git commit -m "initial commit"
+
+- create a commit with message “initial commit”
+
+
+
+Git history
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Going back in time
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+git checkout m2
+- changes the files under version control in your working directory
+- detached HEAD state
+
+
+
+
+Creating a new branch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+git branch my_feature
+
+- always at the current checkout position
+
+git checkout my_feature
+
+- switch to the new branch
+
+
+
+
+
+Committing to current branch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+git push -u origin my_feature
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rewriting history locally
+
+
+
+
+
+
+
+
+
+Assumptions
+
+
+- you are the only person working on the commits
+- you haven’t pushed the involved commits
+
+
+
+Problem in the most recent commit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+- correct files
+- stage them with
git add
+git commit --amend
+
+- alters the last commit instead of creating a new commit
+
+- note that the commit hash will change
+
+
+
+
+Resetting
+
+
+git reset
+
+- unstage all stages changes
+- doesn’t change files
+
+git reset --hard
+
+- revert all changes to the status of the latest commit
+
+git reset --hard HEAD~1
+
+- remove the latest commit
+- revert all changes to the status of the current latest commit
+
+
+
+
+Rebase
+
+
+- add commits from one branch at the end of the another branch
+
+
+- go the branch to which you want to add commits
+
+git checkout my_feature
+
+- rebase the branch you want to add
+
+git rebase other_feature
+
+
+
+
+Git rebase visualised
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Cherry-pick
+
+
+- add one or more individual commits from one branch at the end of the another branch
+
+
+- go the branch to which you want to add commits
+
+git checkout my_feature
+
+- cherry-pick the commit you want to add
+
+
+
+
+Git cherry-pick visualised
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Interactive rebase
+
+
+- allows to change older commits
+
+
+- make sure you have checked out the correct branch
+
+git checkout my_feature
+
+- define the range of commits you want to alter
+
+git rebase -i f2 start at commit f2
+git rebase -i HEAD~2 start 2 commits before HEAD
+
+
+
+
+Interactive rebase
+
+
+- indicate what you want to do with every commit
+
+pick: use as is
+edit: change the commit
+drop: remove the commit
+
+
+
+
+Interactive rebase
+
+
+- rebase will automatically checkout the first
edit commit
+
+- correct the files
+git add changed files
+git commit --amend to update commit
+git rebase --continue to continue the process
+
+
+Use git rebase --abort to undo the changes while the rebase is in progress.
+
+
+
+Rewriting history on a remote repository
+
+
+
+
+
+
+
+
+
+Precautions
+
+
+- warn all active users to stop pushing and pulling until you’re done
+- make sure no one has created a branch start from the range you want to alter
+
+- merge such branches before rewriting the history
+
+- do the work in a different
git clone
+- create a new branch before altering a branch
+
+
+
+Workflow
+
+
+- apply the changes locally as described in the previous chapter
+- a simple
git push will fail because of a diverging history
+- you must use
git push --force or git push -f
+- be careful because you can’t undo that
+
+
+
+Get updated branch in other clone
+
+
+- Checkout the local branch
+
+git checkout <branch-name>
+
+- Get new branches from remote
+
+- Reset to the new origin branch
+
+git reset --hard origin/<branch-name>
+
+
+
+
+Recreate a release by remerging a branch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+- Delete the release and the related tag on GitHub
+git checkout main: go to the main branch
+git pull: make sure you have the latest main
+
+
+
+
+Recreate a release by remerging a branch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+git checkout <commit-SHA>: go the latest commit of the feature branch
+git branch <branch_name>: recreate the feature branch
+git push -u origin <branch_name>: push the feature branch
+
+
+
+
+Recreate a release by remerging a branch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+git checkout main: go back to the main branch
+git reset --hard HEAD~1: remove the latest commit of the main branch
+git push -f: force push the main branch
+
+
+
+
+Recreate a release by remerging a branch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+git checkout <feature_branch>: go back to the feature branch
+- alter the
<feature_branch>
+git push -f
+- create a new pull request
+- merge pull request
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/content/tutorials/git_rewrite_history/presentation.qmd b/content/tutorials/git_rewrite_history/presentation.qmd
new file mode 100644
index 000000000..20f05b131
--- /dev/null
+++ b/content/tutorials/git_rewrite_history/presentation.qmd
@@ -0,0 +1,653 @@
+# Refresher on git basics
+
+## The commit
+
+::: {.callout-note}
+### content
+
+- which files to change
+- how to change the files
+- when (timestamp)
+- by whom (author)
+- description (message)
+- previous commit
+:::
+
+::: {.callout-tip}
+### commit hash
+
+- sha1 digest of content
+- references the commit
+:::
+
+## Commands
+
+### `git add README.md`
+
+- select `README.md` to be added to the next commit
+
+### `git commit -m "initial commit"`
+
+- create a commit with message "initial commit"
+
+## Git history
+
+```{dot}
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ main -> m3 [dir = none, color="#019966"];
+ m3 -> m2 -> m1 -> m0;
+ HEAD -> m3 [dir = none, color="#019966"];
+ main [shape = diamond, color="#019966"];
+ HEAD [shape = diamond, color="#019966"];
+ m3 [color = "#C04384"]
+}
+```
+
+## Going back in time
+
+:::: {.columns}
+
+::: {.column}
+
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ main -> m3 [dir = none, color="#019966"];
+ m3 -> m2 -> m1 -> m0;
+ HEAD -> m3 [dir = none, color="#019966"];
+ main [shape = diamond, color="#019966"];
+ HEAD [shape = diamond, color="#019966"];
+ m2 [color = "#C04384"]
+}
+```
+
+:::
+
+::: {.column}
+
+- `git checkout m2`
+- changes the files under version control in your working directory
+- detached HEAD state
+
+:::
+
+::::
+
+## Creating a new branch
+
+:::: {.columns}
+
+::: {.column}
+
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ main -> m3 [dir = none, color="#019966"];
+ m3 -> m2 -> m1 -> m0;
+ HEAD -> m2 [dir = none, color="#019966"];
+ main [shape = diamond, color="#019966"];
+ my_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#BDDDD7"];
+ my_feature -> m2 [dir = none, color="#019966"];
+ HEAD [shape = diamond, color="#019966"];
+ m2 [color = "#C04384"]
+}
+```
+
+:::
+
+::: {.column}
+
+- `git branch my_feature`
+ - always at the current checkout position
+- `git checkout my_feature`
+ - switch to the new branch
+
+:::
+
+::::
+
+
+## Committing to current branch
+
+:::: {.columns}
+
+::: {.column}
+
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ main -> m3 [dir = none, color="#019966"];
+ main [shape = diamond, color="#019966"];
+ m3 -> m2 -> m1 -> m0;
+ f1 -> f0 -> m2 [color = "#BDDDD7"];
+ my_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#BDDDD7"];
+ my_feature -> f1 [dir = none, color="#019966"];
+ HEAD [shape = diamond, color="#019966"];
+ HEAD -> f1 [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [color = "#C04384", style=filled, fillcolor = "#BDDDD7"]
+}
+```
+
+:::
+
+::: {.column}
+
+
+- `git add`
+- `git commit`
+
+:::
+
+::::
+
+
+## `git push -u origin my_feature`
+
+:::: {.columns}
+
+::: {.column}
+
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ compound=true;
+ subgraph cluster_local {
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ main -> m3 [dir = none, color="#019966"];
+ main [shape = diamond, color="#019966"];
+ m3 -> m2 -> m1 -> m0;
+ f1 -> f0 -> m2 [color = "#BDDDD7"];
+ my_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#BDDDD7"];
+ my_feature -> f1 [dir = none, color="#019966"];
+ origin_my_feature [shape = diamond, color="#019966", label = "origin/my_feature", style=filled, fillcolor = "#BDDDD7"];
+ origin_my_feature -> f1 [dir = none, color="#019966"];
+ HEAD [shape = diamond, color="#019966"];
+ HEAD -> f1 [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [color = "#C04384", style=filled, fillcolor = "#BDDDD7"]
+ label = "local";
+ }
+}
+```
+
+:::
+
+::: {.column}
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ compound=true;
+ subgraph cluster_local {
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ m2 -> m1 -> m0;
+ f1 -> f0 -> m2 [color = "#BDDDD7"];
+ my_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#BDDDD7"];
+ my_feature -> f1 [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [color = "#C04384", style=filled, fillcolor = "#BDDDD7"]
+ label = "origin";
+ }
+}
+```
+:::
+
+::::
+
+# Rewriting history locally
+
+## Assumptions
+
+- you are the only person working on the commits
+- you haven't pushed the involved commits
+
+## Problem in the most recent commit
+
+:::: {.columns}
+
+::: {.column}
+
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ main -> m3 [dir = none, color="#019966"];
+ main [shape = diamond, color="#019966"];
+ m3 -> m2 -> m1 -> m0;
+ f3 -> f2 -> f1 -> f0 -> m2 [color = "#BDDDD7"];
+ my_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#BDDDD7"];
+ my_feature -> f3 [dir = none, color="#019966"];
+ origin_my_feature [shape = diamond, color="#019966", label = "origin/my_feature", style=filled, fillcolor = "#BDDDD7"];
+ origin_my_feature -> f1 [dir = none, color="#019966"];
+ HEAD [shape = diamond, color="#019966"];
+ HEAD -> f3 [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [style = filled, fillcolor = "#BDDDD7"]
+ f2 [style = filled, fillcolor = "#BDDDD7"]
+ f3 [color = "#C04384", style=filled, fillcolor = "#BDDDD7"]
+}
+```
+
+:::
+
+::: {.column}
+- correct files
+- stage them with `git add`
+- `git commit --amend`
+ - alters the last commit instead of creating a new commit
+- note that the commit hash will change
+:::
+
+::::
+
+## Resetting
+
+- `git reset`
+ - unstage all stages changes
+ - doesn't change files
+- `git reset --hard`
+ - revert all changes to the status of the latest commit
+- `git reset --hard HEAD~1`
+ - remove the latest commit
+ - revert all changes to the status of the current latest commit
+
+## Rebase
+
+- add commits from one branch at the end of the another branch
+
+1. go the branch to which you want to add commits
+ - `git checkout my_feature`
+1. rebase the branch you want to add
+ - `git rebase other_feature`
+
+## Git rebase visualised
+
+:::: {.columns}
+
+::: {.column}
+
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ subgraph cluster {
+ main -> m3 [dir = none, color="#019966"];
+ main [shape = diamond, color="#019966"];
+ m3 -> m2 -> m1 -> m0;
+ f3 -> f2 -> f1 -> f0 -> m2 [color = "#BDDDD7"];
+ my_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#BDDDD7"];
+ my_feature -> f3 [dir = none, color="#019966"];
+ origin_my_feature [shape = diamond, color="#019966", label = "origin/my_feature", style=filled, fillcolor = "#BDDDD7"];
+ origin_my_feature -> f1 [dir = none, color="#019966"];
+ HEAD [shape = diamond, color="#019966"];
+ HEAD -> f3 [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [style = filled, fillcolor = "#BDDDD7"]
+ f2 [style = filled, fillcolor = "#BDDDD7"]
+ f3 [color = "#C04384", style=filled, fillcolor = "#BDDDD7"]
+ g0 [style = filled, fillcolor = "#EF972C"]
+ g1 [style=filled, fillcolor = "#EF972C"]
+ g1 -> g0 -> f1 [color = "#EF972C"];
+ other_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#EF972C"];
+ other_feature -> g1 [dir = none, color="#019966"];
+ label = "before"
+ }
+}
+```
+
+:::
+
+::: {.column}
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ subgraph cluster {
+ main -> m3 [dir = none, color="#019966"];
+ main [shape = diamond, color="#019966"];
+ m3 -> m2 -> m1 -> m0;
+ g1b -> g0b -> f3 -> f2 -> f1 -> f0 -> m2 [color = "#BDDDD7"];
+ my_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#BDDDD7"];
+ my_feature -> g1b [dir = none, color="#019966"];
+ origin_my_feature [shape = diamond, color="#019966", label = "origin/my_feature", style=filled, fillcolor = "#BDDDD7"];
+ origin_my_feature -> f1 [dir = none, color="#019966"];
+ HEAD [shape = diamond, color="#019966"];
+ HEAD -> g1b [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [style = filled, fillcolor = "#BDDDD7"]
+ f2 [style = filled, fillcolor = "#BDDDD7"]
+ f3 [style=filled, fillcolor = "#BDDDD7"]
+ g0b [style = filled, fillcolor = "#EF972C"]
+ g1b [color = "#C04384", style=filled, fillcolor = "#EF972C"]
+ label = "after"
+ }
+}
+```
+:::
+
+::::
+
+## Cherry-pick
+
+- add one or more individual commits from one branch at the end of the another branch
+
+1. go the branch to which you want to add commits
+ - `git checkout my_feature`
+1. cherry-pick the commit you want to add
+ - `git cherry-pick g1`
+
+## Git cherry-pick visualised
+
+:::: {.columns}
+
+::: {.column}
+
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ subgraph cluster {
+ main -> m3 [dir = none, color="#019966"];
+ main [shape = diamond, color="#019966"];
+ m3 -> m2 -> m1 -> m0;
+ f3 -> f2 -> f1 -> f0 -> m2 [color = "#BDDDD7"];
+ my_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#BDDDD7"];
+ my_feature -> f3 [dir = none, color="#019966"];
+ origin_my_feature [shape = diamond, color="#019966", label = "origin/my_feature", style=filled, fillcolor = "#BDDDD7"];
+ origin_my_feature -> f1 [dir = none, color="#019966"];
+ HEAD [shape = diamond, color="#019966"];
+ HEAD -> f3 [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [style = filled, fillcolor = "#BDDDD7"]
+ f2 [style = filled, fillcolor = "#BDDDD7"]
+ f3 [color = "#C04384", style=filled, fillcolor = "#BDDDD7"]
+ g0 [style = filled, fillcolor = "#EF972C"]
+ g1 [style=filled, fillcolor = "#EF972C"]
+ g1 -> g0 -> f1 [color = "#EF972C"];
+ other_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#EF972C"];
+ other_feature -> g1 [dir = none, color="#019966"];
+ label = "before"
+ }
+}
+```
+
+:::
+
+::: {.column}
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ subgraph cluster {
+ main -> m3 [dir = none, color="#019966"];
+ main [shape = diamond, color="#019966"];
+ m3 -> m2 -> m1 -> m0;
+ g1b -> f3 -> f2 -> f1 -> f0 -> m2 [color = "#BDDDD7"];
+ my_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#BDDDD7"];
+ my_feature -> g1b [dir = none, color="#019966"];
+ origin_my_feature [shape = diamond, color="#019966", label = "origin/my_feature", style=filled, fillcolor = "#BDDDD7"];
+ origin_my_feature -> f1 [dir = none, color="#019966"];
+ HEAD [shape = diamond, color="#019966"];
+ HEAD -> g1b [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [style = filled, fillcolor = "#BDDDD7"]
+ f2 [style = filled, fillcolor = "#BDDDD7"]
+ f3 [color = "#C04384", style=filled, fillcolor = "#BDDDD7"]
+ g0 [style = filled, fillcolor = "#EF972C"]
+ g1 [style=filled, fillcolor = "#EF972C"]
+ g1b [style=filled, fillcolor = "#EF972C"]
+ g1 -> g0 -> f1 [color = "#EF972C"];
+ other_feature [shape = diamond, color="#019966", style=filled, fillcolor = "#EF972C"];
+ other_feature -> g1 [dir = none, color="#019966"];
+ label = "after"
+ }
+}
+```
+:::
+
+::::
+
+## Interactive rebase
+
+- allows to change older commits
+
+1. make sure you have checked out the correct branch
+ - `git checkout my_feature`
+1. define the range of commits you want to alter
+ - `git rebase -i f2` start at commit f2
+ - `git rebase -i HEAD~2` start 2 commits before HEAD
+
+## Interactive rebase
+
+3. indicate what you want to do with every commit
+ - `pick`: use as is
+ - `edit`: change the commit
+ - `drop`: remove the commit
+
+## Interactive rebase
+
+4. rebase will automatically checkout the first `edit` commit
+ - correct the files
+ - `git add` changed files
+ - `git commit --amend` to update commit
+ - `git rebase --continue` to continue the process
+
+Use `git rebase --abort` to undo the changes while the rebase is in progress.
+
+# Rewriting history on a remote repository
+
+## Precautions
+
+- warn all active users to stop pushing and pulling until you're done
+- make sure no one has created a branch start from the range you want to alter
+ - merge such branches before rewriting the history
+- do the work in a different `git clone`
+- create a new branch before altering a branch
+
+## Workflow
+
+- apply the changes locally as described in the previous chapter
+- a simple `git push` will fail because of a diverging history
+- you must use `git push --force` or `git push -f`
+- be careful because you can't undo that
+
+## Get updated branch in other clone
+
+1. Checkout the local branch
+ - `git checkout `
+1. Get new branches from remote
+ - `git fetch origin`
+1. Reset to the new origin branch
+ - `git reset --hard origin/`
+
+## Recreate a release by remerging a branch
+
+:::: {.columns}
+
+::: {.column}
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ main -> m1 [dir = none, color="#019966"];
+ omain -> m1 [dir = none, color="#019966"];
+ m1 -> m0;
+ f1 -> f0 -> m0 [color = "#BDDDD7"];
+ m1 -> f1;
+ main [shape = diamond, color="#019966"];
+ omain [shape = diamond, color="#019966", label = "origin/main"];
+ HEAD [shape = diamond, color="#019966"];
+ HEAD -> m1 [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [style = filled, fillcolor = "#BDDDD7"]
+ m1 [color = "#C04384"]
+}
+```
+:::
+
+::: {.column}
+1. Delete the release and the related tag on GitHub
+1. `git checkout main`: go to the `main` branch
+1. `git pull`: make sure you have the latest `main`
+:::
+
+::::
+
+
+## Recreate a release by remerging a branch
+
+:::: {.columns}
+
+::: {.column}
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ main -> m1 [dir = none, color="#019966"];
+ omain -> m1 [dir = none, color="#019966"];
+ m1 -> m0;
+ f1 -> f0 -> m0 [color = "#BDDDD7"];
+ m1 -> f1;
+ main [shape = diamond, color="#019966"];
+ omain [shape = diamond, color="#019966", label = "origin/main"];
+ feature [shape = diamond, color="#019966"];
+ ofeature [shape = diamond, color="#019966", label = "origin/feature"];
+ HEAD [shape = diamond, color="#019966"];
+ feature -> f1 [dir = none, color="#019966"];
+ ofeature -> f1 [dir = none, color="#019966"];
+ HEAD -> f1 [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [color = "#C04384"]
+}
+```
+:::
+
+::: {.column}
+4. `git checkout `: go the latest commit of the feature branch
+1. `git branch `: recreate the feature branch
+1. `git push -u origin `: push the feature branch
+:::
+
+::::
+
+## Recreate a release by remerging a branch
+
+:::: {.columns}
+
+::: {.column}
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ main -> m0 [dir = none, color="#019966"];
+ omain -> m0 [dir = none, color="#019966"];
+ m0;
+ f1 -> f0 -> m0 [color = "#BDDDD7"];
+ main [shape = diamond, color="#019966"];
+ omain [shape = diamond, color="#019966", label = "origin/main"];
+ feature [shape = diamond, color="#019966"];
+ ofeature [shape = diamond, color="#019966", label = "origin/feature"];
+ HEAD [shape = diamond, color="#019966"];
+ feature -> f1 [dir = none, color="#019966"];
+ ofeature -> f1 [dir = none, color="#019966"];
+ HEAD -> m0 [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [style = filled, fillcolor = "#BDDDD7"]
+ m0 [color = "#C04384"]
+}
+```
+:::
+
+::: {.column}
+7. `git checkout main`: go back to the main branch
+1. `git reset --hard HEAD~1`: remove the latest commit of the main branch
+1. `git push -f`: force push the main branch
+:::
+
+::::
+
+## Recreate a release by remerging a branch
+
+:::: {.columns}
+
+::: {.column}
+```{dot}
+//| fig-width: 6
+digraph G {
+ rankdir="TB";
+ node [fontname="FlandersArtSans-Bold.ttf,sans-serif"]
+ main -> m0 [dir = none, color="#019966"];
+ omain -> m0 [dir = none, color="#019966"];
+ m0;
+ f2 -> f1 -> f0 -> m0 [color = "#BDDDD7"];
+ main [shape = diamond, color="#019966"];
+ omain [shape = diamond, color="#019966", label = "origin/main"];
+ feature [shape = diamond, color="#019966"];
+ ofeature [shape = diamond, color="#019966", label = "origin/feature"];
+ HEAD [shape = diamond, color="#019966"];
+ feature -> f2 [dir = none, color="#019966"];
+ ofeature -> f2 [dir = none, color="#019966"];
+ HEAD -> f2 [dir = none, color="#019966"];
+ f0 [style = filled, fillcolor = "#BDDDD7"]
+ f1 [style = filled, fillcolor = "#BDDDD7"]
+ f2 [style = filled, fillcolor = "#BDDDD7"]
+ f2 [color = "#C04384"]
+}
+```
+:::
+
+::: {.column}
+10. `git checkout `: go back to the feature branch
+1. alter the ``
+1. `git push -f`
+1. create a new pull request
+1. merge pull request
+:::
+
+::::
+
+# Git recommendations
+
+## Keep your commits small
+
+- easier to give a good description
+- easier to read history
+- easier to revert changes
+- easier to cherry-pick
+
+You don't have to commit all changes of a file in a single commit!
+
+## Agree on a workflow
+
+- don't work in the `main` branch
+- protect the `main` branch on GitHub
+- use `pull request` on GitHub to add feature branches to the main branch
+- only one person at a time should work in a branch
+
+## Use `checklist`
+
+- add an improved `.gitignore`
+- adds a lot of automated checks
+
+## Saperlipopette
+
+[Saperlipopette](https://docs.ropensci.org/saperlipopette/articles/saperlipopette.html) creates Git exercises, that users solve using their local and usual tools.