Version control using Git: Centralized workflow

Overview

Teaching: 20 min
Exercises: 40 min
Questions
  • How can we collaborate with others within one repository?
Objectives
  • Understand how to collaborate using a centralized workflow.
  • Understand the difference between local branch, origin/branch, and remote branch.

Centralized workflow

Git implements a distributed version control. This means that any type of repository links that you can think of can be implemented - not just “everything connects to one central server”.

In this episode, we will explore the usage of a centralized workflow for collaborating online on a gitlab project.

Centralized layout

In Git, all repositories are equivalent but in the typical centralized style, we consider one repository as the main development line and this is marked as “central”. The “central” is a role, not a technical difference.

Features:

  • Typically all developers have both read and write permissions (double-headed arrows).
  • Suited for cases where all developers are in the same group or organization etc.
  • Code review workflow is possible.
  • Code review can be coupled with automated testing.

Advantages:

  • More familiar for Subversion or CVS users.
  • Easier: for each clone there is only one remote.

Disadvantages:

  • Everybody who wants to contribute needs write access.
  • Maintainer needs to trust the developers to not break things (but you can protect branches).

Centralized workflow exercise

In this exercise we will practice collaborative centralized workflow in small groups. We’ll discuss how this leads to code review and discuss a number of typical pitfalls.

Exercise preparation

  • We form small groups (4-5 persons).
  • Each group needs to appoint someone who will host the shared GitLab repository: an administrator.
  • For online teaching, use breakout rooms.
  • One person per group (administrator) generates a new repository by importing the template-centralized-workflow-exercise repository called centralized-workflow-exercise.

  • Then everyone in your group needs their GitLab account to be added as collaborator to the exercise repository:
    • Participants give their GitLab usernames (or gfz email address) to their chosen administrator (in their respective group).
    • Administrator gives the other group members the newly created gitlab repository URL.
    • Administrator adds participants as collaborators to their project (Members → Invite member).
  • You can use this template to share this information in the collaborative document:
# Group N

- administrator: some_user
- exercise URL: https://gitlab.com/someuser/centralized-workflow-exercise
- collaborators:
  - another_user
  - yetanother_user
  - my_username
  - other_username

After participants have been added as collaborators

Watching and unwatching repositories

  • Now that you are a collaborator, you get notified about new issues and merge requests via email.
  • If you do not wish this, you can remove your selected notification (top of the project page).
  • However, we recommend using notification for repositories you are interested in. You can learn things from experts just by watching the activity that come through.

1. Clone your administrator’s group repository

$ git clone https://git.gfz-potsdam.de/swc-bb/swc-lessons/2021-03-25-potsdam-berlin/template-centralized-workflow-exercise.git centralized-workflow-exercise

Where you replace swc-bb/swc-lessons/2020-11-05-potsdam-berlin by the namespace of the repository administrator.

This is a representation of what happens when you clone:

remote:

local:

  • We clone the entire history, all branches, all commits. In our case, we have one branch (we did not include all branches when creating our repository) and we have only one commit (initial commit).
  • git clone creates pointers origin/master so you can see the branches of the origin.
  • origin refers to where we cloned from, try: git remote -v.
  • origin is a shortcut for the full URL.
  • origin/master is a read-only pointer.
  • They only move during git pull or git fetch or git push.
  • Only git pull or git fetch or git push require network.
  • All other operations are local operations.

2. Step into the newly created directory

$ cd centralized-workflow-exercise

3. Create a branch yourname/somefeature pointing at your commit

Create a branch from the current master:

$ git branch yourname/somefeature
$ git checkout yourname/somefeature

The yourname/ prefix has no special meaning here (not like origin/): it is just part of a branch name to indicate who made it.

4. Create a file with a unique name, e.g.: yourusername.txt

In this file share your favourite cooking recipe or haiku or Git trick or whatever.

5. Stage and commit the change

$ git add yourusername.txt
$ git commit

remote:

local:

6. Push your change as a new branch

$ git push origin -u yourname/somefeature

Can we leave out the -u?

7. Browse the network of branches and commits

After you have pushed your branch and other participants have too, browse the network of branches and commits and discuss with others what you see.

8. Submit a Merge request

Submit a merge request from your branch towards the master branch. Do this through the web interface.

A merge-request means: “please review my changes and if you agree, merge them with a mouse-click”. In a popular project, it means that anyone can contribute with almost no work on the maintainer’s side - a big win.

Code review and protected branches

  • Merge requests are like change proposals.
  • We recommend that merge requests are reviewed by someone else in your group.
  • In our example everyone has write access to the “central” repository.
  • A good setting is to make the master branch protected and all changes to it have to go through code review.
  • Centralized workflow with protected branches is a good setup for many projects.

Once the merge-request is accepted, the change is merged:

central:

local:

Finally also discuss /network.

9. Update your local copy

Your branch yourname/somefeature is not needed anymore but more importantly, you need to sync your local copy:

$ git checkout master
$ git pull origin master

central:

local:


Exercise/discussion: Why did we create a feature branch yourname/somefeature?

This exercise is done in groups of 4-5 persons and can be done through a discussion only. Whenever we make update to our repository, we create a new branch and make merge-request. Let’s now imagine that everyone in your group makes a new change (create a new file) but without creating a new branch.

  1. You all create a new file in the master branch, stage and commit your change locally.
  2. Try to push the change to the upstream repository:
$ git push origin master

You probably see something like this:

$ git push
To https://gitlab.com/user/repo.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://gitlab.com/user/repo.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.
  • The push only worked for one participant.
  • Discuss why push for everybody else in this group was rejected?

Discussion: How to make changes to remote branches

We can create a local branch somefeature tracking origin/somefeature:

$ git checkout -b somefeature origin/somefeature

If there is no local branch somefeature and there is a remote branch origin/somefeature, then this is enough:

$ git checkout somefeature

Once we track a remote branch, we can pull from it and push to it:

$ git pull origin somefeature
$ git push origin somefeature

We can also delete remote branches:

$ git push origin --delete somefeature

Key Points