Skip to content

Latest commit

 

History

History
883 lines (708 loc) · 42.5 KB

README.md

File metadata and controls

883 lines (708 loc) · 42.5 KB

Introduction to git

Continuous integration status Total alerts

Background

This is an in-lab exercise where we'll introduce and practice several of the key features of the git version control system, and the GitHub repository hosting service. We'll provide command line means of accomplishing the various tasks in the first part of this lab. For the second part of the lab, we'll provide info on how to use GitKraken along with Visual Studio Code (VS Code) since those tools will be part of our primary workflow this semester. git is essentially a command line tool, and it can be difficult to visualize branching and history; GitKraken provides a nice GUI for git which we find it quite helpful for understanding what's going on. VS Code is our IDE (basically our fancy program editor); there are lots of alternatives, but we're going to use VS Code this semester.

‼️ While in most labs it will be fine for groups to move ahead at their own pace, in this lab we'd like people to keep together because there are moments where we're expecting certain things to happen (e.g., merge conflicts) and we want everyone to be in roughly the same place when that happens.

This definitely will not provide a comprehensive overview of the many features git provides. There are a lot of on-line resources that can provide additional information, including:

As circunstances allow, you might also want to at least skim one or two of the tutorials listed above.

We'll also be using Gradle, a tool for building and running programs. We'll be using Gradle throughout the course, so its useful to see it a bit here. We also use it to automate the tests for this project, which allows GitHub Actions to automatically run our tests whenever someone makes a change, and holler at us if someone breaks the tests.

The discussion below assumes that people are paired up in the lab, but we want to make sure everyone has hands on experience with these tools and ideas. This sort of pair programming will be common throughout the class and beyond, with two people working together. It is common in these settings for one person (the driver, say Pat) to be at the keyboard, while the other person (the navigator, say Chris) is actively engaged in working with Pat, suggesting ideas, noticing typos, and answering questions. For this process to work, both of you have to contribute and be involved, and it's extremely important for you to trade off the roles of driver and navigator now and then. Thus in this lab there will be times where we'll explicitly ask you to trade roles so that everyone has a chance to go through all the activities.

How we're going to use git

git is a piece of software which provides distributed version control, allowing a team of developers to work together on a project, helping manage collaboration and change. We're going to use three related tools:

  • git is the fundamental program (developed to help manage the Linux operating system codebase) that underlies the next two tools. It organizes projects into repositories, which are collections of files and histories of all the changes ever made to that project. It is a command line tool.
  • GitKraken is a GUI for git that provides a nice visual interface to git and display of complex things like git histories and branching.
  • GitHub is a web-based software service that allows people to host, search, and use repositories created and managed with git.

You could use git without ever using GitKraken or GitHub. We've found that a good GUI like GitKraken can be a big help when things get complicated. GitHub is an extremely popular repository hosting service, and it's a good idea for computing folks to be familiar with it. We use it to manage all the labs for this course, and you'll use GitHub to manage all your labs and project iterations in this course.

This lab essentially has two halves:

  • Adding your names in separate Markdown files
  • Adding your greetings in the Java code

We'll use command line git for the first half so you have some exposure to using git on the command line. This is important because you don't always have GUIs for things if, for example, you're remotely logged into some cloud server. We'll then use GitKraken in the second half, also mentioning how you'd accomplish some of the new git tasks on the command line.

When you use git and GitHub, you typically have a single "primary" copy of your repository hosted on GitHub; this will be visible to everyone in your group (and the world if the project is public), and will be the "copy of record". People will transmit changes through that copy, and use GitHub tools like issues, pull requests, and code reviews to discuss potential changes.

Each developer then has one or more private copies of the repository (called clones) that they make local changes to. They can pull changes from the GitHub repository into their local repository, as well as push local changes up to the GitHub repository so that other people can access them.

Configuring your git e-mail

Before we actually start to use git, you should configure your git email so work you do in our lab properly connects to your GitHub account. You only need to do this once and it will "stick" throughout the lab in all systems that use git.

  • Open a terminal window
  • Type git config --global user.email "[email protected]" where you replace [email protected] with the email you used to set up your GitHub account.
  • Verify that it worked by typing git config --global user.email; you should get the address you just configured as the response.

