Many H/FOSS projects use GitHub as the repository for their source code. This activity is designed to familiarize you with the common workflow elements for interacting with H/FOSS projects hosted on GitHub. The activity is divided into four parts:
Prerequisites:
A basic familiarity with git is helpful before beginning this activity. The following sites provide good starting points:
Have completed the Software Installation activity. All work for this Git/GitHub Workflow Activity should be completed in the Ubuntu install from the Software Installation Activity.
In addition, you should have received and accepted the e-mail invitation from GitHub "to collaborate on the github-issues-activity repository."
General Information:
In the following text, commands to be typed at the terminal are shown in mono-spaced type
and any parts of those commands that you will need to customize for yourself are shown in angle brackets and <italics>
. The angle brackets are not part of the command and should be omitted when you fill in the appropriate values.
Each time you reach a Checkpoint
, please stop and wait. These are points at which we will discuss subtleties of the operations and ensure that the class is progressing together. If you reach a checkpoint before other groups, check to see if you might be able to provide assistance.
The slides used during the activity are available for later reference. The titles of the slides illustrating each task correspond to underlined sub-section namess below.
A cheatsheet with a short summary of each of the sets of commands that we use for particular tasks is also available.
Part 1: Before the First ClassIn order to allow us to focus on the more interesting and complicated parts of git/GitHub in class you are asked to do some parts of this activity now, before the first class period. You'll also be asked after this class to do some additional work in preparation for the second class period.
Configuring git
There are a few settings in the git configuration that need to be set before we begin. Note that these commands will only need to be issued once on each machine where you use git. Issue the following commands (customizing as appropriate) to setup the git configuration:
git config --global user.name <GitHubUserName>
git config --global user.email <you@email.org>
git config --global push.default simple
git config --global merge.tool meld
git config --global mergetool.keepBackup false
git config --global credential.helper cache
Use the following command to ensure that you have set all of the configurations:
git config --global --list
Forking the Upstream
Any H/FOSS project on which you will work will maintain a repository on a git compatible site that contains all of the code for the project. We will use GitHub, but a similar process exists for all of the others as well. The project's repository will be read-only except for the core project team that manages the project. So to work on the code for the project you will create a copy of the repository in your own GitHub account. The process of making this copy is called forking and the repository belonging to the H/FOSS project itself is called the upstream repository.
To fork the Upstream Repository:
Cloning your Origin
The fork of the upstream repository in your GitHub account is called your origin repository. Because this repository is in your GitHub account you will be able to both read and write to this repository. It will provide cloud storage for all of the work you do on the project and will also be the means for contributing code back to the main project through pull requests. To work on the code however, you will clone your origin repository onto your local machine making a copy of it into a local repository.
To clone your origin repository:
git clone <Origin Repository URL>
github-issues-activity
in the current directory.
github-issues-activity
directory.
Calculator.java Instructor.md README.md
).
Setting the Upstream Remote
You now have a local repository which is a clone all of the code in your origin repository, which was forked from the upstream repository. Your origin repository and the upstream repository are both referred to as remote repositories in git terminology, reflecting that they are not local to your machine. The git tool on your machine will keep track of the remote repositories (i.e. your origin and the upstream) corresponding to your local repository. This will be useful when working on H/FOSS projects to push changes from your local repository to your origin and to pull changes made by others in the upstream into your local repository. However, at this time your git tool only knows about your origin remote because that is the repository you cloned. You will need to tell git where to find the upstream repository.
To set the Upstream Repository:
github-issues-activity
directory.
git remote -v
origin https://github.com/braughtstu/github-issues-activity.git (fetch)
origin https://github.com/braughtstu/github-issues-activity.git (push)
If it does not and instead contains the course GitHub URL from which you forked the repository you will need to delete the github-issues-activity
directory and repeat the cloning your origin step above before continuing.
git remote add upstream <Upstream Repository URL>
git remote -v
origin https://github.com/braughtstu/github-issues-activity.git (fetch)
origin https://github.com/braughtstu/github-issues-activity.git (push)
upstream https://github.com/COMP491/github-issues-activity.git (fetch)
upstream https://github.com/COMP491/github-issues-activity.git (push)
Snapshot
Make snapshot of your virtual machine!
Checkpoint
Part 2: Hands-On in the First Class
In a common GitHub workflow you will, as you have done, fork a repository (the Upstream repo) into your own GitHub account (your origin repo) and then clone that to your local machine (your Local repo). At that point your local repo, your origin repo and the upstream repo will all be identical. In addition, each of these repositories will have a master branch, which contains the current reference version of the code according to the upstream repository.
In practice you will never edit code on the master branch. Instead, each time you want to work on the code (add a feature, fix a bug, etc) you will create a new feature branch and edit the code there. The feature branch behaves like it is a full copy of the master branch, but git is smart enough to just store the changes you make without making a full copy. In other words, it really just keeps track of the changes that would have to be made to get from the master branch to the version in your feature branch. By editing code on your feature branch, you will be able to leave the master branch in a state that is consistent with the upstream repository. This will be very helpful in integrating changes made by others into your local and origin repositories. It also has the advantage of making it easy to discard changes if you decide they are not working out.
As you work on the feature or bug fix you'll commit changes to the feature branch in your local repo. When you've finished work on the feature or bug fix you'll push your feature branch to your origin and then issue a pull request for that feature branch to the upstream. The manager of the upstream can then merge your changes into the project (most likely after asking for some additional work).
The following steps walk you through the basic process of creating and working on a feature branch, committing changes to your local repository, pushing a feature branch to your origin, creating a pull request and finally bringing your local and origin master branches back into sycnh with the upstream.
Claim An Issue
Go to the GitHub Issues tab on the upstream repository and browse the "Round1" bugs. Comment on one of the "Round1" tickets that you want to fix. Refresh the page and check if you are the first commenter on the ticket. If you are, then the bug is yours. If you are not the first commenter on the issue try another until you are!
Branch and Fix
As described above you should never edit code on the master branch. So any time you plan to make changes to the code you will need to create a new feature branch.
To create a feature branch:
Now edit the If time permits you should also be sure that your modified code compiles:
Status, Stage and Commit
When you edit a file you are changing its contents but not the copy that is in your local repository. To make your changes part of the local repository you will commit the changes to the repository. There are several steps to this process.
Determine which files have been changed, add the changed files to be committed to the repository to the staging area and confirm that they have been added:
Once the files are in the staging area they can be committed to the repository. Each commit should reflect a complete unit of work and the commit should have a clear message indicating what that work was.
Commit your change to your local repository and verify they have been committed:
You can also see a list of the commits that have been made to the repository:
return - advance one line Just to get a little more feel for the way your local repository behaves do the following:
Push Branch to Origin
The changes you have made are now in your local repository with a nice descriptive commit message. To contribute those changes to the original project you'll need to first push your feature branch from your local repository to your origin.
Push your branch to origin:
You will be asked for your GitHub username and password.
Check that your feature branch and changes have been pushed to your origin by looking at the github-issues-activity repository in your GitHub account. You should verify several things:
Making a Pull Request
A pull request is the mechanism by which code changes that you have made can be contributed back to a project. More specifically, it is a request, through GitHub, from you to a project asking them to consider incorporating changes you have in your fork of their project (i.e. your origin) into their repository (i.e. the master branch of the upstream).
Make a pull request for your round1fix branch:
Once you create the pull request it will be reviewed by the project managers. If everything looks good they will merge the changes into the master branch of the project. The more likely scenario is that they will comment on your pull request with some additional things to consider or other changes to make. When you do that you can then update your pull request by pushing the branch to your origin again. They will then review the pull request again. This cycle may repeat several times before your proposed changes are actually merged into the project.
Synchronize Local and Origin with Upstream
Once your pull request, and everyone else's too, has been merged into the upstream master, the master branch of your local and origin repositories will be out of synch with (i.e. different than) the upstream master. This will occur frequently in any project where there are multiple developers contributing. When this happens you will need to synchronize your repositories with the upstream repository. This is done by pulling the changes from the upstream master and merging them into to the master branch of your local repo and then finally pushing them to your origin. Because you have been careful to never edit the code in the master branch of your local repo this is an easy process.
Verify that your local master is out of synch with the upstream:
Synchronize your master branches with the upstream master:
Delete a Feature Branch
Once the changes made in a feature branch have been merged into the upstream there is no need to keep the feature branch around. Thus, the feature branch can be deleted from your local and origin repositories.
Delete the feature branch from your local and origin:
Thus far, the changes you have made and integrated into the project have been carefully selected so that no change you made conflicted with a change made by someone else. This meant that your feature branch was able to be merged into the upstream master automatically. In practice however, it is quite likely that when multiple people are changing code concurrently they will make changes that are in conflict with each other. Complete the steps below before the next class. These steps will have you make a change that will generate conflicts and we will then walk through the process of resolving those conflicts in the next class.
Fix A Round2 Issue
The steps below are the same steps you used in fixing your "Round1" bug and making a pull request.
So, you can refer to the steps above or use the git/GitHub Cheatsheet to refresh your memory on the commands required.
Before this class you made changes that fixed a "Round2" issue and generated a pull request to the upstream to merge your results. In practice, while you are working on your fix other contributors will make pull requests and their work will be merged into the upstream. To simulate this, the instructor has made changes to the upstream. These changes have been designed to conflict (i.e. have changes in the same line of code, or changes that cannot be merged automatically). You may have noticed when you created your pull request that GitHub indicated (in red) that it "Can't automatically merge" your pull request. This is GitHub's way of letting you and the upstream project managers know that there is a conflict between the code in the upstream and the edits in your pull request.
When a branch cannot be merged automatically what is typically done is that the person issuing the pull request will be asked to merge the changes from the current upstream master into their feature branch. During this process you will have to resolve the conflicts that exist manually by deciding what the conflicting code should look like in each case. Once the conflicts are resolved, the pull request is updated by pushing your edited feature branch to your origin. The upstream manager will then be able to merge your updated pull request you issued into the upstream.
Synchronize Local and Origin with Upstream master:
Merge master Branch Changes into your Feature Branch:
Notice that the merge will fail due to conflicts. Git needs your help to manually resolve the conflicts. You can see the conflicts if you look inside the Examine the Conflicts
This is git's way of indicating what has happened. The master branch had been edited to make the Resolve the Conflicts:
Commit and Push (Update Pull Request):
Synchronize Local and Origin master branches with Upstream master:
Delete the feature branch:
Acknowledgements: This assignment builds from and adapts ideas and content from the following activities created by others:
Part 3: Before the Second Class
Checkpoint
git branch
This will list all of the branches in your local repository. Currently there is only a master branch. Also notice that an * appears beside master. This indicates that the files on which you are working are those as they exist in the master branch.
git branch round1fix
This creates a new branch named round1fix in your local repository.
git branch
Notice the difference.
git checkout round1fix
This will switch you to the round1fix branch and allow you to edit the files on that branch, ensuring that the files in the master branch are unchanged and remain consistent with the upstream.
git branch
Notice the difference.
Calculator.java
file to make the fix described in the issue that you claimed. Be sure not to edit any other code in the class.
gedit Calculator.java
javac Calculator.java
Checkpoint
git status
git add <FileToAdd>
git status
git commit -m "a descriptive message here."
git status
git log
space - advance one screen
q - terminate log listing
cat Calculator.java
Is your change there?
git checkout master
git branch
cat Calculator.java
Is your change there? Why not?
git checkout round1fix
git branch
cat Calculator.java
Is your change there?
Checkpoint
git push origin round1fix
Calculator.java
file will contain your change.
Calculator.java
file will not contain your change.
Checkpoint
This is always the branch where you want your changes to go. In this case, into the master branch of the github-issues-activity repository for the course.
This is always the branch that contains the changes that you want to have integrated into the upstream.
Calculator.java
file should be shown.
Use this to explain to the project managers what you have done and why. In particular, because this work resolves an issue from the issue tracker the issue should be referenced in the comment. Include the text "Fixes #bugid" (e.g. Fixes #123) to indicate which bug your changes have fixed. We'll see later that this will allow the issue to be automatically closed if/when the project managers merge your pull request into the upstream master.
Checkpoint
git checkout master
git branch
Ensure that you are on the master branch.
cat Calculator.java
Calculator.java
that is in the upstream repository on GitHub.
git checkout master
git branch
Ensure that you are on the master branch.
git pull upstream master
cat Calculator.java
Calculator.java
that is in the upstream repository on GitHub.
Calculator.java
in your origin on GitHub.
git push origin master
Calculator.java
in your origin on GitHub now contains the changes too, and thus your local and origin master branches are now in synch with the upstream.
Checkpoint
git branch -d round1fix
git branch
Verify that the round1fix branch is no longer in your local repo.
git push origin :round1fix
Notice the ":" before round1fix!
Reload your GitHub origin repository page in the browser and verify that the round1fix branch has been deleted.
Checkpoint
Part 4: Hands-On in the Second Class
git branch round2fix
git status
git add Calculator.java
git commit -m "<Descriptive commit message>"
git push origin round2fix
Checkpoint
git checkout master
git pull upstream master
git push
Checkpoint
git checkout round2fix
.
git merge master
Calculator.java
file.
cat Calculator.java
<<<<<<< HEAD
public double sphereVolume(double r) {
=======
public static double sphVol(double r) {
>>>>>>> master
sphVol
method static
. But the local branch (HEAD) had been edited to rename the sphVol
method to sphereVolume
, as requested in the issue ticket. Because these changes are in the same line git is unable to automatically merge them. You could resolve the conflict by manually editing the file and removing the information about the conflict leaving only the desired code. But it is often easier, more convenient and less error prone to use a graphical merge tool as you will below.
Checkpoint
git mergetool
static
).
cat Calculator.java
and verify that the merged file now appears as desired.
Checkpoint
git status
git commit -m "merged upstream changes"
git push origin round2fix
Checkpoint
git checkout master
git pull upstream master
git push origin master
git branch -d round2fix
git push origin :round2fix
Checkpoint