Collaborating within the same repository

Objectives

  • Understand how to collaborate using a centralized workflow.

  • Understand the difference between local branch, origin/branch, and remote branch.

Instructor note

  • 30 min teaching

  • 30 min exercises

Meaning of “central” in a distributed version control

In this episode, we will explore the usage of a centralized workflow for collaborating online on a project within one repository on GitHub. This means that everyone has access to that central repository - convenient (but doesn’t scale to a huge project).

In the next section, we will see that Git is 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”.

Centralized layout

Centralized layout

Centralized layout. Red is the repository on GitHub. Blue is where all contributors work on their own computers.

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 or project.

  • Everybody who wants to contribute needs write access.

  • Good idea to write-protect the main branch (typically main or master).

Real life examples:

Exercise

We are working on combining the steps into one exercise.

Exercise preparation

In this exercise we will practice collaborative centralized workflow in groups (but you can also collaborate with us as individual). One person (maintainer) will create the exercise repository, and collaborators will contribute to it. We’ll discuss how this leads to code review and discuss a number of typical pitfalls.

Exercise preparation

  • Form not too large groups (4-5 persons).

  • Each group needs to appoint someone who will host the shared GitHub repository: the maintainer. This is typically the exercise lead (if available). Everyone else is a collaborator.

  • The maintainer (one person per group) generates a new repository from the template https://github.com/coderefinery/template-centralized-workflow-exercise called centralized-workflow-exercise (There is no need to tick “Include all branches” for this exercise):

    Screenshot of generating the exercise repository
  • Then everyone in your group needs their GitHub account to be added as collaborator to the exercise repository:

    • Collaborators give their GitHub usernames to their chosen maintainer.

    • Maintainer gives the other group members the newly created GitHub repository URL.

    • Maintainer adds participants as collaborators to their project (Settings → Manage Access → Invite a collaborator).

  • Don’t forget to accept the invitation

    • Check https://github.com/settings/organizations/

    • Alternatively check the inbox for the email account you registered with GitHub. GitHub emails you an invitation link, but if you don’t receive it you can go to your GitHub notifications in the top right corner. The maintainer can also “copy invite link” and share it within the group.

  • Watching and unwatching repositories

    • Now that you are a collaborator, you get notified about new issues and pull requests via email.

    • If you do not wish this, you can “unwatch” a repository (top of the project page).

    • However, we recommend watching repositories you are interested in. You can learn things from experts just by watching the activity that come through a popular project.

    Unwatching a repository

    Unwatch a repository by clicking “Unwatch” in the repository view, then “Participating and @mentions” - this way, you will get notifications about your own interactions.

Exercise: Part 1 - creating a pull request

Centralized-1: Clone a repository, add a file, push changes as a branch, and create a pull request

  • Before we start with the exercise, instructor points to the preparation (above).

  • Then work on steps A-H.

  • There are also optional exercises.

  • Before and after each action you take, run the following informational commands:

    • git graph - almost every time

    • git status - when you modify files

Hint for breakout rooms

If the helper in the room is the one who sets up the central repository, they cannot easily demostrate the steps via screen-sharing as the repository’s maintainer. A good alternative is to have one of the learners screen-share and get advice on the steps from other learners and helpers!

Step A. Clone your maintainer’s group repository

$ git clone REPOSITORY-URL centralized-workflow-exercise

Where REPOSITORY-URL is the repository created by the exercise maintainer.

Clone using the SSH path you get from the webpage (the one that starts with git@github.com:), not the one that starts with https://github.com. Otherwise, you won’t be able to push later.

Step B. Change directory into the newly created directory

$ cd centralized-workflow-exercise

Try to find out where this repository was cloned from using git remote -v.

Step C. Create a branch yourname-somefeature pointing at your commit

Create a branch from the current main. Also adapt “yourname-somefeature” to a better name:

$ git branch yourname-somefeature main
$ git switch 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.

Step D. 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 (we will push soon to a public repository so don’t share something you don’t want to become public for the duration of the exercise).

Step E. Stage and commit the change

$ git add yourusername.txt
$ git commit

Step F. Push your change as a new branch

$ git push origin -u yourname-somefeature

Step G. 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 (on GitHub click on Insights -> Network) and discuss what you see.

Step H. Submit a pull request

Submit a pull request from your branch towards the main branch. Do this through the web interface.

Meaning of a pull request: think of it as change proposal. In a popular project, it means that anyone can contribute with almost no work on the maintainer’s side - a big win.

There are several options to open a pull request:

  • Follow the link printed to terminal output when git-pushing a branch to GitHub/GitLab

  • Visit the GitHub repository in the browser after pushing the branch and click on the green button “Compare & pull request”

  • Click on “Pull requests” on top of the GitHub repository and either “Compare & pull request” or “New pull request”

  • Click on “Branches” and then “New pull request” from the respective branch

