| Title: | Create Example Git Messes |
|---|---|
| Description: | Holds functions creating Git messes, that users would then solve, to follow <https://ohshitgit.com/>. |
| Authors: | Maëlle Salmon [cre, aut] (ORCID: <https://orcid.org/0000-0002-2815-0399>), Jim Gardner [ctb], Yanina Bellini Saibene [aut] (ORCID: <https://orcid.org/0000-0002-4522-7466>), Steffi LaZerte [rev] (Steffi reviewed the 'saperlipopette, a risk-free playground for learning more Git' article., ORCID: <https://orcid.org/0000-0002-7690-8360>), Mine Çetinkaya-Rundel [rev] (Mine reviewed the package for rOpenSci: https://github.com/ropensci/software-review/issues/754#issuecomment-4324492956.), Jeff Oliver [rev] (Jeff reviewed the package for rOpenSci: https://github.com/ropensci/software-review/issues/754#issuecomment-4172245979.) |
| Maintainer: | Maëlle Salmon <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.0.0 |
| Built: | 2026-05-12 09:56:44 UTC |
| Source: | https://github.com/ropensci-training/saperlipopette |
But do not open them!
Having all the exercises as folders within parent_path makes it possible
to resolve them one by one, if one wants to practice all that is available
with the package.
Run this function only if there are no exercise folder already created in
parent_path: you can use a brand-new folder for instance.
create_all_exercises(parent_path)create_all_exercises(parent_path)
parent_path |
Path where to create the exercise repo |
The parent path
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- create_all_exercises(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- create_all_exercises(parent_path = parent_path)
I notice a bug in my codebase.
I can see the bug was not there a bunch of commits ago.
Beside doing regular debugging, I can find out
which commit introduced the bug by using git bisect.
See https://git-scm.com/docs/git-bisect and
https://www.jimhester.com/post/2019-04-24-git-bisect/.
exo_bisect(parent_path)exo_bisect(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_bisect(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_bisect(parent_path = parent_path)
I want to find who added the line x <- x + 1 to the script and when.
The tool for that is git blame path/to/file.
exo_blame(parent_path)exo_blame(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_blame(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_blame(parent_path = parent_path)
An exercice to check your Git's core.editor is set correctly. https://docs.github.com/es/get-started/git-basics/associating-text-editors-with-git
exo_check_editor(parent_path)exo_check_editor(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
git config, git commit --allow-empty.
parent_path <- withr::local_tempdir() path <- exo_check_editor(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_check_editor(parent_path = parent_path)
If debugging for instance created now useless untracked files and directories,
there's no need to remove them "manually".
The tool for that is git clean:
git clean -n for a dry run;
git clean -f to run it;
Add -d to also remove directories.
See https://git-scm.com/docs/git-clean.
exo_clean_dir(parent_path)exo_clean_dir(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_clean_dir(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_clean_dir(parent_path = parent_path)
To go with https://ohshitgit.com/#accidental-commit-master
exo_committed_to_main(parent_path)exo_committed_to_main(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
git reset --hard, git branch, git switch, git checkout.
parent_path <- withr::local_tempdir() path <- exo_committed_to_main(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_committed_to_main(parent_path = parent_path)
To go with https://ohshitgit.com/#accidental-commit-wrong-branch
exo_committed_to_wrong(parent_path)exo_committed_to_wrong(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
git cherry-pick, git reset, git switch, git checkout.
parent_path <- withr::local_tempdir() path <- exo_committed_to_wrong(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_committed_to_wrong(parent_path = parent_path)
I made some work in a feature branch and want to merge it. Meanwhile, the main branch advanced. Unfortunately someone touched the same file as I did. Now I need to fix a merge conflict!
See also https://happygitwithr.com/git-branches.html#dealing-with-conflicts.
exo_conflict(parent_path)exo_conflict(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_conflict(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_conflict(parent_path = parent_path)
To go with https://ohshitgit.com/#change-last-commit-message
exo_latest_message(parent_path)exo_latest_message(parent_path)
parent_path |
Path where to create the exercise repo |
The path
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_latest_message(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_latest_message(parent_path = parent_path)
I want to find which commit deleted script.R.
The tool for that is git log --oneline -- path.
exo_log_deleted_file(parent_path)exo_log_deleted_file(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_log_deleted_file(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_log_deleted_file(parent_path = parent_path)
I want to find which commit deleted the line "iris" from the text file.
The tool for that is git log -S<string> path/to/file
or git log -G<regex> path/to/file.
exo_log_deleted_line(parent_path)exo_log_deleted_line(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
git log -S<string>, git log -G<regex>.
parent_path <- withr::local_tempdir() path <- exo_log_deleted_line(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_log_deleted_line(parent_path = parent_path)
To go with https://ohshitgit.com/#change-last-commit
exo_one_small_change(parent_path)exo_one_small_change(parent_path)
parent_path |
Path where to create the exercise repo |
The path
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_one_small_change(parent_path = parent_path) # Now add "thing 3" to the "bla" file # And amend the latest commitparent_path <- withr::local_tempdir() path <- exo_one_small_change(parent_path = parent_path) # Now add "thing 3" to the "bla" file # And amend the latest commit
I am working in a feature branch that's all my own.
I made many small commits as I was figuring things out.
Now I want the commits to tell a story for the PR reviewers,
and not a story of how many stupid mistakes I made!
The tool for that is git base --interactive also available as git rebase -i.
Useful links:
https://jvns.ca/blog/2023/11/06/rebasing-what-can-go-wrong-/
https://github.blog/developer-skills/github/write-better-commits-build-better-projects/
exo_rebase_i(parent_path)exo_rebase_i(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_rebase_i(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_rebase_i(parent_path = parent_path)
I am working in a feature branch that's all my own.
I made many small commits as I was figuring things out.
Now I want the commits to tell a story for the PR reviewers,
and not a story of how many stupid mistakes I made!
Instead of git base --interactive also available as git rebase -i,
I can also use git reset --mixed and then build the commits.
Useful links:
exo_reset(parent_path)exo_reset(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_reset(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_reset(parent_path = parent_path)
To go with https://ohshitgit.com/#undo-a-file
exo_revert_file(parent_path)exo_revert_file(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
git log, git restore, git checkout, git commit.
parent_path <- withr::local_tempdir() path <- exo_revert_file(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_revert_file(parent_path = parent_path)
I want to find the commit ID and message for HEAD~5 and HEAD^^.
The tool for that is git rev-parse combined with git log or git show.
More on ancestry references: https://git-scm.com/book/be/v2/Git-Tools-Revision-Selection.html#_ancestry_references.
exo_revparse(parent_path)exo_revparse(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
git rev-parse, git log, git show.
parent_path <- withr::local_tempdir() path <- exo_revparse(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_revparse(parent_path = parent_path)
I made many edits to a file, in different places.
This is too much for a commit, since small commits are best practice.
I need to add the changes to Git bit by bit.
The tool for that is git add --patch, also available as git add -p.
If all your changes are presented to you as one chunk by git add --patch,
choose the "s" option for splitting.
See https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging#_staging_patches.
Note that patch is also an option for git commit, if you prefer so.
exo_split_changes(parent_path)exo_split_changes(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_split_changes(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_split_changes(parent_path = parent_path)
To go with https://ohshitgit.com/#magic-time-machine
exo_time_machine(parent_path)exo_time_machine(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_time_machine(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_time_machine(parent_path = parent_path)
To go with https://ohshitgit.com/#undo-a-commit
exo_undo_commit(parent_path)exo_undo_commit(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
parent_path <- withr::local_tempdir() path <- exo_undo_commit(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_undo_commit(parent_path = parent_path)
I want to create a folder containing the project as it was at tag v2,
to read the text file.
The tool for that is git worktree.
https://masalmon.eu/2024/01/23/git-worktree/
exo_worktree(parent_path)exo_worktree(parent_path)
parent_path |
Path where to create the exercise repo |
The path to the new project
Running the function will create the exercise as a new folder in parent_path.
If called from RStudio or Positron, the function will open a new R session in
that IDE.
If not, the user will need to navigate to the path returned by the function,
and launch an R session from there.
The new R session will display messages about what challenge to solve,
and running the tip() function from that new R session will display
additional guiance.
git log, git worktree, git tag.
parent_path <- withr::local_tempdir() path <- exo_worktree(parent_path = parent_path)parent_path <- withr::local_tempdir() path <- exo_worktree(parent_path = parent_path)