Git Remotes^

A particularly useful feature of Git is that it doesn’t require network connectivity. When you have a repository on your local machine, you can operate on that repository to commit changes, switch out branches, revert to earlier versions, and so on as entirely local operations.

So, in the event that you get on a plane and have no wifi for several hours—this fact in no way blocks you from continuing your work in the local repository.

Network connectivity becomes an issue when you want to reach off of your local machine to access a remote repository. The remote can provide you with pull requests from other users, changes made by your collaborators, and allow you to share your own changes with others. Once you have this connection, you can pull down commits and operate on new code locally and only reconnect when you need to share.

In order to make this connection, you need to configure your local repository to access one or more remote repositories.

Local and Remote^

Local repositories exist in your local file system. The data for them is stored in the repository path under the .git/ directory.

Remote repositories are identified by a human-readable key, which Git translates into a URL. The configuration for these repositories are written to the .git/config file, but generally, you’ll operate on them through the git remote command:

$ git remote -v
origin   git@gitlab.com:avocet-tools/atlog (fetch)
origin   git@gitlab.com:avocet-tools/atlog (push)

Add and Remove Remotes^

Remote configuration is not an area that requires a lot of attention. It tends to be something you set up once and then largely ignore after.

To add a remote, use the add sub-command:

$ git remote add upstream git@github.com:avoceteditors/atlog
$ git remote -v
origin     git@gitlab.com:avocet-tools/atlog  (fetch)
origin     git@gitlab.com:avocet-tools/atlog  (push)
upstream   git@github.com:avoceteditors/atlog (fetch)
upstream   git@github.com:avoceteditors/atlog (push)

Note, when you clone from a remote repository, Git automatically sets up the origin remote to handle the source connection. You don’t need to take the extra step of adding it to your local repository configuration.

Manually adding remotes is, however, necessary when you initiate a repository locally (using the git init command) and only later want to push your work up to a remote.

To remove a remote, use the rm sub-command:

$ git remote rm upstream
$ git remote -v
origin     git@gitlab.com:avocet-tools/atlog  (fetch)
origin     git@gitlab.com:avocet-tools/atlog  (push)

Multiple Remotes^

In most cases, you will want a single origin remote, which usually refers to the GitHub or GitLab repository for the project. But, there are cases where you may want to use multiple remotes.

This is common when working with forks. For example, you may go to a project GitHub repository and fork it into your personal GitHub repository. When you clone the repository onto your local machine, you would add the URL for your personal GitHub under origin and the URL for the project GitHub under upstream.

Using this organizational scheme allows you to perform all maintenance operations needed to keep the repositories in sync on your local machine. So, for example, if a change in upstream causes a conflict in origin, you would deal with the conflicts locally and then push them up to origin. You would then create pull requests from origin to merge your own changes back into the upstream repository.

Personally, I mainly use the fork approach with repositories I mean to work on. For example, Suckless Tools in many if not most cases require you to hack on the C to get the tool into a usable state. To keep my local copy in sync with remote developments, I map upstream to the Suckless repository and origin to a private GitLab repository.

For example:

$ git remote -v
origin      home:kennethpjdyer/dyer-dwm     (fetch)
origin      home:kennethpjdyer/dyer-dwm     (pull)
upstream    https://git.suckless.org/dwm    (fetch)
upstream    https://git.suckless.org/dwm    (pull)

Note the variant URL for origin. The home key matches to an SSH configuration in the $HOME/.ssh/config configuration file. This is convenient when you need Git to work with multiple SSH keys or just want to simplify the URL scheme across several projects. I’ll go into more detail on its configuration below.

Clone Remotes^

When you initiate a repository locally, it exists locally and has no remote configuration except what you manually set up yourself. This can sometimes occur when working with new projects or projects that you don’t plan on sharing with the public, but most of the time when you set up a repository on your local machine your first step is to clone it from a remote.

Cloning a repository automatically configures the source URL as the origin remote. You can freely pull or fetch from this repository, though you may need some further configuration to push commits into it.

Basic Clones^

To clone a repository, use the clone command:

$ git clone https://git.suckless.org/st

This clones the repository at the given URL into a new directory, identified by the last component of the URL, (here, st/). If you want to specify the directory, you can pass a relative or absolute path as an argument.

$ git clone https://git.suckless.org/st ~/.local/opt/st

This command would clone the remote repository into the $HOME/.local/opt/st directory, which is a convenient place for projects you don’t plan to do much work on (given that it’s located in the hidden .local directory tree).

Clone for Contribution^

Remote Git repositories, especially those housed on GitHub or GitLab, frequently have certain security measures in place to restrict random users from making changes. This is a good thing, since it makes it harder for unauthorized parties to change your code. But, it can also provide a hassle logging in every time you need to push changes up to remote.

Git can utilize SSH keys to access remote repositories. This requires that you set up an SSH key on your local machine (using ssh-keygen) and then copy the public key to GitHub or GitLab to authenticate the access.

The remote URL for repositories that use SSH keys is also a little different.

For example, if you wanted to clone the atLog repository for your personal use, you would use the usual HTTPS URL:

$ git clone https://gitlab.com/avocet-tools/atlog

But, if you instead wanted to clone it to use the SSH key, such as you were planning on making contributions to the project or would like to manage the repository from your local machine, you would instead use the git@DOMAIN URL:

$ git clone git@gitlab.com:avocet-tools/atlog

By default, SSH uses the $HOME/.ssh/id_rsa key as an identity file—if it exists. The command fails if the file does not exist or if your GitLab user isn’t configured to use the appropriate SSH public key.

Git and SSH^

In cases where you have multiple SSH keys on your local machine or you would like to simplify the Git URL’s, you can edit the $HOME/.ssh/config configuration file to set up keys with the appropriate options.

SSH Configuration^

To set up your local SSH client to provide the correct options to Git, edit the configuration file:

$ vi ~/.ssh/config
Host avocet
   User git
   HostName gitlab.com
   IdentityFile ~/.ssh/id_rsa

When this is done, save the file and exit. Since we’re configuring the SSH client and not the server, you don’t need to perform any further operations beyond saving the file to use the host key.

Clone with SSH^

To use the SSH host key with Git, set the host key in the base URL. For example:

$ git clone avocet:avocet-tools/atlog ~/repos/atlog

Here, Git uses the SSH configuration for avocet to identify the user name, host name, and identity file when connecting to the remote repository at avocet-tools/atlog and creates a local repository in the $HOME/repos/atlog directory.

This is generally my approach when dealing with projects I intend to do extensive work on, as it’s placed right out in the open in the repos/ directory.

Learn More^

Git Branches sent: Simple Presentation Tool