git
(2 points)Due Tuesday 10/29 at 1:00 pm. No late submissions accepted.
Submission: Gradescope
Specification: Spec
This assignment focuses on using git
for version control. In particular, this assignment focuses on using git
by yourself: learning how to clone a repository, move files between the “four phases” of git
, and create + merge a feature branch into your main
branch. This exact workflow is helpful when working on personal projects (or storing your homework for other classes)!
In this homework, you will turn in just one file called homework4.sh
. However, you will also make and push changes to a remote GitLab repository; the autograder will be run against your commands in homework4.sh
and the history of the repository.
Warning
git
is a very complex tool with many ways to do similar things. For this homework, we strongly recommend you use the tools discussed in lecture rather than features that we have not discussed (that you may find online, etc.)
To calculate your final score on this assignment, sum the individual scores from Gradescope.
- if your
score
is between[0, 1)
, you will get0
points - if your
score
is between[1.0, 1.5)
, you will get1
point - if your
score
is between[1.5, 2]
, you will get2
points
Info
This autograder is still relatively new. To clarify things, we’ve added π¬ to explain how we’re evaluating your solution for each problem. Don’t hesitate to post on Ed if you have any issues with the autograder!
Task 0: Setting Up¶
Using CSE GitLab¶
First, please follow the steps in Using CSE GitLab (i.e. finish steps 1-3). As a reminder, you should make an ssh
key on the computer you are doing the homework from.
Find your GitLab repo¶
In order to grade this assignment, we have created a GitLab repository for you. You should have gotten an email inviting you to the cse391/24au/hw4
group on GitLab. Your repository should be within that group with the same name as your GitLab username/NetID (e.g. cse391/24au/hw4/dubs2000
). Navigate to the homepage for that repository.
If you haven’t received an email, you should also be able to find the repository by visiting https://gitlab.cs.washington.edu/ and looking at your listed projects.
Warning
Can’t find your repo? Please let your instructor know ASAP!
Download homework4.sh
¶
Similar to previous assignments, you will turn in a .sh
file to Gradescope; download it to get started:
$ wget https://courses.cs.washington.edu/courses/cse391/24au/homework/hw4/homework4.sh
Note that we will grade this assignment by looking at homework4.sh
and the history of your repository.
Add your repository link to print_link
¶
Our autograder will grade this homework by looking at the contents and history of your repository. To do that, it needs to know where it is.
In homework4.sh
, put the URL to the repository (from the address bar in your browser, not “Clone with HTTPS” or “Clone with SSH”). This should start with https://
and should not end with .git
.
Caution
Do not remove the echo
from this command!! But only for this command!
function print_link {
# Type your answer to problem #1 below this line
echo "https://gitlab.cs.washington.edu/cse391/24au/hw4/name-of-your-repository"
}
For example, if Dubs’ UW NetID is dubs2000 (it’s not), the function would look like
function print_link {
# Type your answer to problem #1 below this line
echo "https://gitlab.cs.washington.edu/cse391/24au/hw4/dubs2000"
}
Caution
Make sure your URL exactly matches the URL for your repo (not Dubs’)!
Task 1: Create, edit, and move files¶
All of the problems in this task are autograded by examining the history of your repository; in order for Gradescope to “know” where your repository is, you must finish the print_link
setup task above and push your changes to the GitLab repository.
Problem 1: Create a main
branch and a README.md
¶
By default, the repository that we’ve created for you is empty. Our first step will be to add a README.md
file and create our main
branch. To do this, we’ll “clone” (make a local copy of) the GitLab repository to make a local copy, make our changes, and then push them.
To do that, we’ll essentially follow the instructions under “Create a new repository”. In particular, run the following commands on a terminal connected to a computer with your SSH key (replacing your_netid
with your GitLab username):
$ git clone git@gitlab.cs.washington.edu:cse391/24au/hw4/your_netid.git
$ cd your_netid
$ git switch -c main
$ touch README.md
$ git add README.md
$ git commit -m "add README"
$ git push -u origin main
Caution
Git should not ask you for a password when running git clone
. If you are asked for a password, check that your SSH key is setup properly.
Info
git switch
might not exist on older versions of Git (e.g. on vergil
). In that case, instead of git switch -c main
, use git checkout -b main
.
After executing these commands, you should be in a directory named after your project; this is your “working directory” in git
terminology. Your working directory is where you will edit and create files to commit in your local repository.
At this point, running ls -a
in your working directory should have two interesting files:
$ ls -a
. .. .git README.md
- The
README.md
should be empty (this was just created with thetouch
command). Most repositories have some sort ofREADME
file that explains how the repository works; the.md
extension stands for Markdown, a language used to quickly style and structure text. - The
.git
directory stores all the information about the local copy of the repository. You should notcd
into the.git
directory or modify this directory directly. Instead, you’ll interact withgit
via commands (e.g.git add
orgit commit
).
If you visit the GitLab homepage for your repository (and refresh), you should see that an empty README.md
is now there and pushed to the repository with a commit titled add README
.
π¬ This question is graded by looking in your repo for a commit that creates a file called README.md
.
Problem 2: Create and add a new file to your repo¶
For the rest of this homework, you’ll interact with a toy program called Facts.java
that calculates the factorial of its command line argument. You can test it by compiling and running it, e.g. with javac Facts.java && java Facts 5
.
Copy the Facts.java
file from the course website into your working directory, using:
$ wget https://courses.cs.washington.edu/courses/cse391/24au/homework/hw4/Facts.java
Now, try typing git status
; notice that Facts.java
is listed as an “untracked file” (and shown in red). This is in the “working directory” phase; we can move it to the staging area by using git add
:
$ git add Facts.java
Warning
If you were testing Facts.java
and have a Facts.class
, please do not add/commit it to your repository!
Now, using git status
again will now list Facts.java
as a file ready to be committed (and shown in green).
We can now commit our change (and moving it to the next “phase” of git). For this problem, you should make sure that your commit message is exactly "Added Facts.java"
.
There are two ways you can do this: either with the -m
flag, which allows you to specify a short commit message:
$ git commit -m "Added Facts.java"
Or, by opening up your editor of choice:
$ git commit
Finally, letβs push the changes in your local copy of the repo to the remote repo on GitLab.
$ git push
On GitLab, if you refresh the files, you should see that Facts.java
is now there.
Run git log
in your directory to see recent commit history.
π¬ This question is graded by looking in your repo for a commit which adds this file and has the exact commit message "Added Facts.java"
.
Problem 3: Edit a file in the repo¶
You may notice that Facts.java
has no comments in it. While it’s a pretty simple program, a comment or two wouldn’t hurt!
In your working directory, edit the file Facts.java
by adding at least one Java comment to the file. The contents of the comment can be whatever you like, but you must add at least one comment (using either //
or /*
) while also not changing the behaviour of the code.
To double-check your work, you can use the commands 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
.
Once you are ready, use the commands we’ve learned from class to commit your changes and push them to the remote repository. You may pick whatever commit message you like.
π¬ This question is graded by looking in your repo for a commit which modifies Facts.java
by adding at least one line that contains (//
or /*
, representing a Java comment).
Problem 4: Rename a file (and class) in the repo¶
We have decided that Facts.java
is an ambiguous name (since you may also want to make a program that gives out fun facts). In order to accomodate for this in our repository, we want to rename Facts.java
to Factorial.java
. In addition, we should rename the class declared inside the Java program to be Factorial
rather than Facts
(if you don’t, your code will no longer compile).
(want to check if your new file works properly? javac Factorial.java && java Factorial 10
should output 3628800
)
After making these changes, use the appropriate commands to stage your new Factorial.java
file, then commit and push your changes to the remote repo. You may pick whatever commit message you like.
π¬ This question is graded by looking in your repo for a commit that renames Facts.java
to Factorial.java
.
Task 2: Exploring git
commands¶
This next task asks you to explore some git
commands and answer questions for common operations. We encourage you to try practicing them in your repository, but you do not need to commit any changes to complete this task; instead, write your answers within the corresponding functions in homework4.sh
.
For these problems, the following commands will be relevant:
git status
git diff
git log
git blame
You will want to look at the man
page for each of these commands and experiment with them (especially git blame
, which we did not cover in the videos).
Problem 1¶
What command provides more information about just the most recent commit?
Hint: you will need to pass a flag to one of the aforementioned commands.
Problem 2¶
What command outputs the differences between the most recent commit and its grandparent (2 commits prior)?
Hint: the most recent commit is often referred to as HEAD
; a commit n
commits before the most recent commit is denoted by HEAD~n
.
Problem 3¶
What command tells you who most recently changed each line of Factorial.java
(and when)?
Hint: the command you’re looking for is not git log
.
Task 3: Make and resolve a merge conflict¶
This final task simulates a part of the “git workflow”: creating a new branch, make some code changes (in this case, refactoring), resolving a merge conflict, and then merging it into main
.
Problem 1: Go to a new branch¶
First, we will create a new branch to make our change. From the main
branch, create a new branch that is exactly called refactor-factorial
:
$ git checkout -b "refactor-factorial"
This command uses git checkout
and the -b
flag to create a new branch called refactor-factorial
and then check it out (i.e. move to that branch).
You will know that you’re successful when git status
indicates that you are on the refactor-factorial
branch, not the main
branch.
Problem 2: Refactor the code¶
Note
The emphasis of this class is not on writing complicated Java code, so we are picking an intentionally small refactor and providing you with the code.
Now that you’re in the branch, we’re ready to make some changes. In this case, your boss has decided that the actual logic that calculates the factorial should live in its own method.
So, create a new method called factorial
that “pulls” out the factorial logic, like so:
public static int factorial(int num) {
int fact = 1;
for (int i = 1; i <= num; i++) {
fact *= i;
}
return fact;
}
Then, in the main
method, call factorial
instead and print out its return value:
public static void main(String[] args) {
// ...
int num = 0;
try {
// ...
} catch {
// ...
}
System.out.println(factorial(num));
}
Before you add and commit your changes, verify that this new refactor still works as intended; e.g., after recompiling your code,
java Factorial 0
should print out1
java Factorial 1
should print out1
java Factorial 5
should print out120
java Factorial 10
should print out3628800
Now, use the appropriate git
commands to stage and commit this refactor to the refactor-factorial
branch. In particular, you should not add the Factorial.class
file — just the Factorial.java
file. We suggest the commit message exactly Refactor factorial to its own method
.
After committing your changes, push your branch to GitLab:
$ git push --set-upstream origin refactor-factorial
You can then check that your branch exists on GitLab. If you don’t push the branch the autograder won’t be able to grade your submission properly, resulting in a potential loss of points.
π¬ This question is graded by examining your refactor-factorial
branch, and making sure that you have defined the appropriate new method without changing the behaviour of the file.
Problem 3: Bugfixes and merge conflicts¶
Note
For this problem, we have you commit to main
to introduce a merge conflict. This is for simplicity’s sake, but in real software development you’d want to make this change on a branch too!
First, switch back to the main
branch of the repository.
$ git checkout main
(note that this should not have any of the changes you made on your refactor-factorial
branch)
Your boss has now separately pointed out that the Factorial
program gives the wrong output for some inputs, such as java Factorial 20
(which outputs -2102132736
— the wrong answer due to integer overflow).
This is mission critical, so your boss says you need to commit the bugfix to main
ASAP. In particular, he suggests changing the fact
variable to a long
. In your main
method, make that change:
public class Factorial {
public static void main(String[] args) {
- int fact = 1;
+ long fact = 1;
}
}
Making just this change should resolve the bug; confirm that by recompiling your program and verifying that java Factorial 20
now outputs 2432902008176640000
.
Now, using the appropriate git
commands, stage and commit your changes to the main
branch (taking extra care to not commit any .class
files). We suggest the commit message Fixes integer overflow bug
.
Finally, you remember that you need to merge in your changes from refactor-factorial
. Run:
$ git merge refactor-factorial
At this point, git
should tell you that there is a merge conflict. To fix this conflict, you will need to edit Factorial.java
with your text editor of choice.
This merge conflict is particularly nasty, since it’s not just a syntax change; you need to make the code represent the merge of the intention of the previous two commits. In particular, your final code should:
- not suffer from the
int
overflow error (at least, onjava Factorial 20
) - and, refactor the factorial logic into its own method called
factorial
- hint: you will have to change the method signature to match with
fact
now being along
- hint: you will have to change the method signature to match with
- still compile and run properly on the examples we’ve mentioned in the spec (e.g.
0
,1
,5
,10
, and20
)- note that this requires you to remove the
<<<<<< HEAD
,=======
, and>>>>>> sort-menu
lines
- note that this requires you to remove the
Once you have resolved the merge conflict, test your code and make sure that it still compiles and runs. Then, add your changes and commit them. For this commit, we suggest that you don’t change the default commit message; simply save and exit the editor. Then, push your changes to remote.
π¬ This part is graded by looking in your repo 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
.