Getting started with Git

Installing Git

Git is available for Linux, Mac OS X, and Windows. For Linux, it will certainly be available in your package manager. For Windows and Mac OS X, download from http://git-scm.com/downloads. If you’re using SourceTree (download from http://www.sourcetreeapp.com), Git is included.

_images/2.png

Once you’ve installed it, you should tell Git about yourself:

git config --global user.name  Andrew Davison
git config --global user.email andrew.davison@unic.cnrs-gif.fr

If using SourceTree, you can set this information in the preferences.

_images/sourcetree_preferences.png

Creating a repository

We start by introducing three concepts:

Working copy
the set of files that you are currently working on
Index
a staging area
Repository
a “database” containing the entire history of your project (all versions)
http://rogerdudler.github.io/git-guide/img/trees.png

As an example, we will use the Brian code from this paper:

Brette R, Rudolph M, Carnevale T, Hines M, Beeman D, Bower JM, Diesmann M, Morrison A, et al. (2007) Simulation of networks of spiking neurons: A review of tools and strategies. J Comp Neurosci 23:349-98

available from http://senselab.med.yale.edu/modeldb/showmodel.asp?model=83319

$ unzip destexhe_benchmarks.zip
$ cd destexhe_benchmarks
$ cp -r Brian ~/my_network_model
$ cd ~/my_network_model
$ ls
COBA.py             COBAHH.py       CUBA.py         README.txt

We’re going to take this code as the starting point for our own project, and we want to keep track of the changes we make.

The first step is to create a repository, where all the versions will be stored. This is very simple:

$ git init
Initialized empty Git repository in /Volumes/USERS/andrew/my_network_model/.git/

Nothing seems to have happened. In fact, the git init command has created a new subdirectory:

$ ls -a
.           ..              .git            COBA.py         COBAHH.py       CUBA.py         README.txt

You almost never need to care about what is in this directory: this is where Git will store all the information about the repository.

With SourceTree, you create a new repository via the File menu:

_images/sourcetree_new_menu.png _images/create_new_repository.png

Adding files to the repository

Now we need to tell Git which files are part of our project. On the command line:

$ git add *
$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   COBA.py
        new file:   COBAHH.py
        new file:   CUBA.py
        new file:   README.txt

In SourceTree, we can see our files listed as “Unstaged”

_images/sourcetree_initial.png

When we check the boxes, they are listed as “Staged”.

_images/sourcetree_staged.png

Committing changes

These files are now queued or staged to be added to the repository, but they are not yet there. Nothing is definitive until we make a commit (also known as a “check-in”). Via the command line:

$ git commit -m "Initial version, downloaded from http://senselab.med.yale.edu/modeldb/showmodel.asp?model=83319 on July 3rd 2014"
[master (root-commit) b0c5d2c] Initial version, downloaded from http://senselab.med.yale.edu/modeldb/showmodel.asp?model=83319 on July 3rd 2014
 4 files changed, 259 insertions(+)
 create mode 100644 COBA.py
 create mode 100644 COBAHH.py
 create mode 100644 CUBA.py
 create mode 100644 README.txt

Via SourceTree; in both cases we have to give a short message summarizing what changes were made.

_images/sourcetree_commit0.png

Viewing the history of changes

The log command lists all the different versions stored in the repository. For now, of course, we have only one:

$ git log
commit d66ee50a3975d6e46be27055bf0ecb4d8091c082
Author: Andrew Davison <andrew.davison@unic.cnrs-gif.fr>
Date:   Thu Jul 3 15:36:45 2014 +0200

    Initial version, downloaded from http://senselab.med.yale.edu/modeldb/showmodel.asp?model=83319 on July 3rd 2014

In SourceTree, we use the “Log” view.

_images/sourcetree_log.png

Now let’s run the code:

$ python COBAHH.py
Network construction time: 0.814524173737 seconds
Simulation running...
Simulation time: 45.7264661789 seconds
126014 excitatory spikes
29462 inhibitory spikes

This pops up a window with the following figure:

_images/brian_figure.png

We’d prefer to save the figure to a file for further use, rather than work with the model interactively, so let’s change the last lines of the script from:

plot(trace.times/ms, trace[1]/mV)
plot(trace.times/ms, trace[10]/mV)
plot(trace.times/ms, trace[100]/mV)
show()

to

