List of exercises

Full list

This is a list of all exercises and solutions in this lesson, mainly as a reference for helpers and instructors. This list is automatically generated from all of the other pages in the lesson. Any single teaching event will probably cover only a subset of these, depending on their interests.

Quick recap on Git Basics: Commits and Branches

In commits.md:

Exercise

In order to achieve an equivalent result, you need to

In commits.md:

Exercise: Practice creating commits and branches (20 min)

  1. Make sure that you now work on your fork of the recipe-book repository (USER/recipe-book, not coderefinery/recipe-book)

  2. First create a new branch and then add a recipe to the branch and commit the change.

  3. In a new commit, modify the recipe you just added.

  4. Switch to the main branch and modify a recipe there.

  5. Browse the network and locate the commits that you just created (“Insights” -> “Network”).

  6. Compare the branch that you created with the main branch. Can you find an easy way to see the differences?

  7. Can you find a way to compare versions between two arbitrary commits in the repository?

  8. Try to rename the branch that you created and then browse the network again.

  9. Try to create a tag for one of the commits that you created (on GitHub, create a “release”).

Inspecting history

In archaeology.md:

Exercise: Explore basic archaeology commands (20 min)

Let us explore the value of these commands in an exercise. Future exercises do not depend on this, so it is OK if you do not complete it fully.

Exercise steps:

  • Make sure you are not inside another Git repository when running this exercise. If you are, first step “outside” of it. We want to avoid creating a Git repository inside another Git repository.

    You can check if you are inside a Git repository with:

    $ git status
    
    fatal: not a git repository (or any of the parent directories): .git
    

    You want to see the above message which tells us that this is not a Git repository.

  • Clone this repository: https://github.com/networkx/networkx.git.

    $ git clone https://github.com/networkx/networkx.git
    
  • Then let us all make sure we are working on a well-defined version of the repository.

    Step into the new directory and create an exercise branch from the networkx-2.6.3 tag/release:

    $ cd networkx
    $ git switch --create exercise networkx-2.6.3
    

    On old Git versions which do not know the switch command (before 2.23), you need to use this instead:

    $ git checkout -b exercise networkx-2.6.3
    

Then using the above toolbox try to:

  1. Find the code line which contains "Logic error in degree_correlation".

  2. Find out when this line was last modified or added. Find the actual commit which modified that line.

  3. Inspect that commit with git show.

  4. Create a branch pointing to the past when that commit was created to be able to browse and use the code as it was back then.

  5. How would you bring the code to the version of the code right before that line was last modified?

In archaeology.md:

(optional) History-2: Use git bisect to find the bad commit

In this exercise, we use git bisect on an example repository. It is OK if you do not complete this exercise fully.

Begin by cloning https://github.com/coderefinery/git-bisect-exercise.

Motivation

The motivation for this exercise is to be able to do archaeology with Git on a source code where the bug is difficult to see visually. Finding the offending commit is often more than half the debugging.

Background

The script get_pi.py approximates pi using terms of the Nilakantha series. It should produce 3.14 but it does not. The script broke at some point and produces 3.57 using the last commit:

$ python get_pi.py

3.57

At some point within the 500 first commits, an error was introduced. The only thing we know is that the first commit worked correctly.

Your task

  • Clone this repository and use git bisect to find the commit which broke the computation (solution - spoiler alert!).

  • Once you have found the offending commit, also practice navigating to the last good commit.

  • Bonus exercise: Write a script that checks for a correct result and use git bisect run to find the offending commit automatically (solution - spoiler alert!).

Hints

Finding the first commit:

$ git log --oneline | tail -n 1

How to navigate to the parent of a commit with hash SOMEHASH:

$ git switch --create BRANCHNAME SOMEHASH~1

Instead of a tilde you can also use this:

$ git switch --create BRANCHNAME SOMEHASH^

Optional: Git Internals

In internals.md:

Changes and their effect: files and commits

Refer to the figure above, and discuss: which SHA-1 hashes would change in the diagram if:

  • the content of the first file is changed,

  • we recreate a commit with another message or author

  • we recreate a commit with the same message or author

Is it possibe to have multiple commits refer to the same tree? What happens when you use git revert?

In internals.md:

A look at the objects

Let us poke a bit into raw objects! Start with:

$ git cat-file -p HEAD

Then explore the tree object, then the file object, etc. recursively using the hashes you see.

Operating on Branches

In branches.md:

Exercise

By changing the content of .git/HEAD we have manually “switched” from a branch to another one that actually points to the same commit.

What would have happened if we changed HEAD to point to a branch that does not point to the same commit as the one we were on before? What would we see with git status?

In branches.md:

Branches on different repositories

How are branches on different repositories related to each other?

Concepts around collaboration

In collaboration-concepts.md:

Exercise

What is the difference between forking and then cloning (your fork, to your computer) vs cloning (to your computer) and then pushing to a brand new repository?

Collaborating within the same repository: issues and pull requests

In same-repository.md:

Exercise

In order to achieve an equivalent result, you need to

  • clone the repository https://github.com/coderefinery/template-centralized-workflow-exercise locally on your computer

  • delete the .git directory to get rid of all the history

  • re-initialize the repo in the directory

  • add the content of the directory and create a first commit

  • create a properly named repository on the forge of your choice

  • push the newly created repository there.

In same-repository.md:

Exercise: Collaborating within the same repository (45 min)

Technical requirements (from installation instructions):

