Lab: 14 - The Git Version Control System

Assigned
Monday, 25 September 2023

OVERVIEW

For this lab, you will use the Eclipse IDE and the Linux terminal. You will have to submit the git log output at different times.

Setup

You may want to have available in your browser window as you work:

SingleBuffers

Create a new Java project and import the following files

  • SingleBuffer.java,
  • BufferEmptyException.java,
  • BufferFullException.java, and
  • SingleBufferTester.java.

These implement a simple, generic, one-object buffer class in Java and a test suite for this class. All four of these files are in the directory /home/jimenezp/csc207/Lab-Git on MathLAN.

Note: Buffer exceptions would be extremely rare in the classroom environment, but could occur in large, distributed systems. Use them today in the spirit of practice.
  • Study the contents of these files to get a sense of what methods are supported by the SingleBuffer class and how they work.

  • Compile all four of the .java files into .class files. Note that SingleBufferTester has a main method and so is executable.

  • Do not run the program yet. What do you expect to see as output when the SingleBufferTester program runs?

  • Run the program and explain any differences between the expected and observed output.

Creating an Empty Git Repository

  • Use the git init command, in your project directory (the one you created for today’s exercise), to create a Git repository for the source files relating to SingleBuffers.

  • Confirm that the repository was created by looking for .git in the current working directory. The unmodified ls command will not display it, because it is a “hidden file” (its name begins with a dot), but ls has a command-line option that causes hidden files to be displayed along with the others. Consult the manual page (man command) for ls to find out what that option is, if you don’t already know.

The Git repository is actually a directory, with several subdirectories beneath it, so ls will show you the first-level files and subdirectories unless you use the correct command-line option to get information about the directory itself. Again, consult the manual page for ls to find out what that option is, if you don’t already know.

Commiting Files to the Repository

  • Use git status to see the state of the working directory and the staging area.
  • Select the files that you want to place under version control and use the git add command to “stage” those files. This command adds the filenames to Git’s index, so that they will be included in the next commit. At this point, you’re about to create a commit object, and you should compose, or at least think through, the message that you want to store in the repository’s log. Good commit messages concisely indicate what changes were made in. Please, take time to read about writing good commit messages.
  • Check again the state of the working directory and the staging area.
  • Use the git commit command, to create the commit object containing the files that you staged in the preceding exercise. Read the provided resources if you do not remember how to do a commit. Your commit must have a descriptive message. No matter how you execute git commit, you should get an acknowledgement back from Git reporting the creation of the commit object, giving you a short hexadecimal handle for it, and listing the files that were copied into the repository.
  • Use the git log command to inspect the repository log.
  • Check again the state of the working directory and the staging area.

.gitignore Files

If the directory containing .git or any of its subdirectories contains a file called .gitignore, containing a list of files and/or wild-card patterns for files, then Git will pay no attention to files in the list or to files that match the wild-card patterns. You can run git add . (don’t miss the period!) command to stage all files in your working directory.

  • Check again the state of the working directory and the staging area. What has happened? (Add your answer to your lab report)

It is pointless and wasteful to place under version control files that are generated automatically, by software tools, from source code or other source documents. Often such automatically generated files have identifiable filetypes, so that you can exclude them all with a wild-card pattern. The git add . command ignores the files that are listed in a .gitignore file. In addition, the git status and git commit commands won’t bother to list them, regardless of whether they have been modified.

  • Create a .gitignore file in the directory containing the SingleBuffer class files, so that Git will pay no attention to the files with names ending in .class. See common .gitignore configurations (You can run touch .gitignore on your terminal window to create a .gitignore file and/or edit it using emacs or any editor of your choice.)
  • Check again the state of the working directory and the staging area. If you want to ignore files that are already in the staging area, remove them by following the instructions presented by git in the terminal (read carefully the output of git status).
  • Your git should ignore any other hidden file created by Eclipse. Update the .gitignore file accordantly.
  • Check again the state of the working directory and the staging area. What has happened? (Add your answer to your lab report)
  • Commit your .gitignore file. Then use the git logcommand to display the commit loggit . (Add the current log output to your lab report)

Revising, Staging and Committing Revisions

Let’s extend the SingleBuffer class to include a replaceContents method, which puts a new datum into the contents field whether or not the buffer is already in use, overwriting any datum that was already present. First, work out what the method signature for replaceContents should look like — what arguments it needs (if any), what kind of value it should return, and what exception (if any) it may need to throw.

  • Revise SingleBufferTester.java to incorporate tests of the replaceContents method, making sure that it has the desired side effect regardless of whether or not the SingleBuffer to which the replaceContents message is sent is already in use.

  • Revise SingleBuffer.java to implement the replaceContents method. Recompile SingleBuffer.java and SingleBufferTester.java, run the SingleBufferTester program, and check that the tests succeeded.

  • Use the git status command to get a list of the files that are under version control and have undergone modifications that haven’t yet been committed to the repository. Use the git diff command to see exactly what these modifications are.

  • Use git add . (don’t miss the period!) to stage all files in your working directory. Then, run git status to verify that .class files are not staged.

  • Use git commit to place the new versions in the repository.Your commit must have a descriptive message.

  • Then use the git logcommand to display the commit log. (Add the current log output to your lab report)

