Working on multiple computersΒΆ

As an extension of the idea of backups, version control systems are excellent for keeping code in sync between multiple computers. Suppose you have a copy of your repository on your laptop, and you were working on the code in the airport.

(laptop)$ git diff
diff --git a/CUBA.py b/CUBA.py
index 84f75be..2bd2fa1 100644
--- a/CUBA.py
+++ b/CUBA.py
@@ -72,4 +72,4 @@ print "Simulation time:",duration,"seconds"
 print Me.nspikes,"excitatory spikes"
 print Mi.nspikes,"inhibitory spikes"
 plot(M.times/ms,M.smooth_rate(2*ms,'gaussian'))
-show()
++savefig("CUBA_output.png")
(laptop)$ git add CUBA.py
(laptop)$ git commit -m 'CUBA script now saves figure to file'

The log on your laptop now looks like this:

(laptop)$ git log
commit 4f568a24ffc4d8695d666bec90c5533dc4db3206
Author: Andrew Davison <andrew.davison@unic.cnrs-gif.fr>
Date:   Thu Jul 3 16:10:24 2014 +0200

    CUBA script now saves figure to file

commit 4b18663c05fd120e101aa14bfe8abea65f7c1700
Author: Andrew Davison <andrew.davison@unic.cnrs-gif.fr>
Date:   Thu Jul 3 15:50:06 2014 +0200

    Save figure to file

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

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

Meanwhile, you’ve started running some simulations on a local cluster, and you’re investigating the effect of changing some parameters:

(cluster)$ git diff
diff -r 416ac8894202 CUBA.py
--- a/CUBA.py       Thu Jul 12 14:28:19 2012 +0200
+++ b/CUBA.py       Thu Jul 12 15:19:49 2012 +0200
@@ -25,9 +25,9 @@
 import time

 start_time=time.time()
-taum=20*ms
-taue=5*ms
-taui=10*ms
+taum=15*ms
+taue=3*ms
+taui=5*ms
 Vt=-50*mV
 Vr=-60*mV
 El=-49*mV
(cluster)$ git add CUBA.py
(cluster)$ git commit -m 'Changed time constants in CUBA model'
(cluster)$ git log
commit 5a13e7c0ad7a21a22e91d2359767a5429f0b0c54
Author: Andrew Davison <andrew.davison@unic.cnrs-gif.fr>
Date:   Thu Jul 3 16:14:01 2014 +0200

    Changed time constants in CUBA model

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

Now the repositories on the two machines are out of sync. The first two commits are the same on both, but the third is different on the two machines. Note that the first two have the same hexadecimal version number on both machines, but that the third has a different hex number:

Laptop Cluster
0:d66ee50 0:d66ee50
1:b535faf 1:b535faf
2:b1092b1 2:5a13e7c

So, how do we get the two machines in sync? This can be done from either machine. Here, we’ll do it from the laptop.

(laptop)$ git pull ssh://cluster.example.edu/my_network_model
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /Volumes/HBP_1GB/my_network_model2
 * branch            HEAD       -> FETCH_HEAD
Auto-merging CUBA.py
Merge made by the 'recursive' strategy.
 CUBA.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Note that git pull is equivalent to running git fetch followed by git merge. “Fetch” pulls changes into the local repository, but does not change the working copy, i.e. it does not change your files. “Merge” is the part that changes your files.

Even though we made two different changes to the same file on different machines, Git is clever enough to realize that we’d edited different parts of the file CUBA.py, it can automatically merge the two changes. If there was a conflict (if we’d edited the same lines on both machines), the merge would fail and we’d have to manually merge the files (see below).

To do this in SourceTree, we just click the Pull button, then select where we want to pull from:

_images/sourcetree_pull.png

Now we can see the full history, with all changes:

(laptop)$ git log
commit 0d285eaf5473c63bc32e7a45771cfbcddd54d6be
Merge: b1092b1 5a13e7c
Author: Andrew Davison <andrew.davison@unic.cnrs-gif.fr>
Date:   Thu Jul 3 16:33:42 2014 +0200

    Merge branch 'master' of /Volumes/HBP_1GB/my_network_model

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

    CUBA script now saves figure to file

commit 5a13e7c0ad7a21a22e91d2359767a5429f0b0c54
Author: Andrew Davison <andrew.davison@unic.cnrs-gif.fr>
Date:   Thu Jul 3 16:14:01 2014 +0200

    Changed time constants in CUBA model

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

This is much clearer in SourceTree, which presents a graph with coloured lines, showing the process of development.

_images/sourcetree_after_merge.png

To complete the sync, we now pull the changes to the cluster:

(cluster)$ git pull ssh://my_laptop.example.edu/my_network_model
From ssh://my_laptop.example.edu/my_network_model
 * branch            HEAD       -> FETCH_HEAD
Updating b2351e1..b2405ed
Fast-forward
 CUBA.py | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

In SourceTree, notice that the label “cluster/master” is now at the same version as the local “master”:

_images/sourcetree_after_merge-push-pull.png