Skills that you will practice:

  • Cloning a repository (CodeRefinery lesson)

  • Creating a branch (CodeRefinery lesson)

  • Committing a change on the new branch (CodeRefinery lesson)

  • Submit a pull request towards the main branch (CodeRefinery lesson)

  • If you create the changes locally, you will need to push them to the remote repository.

  • Learning what a protected branch is and how to modify a protected branch: using a pull request.

  • Cross-referencing issues and pull requests.

  • Practice to review a pull request.

  • Learn about the value of draft pull requests.

Exercise tasks:

  1. Open an issue where you describe the change you want to make. Note down the issue number since you will need it later.

  2. Create a new branch.

  3. Make a change to the recipe book on the new branch and in the commit cross-reference the issue you opened (see the walk-through below for how to do that).

  4. Push your new branch (with the new commit) to the repository you are working on.

  5. Open a pull request towards the main branch.

  6. Review somebody else’s pull request and give constructive feedback. Merge their pull request.

  7. Try to create a new branch with some half-finished work and open a draft pull request. Verify that the draft pull request cannot be merged since it is not meant to be merged yet.

Code review demo

In code-review.md:

Exercise: Practicing code review (25 min)

Technical requirements:

What should be familiar:

What will be new in this exercise:

  • As a reviewer, we will learn how to ask for changes in a pull request.

  • As a reviewer, we will learn how to suggest a change in a pull request.

  • As a submitter, we will learn how to modify a pull request without closing the incomplete one and opening a new one.

Exercise tasks:

  1. Create a new branch and one or few commits: in these improve something but also deliberately introduce a typo and also a larger mistake which we will want to fix during the code review.

  2. Open a pull request towards the main branch.

  3. As a reviewer to somebody else’s pull request, ask for an improvement and also directly suggest a change for the small typo. (Hint: suggestions are possible through the GitHub web interface, view of a pull request, “Files changed” view, after selecting some lines. Look for the “±” button.)

  4. As the submitter, learn how to accept the suggested change. (Hint: GitHub web interface, “Files Changed” view.)

  5. As the submitter, improve the pull request without having to close and open a new one: by adding a new commit to the same branch. (Hint: push to the branch again.)

  6. Once the changes are addressed, merge the pull request.

How to contribute changes to repositories that belong to others

In forking-workflow.md:

Exercise: Collaborating within the same repository (25 min)

Technical requirements:

What is familiar from the previous workshop days:

What will be new in this exercise:

  • Opening a pull request towards the upstream repository.

  • Pull requests can be coupled with automated testing.

  • Learning that your fork can get out of date.

  • After the pull requests are merged, updating your fork with the changes.

  • Learn how to approach other people’s repositories with ideas, changes, and requests.

Exercise tasks:

  1. Open an issue in the upstream exercise repository where you describe the change you want to make. Take note of the issue number.

  2. Create a new branch in your fork of the repository.

  3. Make a change to the recipe book on the new branch and in the commit cross-reference the issue you opened. See the walk-through below for how to do this.

  4. Open a pull request towards the upstream repository.

  5. Team leaders will merge the pull requests. For individual participants, the instructors and workshop organizers will review and merge the pull requests. During the review, pay attention to the automated test step (here for demonstration purposes, we test whether the recipe contains an ingredients and an instructions sections).

  6. After few pull requests are merged, update your fork with the changes.

  7. Check that in your fork you can see changes from other people’s pull requests.

Interrupted work

In interrupted.md:

Interrupted-1: Stash some uncommitted work

  1. Make a change.

  2. Check status/diff, stash the change with git stash, check status/diff again.

  3. Make a separate, unrelated change which doesn’t touch the same lines. Commit this change.

  4. Pop off the stash you saved with git stash pop, and check status/diff.

  5. Optional: Do the same but stash twice. Also check git stash list. Can you pop the stashes in the opposite order?

  6. Advanced: What happens if stashes conflict with other changes? Make a change and stash it. Modify the same line or one right above or below. Pop the stash back. Resolve the conflict. Note there is no extra commit.

  7. Advanced: what does git graph show when you have something stashed?

In interrupted.md:

Stashing all

Sometimes we want to stash files that are not yet tracked by git (i.e., have not been added). How would we do that? Look at the man page using git help stash.

In interrupted.md:

Comments

The option -m to add a message is optional. Why use it?

In interrupted.md:

Stash vs commit

In what sense are stashes similar to commits?

Option 2: Create branches

You can use branches almost like you have already been doing if you need to save some work. You need to do something else for a bit? Sounds like a good time to make a feature branch.

You basically know how to do this:

$ git switch --create temporary  # create a branch and switch to it
$ git add PATHS                  # stage changes
$ git commit                     # commit them
$ git switch main                # back to main, continue your work there ...
$ git switch temporary           # continue again on "temporary" where you left off

Tooling and practices that you might find useful

In tooling.md:

Try them out!

Install and/or configure some of the mentioned tooling that can be helpful for your daily workflow.

Merge and beyond

In merge-tooling.md:

Predict conflicts

Will the merge between branch-1 and branch-2 cause a conflict? Why?

In merge-tooling.md:

Optional: revert a merge commit

When reverting a merge commit, it is not clear which is the parent commit to which we want to revert.

Use the -m option (--mainline) to select the version you want to revert to. See the documentation for git revert.

In merge-tooling.md:

Interactive rebase on another branch

You can practice interactive rebase with

$ git switch rebase-me
$ git reset reset --hard d30163f 
$ git rebase -i rebase-onto-this