If you want to use a different e-mail address than the one you signed up for GitHub with (e.g., you signed up with a non-U email but you'd like to use your UMM email now) you can set your commit email address on GitHub so that they match.

If you'll be using any non-lab machines (like your own computer) to do work, make sure you set your git email on those machines as well. This will ensure that no matter where you commit from, git and GitHub will "know" it's you and properly credit you for your work.

The first half: Adding our names

In this part of the lab we'll add everyone's names and GitHub usernames to the repository so we'll be able to figure out who GitHub user MightyWombat259 is in real life.

clone a local copy of the repository

Before we can start working on the lab proper, each group will need to clone the GitHub repository so they have a local copy to work with. There will only be one copy of the repository on GitHub, but each group should obtain a clone on whatever lab machine they're working on, so there will be lots of local copies. Each of those local copies will be completely independent, and will only share changes through explicit interactions with the GitHub repository through git.

Join our GitHub Classroom team; get your clone URL

We'll be using GitHub Classroom all semester to manage team repositories. For each project we'll post a GitHub Classroom URL on the assignment on Canvas; you'll use that to create/join your team for that lab. GitHub Classroom will create a fork (essentially a copy on GitHub for your team) of our starter repository that your team will use as the starting part for your work.

This lab is unusual in that we will all be on a single large team called Everyone, all making changes to a single shared repository. This will help illustrate the value of version control systems like git in managing this kind of shared resource, and also give us opportunities to see what happens when different people make inconsistent changes to the same files.

So follow the link in the Canvas assignment and join the Everyone team; that should take you to the shared repository on GitHub. From there you can get the URL for that repository from the Clone or download button visible on the "home page" for each repository on GitHub. See GitHub's "Cloning a repository" tutorial for examples. The URL should look like this:

https://github.com/YOUR-ORG-OR-NAME/REPO.git

where YOUR-ORG-OR-NAME is the a user name or (in our case) an organization name and REPO is the name of the repository.

Command line clone

We'll make our local clones via the command line, so open a terminal (or just the one from before if it's still open). Go to whatever directory seems appropriate. Then to clone the respository using command line tools you'd do:

git clone <url>

where you replace <url> with the URL for the GitHub repository.

Using gradle to run tasks

We're using the gradle build tool in our labs. We're not going to talk a lot about Gradle here, but see our Gradle README for more info on what Gradle is and how we're using it.

For the moment there are two things to try on the command line. Make sure you're in the directory containing your clone of the repo (i.e., you're in the lab-0-intro-to-git-everyone directory) and then run

./gradlew run

This will run our program, which should generate output that looks something like

> Task :run
Hello, folks!
KK says 'Hello!'
Nic says 'Howdy!'


BUILD SUCCESSFUL in 3s
2 actionable tasks: 2 executed

To run the tests try

./gradlew test

which should generate output something like

BUILD SUCCESSFUL in 827ms
3 actionable tasks: 3 up-to-date

