Using Git for GNU Radio development

Git makes it easier for anyone to develop and contribute code to gnuradio. This article will describe how to use git with multiple repositiories so you can develop and publish your changes to gnuradio. The goal of this page is to help people manage git repositories so code may easily be shared among GNU Radio developers.

The basic idea is you clone the gnuradio git repository and maintain a public repository with your work on github, or other public git server.
In these examples, we will assume you are using github (with user name USER), as it is the most popular among GNU Radio developers. Also, we host a mirror of the main repository on github, so this is really, really simple.

Creating your local repository of GNU Radio

First, head over to the github repository of GNU Radio at https://github.com/gnuradio/gnuradio, and click the "fork" button at the top. This will automatically create a repository in your github account, called gnuradio. You basically have a copy of the official repository, but you can write to this one.

Clone the repository

Before you can do anything, you need the repository on your local hard drive ("cloning").
github will tell you the correct URL, most likely, it's something like this:

$ git clone https://github.com/USER/gnuradio.git

If you don't want to use github, you can directly clone the GNU Radio repository, but you won't be able to use some very useful features of github, such as pull requests:

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

Setting up git

If you haven't done so yet, git needs some configuring.
First, you need to set up an identity:

$ git config user.name "Your Name" 
$ git config user.email [email protected]

On github, you also need to set up an SSH key; github has excellent documentation on how to do that.

Adding remotes

A remote is a location of a repository.
You can get a list of remotes with the command

$ git remote -v
origin  https://github.com/USER/gnuradio.git (fetch)
origin  https://github.com/USER/gnuradio.git (push)

You need at least one more remote, for tracking the changes to the main repository:

$ git remote add upstream git://github.com/gnuradio/gnuradio.git
$ git remote -v
origin  https://github.com/USER/gnuradio.git (fetch)
origin  https://github.com/USER/gnuradio.git (push)
upstream        git://github.com/gnuradio/gnuradio.git (fetch)
upstream        git://github.com/gnuradio/gnuradio.git (push)

Using Someone Else's Remote Branch

Just in case this wasn't clear from the previous section:
As a collaboration tool, git can set up what's known as a remote to connect to other people's repositories. These repos, in the git distributed system, do not need to be on a single server, but can be anywhere.

Now, someone might be doing something interesting you care about. Say this is Tom Rondeau and you want to track his work:

$ git remote add trondeau git://github.com/trondeau/gnuradio.git
$ git fetch --all # This downloads all available content
$ git branch -r # Lists remote branches

Setting up tracking branches

Say you want to work off the next branch. First, you need a copy of that in your local repository -- a tracking branch:

$ git fetch --all # This downloads all available content
$ git branch -r # Lists remote branches

You can see that github already copied the next branch remotely. So, create a local tracking branch called next from the remote branch called origin/next:
$ git checkout --track -b next origin/next

Important: Never, ever commit (write) to a local tracking branch. Always use them as a base to branch off!

Updates

To make sure your tracking branches are up-to-date:

$ git checkout master # Switch to branch you want to update
$ git pull upstream master # Download the newest code from our repository

Do this anytime you start working on something.

Branching and adding own stuff

Whenever you want to work on something, create a branch for it. Say you want to implement a Heisenberg compensator into the master branch:

$ git checkout master # Go to our starting branch
$ git pull upstream master # Update
$ git checkout -b heisencomp # Create new branch from current branch (master)

Now, you can edit a new file with the fantastic code.
A very useful command to figure out the state of your repository is

$ git status
# On branch heisencomp
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       heisenberg.c
nothing added to commit but untracked files present (use "git add" to track)

So, there's a new file but git doesn't know what to do with it. So, you add it to your repository:

$ git add heisenberg.c # Marks all files that go into the following commit
$ git commit -m 'core: Added a Heisenberg compensator' # Commits the changes

Upload your changes

Your commit is only locally available now. You must manually copy this to your repository:

$ git push origin heisencomp

Which will create a new remote branch with a copy of your local branch.

Deleting branches

When you are done with the branch, delete it locally, and on the remote repository (if needed):

To delete your branch locally:

$ git branch -d heisencomp

To delete your branch from the server:

$ git push origin :heisencomp # If you think this is a weird syntax, you're not alone

Git Graphical Browsing Tools

There are some of the git graphical browsing tools such as gitk and qgit. The gitk is the original TCL/TK GUI for browsing history of Git repositories. The qgit is a QT GUI for browsing history of Git repositories, similar to gitk but with more features. tig is a curses-based GUI.

Publishing (upstreaming) your code

The most important part of the code sharing process is contributing your changes back upstream.

Pull requests

If you're on github, this is the easiest way:

  1. Fork your repo off of our gnuradio repo, then create a remote branch on github with your changes
  2. Go onto the github site, visit your repository
  3. There's a "Pull Request" button that will do all the work for you.

Tell us about your branch

If you have significant changes, you can simply email us (best way is by mailing list) and tell us about your code. All we need is the link to your remote branch.

Submitting and applying patches

Small stuff, bug fixes (and attachments for the issue tracker!) comes in the form of patches.
Going back to the previous example:

$ git format-patch HEAD~
0001-core-Added-a-Heisenberg-compensator.patch

This makes a patch for the latest commit and displays the file name. You can send this patch via email, or upload it to the issue tracker.

Someone else can apply this patch in his repository using

git apply FILENAME.patch

Converting From Old Subversion Repository to the New Git Repository

The subversion imported commits have the revision number at the end of the description in the "git-svn-id" line. For example, you can create and checkout a new branch with svn revision 10184 by doing the following.

  1. Find the commit hash from the git-svn-id.
      $ git log --grep=git-svn-id.*@10184
    
  2. Create and checkout a new branch named r10184 from the commit hash.
      $ git checkout -b r10184 cd7b07f0140ddff6
    

Other Resources

Some external resources that may be useful for learning/working with git: