Painlessly Improve Your Git History

Memory of an old video game

⚙️ The Incredible Machine

Prerequisites

How we’ll work

In your usual Git environment.

Informal poll.

How we’ll work

In temporary folders created by {saperlipopette}.

So we won’t break any important project.

{saperlipopette}

A tool to use Git

An R package to create exercises in distinct folders.

https://docs.ropensci.org/saperlipopette/

install.packages(
  'saperlipopette',
  repos = c('https://packages.ropensci.org', 'https://cloud.r-project.org')
)

saperlipopette

saperlipopette:
R to create Git exercises

  • R to create the exercise in another folder.

  • R in the new session to read the instructions.

  • Your usual tools to solve the Git problem!

saperlipopette:
how to use the package

  • Call a function from an R session.

  • Go to the created folder (shown in the output).

  • Open R in this folder, read the instructions.

  • Work with your Git tools or the terminal.

  • Close the exercise session.

Set up your Git editor

withr::local_language("en") # es, fr
folder <- withr::local_tempdir()
saperlipopette::exo_check_editor(folder)

Fix the Git editor

You have 10 minutes to fix it!

Git is handy

  • Less work loss;

  • Experimentation in branches;

  • History to use (locally and on platforms like GitHub).

Git history

Small commits (changes) with informative messages

A mysterious line of code

a script with a mysterious line 'x <- x - 1'

git blame

simplified diagram of Git blame: for each line of a script on the left, we see who added it, when, with what commit message.

Git blame: click on the commit…

Git blame: click on the commit…

“Add a bunch of files before lunch 🍝

Shows 145 files changed with 2,624 additions and 2,209 deletions.

Git blame: click on the commit…

“fix: adapt code to 0-indexing of the tool”

Shows 2 files changed with 3 additions and 2 deletions.

Git blame: example

In pkgdown

A bad idea 7 commits ago

Oh no, that idea from 7 commits ago is bad! Should we…

  • Manually delete the change;

  • Undo (“Revert”) the commit that added the change?

Git revert

This only works well if the commit is small.

Git revert: let’s try it! 5 minutes

withr::local_language("en")
dir  <- withr::local_tempdir()
saperlipopette::exo_undo_commit(dir)

You doing something three days ago

a bunch of scripts, on which appears an emoji of a happy face wearing sunglasses.

You doing the same thing today

a bunch of scripts, on which appears an emoji of a sobbing face.

Git bisect: commit history

a series of emoji, the first a cool face, then sleeping faces, then a sobbing face.

Git bisect: explore commits optimally

a series of emoji, the first a cool face, then sleeping faces, then a sobbing face. an arrow above a sleeping face.

Git bisect: explore commits optimally

all faces up to the arrow are now cool faces.

Git bisect: explore commits optimally

arrow above a different sleeping face

Git bisect: explore commits optimally

all faces after the arrow are now sobbing

Git bisect: explore commits optimally

arrow on the last sleeping face

Git bisect: explore commits optimally

last sleeping face now sobbing

Git bisect result: one commit!

Git bisect result: one commit!

“Add a bunch of files before exercise 💪”.

Shows 145 files changed with 2,624 additions and 2,209 deletions.

Git bisect result: one commit!

“refactor: start using YAML”

Shows 2 files changed with 3 additions and 2 deletions.

Git bisect: let me show it!

withr::local_language("en")
dir  <- withr::local_tempdir()
saperlipopette::exo_bisect(dir)

Git history

“there’s no need for everyone to see the mistakes you made along the way”

Mike McQuaid, Git in practice

Break 😮‍💨

5 minutes!

How to get a nice Git history

Another dimension to your work.

Working in branches

“The Repeated Amend”™️:
git commit --amend

What is git commit --amend

withr::local_language("en")
dir  <- withr::local_tempdir()
saperlipopette::exo_one_small_change(dir)

Git commit amend: let’s try it!

5 minutes

withr::local_language("en")
dir  <- withr::local_tempdir()
saperlipopette::exo_one_small_change(dir)

“The Repeated Amend”™️:
git commit --amend

https://happygitwithr.com/repeated-amend

  • First part of the work, git commit -m "feat: add cool thing"

  • Second part of the work, git commit --amend --no-edit

  • It’s done! git push

“The Repeated Amend”™️:
git commit --amend

  • git checkout -b 'feature-cool'

  • First part of the work, git commit -m "feat: add cool thing", git push

  • Second part of the work, git commit --amend --no-edit, git push -f

  • It’s done! git push -f

“Squash and merge”: click the right GitHub/GitLab button.

a main branch with several commits, a feature branch with messy commits.

“Squash and merge”: click the right GitHub/GitLab button.

a main branch with several commits, including a new feature commit

“Squash and merge”: click the right GitHub/GitLab button.

Example

“Start from scratch”

  • git reset --mixed Changes in the directory but not the Git history.

  • git add (--patch) Good commits, in hindsight.

Let’s try git add --patch

5 minutes

withr::local_language("en")
dir  <- withr::local_tempdir()
saperlipopette::exo_split_changes(dir)

Break 😮‍💨

5 minutes

“Start from scratch”

withr::local_language("en")
dir  <- withr::local_tempdir()
saperlipopette::exo_reset(dir)

“Mix and match your commits”

git rebase -i

withr::local_language("en")
dir  <- withr::local_tempdir()
saperlipopette::exo_rebase_i(dir)

“Mix and match your commits”

Resources on git rebase

Julia Evans’ rules for rebasing

Julia Evans’ post “git rebase: what can go wrong?”

Start from scratch or rebase

10 minutes

Either

withr::local_language("en")
dir  <- withr::local_tempdir()
saperlipopette::exo_reset(dir)

Or

withr::local_language("en")
dir  <- withr::local_tempdir()
saperlipopette::exo_rebase_i(dir)

Why have small informative commits.

Better history, especially for

  • git blame

  • git bisect

  • git revert

How to create better commits

You don’t need to get it right the first time

  • The Repeated Amend ™️

  • Squash and merge PRs

  • Start from scratch

  • Mix and match your commits

What tools for Git?

  • The terminal: it never changes, and you learn the words.

  • RStudio IDE

  • Positron IDE, GitLens extension

  • Other IDEs

  • GitHub Desktop

Practice safely with the {saperlipopette} playgrounds!

Still other exercises to try. 😉

Thank you! 💙

Thanks to the uRos team especially TA Ciprian Alexandru.

https://uros-git.netlify.app

https://docs.ropensci.org/saperlipopette/

Git resources for beginners