If a test had failed, you would have gotten longer, more detailed information. (Although you get better info from running the tests in VS Code – we'll see that in a bit.)

Opening our project in VS Code

Now we'll want to open VS Code (search for "Visual Studio Code" in the application launcher) and see how we can use it to edit and run our code. Launch VS Code, and then choose File -> Open Folder…. Navigate to your clone of the repo and choose Open.

We've included a file in the project which specifies some VS Code extensions that you should go ahead and install. VS Code will see that file automatically and give a dialog on the bottom right that looks something like:

Dialog suggesting installation of recommended extensions

You can just click "Install All", but feel free to click "Show Recommendations" and install them one at a time if you want to know more about what we're doing here.

Open up src -> main/java -> Hellos.java and you should see a small Java program. Right above public static void main should be Run | Debug in light gray. These aren't part of the code, but are action buttons being inserted by VS Code. Click Run and it should run the program, opening up a terminal window in a pane along the bottom to display the output. The output should look similar to what you got with Gradle on the command line, but with some other info at the start before the program's output is displayed.

Now open up src -> test/java -> HellosTest.java and you should see our JUnit tests. Again, VS Code has inserted a few text Run Test | Debug Test "buttons" in various places. Click Run Test just about public class HellosTest to run all the tests in the class.

Assuming the tests all passed (& they should), it won't really look like anything actually happened. There will, however, be a checkmark to the right of Debug Test that wasn't there before. That tells you the tests passed. If any of the tests had failed, there'd be an x there, and VS Code would open up another pane providing a list of all the tests and details on the failures to help you debug the problem.

You can also run individual tests by clicking Run Test above the appropriate test method.

Create an info page for each pair

We'll come back to this Java code again in the second half of the lab, but for now we're going to return to git by making and sharing changes.

This repository has a user_info directory, and in this part of the lab we'll create a new file in that directory for each pair in the class containing your real names and your GitHub user names. Sometimes it's easy for us to figure out how those names relate, but if your Gihub user name is UnicornWizard375 it's not always obvious who in the class that is, especially if you don't always wear your wizarding regalia to lab.

There will be several steps to this process, each of which is described in more detail below:

  • Create your contact info file/page
  • commit that to your local copy of the repository
  • pull down the changes other people may have made to the central repository on GitHub while you were working, merging them with your changes
  • push your (merged) changes back up to GitHub so they're available to everyone

Creating a page

You'll start by creating your group's contact info page. Each contact info page should:

  • Be created in the user_info directory.
  • Be named <your_names>.md, e.g., Pat_and_Chris.md
  • Contain at least:
    • Each of your names as you preferred to be called
    • Your preferred pronouns
    • Your GitHub usernames (so we can figure out who UnicornWizard375 is in real life)

Feel free to use the file KK_and_Nic.md as a model.

commit your changes (locally)

Before you can share your changes with the class via the GitHub repository, you need to add and commit these changes to your local git repository.

On the command line type git status. That should tell you that something like:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
  user_info/Pat_and_Chris.md

nothing added to commit but untracked files present (use "git add" to track)

This is telling you that while you've created your new file, you need to use git add to stage the file before you can commit it. You might think git should just commit any and all changes you've made since the last commit. That's actually not a great default behavior, though, because sometimes you've made changes to several files and you'd like to commit them separately; with the right tools you can even commit different changes to the same file in separate commits. This is useful because it makes it easier to have a commit message that is specific to the particular changes being committed (instead of a generic "changed a bunch of stuff" message that you often get when there have been a lot of changes). This, and other nifty things beyond the scope of this lab, is why git allows you to specify through staging exactly what you wish to include in a commit.

Stage the new file so git knows you want to commit it through git add <file> on the command line. (Note that the output of git status told you that git add <file> was likely a useful thing to do at that point.)

Check your status again with git status. Now the output should be something like:

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
  new file:   user_info/Pat_and_Chris.md

This tells you that you've successfully staged user_info/Pat_and_Chris.md. It also tells you how you can unstage a file that you might have staged by accident.

Commit the change to your local copy of the repository with git commit on the command line.

  • This will bring up a (command line) editor for you to enter your commit message. By default this is vi/vim for most people; ask for help if you find yourself trapped in vim and can't seem to escape.
  • You can also use git commit -m "Your cool commit message" to avoid being sent to an editor. We strongly discourage this, however, as people rarely enter useful one-line commit messages.
  • If vi/vim bugs you, you should probably set your default git editor to something you like. This GitHub help page shows you how to set various GUI editors like atom, but you could also use something like git config --global core.editor nano to set it to a command line editor like nano.

After entering a commit message that is properly formatted, organized, meaningful and helpful you can exit the editor. That should finalize the commit, and you should get output that looks something like:

[master 47d9c89] Adding the info for Pat and Chris.
 1 file changed, 11 insertions(+)
 create mode 100644 user_info/Pat_and_Chris.md

If you then run git status you should see that your file is no longer staged, because it's been successfully committed!

pushing your work to GitHub

At this point you have your changes committed to your local copy of the repository, and want to push those changes up to the GitHub copy of the repository. This is the potentially tricky part, but in this case things should be well behaved. 😄

The major issue is that other people may have made and pushed changes up to GitHub that could potentially conflict with the changes you've made. So your first step is to pull down any recent changes from GitHub:

git pull

Pay attention to whatever message you get; it's possible that there could be problems (the word "conflict" would be a Bad Sign) so don't just ignore what git tells you. Definitely ask questions if you get some verbiage from git that you don't understand.

If no one else is working on these files in this repository (which is likely in this case since you created a group-specific file for your information) then this should go smoothly. As we'll see below, though, if there have been changes in the same parts of the same files, a pull can lead to conflicts and confusion.

Assuming that your pull works, then it's time to push your work up to the GitHub repository:

git push

Again, look for errors in the output of git push. If someone else managed to do a git push between when you did git pull and tried git push, git will complain and force you to do git pull again. Essentially you can never git push unless git knows that you've got the latest copy of the world in your repository.

When it succeeds, this will push all your commits up to GitHub; if you refresh your view of the GitHub repository you should see your new file along with your contact info, probably along with a lot of other files.

You're now done with the first major part of the lab!

The second half: Collectively editing a program

‼️ Don't move on to this next part until everyone is done with the previous part.

‼️ You should definitely change driver and navigator roles now.

In this second part each group will make a small change to a simple Java program, Hellos.java in the program directory. Each group will make a small extension to that program in a way that virtually guarantees some sort of merge conflict, so everyone will have the experience of dealing with conflicts.

Open GitKraken

Where we used command line commands to do all the git work in the previous half, in this half we'll use GitKraken, which provides a nice GUI and visualization of things like our commit history and branching.

Open up GitKraken. If this is your first time starting GitKraken it will ask you to sign in, providing several options. You want to sign in with your GitHub account as this will do two important things:

  • It will allow GitKraken to push/pull/etc. with GitHub on your behalf.
  • Assuming you've set up your GitHub Student Pack, this will automagically give you a Pro account on GitKraken, which includes some nice features that you'll want to have, like an interactive tool for resolving merge conflicts. ‼️ If you haven't set up your GitHub Student Pack, you should do so before setting up GitKraken.

After you've authenticated with GitHub, GitKraken will ask to setup your git info (like you did at the start for the command line); you should enter your name and whatever email you've used for GitHub.

Once all the setup is finished, select File -> Open and navigate to the directory containing your local clone, and open that up. There's a lot of information here, but you can ignore most of it for now. One thing you should stand out is the commit history graph. You should see all the commits you and all the other groups made today.

Before we move on, it would be a good idea to do a pull just to make sure we have the latest version of the code. In GitKraken you can just click the Pull button in the toolbar at the top of the window. If there were recent changes that you didn't have (which is unlikely), the history would update to show the new commits you just pulled down to your local repository.

Creating a branch

Before we get started on actually editing the program, we want to introduce the concept of branches in git, as they are a powerful tool for isolating work (in progress) on a particular feature from other on-going work on the project. Creating and working in your own feature branch allows you to commit, save, and share incomplete work without breaking the project for other people. This is incredibly valuable; without it you'd be constantly worried about making commits of incomplete work that might mess things up for other people, or worrying that commits from other people in your group might mess up your work. If we're serious about test driven development, for example, we would frequently find ourselves writing and committing tests before we've written the code that will make those tests pass. If we committed those tests to the code that everyone was using, then all of a sudden they'd have breaking tests, the builds would fail, and the continuous integration system would be all shout-y and mad at the whole team. If, on the other hand, you commit those tests to your feature branch, then it will have no impact on people working in other branches or on the build system, so everything will be nice.

Every new git repository has one default branch called master; this is usually where the current "deployed" or "released" version of the project lives, while active development, bug fixes, and the like happen in other development branches that are merged into master when that work is deemed "done done" (passes the tests, has been through a code review, etc.).

To illustrate the use of branches, we'll have each group create a new branch for their modification of the shared program. Assuming, for example, that we still have Pat and Chris, they would create a new branch called something like pat-and-chris-greetings.

In GitKraken we can do this by clicking the Branch button in the toolbar. It won't immediately look like anything actually happened, but there will be a text box to the left of the history diagram where the HEAD (top) of master is. Enter your branch name (e.g., pat-and-chris-greetings) there and hit return. It should now show (part of) pat-and-chris-greetings and a +1 which indicates that there's another branch (master) whose HEAD is at the same place. You should also have pat-and-chris-greetings listed as a new branch under LOCAL in the explorer on the left, and it should be highlighted to indicate that it is the currently checked out branch. That means that any new commits you make will be in that branch instead of in master as they were in the first half.

In the command line you could create and move to a new branch with something like

git checkout -b <new_branch_name>

This creates the new branch and perform a checkout on that branch. The checkout part of the process tells git to "switch over" to that new branch, so subsequent commits will happen on that branch. You use git checkout without the -b to just switch between existing branches; the -b tells git that this is a new branch that needs to be created.

Edit the program

Now that you've created and switched to your new branch, it's time to edit the program. Before we change anything, though, we should re-run our tests in VS Code just to make sure everything's still good. While you're there notice that VS Code automagically noticed that we'd switched to a new branch; down in the left hand corner of the bottom status bar it should now have the name of your branch where it used to say master.

Open up Hellos.java and add more lines in the generateOutput() method of the form

builder.append(patSaysHello());

where you replace pat_says_hello with method names that reflects the names in your group. You should create one new method for every person in your group. If your group is Pat and Chris, then you want

builder.append(chrisSaysHello());
builder.append(patSaysHello());

However, instead of just adding them wherever you want, you need to add them so that everyone's greetings come out in alphabetical order, otherwise the tests won't pass. So if you started with

        builder.append(kkSaysHello());
        builder.append(nicSaysHello());

and you wanted to add Chris and Pat, you'd need to put Chris at the front, and Pat at the end to maintain alphabetical order:

        builder.append(chrisSaysHello());
        builder.append(kkSaysHello());
        builder.append(nicSaysHello());
        builder.append(patSaysHello());

This will create a compiler error because your new methods (e.g., patSaysHello) aren't actually defined anywhere. So let's fix that, by adding a new methods somewhere down amongst the example methods; they should look something like:

    private static String chrisSaysHello() {
        return "Chris says 'Hello!'\n";
    }

Make sure you include the \n (newline) in the string so we don't end up with one really super long line. In fact our tests require that every greeting have the form

   <name> says <greeting>!

so make sure you use the word "says" and end the greeting with an exclaimation mark.

You can put your methods wherever you want in the Hellos class, but probably makes sense to have them in the same order as the calls. Our tests don't check that , though.

Once everything looks good, compile and run your program (by clicking Run in Hellos.java) to make sure that everything is good. If you want to run the program from the command line ./gradlew run should do the trick.

You should also re-run the JUnit tests that will confirm that all the lines in the output have the right form and are in alphabetical order. In general you should always run the tests before you commit as another way of making sure that your work is "done done".

‼️ If you have any problems here, definitely ask questions and get things working before you proceed; you don't want to merge broken code and mess things up for everyone else.

If you get stuck there definitely ask questions!

Commit and Push your branch to GitHub

Now, assuming that your code is all working and happy, let's use GitKraken to commit and push your work.

Commit with GitKraken

To commit in GitKraken click the top line in the history graph; it's circle should be an empty with a dotted line, and it should have // WIP where the commit summary is. On the right you should then have panels labelled "Unstaged Files", "Staged Files", and "Commit Message". Where you use git add to stage files on the command line, in GitKraken you can select a file in the "Unstaged Files" area and click the "Stage" button that appears next to the file name. You can also see the changes you've made in that file, which can be a huge help in forming useful, coherent commit messages.

So stage Hellos.java.

Now enter a commit message below that. GitKraken "enforces" that best practice that your message should have a summary with no more than 72 characters, followed by a more detailed description of the commit. Once you've staged one or more files and entered a commit message, then you can click the "Commit changes" button on the bottom right.

That should introduce a new commit to the history graph branching up from the HEAD of master, with your summary message. Now we'll push!

Push with GitKraken

You could do a pull before the push like we did before, but (a) you aren't expecting any changes on your branch by another group (so the pull shouldn't bring in any changes) and (b) push actually checks for unpulled changes and forces you to deal with those if they exist (so it's safe to just push and see what happens).

So hit Push in the GitKraken toolbar. It won't look like anything happened, but there will be a question where the toolbar used to be. That should be something like:

What remote/branch should "pat-and-chris-greetings" push to and pull from?

The issue here is we created a new local branch, and GitKraken wants to know what remote repository to connect that two, and with what name. It will default to origin (which is in this case another name for the GitHub repository we cloned from) and our branch name (e.g., pat-and-chris-greetings). Those are what we want, so hit Submit. After a second you should get a bubble in the bottom left corner thays that the push was successful.

Assuming the commit and push worked, if you go to the project web page on GitHub (and refresh if necessary), your branch should be in the list of branches, and if you switch to your branch and go look at Hellos.java you should see your changes. Depending on how many other groups have gotten to this point before you, you may see a lot of new branches; these will start to clutter things up, but we can delete unused branches later.

If you go to the GitHub repo in the web, you should see your branch in the branch dropdown. If you select it you should see your last commit just below that. Next to the "Latest commit" label should either be a yellow dot, a green checkmark, or a red x. These show you the build status of that commit. Every time you (or anyone else) pushes to GitHub, we have GitHub Actions set up so they run the JUnit tests against that version of the code. The yellow dot means that it's still building and running the code. A green checkmark means it's done and everything was great (the code compiled and the tests passed). A red x means that something bad happened. If you click on the symbol, you can get more information, including links to pages with details on, e.g., failed tests.

Merging your branch into master

It's cool that your changes are visible in your branch on GitHub, but if you switch back to master on GitHub and look at Hellos.java, your code won't be there. The problem with the current situation is that your nifty new greetings are "trapped" in the branch you created. This is sad, because your code is spectacular and really should be part of the "production" version of the project on the master branch. Right? Right?

So you need to merge your branch into master.

If no one else was working on this repository it would be easy, and all you'd need to do is merge into master and then push your work up to the GitHub repository. But there are other people working on the repository, and you have to make sure you play nice with them.

And that can be tricky because other people may have pushed commits up to GitHub, and those commits might conflict with your changes. Say, for example, Pat and Chris separately notice that someone (who shall remain unnamed) named a variable foo. Chris and Pat both replace that content-free name with a more informative name without realizing the other person was changing the same piece of code. They made different but reasonable choices: Pat renamed it to sum and Chris renamed it to total. If Pat merges the change to sum in first, then when Chris tries to merge in the change to total, there will be a merge conflict. git will realize that the commits from both Pat and Chris changed the same piece of code, but there's no way for git to figure out what the "right" thing to do is, though. So git will block the second merge (from Chris), generate a merge conflict, and ask Chris to resolve the conflict by deciding which change to use.

Dealing with merge conflicts, especially complex ones, can be a real headache, but these tips can help reduce the likelihood of pain here:

  • pull changes into your development branch(es) early and often. The more consistent your branch is with master (or whatever branch you're going to merge into), the less likely conflicts will be, and they'll tend to be smaller when they do happen. The history/branch visualization in GitKraken can give you a sense of how far your branch is from what's on master.
  • Break your work into small, manageable stories/tasks/chunks. Small, well-defined bits of work tend to touch less code and be completed more quickly, both of which reduce the likelihood of a nasty conflict surprise when you come to merge.
  • Give yourself plenty of time to merge into master. You don't want to decide you're going to merge into master at 2am or 15 minutes before Food Service closes for dinner; if there's an unexpected conflict you don't have the time and energy to deal with it properly and your chances are much higher that you'll do something you'll regret.
  • Don't do (big) merges alone (or at least make sure other folks are around). This relates to the previous one. If you're caught off guard by a conflict, and you're in a hurry, and there's no one around to help you understand how your changes relate to and will affect changes other people have made, Badness is very likely to ensue.

The basic process you'll typically want to follow is:

  • Make sure all your changes on your feature branch are committed locally.
    • In GitKraken if there's no WIP entry then you know all your changes are committed. If there is an WIP entry, you can click on it to see what's not yet committed. (There can be times where you have changes you don't yet want to commit.)
    • Or use git status on the command line to confirm that everything you mean to have committed is in fact committed.
  • Checkout the master branch
    • Double click on master in the branch listing on the lefthand side of GitKraken.
    • Or git checkout master on the command line

At this point you should be on the master branch, and all your work on your new contact info page should "disappear" in VS Code. Don't worry, it's still there in your feature branch, but it's not part of master so it's not visible when we have master checked out.

The trick is that this is your copy of the master branch, which is probably out of date with master on GitHub (origin/master) since other people have been committing and pushing changes. So you should first make sure to pull any changes other people have made into your copy:

  • The Pull button in GitKraken
  • git pull on the command line

Assuming you've only made changes to your group's special development branch, this pull should succeed with no difficulties, and git will merge in whatever changes other people have pushed up to master on GitHub into your copy of master. You might want to re-run the tests in VS Code, though, just to make sure someone hasn't broken things.

Now we have the moment of truth, where you merge your changes from your development branch (pat_and_chris_greeting in our example) into your newly updated copy of master.

  • In GitKraken, drag the label with the branch name that you want to merge (e.g., pat-and-chris-greetings) onto the branch you want to merge into (in this case master). That will bring up a dialog with several options. Go with the first one (probably "Fast-forward", but possible "Merge").
  • On the command line git merge <branch_name> will merge the changes in the specified branch onto whatever branch is currently checked out (master) in this case.

If you're lucky, any changes you've made won't conflict with changes other people have made and the merge will succeed immediately. That likely won't be the case here, as the changes other groups have made to the program (or changes we made while you were working on the first part of the lab) will almost certainly conflict with your work.

Dealing with these kinds of merge conflicts can be a frustrating experience, but GitKraken has a nice GUI merge conflict tool that makes it a little easier. The merge tools in VS Code are also quite nice; we'll describe VS Code here, but you should feel free to use whichever you find most useful.

The sequence of events in GitKraken is likely to look something like:

  • The attempt to merge will lead to a conflict; you'll have a message like "A file conflict was found when attempting to merge" up at the top of the commit history graph.
  • All the files with merge conflicts will be listed in the "Conflicted Files" panel on the right hand side.
  • Select a file with a conflict. That should bring up a GUI for resolving merge conflicts with one version (master in this case) on the top left, the version were trying to merge in (e.g., pat-and-chris-greetings) on the top right, and the Output (the result of the merge) at the bottom.
  • You can then choose sections (using the checkboxes) that you want to include in the finished result. You can even choose to include (or not include) individual lines if you wish.
  • When you're done click Save.
  • That will move that file to "Staged Files", and you can move on to a commit like normal.

When that's all done then the merge conflict will be resolved in git terminology and you'll be (nearly) read to push your changes.

Before you do that, however, you should carefully proofread any code that's modified in resolving a merge conflict, though, as it's easy to introduce mistakes in that process. You'll want to make sure you re-run the test suite, for example, to make sure that resolving the merge conflict didn't inadvertently break something.

Once that's all happy, though, you should push your copy of master up to GitHub.

Normally this should just work because you did a pull on master just a few minutes ago. Occasionally, however, someone will manage to sneak in a pushed change between your pull and push, and that's actually pretty likely today with so many people working in parallel on the same file. If that happens you'll get some sort of error saying that your attempt to push master was rejected, and suggesting that you pull or merge remote changes before you push.

So pull again, resolve any conflicts (including running the tests, etc.), and try to push again. Because so many groups are modifying the same file at the same time, it's entirely possible that this could take several rounds before you get your changes pushed, but it will eventually happen.

When your push eventually works, and you should be able to look at the repository on GitHub and see the changes you made to Hellos.java on the master branch of the repository, presumably along with numerous changes made by other groups. Check that the build is still successful (green checkmark) and raise an alarm if it's not. (:bangbang: It's never a good thing if your build on master is breaking, and everyone should stop what they're doing to try to fix it when it does break.)

Huzzah! We're done! :-)

Once everyone has added their changes to Hellos.java then we're done with the lab! Well done! 😄