Exercise: Part 2 - code review and merging changes

Centralized-2: Merge the pull requests (together)

  • We do step 2A and 2B together (instructor demonstrates, and everybody follows along in their repositories).

Instructor note

At this stage it might be good to show how to submit and how to review a pull request.

  • When co-teaching change roles and switch screenshares also.

  • Discuss what you look at when submitting.

  • Discuss what you look at when reviewing.

Step 2A. Discuss and accept pull requests

We do this step together on the main screen (in the main room) or on stream. The instructor shows a submitted pull request, discusses what features to look at, and how to discuss and review.

At the same time, helpers can review open pull requests from their exercises groups.

Finally also discuss the “network” on GitHub.

Instructor note

At this stage demonstrate how to suggest small changes to pull/merge requests:

Discussion

Naming

  • In GitLab or BitBucket these are named merge requests, not pull requests.

  • Which one do you feel is more appropriate and in which context? (The name pull request may make more sense in the forking workflow: next episode).

  • It can be useful to think of them as change proposals.

Pull requests can be used for code review

  • We recommend that pull requests are reviewed by someone else in your group.

  • Collaborative learning

  • OK if students and junior researchers review senior researchers

  • In our example everyone has write access to the “central” repository.

Pull requests are from branch to branch

  • They originate from a source branch and are directed towards a branch.

  • Not from commit to branch.

  • Pull requests create new commits on the target branch.

  • They do not create new branches.

Protected branches

  • A good setting for large projects is to make the main 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.

Read more

Step 2B. Update your local copy

Your branch yourname-somefeature is not needed anymore but more importantly, you need to sync your local copy: Everybody needs to do this step in their exercise repository but we do this together in the main room so that we can discuss this step and ask questions.

$ git switch main
$ git pull origin main
../_images/06-remote.svg

remote or central

../_images/07-local.svg

local

Optional exercises

(optional) Centralized-3: Cross-referencing issues using “#N”

We will submit another change by a pull request but this time we will first create an issue.

  1. Open an issue on GitHub and describe your idea for a change. This gives others the chance to give feedback/suggestions. Note the issue number, you will need it in step 3.

  2. Create a new branch and switch to it.

  3. On the new branch create a commit and in the commit message write what you did, but also add that this “closes #N” (replace N by the actual issue number from step 1).

  4. Push the branch and open a new pull request. If you forgot to refer to the issue number in step 3, you can still refer to it in the pull request form (add a “closes #N” to the title or description).

  5. Note how now commits, pull requests, and issues can be cross-referenced by including #N.

  6. Notice how after the pull request is merged, the issue gets automatically closed. This only happens for certain keywords like closes or fix.

  7. Discuss the value of cross-referencing them and of auto-closing issues with commits or pull requests.

See also the GitHub documentation for more examples.

(optional) Centralized-4: Why did we create a feature branch “yourname-somefeature”? (exercise/discussion)

Pushing directly to the main branch is perfectly fine for simple personal projects - the pull-request workflows covered here are for larger projects or for collaborative development. Guidelines for simpler workflows are given in the how much Git is necessary? episode of the git-intro lesson.

In collaborative development, whenever we update our repository we create a new branch and create a pull-request. Let’s now imagine that everyone in your group (or one person on two different clones) makes a new change (create a new file) but without creating a new branch.

  1. You all create a new file in the main branch, stage and commit your change locally.

  2. Try to push the change to the upstream repository:

    $ git push origin main
    

    You probably see something like this:

    $ git push
    
    To https://github.com/user/repo.git
     ! [rejected]        main -> main (non-fast-forward)
    error: failed to push some refs to 'https://github.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 (one clone).

  • Discuss why push for everybody else in this group was rejected?

Discussion: How to make changes to remote branches

If there is a remote branch somefeature, we can create a local branch and start tracking origin/somefeature like this:

$ git switch 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

Creating pull requests from the command line

There are several possibilties:

How you can find out in which repositories you are a collaborator

Visit https://github.com/settings/repositories where you will see an overview of all repositories you have write access to.

GitHub/GitLab organizations

  • Projects often start under a personal namespace.

  • If you want the project to live beyond the interest or work time of one person, one can share projects under an “organization”.

  • You can then invite collaborators to an organization.

  • This is what we do in the CodeRefinery project: https://github.com/coderefinery

Keypoints

  • Centralized workflow is often used for remote collaborative work.

  • origin refers to where you cloned from (but you can relocate it).

  • origin/mybranch is a read-only pointer to branch mybranch on origin.

  • These read-only pointers only move when you git fetch/git pull or git push.