Developing with Git

:information_source: This article has been migrated from our wiki site. I have not personally tested this against current versions of OpenNMS.

As of January 1, 2010, OpenNMS is now using git as its primary source code management tool.

More information on git:

Viewing the source

To just view the current source, git is not needed. You can browse our Git repository directly at GitHub.

Install the Git source code management tool

Install Git as appropriate for your platform.

On Debian/Ubuntu systems, the following command will install Git.

sudo apt-get install git

If you are starting without any Git experience, “man gittutorial” or look through the tutorial online. “Everyday GIT With 20 Commands Or So” is another good beginning reference.

Fork or clone the OpenNMS repository

Option 1: Getting OpenNMS by forking the GitHub repository

As of 2014, the preferred method for OpenNMS developers to receive code contributions is for you (a potential contributor) to create a GitHub site account and then fork the GitHub repository into a private repository instead of cloning the main OpenNMS repository directly.

Forking the OpenNMS repository creates a private copy of OpenNMS that you can change and commit to that is tied to your GitHub account.

This article describes the overall process: Fork a repo - GitHub Docs

To create a private fork, go to GitHub - OpenNMS/opennms: Enterprise-Grade Open-Source Network Management Platform and then click the “Fork” button in the upper right. This will create a private fork of the codebase.

Then, clone out your fork of the code, not the OpenNMS official repository.

For example:

 mkdir src
 cd src
 git clone
 ... (a directory "opennms" will be created below the current directory)
 cd opennms

Now add the official OpenNMS as your upstream repository so git knows where to merge new changes from done by others.

 git remote add upstream

Now confirm your private fork has the alias “origin” and the official repository as having the alias “upstream”.

 $ git remote -v
 origin (fetch)
 origin (push)
 upstream (fetch)
 upstream (push)

After this, the overall process is to make changes locally and then commit any desired changes to your fork using ‘git commit’ (where you will have commit access since it’s your private fork or copy of the code) and use the instructions in the article below to notify us of the changes as a ‘pull request’. Then we can review them on github and merge them into the OpenNMS/opennms.git repository.

This process is described in more detail below.

Option 2: Getting OpenNMS by cloning the official GitHub repository

This is the option for people who just want a local copy of the source code without the intention make changes or to submit them back, or for people who already have read/write access to the official repository.

First, you must clone the OpenNMS Git repository.

This command is the usual one for people without read-write access to the repository:

 $ git clone git://
 ... (a directory "opennms" will be created below the current directory)
 $ cd opennms

If you have commit access to the OpenNMS repository, you can clone it read-write instead:

 $ git clone
 ... (a directory "opennms" will be created below the current directory)
 $ cd opennms

Unlike Subversion, when you clone a git repository, you have all of the commit history back to the creation of the codebase, as well as access to any branches and tags defined in the remote repository. That means that it is possible to do development on multiple portions of the OpenNMS codebase without needing network access. You can commit changes locally as necessary, without having to go back and forth to the upstream server.

Initial Git configuration

There are some things you should do to configure Git for your repository before you go any further. Ensure you are in the “opennms” top-level source code directory.

First, configure it to know who you are:

 $ git config "FirstName LastName"
 $ git config ""

Or, if you have many git repositories under your current user, you can set this for all of them

 $ git config --global "FirstName LastName"
 $ git config --global ""

If you want pretty colors, you can setup the following for branch, status, and diff commands:

 $ git config --global color.branch "auto"
 $ git config --global color.status "auto"
 $ git config --global color.diff "auto"

Next, if you are comfortable with the way Subversion works, you will probably want to configure Git to push changes to the same location they are branched from:

 $ git config push.default tracking

OpenNMS Repository Branch Workflow

In your local git repository, the branches described below are accessible as “remote” branches, i.e., branches that reference a location on a remote repository (in this case, the OpenNMS git repository).

Active Branches

