Working with write access

Author

Marie-Hélène Burle

Small teams often collaborate by granting everybody permission to write directly to the project. If you work on a paper with your thesis supervisor or a few co-authors, you will probably work this way. This is what we will cover in this section.

Bigger teams (e.g. research labs, big organizations) usually have a different workflow that we will cover in the next section.

Setup

You initiate the project

In this situation, you are the author of a project (you have a project under version control on your own machine) and you want to initiate a collaboration with others using GitHub as a remote.

  • If you took our Getting started with Git course, you can use the repository that we created together (make sure that you cd into it).
  • If you have a project of your own under version control that you want to use, you can cd into that.
  • If you don’t have any Git repository ready on your machine, quickly run the following to create a tiny test repo:
mkdir test_repo
cd test_repo
touch file.txt file.md file.py
git init
git add .
git commit -m "Initial commit"

Create a remote on GitHub

Now, you need to create a remote on GitHub.

Create a repository on GitHub
  • Go to the GitHub website, login, and go to your home page.
  • Look for the Repositories tab & click the green New button.
  • Enter the name you want for your repo, without spaces.
  • Make the repository public or private.

Push to the remote

The remotes section of our introductory course to Git covers managing remotes, as well as pushing and pulling to/from them. But here is what you need for now.

The first time you push to a remote, you need to set an upstream branch that will track a local branch. You do that with the -u (or --set-upstream) flag:

git push -u <remote-name> <branch-name>

Example:

git push -u origin main

From now on, all you have to run when you are on the main branch is:

git push

Invite collaborators

If you don’t want to grant others write access to the project, and you only accept contributions through pull requests, you are set. In that case, go to the next page (Working without write access) to see how to work from there.

If you want to grant your collaborators write access to the project however, you need to add them to it:

  • Go to the GitHub project page.
  • Click on the Settings tab for the project (not the general Settings for your account).
  • At the top of the left-hand menu, click on Collaborators.
  • Click on Add people.
  • Invite your collaborators with one of their GitHub username, email address, or full name.

You are invited to a project

In this second situation, someone else started a project and they are inviting you to collaborate to it, giving you write access to the project.

In this case, you need to clone the project:

  • Go the link they gave you for their project on GitHub.
  • Click on the Code green button.
  • Select either of SSH or HTTPS (depending on how you have set your access to GitHub).
  • Copy the address.
  • On your machine, cd to the location where you want your local copy.
  • Run:
git clone <remote-address> <local-name>

Example:

# With SSH address
git clone git@github.com:john_doe/test_repo.git

# With HTTPS address
https://github.com/john_doe/test_repo.git

This sets the project as a remote to your new local copy and that remote is automatically called origin.

Without <local-name>, the repo will have same name it has on GitHub.

The remote branch is also automatically set as the upstream branch to your local branch, so you can push directly with git push.

Collaborative workflow

Pulling and pushing

When you collaborate with others, you will not be the only person accessing a remote. Git is extremely powerful in that it allows for collaborators to work on a project synchronously, but if one of your collaborators has made changes to the remote (pushing from their own local version of the project), you won’t be able to push.

Instead, you will get the following message:

To <your-project>.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'xxx.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

So how does this work?

You first have to update your local version of the project with their change by running git pull.

If there are no conflicts (the same lines of the same files having conflicting versions) Git will automatically merge their changes with yours and now you can push the merged changes back to the remote.

Now… what if there are conflicts?

Resolving conflicts

Git works line by line. As long as your collaborators and you aren’t working on the same line(s) of the same file(s) at the same time, there will not be any problem. If however you modified one or more of the same line(s) of the same file(s), Git will not be able to decide which version should be kept.

When you git pull their work on your machine, the automatic merging will get interrupted and Git will ask you to resolve the conflict(s) before the merge can resume. It will conveniently tell you which file(s) contain the conflict(s).

There are fancy tools to resolve conflicts, but you can do it in any text editor: simply open the file(s) listed by Git as having conflicts and look for the following markers:

<<<<<<< HEAD
This is your version.
=======
This is the alternative version of the same section of the file.
>>>>>>> alternative version

These markers are added by Git to signal the areas of conflict. It is up to you to choose between the two versions (or create a third one) and remove the conflict markers. After that, you can stage the file(s) which contained the conflicts to finish the merge (and then you can commit).