Skip to content
goodell edited this page Oct 2, 2014 · 15 revisions

Obtaining Git

You can obtain source releases from http://git-scm.com/. Alternatively, most operating systems have a way to obtain a modern version of Git through the package management system (e.g, yum, brew, etc.).

Configuring Git

Add the following to your ~/.gitconfig file. Don't forget to change the user name/email!

# You need to have name and email values.  If you don't,
# git will use your_local_username@your_local_hostname,
# which is almost certainly not what you want.
[user]
        name = Joe Developer
        email = [email protected]

######################################################
# The rest of these are optional, but helpful.
######################################################

[color]
        diff = auto
        status = auto
        branch = auto
        ui = auto

# Helps to distinguish between changed and untracked files
[color "status"]
        added = green
        changed = red
        untracked = magenta

# Allows git to create 8-character abbreviated hashes and
# highlight extra whitespace.
[core]
        whitespace = trailing-space,space-before-tab,indent-with-tab
        abbrev = 8

# Allows better view of commits.
[alias]
        graph = log --graph --decorate --abbrev-commit --pretty=oneline

Obtaining a GitHub Account

Sign up right on the home page at https://github.com/. If you expect to also have direct commit privileges to open-mpi/ompi:master, then send a mail to [email protected] so that someone can add you to the open-mpi organization. Note that in order to commit directly, you need to have signed the Open MPI Contributor License Agreement. See https://www.open-mpi.org/community/contribute/

Configuring git to Talk to GitHub

Please see the GitHub article on this topic.

OPTIONAL: Installing gh and hub on OS X

(These packages enable some interactions with GitHub via the command line.)

Install Homebrew: http://brew.sh/

Then:

$ brew install npm
...

$ sudo npm install -g gh
...

$ brew install hub
...

### configure credentials (my account is set up for 2FA)
### token came from: https://help.github.com/articles/creating-an-access-token-for-command-line-use
$ cat ~/.gh.json
{
    "github_user": "goodell",
    "github_token": "0123456789abcdef0123456789abcdef01234567"
}

OPTIONAL: Installing gh On RHEL

(Note: the RHEL instructions probably require the EPEL repository)

### install the Node Package Manager
$ sudo yum install npm
...

### install the "gh" package to get the "gh" command
$ sudo npm install -g gh
...

### configure credentials (my account is set up for 2FA)
### token came from: https://help.github.com/articles/creating-an-access-token-for-command-line-use
$ cat ~/.gh.json
{
    "github_user": "goodell",
    "github_token": "0123456789abcdef0123456789abcdef01234567"
}

OPTIONAL: Installing hub On RHEL

(Note: the RHEL instructions probably require the EPEL repository)

$ sudo yum install rubygem-rake
...

$ git clone https://github.com/github/hub.git
...

$ cd hub

$ rake install prefix=/path/to/install/root
...

Setting Up A New Local Developer Repository

Here we clone the primary Open MPI repository to our local machine. This gives us a complete local copy of the repository history.

$ git clone [email protected]:open-mpi/ompi.git
Cloning into 'ompi'...
remote: Counting objects: 250629, done.
remote: Compressing objects: 100% (42816/42816), done.
remote: Total 250629 (delta 206704), reused 250629 (delta 206704)
Receiving objects: 100% (250629/250629), 67.77 MiB | 12.65 MiB/s, done.
Resolving deltas: 100% (206704/206704), done.
Checking connectivity... done.

$ cd ompi

$ git remote add release [email protected]:open-mpi/ompi-release.git

$ git fetch release
warning: no common commits
remote: Counting objects: 231486, done.
remote: Compressing objects: 100% (39315/39315), done.
remote: Total 231486 (delta 191101), reused 231486 (delta 191101)
Receiving objects: 100% (231486/231486), 62.70 MiB | 12.39 MiB/s, done.
Resolving deltas: 100% (191101/191101), done.
From github.com:open-mpi/ompi-release
 * [new branch]      v1.7       -> release/v1.7
 * [new branch]      v1.8       -> release/v1.8

Now at this point we also want to create a user fork of open-mpi/ompi-release on the GitHub site. This user fork will be used to submit pull requests back to the restricted release branches (e.g., 1.8 and 1.9). We can do this via the web interface by visiting: https://github.com/open-mpi/ompi-release/fork

You can also do this with the gh command if you already installed it (goodell is my username below, replace it with your github user name):

$ gh repo --fork ompi-release --user open-mpi
gh [info] Forking repo open-mpi/ompi-release on goodell/ompi-release
gh [success] https://github.com/goodell/ompi-release

$ git remote add goodell https://github.com/goodell/ompi-release

Workflow For Cherry-Pick Model

