GitLabTM[1]#

Objectives📍

  • What is GitLab

  • local vs. remote repository

  • push

  • pull

  • clone

  • fetch

  • merge

  • Merge conflict between your local and remote repository

As mentioned in the introduction, GitLab is a platform for collaborative code development. Everything we did so far in this Git course we did on our local machine and nobody has access to our project. Because collaboration is a major part in science, we need to be able to have a centralized workflow without needing to send all of our files back and forth with emails. This is very cumbersome and also no one ever knows what is the current version because between sending an email and actually getting feedback some time will pass. By putting your project on a centralized repository and giving your collaborators access to this repository, they will:

  • always see the latest version of the project

  • see the development stream of the project (aka commit history)

  • they can retrieve the project and make changes and either commit them directly or ask you if you want to incorporate those changes (merge request)

  • they can comment on it

  • they can open a discussion (issue)

  • and much more…you can even do project management on gitlab if you want to

All we have to do is to set up a remote repository on gitlab and synchronize our local work with this remote repository. First we need some more vocabulary:

More Git vocabulary

  • git push: synchronize your local repository with the remote repository by pushing changes in the local repository into the remote repository

  • git pull: synchronize your local repository with the remote repository by pulling changes from the remote repository into the local repository

  • git clone: this gives you an exact copy of a remote repository on your local computer

  • git fetch: fetching the latest version from the remote repository into your staging area

Task 9

  • go to gitlab.com and log in

  • click on “new project” –> “create a blank project”

  • give the project the name choice_rtt

  • under “Project URL” select your name

  • select “public” as visibility level

  • uncheck the box “Initialize with a README”

We are now presented with this page:

first step gitlab

This page basically presents you with different options on how to fill your gitlab repository. Because we already have a git repository, namely our choice_rtt project on our local machine, we need the last option “Push an existing git repo”.

Task 10

Follow the instructions given by gitlab for “Push an existing git repo”. After you did all of this, refresh the page.

Through the command git push --set-upstream origin --all we set up remote branches to track our local branches. The remote branches have the same names as our local branches but have a origin/... added. That’s how git can distinguish local and remote work.

Local vs. Remote Repository

The local and the remote repository are two different things. You need to actively initiate the synchronization between the two (push-pull).

One important thing to remember for understanding how the synchronization between git and GitLab works is:git makes you think you work on the same branches locally and remotely: they follow the same working stream and share the same version history, you don’t need to switch between branches. But technically it’s handled as if it’s different branches: main vs. origin/main. This is necessary for the communication between local and remote repository to enable functions like git merge and git diff.

Let’s take a look at how the main page of a gitlab repository looks like:

gitlab overview

  • at the top left we can see which branch of the project is currently displayed in the remote repository. When you click on it, you can change the branch and the files shown will automatically update according to the state of the files on this other branch

  • on the top right you’ll find the code for the repository which you (and others) will need to connect to the gitlab repo, for example for cloning the repository

  • the marked part in the middle shows a commit message. Here it becomes evident why you should not just blindly add and commit everything at once. Because here you can see that your commits are bound to your files. If you always do git add . and commit, all your files will have the same commit message so the benefit of seeing at first sight what was last changed in this file is lost

  • Lastly, you can see that README files in your repository will always be automatically rendered on the main page of the repo. This is another reason why you should have a nice and informative README file for your project

gitlab in VSCode#

Now that we have our project on gitlab, VSCode automatically noticed that we have a remote repository involved. When you click on the git graph on the left bar you can see the remote repository under SOURCE CONTROL REPOSITORIES and when you click on the arrow next to commit you can see that now you also have the option to commit & push with one click.

gitlab as an Add-on on OSF#