Here are the currently active branches, and their uses:

  • foundation: Foundation is a branch based on OpenNMS Horizon 14, plus a number of additional bug fixes as well as the GUI rework that went into Horizon 15. It is the basis of OpenNMS Meridian 2015.x.
  • foundation-2016: Foundation 2016 is a branch based on OpenNMS Horizon 17. It is the basis of OpenNMS Meridian 2016.x.
  • foundation-2017: Foundation 2017 is a branch based on OpenNMS Horizon 19. It is the basis of OpenNMS Meridian 2017.x.
  • foundation-2018: Foundation 2018 is a branch based on OpenNMS Horizon 21. It is the basis of OpenNMS Meridian 2018.x.
  • release-*: If there is an active release pending (ie, Horizon 17.0.1, for example) there will be a “‘release-XX.X.X’” branch created. This branch should only receive bugfixes, and then be removed after release.
  • develop: Future development of features that will go into the next future major OpenNMS Horizon.

Merge Schedule

Bamboo is configured to auto-merge code from branch to branch so you should only have to make changes in the “oldest” relevant branch.

  • foundation → foundation-2016 : Only critical security or bug fixes should go into Foundation. These will auto-merge forward to the 2016 Foundation branch, for inclusion in future stable Horizon and Meridian 2016 releases.
  • foundation-2016 → foundation-2017 : Foundation 2016 will auto-merge-forward to Foundation 2017.
  • foundation-2017 → foundation-2018 : Foundation 2017 will auto-merge-forward to Foundation 2018.
  • foundation-2018 → release-XX.X.X : Foundation 2018 will auto-merge-forward to the next release branch, if one is active, so that security and bug fixes from Foundation and Foundation 2016 automatically make it into the next release.
  • release-XX.X.X → develop : If a release branch is active, it will be automatically merged forward to develop, so that all bug fixes and changes make it into future releases.
  • foundation-2018 → develop : If a release branch is ‘‘not’’ active, Foundation 2018 is automatically merged forward to develop, so that bug and security fixes make it into future releases.
  • foundation-2018 → Meridian develop : Foundation 2018 is also merged automatically into the Meridian development codebase, to become part of a future Meridian release. Meridian develop is a very thin set of changes on top of the foundation branches, mostly for branding and a few default configuration changes.

Where to Merge Code

In short, here is what you should branch from if you are writing new code:

  • Critical Security or Bug Fixes : foundation
  • Non-Blocker Bug Fixes : foundation-2016
  • New Features : develop

Currently, there are a few projects in-progress that may be eligible for a new minor (17.1, 17.2, etc.) release, eg, syslog performance improvements or Enlinkd improvements, and some other smaller feature work. Those particular changes should be done in a branch from the latest ‘’‘master’’’ or ‘’‘release-17.X.X’’’ branch, if it exists.

Creating a Branch and Making Changes

At this point, you have a locally cloned copy of your private fork of the OpenNMS repository, as described above. Change to the “src/opennms” folder.

Listing Branches

For a full list of branches in your cloned repository, use git branch -a:

$ git branch -a
* master

To view just your local branches, leave the -a flag off. The “master” branch is the default initial branch

$ git branch
* master

Create an OpenNMS Issue Ticket

All OpenNMS patches should be associated with a JIRA issue ticket number, e.g. NMS-1234. By convention, the branch below should be named to include the NMS-1234 ticket name, so the first step is to go to JIRA at and create a new issue by clicking the “Create” button. You will need to create an account on JIRA if you don’t have one already.

Name the issue in a way that reflects the purpose of your upcoming patch. The ticketing system will assign a ticket number automatically. Note the ticket number for later use, below.

Checkout a Remote Branch to Create a New Local branch

If you are used to Subversion, you will notice that branches work a bit differently in Git. Remote branches are not directly accessible, since they represent the state of a branch in another Git repository. If you attempt to check one out directly, you will get a warning “Note: moving to ‘(branchname)’ which isn’t a local branch”.

Instead, what you want to do is create a local branch from the remote one, using the syntax

 git checkout -b (new_local_branch_name) (existing_remote_branch_name)

In most cases, it is recommended that you branch from the main “develop” branch of the upstream OpenNMS GitHub repository. Name your new local branch to reflect the associated JIRA ticket created above.

 $ git checkout -b NMS-1234-feature-new-awesome-thing remotes/upstream/develop
 Branch NMS-1234-feature-new-awesome-thing set up to track remote branch develop from upstream.
 Switched to a new branch 'NMS-1234-feature-new-awesome-thing'

