Homework 4
Version control
This assignment focuses on introducing the git version control system (VCS) by practicing a very frequently-followed workflow: cloning a repository, staging and committing changes, and merging a feature branch into your main branch. While your work for some of the tasks will be submitted as in an sh file to Gradescope just as before, the Gradescope autograder will also check your CSE GitLab repository history and verify the tasks were completed and pushed successfully.
git is a very complex tool. We strongly recommend using only commands introduced in class.
Enrolled students will have received email inviting them to a private repository in CSE GitLab. If you can’t find the email, you should also be able to find the repository by logging into CSE GitLab. If you can’t find your repository after logging in, be sure to ask on the discussion board!
Download the homework files on attu
After logging into attu, download the homework files.
git archive --remote=git@gitlab.cs.washington.edu:cse391/25wi/hw4.git --prefix=hw4/ HEAD | tar -x
Add your repository link
In homework4.sh, complete the print_link function so that it prints-out the https URL to your private repository exactly as it appears in your web browser address bar without any trailing # character. The URL should end with your NetID.
For this part only, be sure to keep the echo command so that running print_link will print out your private repository URL.
Our autograder will grade this homework by cloning your private repository. Keep the your private repository page open in your browser since we’ll be using it frequently throughout this assignment.
Task 1: Create, edit, and move files
Let’s setup your repository. All the problems in this task are autograded by examining your remote repository history. You don’t need to edit homework4.sh for the entirety of this task.
Clone your repository and add a README.md
On attu, follow the Command line instructions on your private repository page to Create a new repository. The first command will clone (download) the repository from CSE GitLab, and the second command will change directory into your new, local copy of the repository.
git clone git@gitlab.cs.washington.edu:cse391/25wi/students/YOUR_CSE_NETID.git
cd YOUR_CSE_NETID
The next sequence of commands will create a main branch, write an empty text file called README.md, stage the empty README.md file, commit the staged changes to the local repository, and finally push the new commit to the remote repository.
git switch --create main
touch README.md
git add README.md
git commit -m "add README"
git push --set-upstream origin main
At this point, running ls -a should list the README.md file alongside a hidden .git directory.
- README.md
- This empty file was just created with the touchcommand. Most repositories have some sort ofREADME.mdfile that explains how the repository works. The.mdextension stands for Markdown, a language for styling and structuring plain text.
- .git
- This hidden directory stores important information about your local copy of the repository. gitcommands likegit addandgit commitrecord their changes in specially-formatted files stored in the.gitdirectory. There is usually no reason to make any changes to files inside the.gitdirectory.
After pushing commits from your local repository to the remote repository, if you now refresh your browser tab with your remote repository, you should see the empty README.md file and your commit titled add README.
This question is graded by looking in your repository for a commit that creates a file called README.md. No edits need to be made to homework4.sh.
Add a new Java file to your repository
Now that we’ve setup our local repository, let’s use it to develop software!
Copy the Facts.java file from your hw4 directory into your local repository. Facts.java calculates the factorial of its command line argument: we can calculate 5! by compiling and running it with javac Facts.java && java Facts 5.
Since this is a new file, if we now run git status, the output will explain that it is an untracked file. Stage the new file using the git add command to add only Facts.java.
git add Facts.java
If you previously compiled Facts.java and now have a Facts.class, be sure to only add Facts.java. Do not add or commit any compiled .class files to your repository!
Now that Facts.java has been staged, we can now commit the change. For this problem, be sure that your commit message is exactly "Added Facts.java".
git commit -m "Added Facts.java"
Finally, push the changes in your local repository to the remote repository on GitLab.
git push
On GitLab, if you refresh the files, you should see that Facts.java is now there.
This question is graded by looking in your repository for a commit that adds the Facts.java file with the exact commit message Added Facts.java.md. No edits need to be made to homework4.sh.
Edit a file in your repository
If you open Facts.java in vim, you’ll notice that it contains no documentation. Adding documentation not only helps explain how to use the program, but it also signals a degree of professionalism about the software: particularly important in helping users make a decision about which implementation to use.
Edit the file Facts.java by adding at least one Java comment to the file. The contents of the comment aren’t graded, but you must add at least one comment using either // or /*.
To double-check your work, use git status and git diff. You can also check if your Facts.java file still works properly by verifying that javac Facts.java && java Facts 10 outputs 3628800.
Stage your changes, commit them, and push the changes to your remote repository with any descriptive commit message.
This question is graded by looking in your repository for a commit that modifies Facts.java by adding at least one line that contains // or /*, representing a Java comment. No edits need to be made to homework4.sh.
Rename a file (and class) in your repository
Facts.java is great for computing factorials, but not so great for generating fun facts.
In order to accomodate both goals, rename Facts.java to Factorial.java so that we can later write a Facts.java program that generates fun facts. Be sure to rename the class declared inside the Java program to Factorial rather than Facts too: if you don’t, the code will no longer compile!
Stage your changes, commit them, and push the changes to your remote repository with any descriptive commit message.
This question is graded by looking in your repository for a commit that renames Facts.java to Factorial.java. No edits need to be made to homework4.sh.
Task 2: Exploring git commands
In homework4.sh, write your answer to the following questions using only git status, git diff, git log, or git blame. It’s not necessary to run any commands in your local repository; instead, write your answers within the corresponding functions in homework4.sh. Read the man page for each command and experiment with them (especially git blame, which we did not cover in the prework).
- Which command provides more information about just the most recent commit? Read the manpages to identify the necessary flag.
- Which command outputs the differences between the most recent commit and its grandparent (2 commits prior)? The most recent commit is HEAD; a commitkcommits before the most recent commit is denoted byHEAD~k.
- Which command tells you who most recently changed each line of Factorial.java(and when)? Don’t usegit log.
Task 3: Make and resolve a merge conflict
In real-world collaborative software development, we’ll often create a new branch, make some code changes, resolve a merge conflict, and then merge the new branch back into the main branch. Specifically, we’ll focus on refactoring code, or reorganizing the program to improve code quality without affecting its behavior.
Switch to a new branch and refactor the code
First, we will create a new branch to make our change. From the main branch, create a new branch called refactor-factorial.
git switch -c refactor-factorial
In the main method, remove the existing factorial calculation code:
-  int fact = 1;
-  for (int i = 1; i <= num; i++) {
-    fact *= i;
-  }
-
-  System.out.println(fact);
Then, copy the following factorial method and paste it inside the Factorial class.
  public static int factorial(int num) {
    int fact = 1;
    for (int i = 1; i <= num; i++) {
      fact *= i;
    }
    return fact;
  }
