Skip to contents

The goal of saperlipopette is to hold functions creating Git exercises, that users solve using their local and usual tools.

Why this name?

This package is intended to be a companion to https://ohshitgit.com/, so its name had to honour the exclamation. “saperlipopette” is an old-fashioned French exclamation. You can say “Saperlipopette, Git!”.

Example

library("saperlipopette")
parent_path <- withr::local_tempdir()
path <- exo_one_small_change(parent_path)
#> [36mℹ[39m Follow along in /tmp/RtmpUZsb93/file784440a25ad/one-small-change!
# what's in path
fs::dir_tree(path)
#> [01;34m/tmp/RtmpUZsb93/file784440a25ad/one-small-change[0m
#> ├── [01;34mR[0m
#> └── bla
# with Git in a command line: git log
# or the gert R package
gert::git_log(repo = path)
#> [90m# A tibble: 2 × 6[39m
#>   commit                          author time                files merge message
#> [90m*[39m [3m[90m<chr>[39m[23m                           [3m[90m<chr>[39m[23m  [3m[90m<dttm>[39m[23m              [3m[90m<int>[39m[23m [3m[90m<lgl>[39m[23m [3m[90m<chr>[39m[23m  
#> [90m1[39m 2ff0d31f566e68ae0ee94b6028a3fa… Jane … 2023-12-15 [90m15:25:00[39m     1 FALSE [90m"[39mfeat:…
#> [90m2[39m e227ecc55e421f70b6e30602e6a2ee… Jane … 2023-12-15 [90m15:25:00[39m     2 FALSE [90m"[39mFirst…

At this stage, the user would open the newly created R project and launch an R session, where messages would indicate them what to do, and which URL to follow, to find, in this case, the corresponding ohshitgit entry. In practice here the user would change a file, then Git add it, then run git commit --amend --no-edit. The user would examine the Git history before and after this.

#> [31m✖[39m "Oh shit, I committed and immediately realized I need to make one small change!"
#> [31m✖[39m I wanted to list 3 things in my bla file, not only two!
#> [36mℹ[39m See [3m[34m[3m[34m<https://ohshitgit.com/#change-last-commit>[34m[3m[39m[23m
#> [36mℹ[39m For more help use `tip()`

If they need more instructions than what is initially provided, the user can run:

tip()
#> • Add 'thing 3' to the [34mbla[39m file and save it.
#> • `git add bla`
#> • `git commit --amend --no-edit`
#> • Examine Git history.

That interface relies on adding an .Rprofile to the newly created project, with instructions formatted with the cli package.

We’ve set the Git author, committer and date so that the automatic commits get the same hashes, which can be useful when teaching a group: everyone should be looking at the same hashes on their machine, except for those commits they create themselves.

Below we use gert::git_log(), as opposed to git log in a command line, because that integrates better with R Markdown that we use for building documentation.

parent_path <- withr::local_tempdir()
path <- exo_one_small_change(parent_path)
#> [36mℹ[39m Follow along in /tmp/RtmpUZsb93/file78460b59df6/one-small-change!
gert::git_log(repo = path)
#> [90m# A tibble: 2 × 6[39m
#>   commit                          author time                files merge message
#> [90m*[39m [3m[90m<chr>[39m[23m                           [3m[90m<chr>[39m[23m  [3m[90m<dttm>[39m[23m              [3m[90m<int>[39m[23m [3m[90m<lgl>[39m[23m [3m[90m<chr>[39m[23m  
#> [90m1[39m 2ff0d31f566e68ae0ee94b6028a3fa… Jane … 2023-12-15 [90m15:25:00[39m     1 FALSE [90m"[39mfeat:…
#> [90m2[39m e227ecc55e421f70b6e30602e6a2ee… Jane … 2023-12-15 [90m15:25:00[39m     2 FALSE [90m"[39mFirst…
parent_path2 <- withr::local_tempdir()
path2 <- exo_one_small_change(parent_path2)
#> [36mℹ[39m Follow along in /tmp/RtmpUZsb93/file784350a33b8/one-small-change!
gert::git_log(repo = path2)
#> [90m# A tibble: 2 × 6[39m
#>   commit                          author time                files merge message
#> [90m*[39m [3m[90m<chr>[39m[23m                           [3m[90m<chr>[39m[23m  [3m[90m<dttm>[39m[23m              [3m[90m<int>[39m[23m [3m[90m<lgl>[39m[23m [3m[90m<chr>[39m[23m  
#> [90m1[39m 2ff0d31f566e68ae0ee94b6028a3fa… Jane … 2023-12-15 [90m15:25:00[39m     1 FALSE [90m"[39mfeat:…
#> [90m2[39m e227ecc55e421f70b6e30602e6a2ee… Jane … 2023-12-15 [90m15:25:00[39m     2 FALSE [90m"[39mFirst…

Multilingual!

The saperlipopette can create messages in English (default) but also in French and Spanish. Example in French:

library("saperlipopette")
withr::local_language("fr")
parent_path <- withr::local_tempdir()
path <- exo_one_small_change(parent_path)
#> [36mℹ[39m L'exercice attend dans /tmp/RtmpUZsb93/file784317d75a0/one-small-change !
# what's in path
fs::dir_tree(path)
#> [01;34m/tmp/RtmpUZsb93/file784317d75a0/one-small-change[0m
#> ├── [01;34mR[0m
#> └── bla
# with Git in a command line: git log
# or the gert R package
gert::git_log(repo = path)
#> [90m# A tibble: 2 × 6[39m
#>   commit                          author time                files merge message
#> [90m*[39m [3m[90m<chr>[39m[23m                           [3m[90m<chr>[39m[23m  [3m[90m<dttm>[39m[23m              [3m[90m<int>[39m[23m [3m[90m<lgl>[39m[23m [3m[90m<chr>[39m[23m  
#> [90m1[39m 8f4f4f6fc6c4423d2c67caf93bdd92… Jane … 2023-12-15 [90m15:25:00[39m     1 FALSE [90m"[39mfeat:…
#> [90m2[39m 65bee703cbbcc9f809594e17835551… Jane … 2023-12-15 [90m15:25:00[39m     2 FALSE [90m"[39mPremi…
#> [31m✖[39m "Et merde, je viens de commiter et il manque une toute petite modification !"
#> [31m✖[39m Je voulais lister 3 choses dans mon fichier bla, pas seulement 2 !
#> [36mℹ[39m Voir [3m[34m[3m[34m<https://ohshitgit.com/fr#modifier-le-dernier-commit>[34m[3m[39m[23m
#> [36mℹ[39m Pour plus d'aide, `tip()`
tip()
#> • Ajouter 'chose 3' au fichier [34mbla[39m puis l'enregistrer.
#> • `git add bla`
#> • `git commit --amend --no-edit`
#> • Examiner l'historique Git.

Exercises

Consult the reference.

Exercises cover:

  • Oh Shit, Git!: exercises inspired by https://ohshitgit.com/ by Katie Sylor-Miller.
  • Clean history: exercises on how to get a clean Git history, for instance using rebase interactive.
  • Use history: exercises on how to use the Git history, for instance using blame.

As an individual learner, pick what you want to learn or try out! As an instructor, you can mix and match exercises: for instance focussing the session on solving common mistakes (Oh Shit, Git!) or on why and how to create a clean Git history (exercises from “Use history” then exercises from “Clean history”).

Feel free to suggest new exercises by opening a GitHub issue.

For beginners:

For users less new to Git: