In the previous section we created our own bare repository in the directory server/test-git.git. We used this bare repository as our remote origin in both you/test-git and colby/test-git. We assumed that both you and Colby had access to this directory allowing server/test-git.git to act as a remote with which you could collaborate.

Since it is not so easy to share a directory with other collaborators, there exist Git platforms that allow you to share Git repositories to collaborate. Various alternatives exist such as GitHub and GitLab. GitLab allows you to install it on your own server, which is what Fab City Hamburg did, so this primer is hosted on https://gitlab.fabcity.hamburg. Note that this is a different GitLab instance than the GitLab instance https://gitlab.com. In particular, the usernames and passwords for Fab City Hamburg’s GitLab instance cannot be used on the “main GitLab instance” hosted on https://gitlab.com and vice versa.

You can consider these platforms to provide you with a web interface to Git repositories, but in practice they offer more functionality. Most notably they provide issue tracking and continuous integration, two things that help organize development and that we discuss below. Let’s first discuss how collaboration works via these platforms. We use as an example the very repository that hosts this primer on Fab City Hamburg’s GitLab instance. We will explain everything in terms of GitLab but also mention differences with GitHub.

Collaboration

To collaborate with a Git platform, it is required to have an account there. So, if you want to collaborate on this primer, it is necessary to register an account and log in.

Issue tracking

One of the easiest ways to contribute to Git repositories is by means of creating issues. By the way, GitLab calls Git repositories projects and GitHub calls them repositories. In principle any user can open an issue on a Git repository and typically an issue has a title and a description explaining to other users what the issue is. Examples of issues are bugs in software, requests for new features, a typo in text, mentioning license violations, etc. As you can see, an issue can be very broad. The issue tracker for a Git repository helps developers to organize the issues, such as prioritizing them, categorizing them, or most commonly, start a discussion with other developers and users.

The person creating an issue does not necessarily have to work on the issue. In fact, most often, issues are picked up by others and assigned to persons who can resolve the issue. It is common that issues are related to other issues and Git platforms provide means to relate issues. A common workflow is that after discussion of the issue, the issue is assigned to a core developer who will work on the issue and close it. We will discuss the complete workflow below, but an important message of this primer is, that simply creating issues on open source project, software or hardware, is already a great way to collaborate and contribute.

Contributing as a developer to Git repositories

Although issue tracking is a lightweight way to collaborate, also for non-developers, it does not explain how users can actually contribute in terms of development. As a developer on a Git platform, we can make a distinction between two roles: a core developer or a contributor. Core developers are persons that have direct access to a Git repository, meaning that they can directly push commits to the Git repository. To give an example, you and Colby could both directly push to server/test-git.git which makes you both core developers of this Git repository.

Contributing as core developer

Core developers typically have a clone of the repository on their own computer. They will most likely react on an issue that they or others have created. After discussion in the issue that clarifies what has to be done, a core developer will most likely create a merge request (or in GitHub speak, a pull request). Typically for this merge request a topic branch is created automatically. Core developers pull the new branch in their own local copy on their computer and make changes in this topic branch until the problem is resolved. The developer pushes the changes to the origin remote and can then mark the merge request as ready. The Git platform then provides a way to merge the branch associated with the merge request into the main branch. Often this automatically closes the issue that is associated with the merge request.

Contributing as a non-core developer

In Git platforms, every user always has the role contributor and can always contribute to repositories or projects, albeit in a different way than directly pushing: Users that want to contribute to a project are expected to fork the project. This means that a copy of the whole history of the project is created in your own account on the Git platform. You can then clone your fork onto your own computer and start developing there. You can push to the repository on your account (because you own it) but you cannot push to the repository from which you forked. Let’s give an example:

This primer has the project name oss-for-osh-primer and is located in the group software. Therefore its URL is https://gitlab.fabcity.hamburg/software/oss-for-osh-primer. Suppose Colby joins https://gitlab.fabcity.hamburg with username colby and wants to improve this incomprehensible primer. He can then fork the repository by clicking on the fork button on the main project page of the primer, which creates https://gitlab.fabcity.hamburg/colby/oss-for-osh-primer (after selecting Colby’s own name space). Git platforms keep track of forked projects and on Colby’s primer project page Colby can see that this is a fork of software/oss-for-osh-primer.

Colby can now clone the repository on his or her own computer with:

git clone https://gitlab.fabcity.hamburg/colby/oss-for-osh-primer.git

This repository will automatically have remote origin configured to be:

https://gitlab.fabcity.hamburg:colby/oss-for-osh-primer.git

Typically, we call the original repository, so software/oss-for-oss-primer, the upstream repository and we can configure the upstream repository as a remote as well:

git remote add upstream https://gitlab.fabcity.hamburg/software/oss-for-osh-primer.git

This allows us to track changes of the upstream repositories as well:

git fetch upstream

The fetch command is similar to pull but while pull updates your current branch to a remote branch if the current branch tracks the remote branch, fetch will only fetch the changes from the remote not updating any local branch. By adding the upstream remote, you can synchronize your origin remote with it. So, having the remotes upstream and origin means that if changes are made on upstream by other developers, you can update origin with those new changes.

Although Colby is not a core developer, Colby can create a topic branch in his or her copy of the repository (origin) and improve the primer in that branch. An example is making the branch make-comprehensible on the local computer and improve the primer in this branch. When satisfied the work can be pushed to remote origin which is colby/oss-for-osh-primer, but it is not possible to push to upstream (software/oss-for-osh-primer) because Colby doesn’t have (push) access to this repository.

So, how can Colby make sure that the changes are merged in upstream, so software/oss-for-osh-primer? Colby can create a new merge request (or pull request in GitHub terms) based from the repository Colby’s account, so colby/oss-for-osh-primer. In the merge request Colby can specify which branch to merge which is make-comprehensible. More notably, it is also necessary to specify in which branch you want to merge, the target branch. This target branch can be a branch of the original repository, the upstream and when you complete this merge request, the merge request is registered with the original repository allowing it to be reviewed by core developers and merged in. So, Colby can choose as target branch main from software/oss-for-osh-primer and by completing the merge request, the core developers of software/oss-for-osh-primer will be notified that someone has made a contribution and would like to merge this contribution in.

This workflow may seem complicated, but it means that anyone can contribute to repositories without having to give direct (push) access to repositories. Typically, these outside merge requests are reviewed by the public, that may lead to requests to the author to change/improve some things. If the work is deemed a good contribution, the core developers typically merge the changes in, meaning that a new contribution to the project has been made!

Access to repositories

Git platforms allow access to repositories in different ways. For public repositories, it is possible to clone repositories via the HTTPS protocol. A typical example is:

git clone https://gitlab.fabcity.hamburg/software/oss-for-osh-primer.git

For private repositories, this is also possible but it requires you to fill in your username and password when cloning, pulling, pushing. Since this is not so user friendly, it is also possible to set up a public/private key pair via the SSH protocol. A public/private key pair provides you with two keys, a public one that you can give to anybody, and a private one that you keep private. You store your public key in your account on the Git platform, and with this public key the Git platform verifies on each access if your computer has the private key that is associated with the public key.

You may already have a private/public key pair which will most likely be stored in $HOME/.ssh/ in the files id_rsa (the private key) and id_rsa.pub (the public key). If not, you can generate it with the following command, and I would suggest to leave the passphrase empty.

ssh-keygen -t rsa -b 4096

An example of Jamie performing this command:

/home/jamie                                                                     
$ ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/jamie/.ssh/id_rsa): 
Created directory '/home/jamie/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/jamie/.ssh/id_rsa
Your public key has been saved in /home/jamie/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:0OR3eH9Hu677GTpVg9VgSj+UjpQ8Re/J2Ugh+8Ayrc8 jamie@computer
The key's randomart image is:
+---[RSA 4096]----+
|        .  .o+Bo.|
|       +   ==B.+.|
|      . o =.O+* o|
|       . . *.*o**|
|        S .   +=B|
|           o   oo|
|            E .o |
|             .o o|
|             +=+ |
+----[SHA256]-----+

/home/jamie                                                                     
$ 

To register your public key on a Git platform, go to the preferences or settings of your account and search for SSH. You can then show your public key with the following command:

cat ~/.ssh/id_rsa.pub
/home/jamie                                                                     
$ cat ~/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDOj7PD8IIomIKtLv8bkumtyIgXNcda5ZSGHpDNluIIZoG0Vcjzk0YhKTEA4Fio+LsCk1xYUDPhAK+xgWHnImZyLJ5CUNeTV3tnLNA0hH8RR9UlmmF3qisdqrkButYBiSQBhbUtaeQaNM7XJTbDDN0utNtJtMZKgKH4XTzR51S+L8hekwsGJ267VhDfyTGbz9tEf5DKm7mGVvGQUwqQ7N95ra4PNVdX28rZOtN8wubZ9IsF6CMKvHcKDZY5YVdCyEfnenbiVndTX6Zqr1B71wN/BSuL8lg+C9cTbQMDMZj9JdST8qvoX4dX3ihPyILg29gBGzANMNCL+uXeIxHbAxjaQx5oAQ/EdD2LjXn6Lwd4bmp9qVK3AFhYhGRTbLsmN2PQxKapzS5TPJeoA1P/SCgqju/CxwxFqF2CqfNqksm0lV/PavZ6QFT9LKNQbthGfTXDTjZMGzyxWyfnCqMsufiDWemyuohGfArtSu5xV/MRLdLzCNsHSeWBqhCFNWE2a/ANXiQP6Zgsurn5kv+TcnzbeT9icEdOakDClS0bvaj0Y56qi6AxPyG1NNhAnGFOzCf3JeTnmCmzEsJ84V7xgvcoEaNcLLq8fy4Any03K4jCkX2ec8BX0GiQdUggbm7r6vFsCsYEeCnZGoh2r+fHZZaplx909zEAKvZ18wYkScjsgQ== jamie@computer

/home/jamie                                                                     
$ 

You can copy paste that text into one of the forms in your settings page and store it. You can now clone, push to and pull from repositories without password using the following URL that chooses the SSH protocol:

git clone git@gitlab.fabcity.hamburg:software/oss-for-osh-primer.git

Notice the slightly different syntax after gitlab.fabcity.hamburg: For using SSH, there is a : after the hostname, for using HTTPS, there is a / after the hostname.