Remote Repositories

References:

Gits distributed nature makes collaboration extremely easy. It is very easy to have your local repository associated with another repo either on the local system or on a remote system. You can even associate your repo with any number of other repos.

Before you can access the repo hosting server (gitlab, github, bitbucket, etc) using git, be sure you have created an account and setup your ssh key (see SSH Setup).

For the sake of simplicity, gitlab will be used as the hosting service in the examples and exercises that follow.

Create the git training playground Repository

To facilitate the exercises which follow, a git training playground repository needs to be created. If you want to work collaboratively with others, multiple people will need access this repo.

For convenience, a template git training playground has been created:

Fork this repository by clicking on the Fork button. This fork will be your personal remote repo. You will push your changes to this fork and share it with other collaborators.

Note

Forking repository using the web UI on the cloud hosting services will create clone of the parent repository in your account (or into a group or team in which you have permission to create repos) on the server. This new repo is linked back to the parent repo such that when you push changes into your fork, you will be able to generate merge requests back to the parent repo (merge requests will be covered later). You can also make a fork of a fork and generate merge requests from your fork back to the intermediate fork.

Note

If you do not wish to use the template git training playground, you can create a new empty repository on gitlab for your use (note that it will not have the files referenced below). Log in to gitlab and create the repo using the New Project menu item which should land you on this page:

Cloning A Remote Repo

We’re now going to create a local copy of a remote repo using the git clone command. The rest of this training session will involve working with the git-training-play.git repository which resides on the gitlab server (replace <userid> in what follows with the your user id on gitlab).

This git-training-play.git is the git training playground repo that was referred to in the Prerequisites.

Clone the git-training-play.git repo:

[1]$ cd ~/repos
[2]$ git clone gitlab:<userid>/git-training-play.git playground
[3]$ cd testing

Note

I’m using gitlab: as a short hand (defined in my ~/.ssh/config) which is equivalent to git@gitlab:

From now on, we will assume that we are working in the ~/repos/playground/ directory.

To see what remote repos you have configured, run the following command:

[4]$ git remote -v

Pushing to Remote Repos

Let’s create a feature branch where we will do our collaboration work (replace <name> with your name or user id, but keep it simple):

[5]$ cd ~/repos/playground
[6]$ git branch -a
[7]$ git checkout -b feature/train-<name> origin/master
[8]$ git branch

Add your name to the students list:

[9]$ vim students.py

Commit your change to the local branch:

[10]$ git add students.py
[11]$ git commit

Now push your changes up to gitlab:

[12]$ git push origin feature/train-<name>

Verify that your changes are on the gitlab server via the web interface.

Using the gitlab web interface, generate a merge request and assign it to one of your collaborators (or yourself if not working with a group).

Pulling from a Collaborators Repository

One great feature of git is the ability to have one local repository which can pull from any number of remote repositories. When you first clone a repo (like we did above), there will be a single remote called origin. Use the following to see the remotes configured for your local repo:

[13]$ git remote -v

At this point, you will need to find a collaborator, teammate or buddy that is working through these exercises. You can setup your local repository to pull in changes that they have pushed up to their remote on the gitlab server.

Adding your buddy’s repo on gitlab as one of your remotes, is done with the following command:

[14]$ git remote add <buddy> gitlab:<buddy>/git-training-play.git

Now pull in their feature branch:

[15]$ git pull <buddy> feature/train-<buddy>

You should now have their changes in your branch:

[16]$ git log

Once you have pulled from your partner and resolved any merge conflicts, push your local repo out to your gitlab repo:

[17]$ git push origin feature/train-<name>

Once your buddy has pushed to his gitlab repo, pull his changes again. You should now both be in sync.

Using a Shared Team Repository

For the next exercise, we will all make changes to our local repo and push them directly into the gitlab:<team>/git-training-play.git repo and bypass your personal gitlab:<user>/git-training-play.git repo.

Someone on your team (or group of buddies) will need to fork the template git training playground and add all of the team members as members of the forked project. Each team member will need to be assigned a role which allows them to push to the git training playground repo. On gitlab, the roles the members will need to be developer, master or owner.

