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.