1. Introduction

Although we can employ Git version tracking for local projects, collaboration is one of the benefits that the system offers. In particular, remote synchronization with a Git server enables multiple participants and contributors in a repository to share data and work in parallel. However, project locations change and we might have to adjust the local configuration accordingly.

In this tutorial, we explore so-called Git remotes and ways to handle and modify them. First, we briefly describe remotes and when they are useful. After that, we configure two repositories and link them by making one a remote of the other. Next, we go through ways to check the current remotes of a repository. Finally, we delve deeper into Git remote URL management.

We tested the code in this tutorial on Debian 12 (Bookworm) with GNU Bash 5.2.15 and Git 2.39.2. Unless otherwise specified, it should work in most POSIX-compliant environments.

2. Git Remotes

A Git repository is a data store with version control that tracks and keeps information about the progress of a project in terms of changes. This functionality alone can be enough for a one-person team.

However, often, multiple participants collaborate and contribute to the same Git repository, making local storage of all changes difficult without a central location for the data.

Because of this, Git implements the concept of a remote, a secondary repository that the local one can push to and pull from. Notably, these operations synchronize the local and remote branches or tags, as requested.

This way, involved entities can perform the operations separately without disturbing the work of others. Importantly, each push or pull can result in merge conflicts depending on the branch and commit difference.

So, local Git repositories can be connected to remote ones, although that’s not always the case.

3. Configure Remote

To begin with, let’s create a repository:

$ mkdir repo1 && cd repo1 && git init

Next, we write files and create some commits:

$ git log --all --decorate --oneline --graph
* 5e59445 (tag: v0.1, branch1) branch feature
| * 510849f (branch2) secondary feature WIP
| * 10b9231 secondary branch modifications
|/
| * 0534510 (branch3) experimental
|/
* bfeafbf branch modifications
| * dbecb51 (HEAD -> master) new structure
| * 27bdef5 wipeout
| * 85437a0 major modifications
| * 5df1bbc minor modifications
|/
* 10285c5 restructuring
* 8dd29cf structuring
* 59ddc2d init commit

At this point, we can create a remote repository in an online service such as GitHub or even use another repository on the same machine as a remote:

$ mkdir ../remoterepo/ && cd ../remoterepo && git init --bare

Notably, the –bare flag tells Git that we want this repository to act as a container without a working tree.

Finally, we link the two repositories via the remote subcommand:

$ cd ../repo1 && git remote add origin ../remoterepo

In particular, we add a remote called origin that points to the remoterepo bare repository.

4. Synchronize With Remote

After adding the remote, we push into it all of the current repository contents:

$ git push --all origin
[...]
To ../remoterepo/
[...]

Now, remoterepo should be in sync with repo1. In this case, we can skip the origin argument, since we only have one remote.

After pushing and thus populating the remote, we can create a new repository with the same remote:

$ mkdir repo2 && cd repo2 && git init

Then, we can pull data from remoterepo, thus effectively cloning remoterepo:

$ git remote add origin ../remoterepo
$ git pull --all

Now, we have a second repository, repo2, that’s also in sync with remoterepo. Of course, even if we now remove the remote, the contents remain.

Importantly, we supply a local path URL as a remote in this case. However, we can also do the same with an online URL via HTTP(S) for example.

5. Check Current Remotes

At this point, we have a repository with a remote.

Let’s list all remotes by skipping the arguments to remote:

$ git remote
origin

Although this listing shows origin, it doesn’t provide more information.

So, we make the remote subcommand more –verbose (-v):

$ git remote --verbose
origin  ../remoterepo/ (fetch)
origin  ../remoterepo/ (push)

Now, we see the output is in three columns:

  1. remote name
  2. remote URL
  3. remote operation

Thus, we can both fetch (pull) from and push to origin.

6. Handle Remote Repository URL

Git also provides two commands to manage the URL of a remote.

Let’s use get-url to extract the URL of a given remote by name:

$ git remote get-url origin
../remoterepo/

Here, we see that origin points to ../remoterepo/. This can be critical, as the relative path can cause issues if we move either repository.

So, let’s change the URL of origin to point to an absolute path:

$ git remote set-url origin /repos/remoterepo

After the operation, we can verify the results:

$ git remote get-url origin
/repos/remoterepo

Thus, we switch the URL. Notably, no checks are in place to ensure that the new URL is valid or that it contains the expected data.

In addition to the basic remote operations, we can add more than one URL:

$ git remote set-url --add origin https://gerganov.com/remoterepo

This way, push operations to origin affect all targets.

However, fetch (pull) has to be configured only for a single URL for consistency:

$ git remote --verbose
origin  /root/remoterepo1/ (fetch)
origin  /root/remoterepo1/ (push)
origin  https://gerganov.com/repos/remoterepo (push)

If any URL becomes invalid or we don’t want to use it anymore, we can change or –delete it:

$ git remote set-url origin https://gerganov.com/repos/remoterepo https://gerganov.com/remoterepo

In this case, the last argument specifies the old URL that we want to change. This is important in the case of more than one configured target.

7. Summary

In this article, we discussed Git repository remotes, their role, and ways to list and manage them.

In conclusion, although we can work exclusively with local Git repositories, remotes enable easier collaboration and better workflows.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.