Git
What is git? And why would you want to use it?
Git is a version control system. In essence, it is a piece of software that handles changes to source code, and helps manage collaborative software development.
Git was initially developed by Linus Torvalds to be used as the version control system for the core components of the Linux family operating systems. It launched in 2005, and has since risen to become the most commonly used version control system in the world.
One way to get a nice introduction into why and how to setup git within RStudio is an example here called 'happy git with R'.
How does git work?
Files in git are stored in what is called repositories. These repositories, or repos for short, are file areas where changes to files are tracked. When users upload a file to the repository, the repository makes note of how the file has changed, what these changes were, and who uploaded them. This is written to a log for future reference, and can be used to go back to previous versions of the file or the repository.
Users upload files by adding them to a commit, and then pushing that commit to the server. This is called the add-commit-push cycle, and is one of the core workflows of git. When an upload is pushed, it is synchronized with the server and added to the repository. It is also added to the log of commits that have been pushed, and thus the changes to the repository are catalogued.
Git @ SESLINK
The SESLINK project uses Bitbucket as our git provider. Because of that, you will need a Bitbucket account to access the SESLINK repositories. Ideally our members should also apply for an academic license at bitbucket. This removes many of the restrictions on free accounts, and gives us more freedom to use the Bitbucket service. When applying for an academic license you will need to provide a bit of extra information, mostly in the form of the address of the department. Use the following:
Stockholm Resilience Center Kräftriket 2B ZIP: SE-10691 City & state/province: Stockholm
Once the application is submitted you should receive your academic license within a few days. You can, however, start working before you receive it.
In the SESLINK git we have a two level stucture. Each model produced by the group is set up as a project in Bitbucket. Within each of these projects there are repositories, where each repository represents a version of them model. This could for example be variations of a model sent to different journals, or just side projects.
The SES-TEST project
We have a project called SES-TEST, which is a testing project where people can play around with the various functions in Bitbucket. This project also has a repository connected to it, called ses-test. See below for instructions on how to access it.
Using git
Installing git
Download git from the downloads section of the git website. Pick the version for your platform and install the file. Just click through the installer and go with any default options
Cloning repositories
Accessing the SESLINK repositories requires that you clone the repository to your local computer, which creates a folder with a local copy of the repository. Although there are graphical utilities available these seem to cause some issues, and because of that managing git is done preferably done using the command line (Command Prompt in Windows, Terminal in MacOS X). If you are previously unfamiliar with how to use the command line, here's a guide for Windows and one for MacOS X.
Once you've opened your command line utility, change directory to where you want to keep your repositories. From here, we'll use the git clone command to clone the repository. The basic syntax of this command is:
git clone https://USERNAME@bitbucket.org/seslink/REPOSITORY.git
In the example above, USERNAME is your username at bitbucket, and REPOSITORY is the repository that you want to clone. For example, if the user hwarpefelt wants to clone the ses-test repository they would issue the following command:
git clone https://hwarpefelt@bitbucket.org/seslink/ses-test.git
If they instead wanted the CP-norm repository, the command would be:
git clone https://hwarpefelt@bitbucket.org/seslink/CP-norm.git
We'll start out by cloning the ses-test repository, which is a testing repository for the SESLINK git. This is a space where we are free to play around and nothing of worth is kept. You cannot break anything of importance in this repository, so feel free to experiment. We'll clone the repository using the git clone command, and should see output similar to this:
$ git clone https://hwarpefelt@bitbucket.org/seslink/ses-test.git Cloning into 'ses-test'... remote: Counting objects: 58, done. remote: Compressing objects: 100% (50/50), done. remote: Total 58 (delta 17), reused 0 (delta 0) Unpacking objects: 100% (58/58), done. Checking connectivity... done.
If you are issuing the command for the first time you will be prompted to provide a username and password for bitbucket.
The exact number of objects in the example above aren't important at this stage, but if we list the contents of the directory we'll see that we now have a folder called ses-test in our folder. By changing into that we can now access the ses-test repository.
This same procedure can be repeated for any repository you wish to access within the SESLINK bitbucket. Simply put the name of the repository between the final slash (/) and the .git suffix, as shown above.
Updating a repository
Since multiple people may be working against the same repository, we might need to update our local copy. This is done using the pull command:
git pull
If you are already up to date, git will tell you. Otherwise it will download changes and try to merge them to your local copy. This may, however, cause conflicts to appear if multiple people have uploaded changes to the same files that you have changed in your local copy. See below for information on how to handle conflicts.
Adding files to a repository
In order for files to be stored in a git repository they need to be added and uploaded to it. This is done via what is called the add-commit-push loop.
Files can be added to a repository using the add command:
git add FILENAME
Thus, if we wish to add the file model.nlogo we would issue the command:
git add model.nlogo
It is of course possible to add several files at once, for example:
git add model.nlogo test test2
or several files using wildcards, for example all files with names ending in .nlogo:
git add *.nlogo
After we've added the files we want to upload, we need to commit our add to the repository using the commit command:
git commit -m "Added the model"
Note the -m argument to the commit command. This adds an inline comment. If you fail to provide this, git will launch you into an editor to provide a comment. By default, this is the vim editor. See below for instructions on how to escape the vim trap.
When you've issued the commit you should see a message similar to this:
$ git commit -m "Added a test file"
[master 1190453] Added a test file
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 model.nlogo
You can then upload the actual changes to the repository using the push command:
git push
You should see results similar to this:
$ git push Counting objects: 2, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (2/2), 246 bytes | 0 bytes/s, done. Total 2 (delta 1), reused 0 (delta 0) To https://bitbucket.org/seslink/ses-test.git f21211e..1190453 master -> master
You may also get an error message saying that you tried to do an out or order push. That means that your repository needs to be updated before you can upload your changes. If so, just issue the pull command to update you repository.
Help! I'm stuck in some kind of strange program!
If you see a screen similar to this:
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Your branch is up-to-date with 'origin/master'. # # Changes to be committed: # new file: model.nlogo
You probably forgot to add a comment to your commit, and now you've ended up in vim. If you end up in vim, simply press the i key to enter insert mode and input your comment. Then press the Escape key to exit insert mode, and type :wq to tell vim to save the changes and quit.
As a side note vim is a extremely powerful and versatile editor, and a very good thing to know if you're venturing into the world of software development and UNIX systems. This online tutorial will help you get started.
Handling conflicts
If git detects a conflicting edit in a file, it will mark the file as conflicted. It will then attempt to automatically resolve the conflict, but if it is unable to do is it will require that the a user resolves the conflict before pushing their work to the repository. This is most easily done by editing the conflicting file, and then using the add-commit-push procedure to upload a revised version to the repository.
The most common reason for a conflict is that two people have edited the same line in a file. Let's say that we have this original file:
def is_positive(arg):
if(arg >= 0):
print("Number is positive!")
else:
print("Number is negative!")
This code is slightly wrong, since it will say that the number is negative if it's 0. Now, let's say that A and B both try to fix the code. This is A's version:
def is_positive(arg):
if(arg >= 1):
print("Number is positive!")
else:
print("Number is negative!")
And this is B's attempt:
def is_positive(arg):
if(arg > 0):
print("Number is positive!")
else if (arg == 0):
print("Number is zero!")
else:
print("Number is negative!")
If we look at the third line, we'll see that A set it to be if (arg >= 1):, and B if (arg > 0):. These changes cannot be automatically merged since they are conflicting, and thus someone will need to edit the file to reflect the correct change. In this case, going with B's solution is probably better since it's also formally correct. Also, note that the other changes done in B's code will not cause conflicts, since git will be able to understand that this is an addition instead of an alteration.
Collaborating using Git
The SESLINK team on Bitbucket has support for issue tracking on a per-repository basis. Since each model is in its own repository, there will also be an issue tracker assigned to that particular repository.
When you encounter problems with a model, please use the issue tracker to file an issue with it rather than e-mailing the model owner. This will notify the owner of the model, and also create a history of issues that the model has had, and how these can be resolved. Additionally, it makes working with models in teams much easier since everyone can see the whole flow of communication.
For instructions and exercises on how to use the issue tracker, please see slide 8-9 in Henrik's presentation from the 2016 retreat.
Further reading
This page only provides a basic introduction to git, aimed at providing readers with the fundamentals they need to get started and able to experiment on their own. If you want to know more about git, Henrik's presentation from the 2016 retreat on Utö is available as a PDF in the project's Google Drive.
Graphical git clients
Although this tutorial uses the command line, there are several graphical clients for git.
Windows
- TortoiseGit, similar to TortoiseSVN or TortoiseCVS
- Git extensions
- SourceTree
MacOS X
Linux and other *nixes
- gitk - a very simple git repository browswer
- cola - The highly caffeinated Git GUI
- Giggle - gitk on GTK+
- gitg - a GNOME gui client
A full list of more GUIs for all platforms can be found git GUI Clients
'Distributed is the new centralized'
Cheat sheets and tutorials
- Henrik's tutorial PDF from the 2016 retreat
- basic git commands
- git - the simple guide, a cheat sheet
- Try Git, an online tutorial for git
- OpenVIM, a tutorial for the vim editor
- git-scm, an everything you want to know-have-download-and-discuss-about-git site