Branching

  • Use the git log command to inspect the repository log. It should list the commit(s) done so far. Which, if either, is the parent of the other? Which, if either, is HEAD? What is the SHA1 name of the current commit object?

  • Suppose that we want to experiment with a different design for the SingleBuffer, one that supports the operation of inspecting the contents of a buffer without removing them. Let’s call the new method that would support this operation peekAtContents. Use the git branch command to start a new branch with the older of the listed commit objects, naming it experimental. (You’ll need some way of referring to that commit object—its SHA1 name, for example, or a description in terms of its relationship to the current commit.)

  • Then use the git logcommand to display the commit log. (Add the current log output to your lab report). What has happened? (Add your answer to your lab report)

  • Use the git checkout command to switch over to the experimental branch. Refresh the files in Eclipse. Inspect the files that you previously edited to add support for the replaceContents method; you should find that they have been restored to their previous state. If you were editing one of those files while Git was changing it, the editor should warn you that that buffer is now out of sync with the file and offer you an opportunity to reload the file in its current state.
    1. Design the signature for the peekAtContents method proposed two exercises back.
    2. Revise SingleBufferTester.java so that it determines whether the method, once implemented, will give the expected results.
    3. Revise SingleBuffer.java to implement the peekAtContents method.
    4. Compile SingleBuffer.java and SingleBufferTester.java and run the SingleBufferTester program. Repeat steps (2) through (4) until all the tests give correct results.
  • Use git status to check which files have changed. Decide which modifications and new files you want to commit to the repository, then use git add and git commit to create a new commit object on the experimental branch.

  • You should now have several commit objects in the repository. (Confirm this by giving Git the appropriate command.) Which one is now HEAD? (Add the current log output to your lab report)

Merging

Now let’s merge the experimental branch into the main branch, so that we can have both replaceContents and peekAtContents as features of the SingleBuffer class.

  • If, for any reason, you have uncommitted changes in files under version control, revise the files as necessary to produce the versions that you want to keep on the current (experimental) branch, then run git commit to commit the changes. It is a precondition for merging that you have no uncommitted changes to files under version control.

  • Use git checkout to return to the main (“master”) branch. The changes that you made on the experimental branch are now removed from your working files (although the repository remembers them), and the changes that you made on the main branch are restored. Examine your files to confirm that peekAtContents is gone and replaceContents is back.

  • Use the git merge command to merge the experimental branch into master.

Depending on which files you changed and which ones you put under version control, you may find either that Git succeeded in combining the improvements without difficulty or that it encountered a conflict that it wasn’t able to resolve. If Git does encounter an irreconcilable inconsistency, it will report it in some such language as this:

Auto-merging SimpleBuffer.java
CONFLICT (content): Merge conflict in SimpleBuffer.java
Automatic merge failed; fix conflicts and then commit the result.  This report indicates that youll need to edit `SimpleBuffer.java` and reconcile the differences. When you do, youll find that Git has added marker lines to your files, enclosing the inconsistent lines in the different versions (The markers start with ==, , and ). You must edit out the marker lines and make any other changes necessary to reconcile the two versions before making another commit.
  • Edit the specified files to resolve any such conflicts. In addition, merging may have introduced other oddities that you’ll want to correct (for instance, SimpleBufferTester.java may now have duplicate test numbers). Correct these as well.

  • Use git status to check which files have changed, select the ones that you want to commit, and use git add and git commit to complete the merge.

  • Then use the git logcommand to display the commit log. (Add the current log output to your lab report)

Deleting a Branch

Now that the changes have been merged into the main development line, the experimental branch isn’t really needed.

Use the git branch command with the -d option to remove the experimental branch from the repository.

  • Then use the git logcommand to display the commit log. (Add the current log output to your lab report)

Lab Submission

You will submit your lab report, SimpleBuffer.java, and SingleBufferTester.java via Gradescope by the end of the week.

I strongly recommend that each student keep a copy of the lab. Therefore, don’t forget to share the files/folder with your lab partner!

Remember: Write your code anticipating errors and print user-friendly error messages, all your public methods should be well documented (use Javadoc comments). You should include comments or organize your code and report in a way that will help the grader to find the answer to the exercises or posted questions.