The Open MPI project has long-favored the "cherry-pick" model for development. Meaning: we commit to the main development branch, and then individually pick commits from that branch over to the release branches.

In Github terms, there are two components to this model:

  1. Committing to the main development branch
  2. Submitting a pull request for the release branch

The following sections detail the steps in both of these components.

Committing to master in the main ompi repo

A.K.A. Committing to open-mpi/ompi:master

Many prior-SVN-using-developers are used to directly committing their work to the trunk. And you can still (effectively) do that with Git: clone the main ompi repo, commit some work on to the master branch, and then push back to Github.

However, there's a different/better way that you are encouraged to use.

In Git, you can create a topic branch (branches are super lightweight; creating a branch is a trivial action). Topic branches are just for a single topic (e.g., a single feature, or a single bug fix). You do all your work for that topic on that branch, then then merge that branch back into master before pushing up to the main ompi Github repo.

The following example demonstrates creating a topic branch, checking it out, and then creating two commits on that new topic branch. Then the topic branch is merged back to master and pushed up to GitHub.

#####################################################
# Step 1: Make a topic branch and check it out
#####################################################

$ cd my-ompi-git-clone
$ git checkout -b topic/fix-examples master

#####################################################
# Step 2: Make your changes and commit them
#####################################################

$ vim examples/ring_c.c
...

$ git diff
diff --git a/examples/ring_c.c b/examples/ring_c.c
index 353be3b..19b10f2 100644
--- a/examples/ring_c.c
+++ b/examples/ring_c.c
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])

         if (0 == rank) {
             --message;
-            printf("Process 0 decremented value: %d\n", message);
+            printf("Process 0 DECREMENTED value: %d\n", message);
         }

         MPI_Send(&message, 1, MPI_INT, next, tag, MPI_COMM_WORLD);

$ git commit -a -m 'ring_c: turn up the volume!'
[topic/fix-examples 5b8249b] ring_c: turn up the volume!
 1 file changed, 1 insertion(+), 1 deletion(-)

$ vim examples/hello_mpifh.f
...

$ git diff
diff --git a/examples/hello_mpifh.f b/examples/hello_mpifh.f
index 238bf94..f66a111 100644
--- a/examples/hello_mpifh.f
+++ b/examples/hello_mpifh.f
@@ -7,6 +7,7 @@ C $COPYRIGHT$
 C
 C Sample MPI "hello world" application in Fortran 77
 C
+C Uses the *ANTIQUATED* mpif.h interface.
         program main
         implicit none
         include 'mpif.h'

$ git commit -a -m 'hello_mpifh: this example uses an old interface'
[topic/fix-examples 17aa2bf] hello_mpifh: this example uses an old interface
 1 file changed, 1 insertion(+)

#####################################################
# Step 3: Merge your topic branch back to master
#####################################################

$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

# Not needed because it says we are up-to-date above,
# but you would usually issue this command:
$ git pull --rebase
Current branch master is up to date.

# "--no-ff" can be omitted if "merge.ff=false" is set in
# your git configuration.  We usually want this for
# fixes/features comprised of more than one commit to
# make cherry picking easier later on.
$ git merge --no-ff topic/fix-examples
[drops you into $EDITOR to write a commit message]

#####################################################
# Step 4: Push your new master commits back to Github
#####################################################

$ git push origin master
Counting objects: 7, done.
Delta compression using up to 32 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 382 bytes | 0 bytes/s, done.
Total 4 (delta 3), reused 0 (delta 0)
To [email protected]:open-mpi/ompi.git
   a8540fe..5b8249b  master -> master

And just to illustrate what really happened there, look at the output of git log with some handy graphing options:

#####################################################
# Just before the "git push"
#####################################################
$ git log --oneline --decorate --graph | head -n 7
*   d9c7734 (HEAD, master) Merge branch 'topic/fix-examples'
|\
| * 17aa2bf (topic/fix-examples) hello_mpifh: this example uses an old interface
| * 5b8249b ring_c: turn up the volume!
|/
* a8540fe (origin/master, origin/HEAD) Fortran: add ompi/mpi/fortran/use-mpi-f08/mpi-f08-sizeof.F90 to the dist tarball.
* 184b497 Fortran: fix OMPI_GENERATE_F77_BINDINGS macro invokation

#####################################################
# Just after the "git push" (note the moved branch labels)
#####################################################
$ git log --oneline --decorate --graph | head -n 7
*   d9c7734 (HEAD, origin/master, origin/HEAD, master) Merge branch 'topic/fix-examples'
|\
| * 17aa2bf (topic/fix-examples) hello_mpifh: this example uses an old interface
| * 5b8249b ring_c: turn up the volume!
|/
* a8540fe Fortran: add ompi/mpi/fortran/use-mpi-f08/mpi-f08-sizeof.F90 to the dist tarball.
* 184b497 Fortran: fix OMPI_GENERATE_F77_BINDINGS macro invokation