On Monday we created a project on OSF for our choice_rtt project. Of course, we want to share our code and data there. Because we do have everything in a public gitlab repository we can simply create an Add-on for gitlab on our OSF project and all the files will be added to the OSF repo. The advantage in having both, gitlab and OSF (or another data repository) is that OSF can give you a DOI, gitlab cannot. Also, in our case we can put the data on gitlab, because we have very little data and small files. However, gitlab is NOT a data repository but a code development platform. So, if you have lots of data you will need to have it separately. E.g., have the data on OSF and code on gitlab and combining it via the gitlab Add-on on OSF with just a simple click.

Task 11

Go to the OSF project you created on Monday and add the GitLab repository.

Working collaboratively#

Because gitlab is the best to learn via working collaboratively, this is what we will do!

Task 12

  • Find a partner. Choose one of your gitlab repos to be the one you will both work on during the rest of this session

  • Add the person who is not the owner of the repository as a project member with the role “Developer”

From now on the owner of the repository is called owner and the collaborator is called developer.

  • developer clones the repository:

    • navigate with the terminal to your desktop

    • got to the owners gitlab repo by searching for their name. Click on the respective repo.

    • click on the code button on the upper right

    • copy the “clone via ssh”

    • type in your terminal git clone repo-link-you-just-copied

  • developer opens a file, makes a change, adds and commits it

  • developer pushes the change to the repo by doing git push repo-link-you-just-copied

  • owner refreshes gitlab repo to see if the change was updated

  • owner needs to incorporate the changes from the remote repo into the local repo: git pull repo-ssh-link

  • owner opens a file, makes a change, adds and commits it

  • ownerpushes the change to the repo by doing git push

git clone

  • if you clone a repository it will only clone main

  • to get the other branches of the remote repo:

    • git branch –a shows you all available branches (e.g., origin/eyetrack)

    • git checkout eyetrack: creating a local Branch and git automatically detects that there is a remote sibling branch

    • git output: branch ‘Party2’ set up to track ‘origin/eyetrack’

    • repeat for every branch you want to have locally available

git pull

git pull means you are pulling the version from the remote origin branch directly into your working directory which also means an automatic merge of remote and local branch. It therefore updates your git repo AND your working directory in one command.

git fetch

  • git fetch means that git is updating the remote branch in your local git repo called origin/main where it contains the latest remote version of the project. It is not updating your local branch main.

  • that’s why you have to (or can) merge: your corresponding local branch main in your working directory contains a different version of the project than the remote branch origin/main

  • that’s also the reason why you can do git diff: it compares our main branch in the working directory with the origin/main branch in the git repo

  • git fetch is helpful if you want to inspect the changes from the remote repository first before incorporating them locally. Because maybe a merge conflict is hiding in the remote version

Summary gitlab workflow#

git commands [2]

Merge conflict between local and remote repository#

Like mentioned previously, merge conflicts are not unusual and happen more often when you work collaboratively. It is very likely that your collaborator works on the project at the same time as you and sometimes those changes overlap. This is why we want to practice how to solve a merge conflict with the remote repository.

Task 13

  • work with your partner from the previous task again

  • developer does a git pull

  • developer and owner both make a change to the project at the same spot, e.g., modify the same line in the instructions

  • developer does a git push first

  • then owner does a git push

  • owner should get a message saying:

rejected! error: failed to push some refs to ‘repo url’
hint: Updates were rejected because the remote contains work that you do not have locally. This is usually caused by another repository pushing to the same ref. You may want to first integrate the remote changes (e.g., ‘git pull …’) before pushing again.

This error message is not due to the merge conflict but due to the fact that owner made one more commit to the commit history and therefore expanded the commit history. As you both work on the same branch and git works in a linear way, git cannot put two commits at the same place but only one after another. So git expects you to have the latest version with all commits before you make another one. So, you will also receive this message when you don’t have a merge conflict but simply didn’t pull the latest version first.

Task 14

  • work with your partner from the previous task again

  • owner does a git pull

  • owner should get a merge conflict message like the one we saw before

  • owner needs to resolve merge conflict (we learned how to do that already, yeah!)

  • owner can now do a git push