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.
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.
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.
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.
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.
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!
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.