Each member of the team will need to add the team repo as remote:

[18]$ git remote add <team> gitlab:<team>/git-training-play.git

Create a branch for the team to collaborate on, and push it to the server (only one person on the team needs to do this):

[19]$ git checkout -b feature/train-<team> master
[20]$ git push team feature/train-<team>

Each team member will need to fetch all of the branches from the team remote and checkout a local version of the branch:

[20]$ git fetch <team>
[21]$ git branch -a                   # show all branches for all remotes
[22]$ git checkout -b feature/train-<team> <team>/feature/train-<team>

Make some changes to the students.py file and publish your changes to the remote:

[23]$ vim students.py
[24]$ git add students.py
[25]$ git commit
[26]$ git pull team feature/train-<team>
[27]$ git mergetool                         # resolve conflicts if needed.
[28]$ git push team feature/train-<team>

You should keep pushing and pulling from the origin repo until you have pulled everyone else’s changes without getting a merge conflict.

Merge and Pull Requests

After you have committed changes locally to your clone of a project on which you are working, you will likely want to get your changes into the upstream git repository. Most of the time you will not have permissions to push directly into a git repository you forked (or the central shared repo where you work has restrictions on who can push into certain branches, e.g. master).

The work flow in the situation where you need to work through a fork typically follows this pattern:

  1. Fork the parent repo into your account (via gitlab Web UI).
  2. Clone forked repo from your account, not the upstream parent repo.
  3. Make changes locally.
  4. Commit locally to a feature branch.
  5. Push your feature branch into your remote fork on gitlab.
  6. Use the gitlab Web UI to create the merge request from your fork.
  7. The maintainer of the parent repo will either merge your changes into master, make comments for you to address and resubmit or reject the request outright.

Replace gitlab in the above with the hosting service you are using.

The work flow when you can push a feature branch to a shared, centralized parent repo, but are not allowed to push directly into the master branch follows this pattern:

  1. Clone upstream repo.
  2. Make changes locally.
  3. Commit locally to a feature branch.
  4. Push you commits into a feature branch on the centralized upstream repo.
  5. Create a merge request from your branch on the master branch.
  6. Another person on the team will need to review the request and either merge, comment or reject the request.

See the Pro Git Book for detailed discussions on contributing to a project:

Merge/Pull Requests on Hosting Services

On gitlab, Merge Requests are how you notify the parent of your fork that you would like them to merge code you have pushed into your fork into their repository:

Merge Requests on github are called Pull Requests (but will work the same as Merge Requests on gitlab):

Similarly on bitbucket:

Pull Requests via Command Line

You can also generate a Pull Request from the git from the command line with the git request-pull.

This is used to send and email request to an upstream maintainer to pull your changes from you public repository.

You will probably not use this method when working with the cloud hosting services, although it is how Linux Kernel maintainers submit changes to the maintainer up the hierarchy of maintainers.

For more information:

$ git help request-pull

Deleting a Branch from a Remote Repo

Sometimes you will need to delete a branch from a remote repo you own. Let’s push a dummy branch to gitlab:

[29]$ git checkout master
[30]$ git push origin master:tmp/dummy

On second thought, you decide that was not a good idea. You can delete the branch on the remote quite easily:

[31]$ git push origin :tmp/dummy

This probably looks a little odd. From the git help push command:

The format of a <refspec> parameter is an optional plus +,
followed by the source ref <src>, followed by a colon :, followed
by the destination ref <dst>. It is used to specify with what
<src> object the <dst> ref in the remote repository is to be
updated.


Pushing an empty <src> allows you to delete the <dst> ref from the
remote repository.

Deleting a Repo from a Hosting Service

It is possible to delete an entire repo from the gitlab server.

This varies from service to service. It can be done, but use caution when deciding to delete a repository from the hosting service.

The how-to is left as an exercise for the student. Recommend creating a private repo on the hosting service and digging into the repo settings to figure out how to delete it.