Skip to content

Contributing with Git

Morten Piibeleht edited this page Oct 25, 2018 · 10 revisions

This page describes the basic workflow for making changes to the code in the GRASP 2018 repository.

Introduction

The GRASP code is now version controlled with Git. A Git repository stores all the source files and the full history of changes. It can also store multiple versions of the code simultaneously via branches.

When your are working on the code and are following the standard workflow outlined here, you technically interact with three different respositories. Two of them are remote repositories, hosted on GitHub, and one is a local repository, stored on your computer. They are:

  1. The official CompAS repository compas/grasp2018 (https://github.com/compas/grasp2018)

    This contains the official version of the source code. It also functions as the project's website. Only the maintainers have direct access to modify the code in this repository.

  2. On GitHub you can create a copy of any repository, called a fork, that will live under your own user account (unlike the main repository, which lives under the CompAS organization account).

    Examples of forks of the compas/grasp2018 repository are:

    On the fork, which is your own personal separate copy of the main repository, you can freely make any modifications to the code you wish.

    Once you have updated your version of the code on your fork, you want to incorporate the changes into the main CompAS repository. For that the maintainers have to pull your changes into the main repository. See the "Proposing changes to the upstream" section for more details on this.

  3. Finally, to actually compile and edit the code, and to modify the code in the repositories, you need a local copy of the repository on your own computer. You need the Git command line tool installed for this (it normally is by default on Linux).

    To download the remote repository from GitHub to your computer, you clone it with git clone:

    $ git clone URL-THE-REPOSITORY
    

    where URL is specific to the repo repository (more on this below).

    This creates a directory which is now your local clone/copy of the repository, containing a copy of all the information from the remote repository. The actual local Git database lives in the .git subdirectory.

    You can then use the git program on your computer to modify the repository, and to also interact with remote repositories. But remember that most things you do with the repository (such as creating new commits, creating branches etc.) only affect your local clone. To make them appear on GitHub, you have to explicitly push your changes to the remote repositories living on GitHub.

So, with that in mind, the basic idea of how to merge your modifications with the offical code is to:

  1. Make your changes locally in your local copy of the repository,
  2. push your changes to your fork of the main repository, and
  3. ask the maintainers to incorporate the changes into the official repository.

This is a very high level overview of how one makes changes to the repository. I suggest you refer back to this as you start playing around with various git commands.

But to actually get started with coding:

  1. Make sure you have git installed on your computer and you are comfortable with the basic operations.

    For the basics, you can start with the 10-minute tutorial on GitHub, "Git Handbook" (https://guides.github.com/introduction/git-handbook/). It covers the basic Git commands necessary to get started with Git on your computer.

    Also, see the "Resources for Git" section at the end of this page.

  2. Once you have git, hop over to the "Working on forks" section, fork and clone the repository.

  3. Refer to the "Example Git usage" section for a few basic GRASP-related examples.

Working on forks

Every developer should work on their own fork of the repository. That is, instead of directly working in the CompAS/grasp2018 repository, you work on a copy of the main GRASP repository under your own user account on GitHub.

This allows different developers to work independently, without interfering with each other's work. Once the work is ready to be merged into the main repository, GitHub allows changes to be easily merged upstream (i.e. into the original repository) via pull requests.

To create a fork, navigate to the CompAS grasp2018 repository and click on the "Fork" button in the top right corner:

Once you have created a fork, you can clone it (i.e. download it) to your own computer with git clone. To easily get the URL, click on the green "Clone or download" button on your fork and copy the URL there.

Note: you need to have Git set up locally on your computer, and make sure you understand how to authenticate with GitHub. See "Set up git" in GitHub Help for more information.

You are now ready to make changes to the code and push (upload) the changes to your own copy of the repository on GitHub.

Example Git usage

This section gives a few quick examples of Git commands to get you started. For a proper overview of Git and how to use it, please pick your favorite site in the "Resources for Git" section.

In the following, USERNAME refers to your GitHub username. E.g. you can find all your repository etc. under https://github.com/USERNAME/.

Also, note that some in some examples I show the expected output from the commands. In those cases I prepend $ to those lines, to distinguish the command and the output. You should not copy the $ part of the command when running the commands yourself.

Cloning your repository

This is an example of how you can clone a remote repository to your computer. The prerequisites are:

  • You have created a fork of the main GRASP repository (see "Working on forks"). You should see a repository at the following URL: https://github.com/USERNAME/grasp2018

You can then do the following to clone (i.e. create a copy of) the repository:

# Clone the repository with `git clone`:
git clone https://github.com/USERNAME/grasp2018.git

# ProTip: set up SSH keys to GitHub so you wouldn't have to type in your password
# all the time. See https://help.github.com/articles/connecting-to-github-with-ssh/
# for more information.
#
# If you have the keys set up, you need to clone with the following command instead:
#
#     git clone git@github.com:USERNAME/grasp2018.git
#


# The clone command will create a grasp2018/ directory. If you cd into it and see
# what files it has, you should see something like:
$ cd grasp2018
grasp2018/$ ls -A
bin  .git  grasptest  lib  make_environment_gfortran_UBC  make_environment_ifort_CC  README  src

# Note the .git/ directory -- this is where Git stores all the local information.


# You can also see what "remotes" have been set up -- i.e. shorthands that point
# to remote repositories. You can do that with `git remote` and it should look like:
grasp2018/$ git remote -v
origin	git@github.com:USERNAME/grasp2018.git (fetch)
origin	git@github.com:USERNAME/grasp2018.git (push)

# The default _remote_ is called "origin" by convention. This should point to your fork.

Making and pushing a code change

This section shows a simple example how record a code change in the repository and push it to the remote GitHub fork. The prerequisites are:

# Before you start, you should make sure that you are on the `master` branch.
# You can quickly check the current status of the repository and working tree
# by running:
git status

# It will tell you which branch you are on and whether there are any modified files
# in the _working tree_.
# If you are not on master, you can switch to it with:
git checkout master


# You should not normally work on the master branch, especially if your goal is
# to prepare a change that is to be included in the main repository.
#
# To create a new branch, simply run the following, where BRANCHNAME is a name
# of your choosing. It usually looks something like `fix-csl-bug`.
git branch BRANCHNAME


# At this point you are now ready to edit the code. Do your modifications as you
# would normally do.
#
# One you're done, you need to _commit_ your changes to the repository.
#
# First, it is good practice to review your changes. You can run
git status

# .. to get a general overview. And you can run
git diff

# .. to get a detailed diff of the changes.


# Next you need to add your changes to the _index_ with `git add`. Suppose
# that you modified src/appl/rmcdhf90_mpi/getscd.f90, then you run:
git add src/appl/rmcdhf90_mpi/getscd.f90

# You need to, of course, `git add` all the changes. You can also add e.g. whole
# directories at once.

# When you are done, quickly check again with `git status` that you have _staged_
# everything you wanted.
#
# If it looks good, you should now _commit_ your changes. This finally makes an
# entry in the (local) Git database of the repository.
git commit

# It will open an editor where you need to write a brief commit message.
#
# ProTips:
#
# 1. Good commit messages describe briefly why the change is necessary.
# 2. The first line of the commit message is written conventionally in the
#    imperative mood (i.e. "Fix a bug", not "Fixes a bug" or "Here I fix a bug").
# 3. Each commit should have a single purpose (i.e. it should only include the
#    code modification that are relevant for the particular change, no more, no
#    less).
#

# At this point you can run `git log` to see your new commit in the chronological
# list of commits:
git log


# Finally, you want to _push_ (i.e. upload) your changes to the remote fork (origin):
git push --set-upstream origin BRANCHNAME

# The --set-upstream part is only necessary once, to let Git know what the
# corresponding remote repository and branch should be. If you make additional
# changes you can just push with
git push

At this point, if all the commands ran successfully, you should be able to see your branch in your fork on GitHub:

The next step would now be to ask the maintainers of the main GRASP repository to include your changes in the main repository. To do this, you need to open a pull request -- see the "Proposing changes to the upstream" for more information.

Merging changes from the main repository

It will likely happen that other people's changes have been merged into the main compas/grasp2018 repository as you are working on your own modifications. So you will often want to merge your version of the code with the updated upstream version.

In the following, I am assuming the following:

  • You are normally working on your own branches and have not made changes to the master branch in your local repository.
  • The origin remote is set up to point to your fork (i.e. USERNAME/grasp2018.git, not compas/grasp2018.git). This will be the case if you cloned your fork of the repository. You can verify it by running git remote -V.
# Set up the remote for the main repository. In the following I will assume it is
# called "compas".
git remote add compas https://github.com/compas/grasp2018.git
# .. or if you use SSH based authentication:
git remote add compas git@github.com:compas/grasp2018.git

# Fetch the updates from the remote repository (this does not merge anything yet)
git fetch compas

# You can look at what changes have been made in the CompAS repository:
git log compas/master
git diff compas/master


# To merge changes from the CompAS master branch into your current branch you
# can just call `git pull`. This will usually create a merge commit.
git pull compas master

# Alternatively, you may want to _rebase_ your changes on top of instead.
git rebase compas/master

If there are conflicts (i.e. the main repository has changes to the same parts of the code that you are working on), Git will try to help you through that as much as possible. In many cases (e.g. if the changes are in different files or far enough from each other in the same file), Git can do the merges automatically. If it can't, it will let you know and ask you to resolve the conflicts manually before it finishes the merge.

Merging, rebasing and resolving merge conflicts are a non-trivial part of Git usage. Fortunately, the Git book has helpful sections covering these topics:

Proposing changes to the upstream

Once you have prepared a branch with a code change that is ready to be merged into the main GRASP repository, and you have pushed (uploaded) that to GitHub, you need to open a pull request from your forked repository to the original repository.

To do that, on your fork, find and select the branch you want to merge with the upstream repository:

Next, click on the "New pull request" button, to open up an interface to prepare the pull request:

The pull request interface will look like this:

To create a good pull request:

  • Make sure that "base fork" in the top left is compas/grasp2018.
  • Make sure that "base" is master.
  • Pick a descriptive title for the pull request.
  • Preferably, also write a brief summary of the changes, especially if the changes are non-trivial.

Once you have filled it all out, open a pull request by clicking on the green "Create pull request" button.

See the GitHub Help page on Pull Requests for more information.

Resources for Git

If you are new to Git, you should use one of the following resources to get started. Each of these should be complete on their own, but it might be helpful to refer to the other resources if something is confusing in whichever one you chose as your primary resource.

Git itself is a command line tool, but there are numerous helpful graphical user interface (GUI) frontends to it. Git comes with built-in GUI tools for committing (git-gui) and browsing (gitk), but there are various other programs e.g. GitKraken and GitHub Desktop (the latter is Windows & macOS only). A more thorough list can be found here https://git-scm.com/downloads/guis.

Additionally, since Git is widely used, many questions regarding Git usage are already answered on StackOverflow, and can usually be found via googling.

ProTip for Git novices: take a few minutes to read chapter 1.3 "Getting Started - Git Basics" from the Pro Git book. It explains the basic concepts and terminology, which will significantly help you understand what is going on as you run the various Git commands.