Attribution: The content of this page is largely taken from the GitHub-blog.
Git is very flexible in organizing a distributed development team. We use a so called Forking workflow.
The following explanation is taken from an in-depth article on that model:
Instead of using a single server-side repository to act as the central codebase, it gives every developer a server-side repository. This means that each contributor has not one, but two Git repositories: a private local one and a public server-side one.
The main advantage of the Forking Workflow is that contributions can be integrated without the need for everybody to push to a single central repository. Developers push to their own server-side repositories, and only the project maintainer can push to the official repository. This allows the maintainer to accept commits from any developer without giving them write access to the official codebase.
The result is a distributed workflow that provides a flexible way for large, organic teams (including untrusted third-parties) to collaborate securely. This also makes it an ideal workflow for open source projects.
The workflow is summarized in the following image from the GitHub blog:
You always fetch changes from the official repository (called
upstream), develop on your local repository and push changes to your personal server-side repository (called
First thing to do when you start working on your local repository is to create a topic branch (based on the current master branch of the official repository) specific to a well defined feature or bugfix you are about to implement. Never work on the master-branch (it is reserved for the official version)! See also this tutorial on branching.
Start committing changes in logical chunks. After you are happy with your implementation push your topic branch to your forked repository on GitLab.
Open a Merge Request which will initiate the code review process.
This creates a new fork under your account with the URL
You can use the git command line tool to clone the remote repository on GitLab to your PC:
git clone --filter=blob:limit=100k email@example.com:YOUR-USERNAME/ogs.git cd ogs git config remote.pushdefault origin git config push.default current
This creates a new folder
ogs in your current working directory with the OGS source code. After this step, the remote called
origin refers to your fork on GitLab. It also sets the default remote for pushes to be
origin and the default push behavior to
current. Together this means that if you just type
git push, the current branch is pushed to the
--filter=blob:limit=100k-parameter instructs git to only fetch files which are smaller than 100 Kbyte. Larger files (e.g. benchmark files, images, PDFs) are fetched on-demand only. This happens automatically and is a replacement for the previous Git LFS tracked files. Requires at least git 2.22!
Create a second remote called
upstream that points at the official OGS repository and fetch from it:
git remote add upstream https://gitlab.opengeosys.org/ogs/ogs.git git fetch upstream
Git hooks help to check for several issues before doing commits or pushes and it is highly recommended to enable these checks.
Install pre-commit (a git hook manager) via Pythons
pip3 install --user pre-commit
.local/bin in your home directory or to
C:\Users\[username]\AppData\Roaming\Python\Python37\Scripts on Windows. Make sure to have this directory in your
Enable the hooks in the source code with:
cd ogs pre-commit install
You will also need to install
Install clang (which contains
clang-format) with the official installer
sudo apt-install clang-format
brew install clang-format
You only have to follow the above steps once. From then on, whenever you want to work on a new feature, you can more easily interact with the remote repositories.
Make sure that your local repository is up-to-date with the upstream repository:
git fetch upstream
Create a branch
feature-name off of upstream
master-branch to work on a new feature, and check out the branch:
git checkout upstream/master # Switch to newest master git checkout -b feature-name # Create and checkout a new branch
To keep up to date with the developments in the official repository it is recommended to rebase your feature-branch regularly (at least weekly). To see what has been updated, load a new set of changes with
git fetch --all -p
Then rebase your
feature-branch on to the newest master branch in the official repository with
git rebase ufz/master feature-name
This can potentially lead to conflicts, which have to be resolved.
You may want to streamline the updating workflow a bit using the
git pull --rebase --autostash-functionality. Enable it with:
git config pull.rebase true git config rebase.autoStash true
Then simply use
git pull upstream master.
Now after you implemented the feature and committed your work you can push the new commits to the
feature-name-branch on your GitLab fork:
git push -u origin feature-name # -u is required only first time to set up the remote-tracking.
If your work is done submit a merge request.
Again this triangular workflow is summarized with this picture:
[…] the Forking Workflow requires two remotes—one for the official repository, and one for the developer’s personal server-side repository. While you can call these remotes anything you want, a common convention is to use origin as the remote for your forked repository […] and upstream for the official repository.