| CPSC 329 | Software Development | Fall 2026 |
This lab introduces working in teams with Git, using GitHub for the shared repository. Part 1 is individual: setting up GitHub and practicing the basic solo workflow with a shared (central) repository — specifically, the distinction between committing (local only) and pushing/pulling (syncing with the remote). Part 2 is done with a partner: a full GitHub Flow workflow, including checking out an already-created project as a collaborator, feature branches, pull requests, merging, and resolving a merge conflict.
Successful completion of this lab means that you:
Labs are for learning and practice — you may help and be helped by others when it comes to figuring out what to do, but in the end you need to understand and be able to do the things for yourself.
In this lab, part 1 is individual — everyone needs their own GitHub account and needs to go through the setup themselves. Part 2 is done with a partner — while you'll each be working on separate computers and switching back and forth between who is typing, you are each responsible for understanding the whole process and not just the parts where you were at the keyboard.
You may not use AI to figure out what to do or to do the task for you.
due Fri 9/25 at the start of class
To hand in your work:
Copy your entire ~/cs329/dev/lab4-solo directory into your handin directory. Make sure you end up with a lab4-solo directory inside your handin directory that contains the src directory (with your code) — you shouldn't have a bunch of stuff loose in the top level of your handin directory or multiple levels deep of lab4-solo folders.
In Eclipse, take a screenshot of the History view that shows your commits (with the commit comment, author, and timestamp info) and save it with the name "commit.png" in the top level of your handed-in lab4-solo directory (the one in your handin folder).
Person A only: Add sbridgeman (me) to the lab4-pair repository as a collaborator so that I can see your work.
You'll be working with a simple dog door simulation program. The provided version has a remote controlled dog door which closes automatically a bit after it has been opened.
In this part you'll set up a personal GitHub repository, connect it to an Eclipse project, and practice the difference between committing and pushing/pulling.
GitHub is the largest and most widely used Git hosting service, especially for open-source projects, and it is the one you are most likely to encounter again. In addition to hosting Git repositories, it layers on collaboration features that Git itself doesn't provide, like pull requests for reviewing changes before they're merged and simple tools for managing who has access to a repository.
GitHub account creation notes:
A free account is all you need. You can use any email address (it doesn't have to be your HWS email) and you do not need to sign up for GitHub Education or a student developer pack.
Decline or skip past anything about Copilot. Copilot is an AI coding tool and is not permitted in this course.
Pick a username you are comfortable with long-term. Your GitHub username shows up in commit history, repository URLs, and (if you ever go public with a project) potentially to employers — a professional or neutral username is a reasonable default over something you might not want tied to your name later. You can change it later, but other people's existing links to your profile break if you do.
Two-factor authentication is worth turning on, but if you do, make sure you've saved your recovery codes somewhere before you need them. Getting locked out of your own account is an avoidable headache.
Start the same way you'd start any Eclipse project with Git, by creating the Eclipse project and sharing it to a local Git repository:
Create a new Eclipse project named lab4-solo. Remember that the project directory should end up under ~/cs329/dev, not in Eclipse's workspace.
Import all of the Java files from /classes/cs329/lab4 into your project. Make sure they end up under the src folder in the project.
Confirm that it builds with no errors — there shouldn't be any error icons shown in the Package Explorer. (Run DogDoorSimulator to see what the program does.)
Create a new (local) Git repository, create/set up .gitignore, and do the initial commit. Include a meaningful commit message (e.g. "Added dog door starter files").
So far the project lives only in your local repository. Time to push it to GitHub! Note that when you push, git isn't just sending your current code — instead, you must tell it which local branch should update which remote branch. This mapping is what a "ref specification" (or "ref spec") defines, and setting up the desired ref spec(s) is part of the push process.
On github.com, create a new repository. (If you don't see a "Top repositories" panel with "New" button on the left side of the page, use the hamburger menu in the upper left corner to go to your GitHub home page.) Name the repository lab4-solo, make it private, and do not initialize it with a README, a .gitignore, or a license — you've already started things in your local repository and creating an empty GitHub repository avoids having to reconcile two separated starting points.
Copy the new repository's URL — use the HTTPS URL shown in the "Quick setup" section. (It should have the form https://github.com/username/lab4-solo.git, where username is replaced by your GitHub username. If you need this URL again after you've pushed files, you can find it by going to the repository's page and clicking the green "Code" button.)
Back in Eclipse, right-click the project → Team → Remote → Push... Paste the repository's URL in the Location URI box and click Next.
The first time you connect to GitHub, you will be prompted for your login credentials. Enter your GitHub username, but for the password you will need a personal access token instead of using your GitHub password: while logged in on github.com, click on your profile picture (upper right corner) → Settings → Developer settings (bottom of the left side panel) → Personal access tokens → Tokens (classic) → General new token (classic). Give it a name ("note") (e.g. "eclipse token"), set an expiration date past the end of the course (e.g. Dec 31, 2026), and check the "repo" box for the scope. Generate the token and paste the token into Eclipse's password field. Check the "Store in Secure Store" box so you don't have to do this every time. (It's also a good idea to save your token somewhere — you can't retrieve it from GitHub so if Eclipse forgets it, you'll have to regenerate the token and update anywhere it might be stored.)
For "refs to push", choose main as the source ref, confirm that the destination ref is updated to match, and click "Add Spec". You should now see a specification listed that reflects the desired operation: update from the main branch in the local repository (source) to the main branch in the GitHub repository (destination).
Click Next, confirm (again) the expected push (from main to main), and click Finish.
Visit the repository on github.com — you should be able to see that your files are now visible there. (You may need to refresh the page.)
The basic individual workflow with a remote repository is commit-push: each time you have a working bit committed, do a push to send it to the GitHub repository.
In DogDoor, add a description of the class to the current class comment in DogDoor (it's a dog door).
Commit this change locally. (Team → Commit...)
Check GitHub in your browser before pushing — confirm the change isn't there yet. (This is just to reinforce the difference between commit and push — it's not a necessary step of the process.)
Push — since you just want to update the same branch, you can click "Push HEAD..." in the Git Staging view instead of going through the full wizard (right-click the project → Team → Remote → Push...). Confirm that the destination repository information is correct (fill it in if needed) and click Preview, then confirm the source and destination and click Preview, then confirm (again!) the expected push result and click Push.
Refresh the repository page in GitHub and observe the updates.
At this point you are a solo developer using a single computer so no one else is making changes to the remote repository. However, GitHub lets you edit files directly in the browser — something you should generally be very cautious about! — which makes it possible to simulate a partner pushing their own changes without (yet) having a partner.
On github.com, open Remote.java in your repository and click the pencil (edit) icon.
Add a description of the class to the current class comment (it's a remote control for a dog door which auto-closes the door after a period of time).
Commit the change to the main branch directly on GitHub. (green "Commit changes..." button) Include an informative commit message.
Back in Eclipse, open Remote.java and confirm that the change isn't there yet. (Nothing happens automatically — changes in a local or remote repository are not propagated to the other without an explicit push or pull operation.)
Right-click the project → Team → Pull. (Note the two similar options: Pull pulls from a tracked branch while Pull... lets you configure where to pull from. If Pull doesn't work, use Pull... instead — "Remote" is the location of the remote (GitHub) repository, "Reference" is which branch to pull from (start typing the name of the branch, then select from the list of matches), and "When pulling" should be "Merge".)
Open Remote.java and confirm that the changes are there.
Pull is the mirror image of push: push sends changes from your local repository to the remote, while pull brings changes from the remote into your local repository.
In this part, person A will create and own the shared repository; Person B will check it out as a collaborator. You'll each work on your own feature branch, and you'll deliberately create (and then resolve) a merge conflict. Keep in mind that both partners should be familiar with / understand both roles — that of repository owner and that of collaborator — so you should work through each part together (switching who is typing and whose computer you are using as indicated) rather than completing tasks independently in parallel.>
Person A:
As in part 1, create a new Java project, a new local Git repository, and a new remote GitHub repository and connect the repositories:
Create a new Java project in Eclipse (call it lab4-pair), import the provided code from /classes/cs329/lab4, and run the program to make sure it works.
Create a new (local) Git repository, create/set up .gitignore, and do the initial commit. Include a meaningful commit message (e.g. "Added dog door starter files").
Create a new (remote) GitHub repository on github.com. Name it lab4-pair, make it private, and do not initialize it with a README or anything else.
Push your main branch to connect your local repository to GitHub. (Check the GitHub repository page to make sure everything is as you expect.)
Go to the repository page on github.com, click Settings → Collaborators, and add your partner (person B) by their GitHub username. They will need to accept the invitation (check email or GitHub notifications).
Person B:
Accept the collaborator invitation from Person A (check your email or GitHub notifications).
Once Person A has pushed the starter files (which should have already been done), create a new Eclipse project by checking out the files from GitHub:
In Eclipse, go to File → Import → Git → Projects from Git → Clone URI. Use the lab4-pair repository's URL and click Next. (If you need the URL, you can find it by going to the repository's page on GitHub and clicking the green "Code" button.)
Branch Selection: choose the main branch and click Next.
Local Destination: the "local storage location" is where your working copy and local repository will go — this should be ~/cs329/dev/lab4-pair in keeping with our directory organization and project naming customs. The initial branch is main. Click Next.
Select the "Import using the New Project wizard" box and click Finish, then go through the usual steps to create a new Eclipse project. Name it lab4-pair and make sure the location is ~/cs329/dev/lab4-pair.
Check the project structure in Eclipse and use the file browser to check the directory structure in ~/cs329/dev — make sure both are correct.
Run DogDoorSimulator to confirm that your checked-out copy works.
Now both partners should have an Eclipse project named lab4-pair which is linked to a shared GitHub repository and which contains identical copies of the starter code.
Now you'll each work on the dog door simulator — Fido always coming back inside quickly is not very realistic. Person A will fix this by increasing Fido's time outside to 7500ms. Person B will instead make the time a random value up to 10000ms. (This is a bit contrived, but it makes it possible to ensure a conflict to be resolved.)
Start by creating a new branch for your work:
Person A:
Make sure your local main is up to date: Team → Pull or Pull...
Create a new branch: right-click the project → Team → Switch To → New Branch. Name the branch more-time-fix. Make sure the source (what you are branching from) is main and that "check out new branch" is checked (so your working copy will be switched to the new branch). Click Finish and note that the Package Explorer now shows "lab4-pair [lab4-pair more-time-fix]" instead of "lab4-pair [lab4-pair main]".
Person B:
Make sure your local main is up to date: Team → Pull or Pull...
Create a new branch: right-click the project → Team → Switch To → New Branch. Name the branch random-time-fix. Make sure the source (what you are branching from) is main and that "check out new branch" is checked (so your working copy will be switched to the new branch). Click Finish and note that the Package Explorer now shows "lab4-pair [lab4-pair random-time-fix]" instead of "lab4-pair [lab4-pair main]".
Implement the changes:
Person A:
Change the Thread.sleep line in main (in DogDoorSimulator) to wait for 7500ms instead of 3000.
Run the program — and ignore that now the door closes before Fido comes back inside.
Commit the changes to the branch in your local repository. Include an appropriate commit comment.
Push the more-time-fix branch to the GitHub repository. (Pushing a branch before merging is also what would let a teammate review it first — a common practice, but not something for this lab.)
Check the repository page on GitHub to see the branch.
Person B:
Add
Random random = new Random();
at the beginning of main (in DogDoorSimulator).
Also in main, change the Thread.sleep line to
Thread.sleep(random.nextInt(10000));
Fix any compiler or runtime problems (e.g. missing imports) and run the program to make sure it works. (Again, ignore the problem that the door might close before Fido comes back in.)
Commit the changes to the branch in your local repository. Include an appropriate commit comment.
Push the random-time-fix branch to the GitHub repository. (Pushing a branch before merging is also what would let a teammate review it first — a common practice, but not something for this lab.)
Check the repository page on GitHub to see the branch.
Merge the branches into main:
Person A:
On github.com, go to the repository page and open a pull request from more-time-fix into main. You may see a banner noting the recent changes to more-time-fix with a green "Compare & pull request" button; you can also select the more-time-fix branch from the dropdown menu and click Contribute → Open pull request or "View all branches" from the same dropdown menu and choose "New pull request" from the ... menu for the desired branch.
Check that the pull request will merge more-time-fix into main, update the title and description as appropriate, and click "Create pull request".
You should see a green check "no conflicts with base branch" and a green "merge pull request" button. Click it, update the commit message as appropriate, and click "Confirm merge" to merge the branch into main.
The fix is complete, so it is safe to delete the branch.
Still in GitHub, return to the repository's main page and note that the change has been incorporated into main.
Person B:
On github.com, go to the repository page and open a pull request from random-time-fix into main. You may see a banner noting the recent changes to random-time-fix with a green "Compare & pull request" button; you can also select the random-time-fix branch from the dropdown menu and click Contribute → Open pull request or "View all branches" from the same dropdown menu and choose "New pull request" from the ... menu for the desired branch.
Check that the pull request will merge random-time-fix into main, update the title and description as appropriate, and click "Create pull request". (Note that there is a "can't automatically merge" warning — that's OK, we'll resolve the conflicts shortly.)
You'll see a gray warning icon with "This branch has conflicts that must be resolved". It is possible to resolve conflicts directly on GitHub through the web editor, but if there are more than just simple edits, it is better to use Eclipse — and using Eclipse also means you can actually run the program to check your resolution works, which the GitHub web editor won't let you do:
First bring your local main up to date: switch your local working copy to main (Team → Switch To → main), then Pull or Pull... (This isn't strictly necessary in order to pull changes from main into another branch, but being in the habit of updating your local main when you know changes have occurred helps prevent problems due to an outdated snapshot if you forget to pull before doing something with main later.)
Switch back to your own branch: Team → Switch To → random-time-fix.
Right-click the project → Team → Merge..., and merge main into your current branch — because you just updated your local main, you can choose main from either the Local or the Remote Tracking options. (Otherwise choose the Remote Tracking branch to pull from the GitHub repository.) This brings main's commits — including Person A's already-merged fix — into your branch, which is what triggers the conflict.
You should get a conflict on the Thread.sleep line. You'll see red icons marking files with conflicts in the Package Explorer — open DogDoorSimulator.java.
In that file, you'll see conflict markers (<<<<<<<, =======, >>>>>>>) showing both versions of the code. Decide on what version you want (keep the random interval) and delete the rest, include the conflict markers themselves.
When the conflicts are resolved, commit to your local repository and push the branch to GitHub. Note that in both cases you are still working in the random-time-fix branch.
Go to the repository page on GitHub and click on the "Pull requests" tab. You should now see a green check "no conflicts with base branch" and a green "merge pull request" button. Click it, update the commit message as appropriate, and click "Confirm merge" to merge the branch into main.
The fix is complete, so it is safe to delete the branch.
Still in GitHub, return to the repository's main page and note that the change has been incorporated into main.
This section is optional, but is encouraged for additional practice with branching, merging, and GitHub.
Now person A will add a new feature — a bark recognizer so the door will open automatically when Fido barks.
Person A:
Create a new branch called bark-recognizer from main: switch your working copy back to the main branch if necessary, make sure it is up to date (Team → Pull or Pull...), and then create the new branch.
Start the bark recognizer by adding a new class BarkRecognizer:
public class BarkRecognizer {
private DogDoor door_;
public BarkRecognizer ( DogDoor door ) {
super();
door_ = door;
}
public void recognize () {
System.out.println(" BarkRecognizer: Heard a 'bark'");
door_.open();
}
}
Commit the changes to the branch in your local repository. Include an appropriate commit comment.
Meanwhile, person B has realized there's a bug: Fido still manages to come back inside even if the door closes before he's done. Instead, he should bark to be let back in if the door has closed.
Person B:
Create a new branch called bark-fallback-fix from main: switch your working copy back to the main branch if necessary, make sure it is up to date (Team → Pull or Pull...), and then create the new branch.
Fix the bug: in main (in DogDoorSimulator), add the following between "Fido's all done..." and "Fido's back inside...":
if ( !door.isOpen() ) {
System.out.println("\nFido barks to come inside...");
remote.pressButton();
}
Test the program to make sure it works. You may have to run it several times to get an instance where the door closes before Fido's done.
Commit the changes to the branch in your local repository (include an appropriate commit comment) and push the branch to the GitHub repository.
On github.com, go to the repository page and open a pull request from bark-fallback-fix into main. Check that the pull request will merge bark-fallback-fix into main, update the title and description as appropriate, and click "Create pull request".
There shouldn't be any conflicts — click the green "merge pull request" button, update the commit message as appropriate, and click "Confirm merge" to merge the branch into main.
The fix is complete, so it is safe to delete the branch.
Person A pulls in the bug fix from main before continuing with the bark recognizer:
Person A:
Bring your local main up to date: switch your local working copy to main (Team → Switch To → main), then Pull or Pull.... (This again isn't strictly necessary in this case, but it is a habit that helps prevent problems later.)
Switch back to your own branch: Team → Switch To → bark-recognizer.
Right-click the project → Team → Merge..., and merge main into your current branch — because you just updated your local main, you can choose main from either the Local or the Remote Tracking options. (Otherwise choose the Remote Tracking branch to pull from the GitHub repository.) There shouldn't be any conflicts here — you've only added BarkRecognizer and haven't touched DogDoorSimulator, which is where person B's edits were.
Now person A continues with the bark recognizer:
Person A:
In main, create an instance of the BarkRecognizer to work with the existing dog door and replace the remote button press when Fido barks to come back in with the bark recognizer recognizing the bark. (Only use the bark recognizer when Fido wants to come in — still use the remote when Fido wants to go out.)
Run the program to make sure it works. (You might have to run it several times to see the bark recognizer in action.)
Commit the changes to the branch in your local repository (include an appropriate commit comment) and push the branch to the GitHub repository.
On github.com, go to the repository page and open a pull request from bark-recognizer into main.
Check that the pull request will merge bark-recognizer into main, update the title and description as appropriate, and click "Create pull request".
You should see a green check "no conflicts with base branch" and a green "merge pull request" button. Click it, update the commit message as appropriate, and click "Confirm merge" to merge the branch into main.
The new feature is complete, so it is safe to delete the branch.
Finally:
(both partners)
Switch your local working copy to main and Pull or Pull..., so you both end up with a local copy that has the (currently) final version: the random wait, the bark-if-door-is-closed fix, and the bark recognizer.
Run the program a few times to confirm everything still works together.