This created a local branch called “NMS-1234-feature-new-awesome-thing” based on the official OpenNMS repository remote branch “remotes/upstream/develop”.

Note that it says it is set up to track the remote branch. That means that Git knows that your branch was created from the remote branch, and will automatically know what to do if you wish to push changes to that branch.

Now when you do a “git branch” it will show that your active branch is the one you created:

$ git branch
* NMS-1234-feature-new-awesome-thing

Make Changes

Create your changes as normal, editing/adding/removing files, and committing them to the local repository with “git commit”.

Git is slightly different from SVN in that by default, no changes you make to files will be committed unless you specifically git add them. Otherwise, you will get something like this from git status:

In the following example, one local file has been changed compared to the repository.

$ git status
# On branch NMS-1234-feature-new-awesome-thing
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#       modified:
no changes added to commit (use "git add" and/or "git commit -a")

If you are only modifying files, you can just run

 git commit -a

when it’s time to commit your changes, and it will automatically git add any modified files. Note that this does not add any new files or directories that have been created, however.

Also note, this is only committing files to your ‘‘local’’ repository. Once you have your local branch to your liking, it’s time to push the changes back to your online repository.

View Your Changes==

This displays each recent commit in commit order. Each commit will have a unique commit identifier, the author and the time of the commit. Note that this displays the entire commit history of the current branch, yours and others.

 $ git log

After committing changes, “git status” will show your local branch as ahead of the upstream repository.

$ git status
# On branch ...
# Your branch is ahead of 'upstream/develop' by 9 commits.
nothing to commit (working directory clean)

Make Your Branch Public

When you are ready for your code to be accessible by other people, you can push your feature branch back to your online GitHub repository like so:

 $ git push -u origin NMS-1234-feature-new-awesome-thing:NMS-1234-feature-new-awesome-thing

This will create a new “NMS-1234-feature-new-awesome-thing” branch in your online GitHub repository and then push your local branch of the same name to this GitHub branch where now other people can check it out as well.

Pushing Changes Upstream

First of all, if you’re going to submit patches, please fill out the [[OCA|OpenNMS Contributor Agreement]].

Second, each OpenNMS patch should be associated with a related JIRA issue tracking ticket (already created above).

Option 1: No Commit Access, using a GitHub pull request

Submitting a GitHub pull request is now the preferred method for submitting patches to OpenNMS.

This page describes the general process: About pull requests - GitHub Docs

By this point, you have pushed your new branch to your online fork of the OpenNMS repository on GitHub.

  • Go to your personal GitHub OpenNMS repository and ensure your branch “NMS-1234-feature-new-awesome-thing” is selected in the branch drop-down. You should see GitHub report something like “This branch is n commits ahead, n commits behind OpenNMS:develop”.
  • Click the “Compare” button to the right on the “This branch is n commits ahead…” line. Review your changes.
  • When you’re ready to submit your pull request, click “Create pull request”.
  • On the next screen, give a descriptive title to your pull request, including the OpenNMS JIRA issue tracker NMS-xxxx ticket number related to your change. The pull request can also be described in the comment block. Click “Create pull request” on the right to finish submitting the pull request.
  • Your pull request will be assigned a number and go into queue for review. Add the pull request URL to the JIRA ticket associated with it in JIRA so there is a record in the ticket that a pull request exists to address it.

Option 2: No Commit Access, using a patch submission

This method prepares a text patch for posting in the bug tracker web site or for submitting by e-mail.

Just run

 git format-patch -M -C (upstream-branch)

to generate a set of commit patch files between the upstream branch and your current branch. (Note: The -M flag is necessary to track file renames):

 $ git format-patch -M -C remotes/upstream/develop

