In-class exercise Git bisect: Instructions

High-level goal

The high-level goal of this two-part exercise is to improve git proficiency and to learn about systematic debugging, using git bisect.

Part 1: Debugging

Instructions

  1. Team up in groups of size 2, and self-assign to a group (In-class1-Git groupset) on Canvas. (If you are in a Canvas group of size 1, you can still submit.) In the past, groups found a pair-programming set up (in person or using screen-sharing for remote work) to be beneficial.

  2. Clone the following git repository and read its README.md file: https://bitbucket.org/rjust/basic-stats

  3. Test your set-up: compile and test the application. Note that one test failure is expected on the most recent commit of the main branch.

  4. Check out the version v1.0.0 (git checkout v1.0.0), and compile and test the application again. Note that all tests are expected to pass on this revision.

Background (story time)

The developers of this application followed reasonable development practices and used a test-driven approach until they published the first release. Everything just went haywire from there – a lot of late-night, sleep-deprived, pizza-and-drinks hacking.

Unfortunately, the developers introduced a defect at some point after the first release (v1.0.0), which has existed in the code since. While the developers thought about and implemented some automated testing, their automated testing infrastructure did not catch the defect, and since they were so excited about coding, they never manually checked a single test run. The testing infrastructure is a nightly run cron job, which executes the following command: ant clean test || reportBug

This command builds the application from scratch and runs all tests using Ant. If ant fails (i.e., returns a non-zero exit code), then the reportBug command notifies the developers via email; otherwise nothing happens. Note that || is a short-circuit OR operator: the command on the right-hand side (reportBug) is only executed if the command on the left-hand side (ant clean test) fails.

Now what?

  1. Checkout the most recent commit on main (git checkout main) and run: ant clean test. Note the test failure and figure out why the testing infrastructure described above does not catch this failure,i.e., does not send an email (hint: run ant clean test || echo "Test failure" to simulate the error reporting).

  2. Familiarize yourself with the version control history and determine the number of commits between v1.0.0 and main (current HEAD revision). Include v1.0.0 and HEAD when counting, and note the command(s) that you used to automatically compute this number.

  3. Familiarize yourself with the git bisect command and use it to identify the commit that introduced the defect between version v1.0.0 and main. Note the commit hash and log message of the defect-inducing commit. Verify that you correctly identified the defect-inducing commit. You may automate git bisect with a script.

Questions

  1. Why does the described automated testing infrastructure not catch the test failure? How could you improve it?

  2. How many commits exist between version v1.0.0 and main (including v1.0.0 and main)? List the command(s) that you used to automatically compute this number.

  3. Which commit (commit hash and message) introduced the defect? How did you verify that this commit indeed introduced the defect?

  4. How many steps (git bisect calls) did it take you to identify the defect-inducing commit? List each of the steps.

  5. What is the best-, worst-, and average-case run-time complexity of git bisect to return the defect-inducing commit? Why?

  6. Which git command can you generally use to undo a defect-inducing commit – like the commit you identified in question 3? Can you undo this defect-inducing commit using the proposed git command? Briefly explain what problem may generally occur when undoing a commit and what best practices mitigate this problem.

Part 2: Dependency upgrade

Instructions

  1. Clone the following git repository and read its README.md file: https://bitbucket.org/rjust/jp-example

  2. Test your set-up: compile and run the application.

Now what?

  1. Upgrade the JavaParser dependency in the build.gradle file: change the version number from 3.7.0 to 3.24.0.

  2. Compile and observe three compilation errors. Two of the compilation errors have the same root cause: all static helper methods now live in a class called StaticJavaParser. The third compilation error, however, is a bit more tricky and it’s not quite clear how to fix it.

  3. Use git bisect over the https://github.com/javaparser/javaparser to identify the commit that introduced the breaking change – the one that causes the third compilation error in the jp-example code. Automate this process. (Note: it is easier to only compile the ThisExprVisitor during bisection.)

  4. Fix all compilation errors and complete the dependency upgrade. (Note: give yourself about 15 minutes after you identified the commit that introduced the breaking change; if you get stuck ask the course staff for help.)

Questions

  1. Which commit (commit hash and message) introduced the breaking change?

  2. What changes were required to perform the dependency upgrade (output of git diff)?

Deliverables

  1. A plain-text (or PDF) file with your answers to the 8 questions above. Please list all group members.

Steps for turn-in

One team member should upload the deliverables to Canvas, via the Canvas submission site for this course.