plot(trace.times/ms, trace[1]/mV)
plot(trace.times/ms, trace[10]/mV)
plot(trace.times/ms, trace[100]/mV)
savefig("COBAHH_output.png")

Seeing what’s changed

Now if we run git status we see:

$ git status
On branch master
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:   COBAHH.py

no changes added to commit (use "git add" and/or "git commit -a")
$ git diff
diff --git a/COBAHH.py b/COBAHH.py
index d9eda02..22bcf1a 100644
--- a/COBAHH.py
+++ b/COBAHH.py
@@ -93,4 +93,4 @@ print Mi.nspikes,"inhibitory spikes"
 plot(trace.times/ms,trace[1]/mV)
 plot(trace.times/ms,trace[10]/mV)
 plot(trace.times/ms,trace[100]/mV)
-show()
+savefig("COBAHH_output.png")

This is even easier in SourceTree: we automatically see a list of files that have been changed, and a colour-coded view of what has changed.

_images/sourcetree_firstchange.png

Now let’s commit the changes...

$ git add COBAHH.py
$ git commit -m 'Save figure to file'
[master 1c5d37f] Save figure to file
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git log
commit b535fafe86c0caeb2b38ef30f0e96c9904ff56d6
Author: Andrew Davison <andrew.davison@unic.cnrs-gif.fr>
Date:   Thu Jul 3 15:47:45 2014 +0200

    Save figure to file

commit d66ee50a3975d6e46be27055bf0ecb4d8091c082
Author: Andrew Davison <andrew.davison@unic.cnrs-gif.fr>
Date:   Thu Jul 3 15:36:45 2014 +0200

    Initial version, downloaded from http://senselab.med.yale.edu/modeldb/showmodel.asp?model=83319 on July 3rd 2014
_images/sourcetree_commit1.png

... and look at the log again:

_images/sourcetree_log1.png

We see both versions, with commit messages, the author name and the date.

Switching between versions

To switch between versions (you should not do this if you have modified any of the files - commit your changes first), use git checkout:

$ git checkout d66ee50a3975d6e46be27055bf0ecb4d8091c082
Note: checking out 'd66ee50a3975d6e46be27055bf0ecb4d8091c082'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at d66ee50... Initial version, downloaded from http://senselab.med.yale.edu/modeldb/showmodel.asp?model=83319 on July 3rd 2014

This will change the files in your working copy to reflect the state they had when you committed that particular version. (You can ignore the message about ‘detached HEAD’ for now). We can check that our working copy has really changed by looking at the end of the COBAHH.py file: we see that we are back to using the “show()” command instead of “savefig()”.

$ tail COBAHH.py
run(1000*msecond)
duration=time.time()-start_time
print "Simulation time:",duration,"seconds"
print Me.nspikes,"excitatory spikes"
print Mi.nspikes,"inhibitory spikes"

plot(trace.times/ms,trace[1]/mV)
plot(trace.times/ms,trace[10]/mV)
plot(trace.times/ms,trace[100]/mV)
show()

Using git branch we can see which version we are currently using:

$ git branch
* (detached from d66ee50)
  master

In SourceTree, just click on the version you want to use. This will add a label “HEAD” to show you which version is currently checked out.

_images/sourcetree_checkout_v0.png

To switch to the most recent version, use git checkout master

$ git checkout master
Previous HEAD position was bfb2cd7... Initial version, downloaded from http://senselab.med.yale.edu/modeldb/showmodel.asp?model=83319 on July 3rd 2014
Switched to branch 'master'
$ git branch
* master

Giving informative names to versions

Remembering the version number for a particular version of interest (for example, the version used to generate a particular figure in your manuscript) can be difficult. For this reason, the git tag command can be used to give descriptive and memorable names to significant versions:

$ git tag Figure-1

You can now switch to a tagged version using the tag name:

$ git checkout Figure-1

In SourceTree, just right-click on the version you want to tag.

_images/sourcetree_tag.png

The tag is now shown in the log.

_images/sourcetree_tag2.png

Recap #1

So far, we have learned how to:

  • Create a repository
  • Add files to a repository
  • Commit changes
  • Move your code-base backwards and forwards in time

These operations are so easy and so useful that there is no reason not to use them for almost any work you do as a scientist. Any time I start a new project, whether writing code or writing a paper with LaTeX, I now run git init as soon as I’ve created a new directory for the project.