Fixing a Bug In Both master and v1.8

A.K.A. Fixing a bug in master and then submitting a pull request to get it over to the appropriate release branch.

In general, the sequence of steps are:

  1. Start by performing the steps in the previous subsection to fix the bug on master.
  2. Cherry pick the commit(s) to a topic branch created from the desired release branch (in your local clone).
  3. Push a topic branch containing these cherry-pick commits up to your personal Github fork of the ompi-release repo
  4. Submit a Pull Request to pull your commits to the official ompi-release repo
  5. When the pull request is complete, you can optionally delete the topic branch on your local and Github clones

Here's an example showing how to create a topic branch for the v1.8 release branch, and how to create a pull request for the master commits we made in the previous section:

#####################################################
# Step 1: Fetch upstream commits from the release
# branch
#####################################################

# The "release" in the command line below refers
# to the git remote named "release" that we added
# earlier in this tutorial via "git remote add
# release ...".  It refers to the ompi-release repo.
$ cd my-ompi-git-clone
$ git fetch release
...

#####################################################
# Step 2: Make a topic branch for these v1.8 commits
#####################################################

# Yes, you *must* make a topic branch just for
# these commits
$ git checkout -b topic/fix-examples-v1.8 release/v1.8
Branch topic/fix-examples-v1.8 set up to track remote branch v1.8 from release.
Switched to a new branch 'topic/fix-examples-v1.8'

#####################################################
# Step 3: Cherry pick the appropriate commits
#####################################################

# NOTE: You can use any other method to get your work
# to this new topic branch; you do not *have* to use
# "git cherry-pick".  This example just shows the
# cherry-pick method.

# Figure out the commits to cherry-pick from master
# to this new topic branch
$ git log --oneline topic/fix-examples
17aa2bf hello_mpifh: this example uses an old interface
5b8249b ring_c: turn up the volume!
a8540fe Fortran: add ompi/mpi/fortran/use-mpi-f08/mpi-f08-sizeof.F90 to the dist tarball.
184b497 Fortran: fix OMPI_GENERATE_F77_BINDINGS macro invokation
...

# Use the -x option to indicate that it's a
# cherry-picked commit.
$ git cherry-pick -x a8540fe..topic/fix-examples
[topic/fix-examples-v1.8 3f4c4f2] ring_c: turn up the volume!
 1 file changed, 1 insertion(+), 1 deletion(-)
[topic/fix-examples-v1.8 209f14a] hello_mpifh: this example uses an old interface
 1 file changed, 1 insertion(+)

The above example shows simple cherry-picks that have no conflicts. If your cherry-picks have conflicts (e.g., if master and the release branch have diverged), you need to resolve them and commit the resolved cherry-pick.

REMEMBER: If you get totally hosed or confused, see this awesome flow chart for how to resolve Git messes and/or ask for help on the Open MPI developer's list. DO NOT KNOWINGLY PUSH A MESS UP TO GITHUB!

Continuing with the example...

#####################################################
# Step 4: Push your topic branch to your Github fork
#####################################################

# Push the topic to your personal Github fork
# (remember: we made a fork of the ompi-release
# repo earlier in this tutorial)
$ git push goodell topic/fix-examples-v1.8
Counting objects: 14, done.
Delta compression using up to 32 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 808 bytes | 0 bytes/s, done.
Total 8 (delta 6), reused 0 (delta 0)
To [email protected]:goodell/ompi-release.git
 * [new branch]      topic/fix-examples-v1.8 -> topic/fix-examples-v1.8

Finally, you need to open a pull request to request that the Release Manager pull these commits to the official ompi-release repo.

You can do this in one of several ways:

  1. Via the web. Goto https://github.com/goodell/ompi-release and click on "Compare & pull request".
  2. Via the command line:
$ hub pull-request -m "fix examples" \
    -b open-mpi/ompi-release:v1.8 \
    -h goodell:topic/fix-examples-v1.8
# DJG: I think there's a way to do this with `gh` too,
# but I haven't sorted out the syntax yet

NOTE: When creating the pull request, follow the procedures listed in SubmittingBugs -- assign appropriate labels and a milestone. Otherwise, the Release Manager may not see your PR.

Pull Requests must also be reviewed before the RM will complete them. Get someone to review your PR. You may need to iterate to get to a good final solution. Once your code has been reviewed successfully, have the reviewer place the Gihub "reviewed" label on the PR. This is the signal to the RM that the PR is reviewed and ready to go.

The RM for the v1.8 release will then either approve the PR or request further modifications. Assuming the PR is approved, the RM will perform the merge as part of approving the request (often with a one-click merge from the web UI).

Clone this wiki locally