Finally, call the factorial function at the end of the main method.
System.out.println(factorial(num));
Before you add and commit your changes, check that your refactored code still works as intended.
- java Factorial 0should print out- 1
- java Factorial 1should print out- 1
- java Factorial 5should print out- 120
- java Factorial 10should print out- 3628800
Be sure not to commit the Factorial.class file!
After committing your changes, push your branch to GitLab:
git push --set-upstream origin refactor-factorial
This question is graded by looking in your repository for a refactor-factorial branch for a refactored Factorial.java program that still works as intended. No edits need to be made to homework4.sh.
Fixing an integer overflow bug
Since we’ve finished refactoring the code, it’s time to switch back to the main branch so that we can keep up to date with everyone’s changes.
git switch main
Factorial.java should no longer contain your refactored code. But we might realize that our Factorial program gives the wrong answer for some larger numbers, such as java Factorial 20, which outputs the negative number -2102132736 due to integer overflow. To fix this issue, change the type of the fact variable to long.
-      int fact = 1;
+      long fact = 1;
Recompile the program and check that java Factorial 20 now outputs 2432902008176640000. Stage your changes, commit them, and push the changes to your remote repository with any descriptive commit message.
Be sure not to commit the Factorial.class file!
Merge the refactor back to main
Now that we’ve addressed the bug in the main branch, it’s time to merge the refactor-factorial branch back to the main branch. From the main branch:
git merge refactor-factorial
git should report a merge conflict! To fix this conflict, edit the Factorial.java file so that the resulting code merges the ideas from both branches:
- The resulting code addresses the integer overflow problem at least on java Factorial 20.
- The resulting code refactors the math logic into its own method called factorial. Remember to update the method signature to return alongrather than anint!
- The resulting code compiles and runs properly on all previous examples.- java Factorial 0should print out- 1
- java Factorial 1should print out- 1
- java Factorial 5should print out- 120
- java Factorial 10should print out- 3628800
- java Factorial 20should print out- 2432902008176640000
 
Stage your changes, commit them, and push the changes to your remote repository. For this commit, we suggest keeping the default commit message; simply save and exit the editor. Then, push your changes to remote.
This question is graded by looking in your repository for a merge commit in main as well as the final main branch providing the correct output for java Factorial on 0, 1, 5, 10, and 20. No edits need to be made to homework4.sh.