Just like in homework 1, you should have received a repo if you filled out the partner form or are enrolled in this course. To get started on the coding, you should git clone with IntelliJ (or your terminal if you prefer) just like you did for homework 1. If you are not enrolled in this course, you can access the public repo here.
In homework 1, you had to clone your repo, commit, and push, but you didn't really need to use the 3rd main command of Git: pull. For Git, pulling encompasses both downloading updated code and replacing any existing files with those updates. (In more technical words, it copies new commits from the remote repo to the local repo, then applies the changes from those commits to the working directory.)
Because you will be working with a partner in this next part, you may encounter situations where you need to pull updates that were made on your partner's computer, unlike homework 1, where your computer was the one pushing out all the updates.
In particular, if your partner pushes some changes to your repo on GitLab, and then you attempt to push more changes without first pulling the changes your partner made, GitLab will refuse your changes until you pull. In this case, IntelliJ will present you this window after you attempt to push:
You'll need to pull and merge in your partner's changes before you can continue; to do this, just click "Merge". If there are any conflicts that cannot automatically be resolved, the "Conflicts" window will open; see the next section for more details.
After completing the merge, we recommend checking that all relevant code still works properly. You should check this even if the merge completes automatically: an automatic merge just means that the changes were in different parts of the file—not necessarily that the automatically-merged version of code is correct.
After you've made sure your merge is correct, you'll need to tell IntelliJ to push again. If you merged properly (and nobody else has pushed again after you merged), the push should no longer be rejected.
You can (and should) also pull code when you're not about to push, too. The instructions for pulling were described in homework 1. When you pull code, if there are new changes on both your machine and the remote repository, Git will automatically attempt to merge the two sets of changes. However, sometimes the automatic merging will fail:
Merging is the process of combining two versions of code that branched off from some common ancestor commit. Git will try to automatically handle a merge when you pull: if the two sets of changes involve different files, it will just apply both sets; additionally, if both sets of changes alter different parts of the same file, Git will attempt to integrate both sets of changes automatically.
However, if both sets of changes touch the same line, you'll need to manually resolve the merge; this is called a merge conflict. In this case, for each altered part of the files with conflicts, Git will include and mark the results of both sets of changes directly in the files in the working directory. (Many GUIs for Git will include functionality to display this nicely; otherwise, you'll need to edit the files manually.) The merge finishes after all conflicts are resolved and the changes are committed.
Check out IntelliJ's page on Resolving Merge Conflicts; there's a nifty window that will pop up that should help you resolve these relatively pain-free. And feel free to come to office hours if you have trouble with this stuff.
Note that if you aren't careful in this process and cancel the merge (e.g., by clicking "Abort"), your repository may be left in a half-merged state, which will prevent most Git functionality from working properly. If anything goes wrong, we recommend coming in to office hours for help unless you're confident in your Git knowledge—Googling and trying random things may make things worse if your problem doesn't exactly match the solutions you find, and it tends to be difficult to debug these issues online on the discussion board.
As an aside, the fact that merges are commits means that commits can have multiple parent commits, so the Git history isn't quite a linked list. Also, because there must be "branching" in order for the merge operation to make sense, the history isn't quite a tree either; we call this kind of data structure a graph. Graphs are a very interesting and flexible data structure, and we'll be going over them later in the course.
We'll also take this moment to note that not all sections will take the same amount of time and effort, so if you are working with a partner, it is not a good idea to divide-and-conquer the separate sections. Instead, we strongly recommend pair programming—this will ensure that both parties contribute equally and that both parties know what the code does and how to debug it when using it in later assignments. Additionally, your partner is super invaluable for helping you debug and helping you talk through and plan your code.
If you have 5–10 minutes, we strongly recommend you read the letter from a TA about pair programming. It has several tips and motivations for pair programming. It even has a recap at the end if you only have 1 minute to spare.