Each commit gets a file which contains the patch, as well as some metadata (in the form of a standard email) that makes it easy to import into someone’s git repository.

 $ cat 0001-testing-commits.patch
 From 26ed1d96e18db80ff76d0f462bb4b33b648e94e5 Mon Sep 17 00:00:00 2001
 From: Benjamin Reed <>
 Date: Tue, 22 Dec 2009 15:41:05 -0500
 Subject: [PATCH 1/2] testing commits

 --- |    1 +
  1 files changed, 1 insertions(+), 0 deletions(-)
 diff --git a/ b/
 b82d49b..cc57eb8 100644
 --- a/
 +++ b/
 @@ -1 +1,2 @@
  See the instructions at

Just open a bug in as an enhancement, and attach your patches.

If you want to get fancy, see [[Git Refactoring Commits|this page]] for details on how to “rewrite history” so you can have one patch per feature.

Option 3: With Commit Access

If you have commit access, all you need to do is run “git push” from your branch. If you have configured “push.default” as above, you don’t need to give it any arguments:

 $ git push

Other useful git operations

Getting Updates

To get the latest updates from your repository on GitHub to in your local system, run git pull:

 $ git pull
 Already up-to-date.

This will retrieve any changes that have been made and apply them to your repository.

However, the larger source of changes will be in the OpenNMS upstream repository. To stay current, sync your local private repository to the OpenNMS upstream public repository.

This page describes the process in more detail: Syncing a fork - GitHub Docs

First, fetch changes:

 $ git fetch upstream

Switch to your local "develop" branch
 $ git checkout develop

And merge changes from the upstream develop branch to your local “develop” branch:

 $ git merge upstream/develop

Then, optionally, push the changes on your PC up to your GitHub online private repository.

 $ git push origin develop

Cleaning up after switching branches

Switching between two branches that are based on very different remote branches (e.g. ‘‘1.12.3’’ and ‘‘develop’’) may leave stuff from the switched-from branch in your filesystem that is not present in the switched-to branch. The following commands are useful for correcting this problem; note that running them causes all uncommitted changes in your current branch to be lost:

 $ git reset --hard HEAD
 $ git clean -f -d -x

Deleting your branch

If you’re done with the feature branch, you can delete it.

To delete the local branch, use git branch -D:

 $ git branch -D NMS-1234-feature-new-awesome-thing
 Deleted branch NMS-1234-feature-new-awesome-thing (was 732c8a5).

To delete the remote branch, the syntax is a little funky, since it’s just like pushing a branch: git push origin (local-branch) (remote-branch). In this case, you push nothing (an empty string) as the local branch:

 $ git push origin :NMS-1234-feature-new-awesome-thing
  - [deleted]         NMS-1234-feature-new-awesome-thing

Applying a patch made on one branch to another branch

If you originally made a patch against one branch and would like to apply the same patch to another branch, the git cherry-pick command can do this.

Use git log to identify the patch commit hash value and then checkout the desired branch and re-apply the patch.

 git checkout (new-branch-name, e.g. develop)
 git cherry-pick (patch hash)

Git Resources

There are a lot of other resources for help with git:

Additionally, every single git command has pretty extensive documentation. Just run git help <command> for help with a given command.

  usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]
  The most commonly used git commands are:
     add        Add file contents to the index
     bisect     Find by binary search the change that introduced a bug
     branch     List, create, or delete branches
     checkout   Checkout a branch or paths to the working tree
     clone      Clone a repository into a new directory
     commit     Record changes to the repository
     diff       Show changes between commits, commit and working tree, etc
     fetch      Download objects and refs from another repository
     grep       Print lines matching a pattern
     init       Create an empty git repository or reinitialize an existing one
     log        Show commit logs
     merge      Join two or more development histories together
     mv         Move or rename a file, a directory, or a symlink
     pull       Fetch from and merge with another repository or a local branch
     push       Update remote refs along with associated objects
     rebase     Forward-port local commits to the updated upstream head
     reset      Reset current HEAD to the specified state
     rm         Remove files from the working tree and from the index
     show       Show various types of objects
     status     Show the working tree status
     tag        Create, list, delete or verify a tag object signed with GPG
  See 'git help COMMAND' for more information on a specific command.

:woman_facepalming: You can fix me, I’m a wiki post.