Part V: Chapter 5.1

What is a Remote?

A named URL, plus a set of read-only branch snapshots.

A remote is not a separate program, a live connection, or a special server. It is two things stored locally: a name-to-URL mapping in .git/config, and a folder of remote-tracking branches in .git/refs/remotes/ — read-only snapshots of where each remote branch was the last time you talked to it.

Explore the Internals

Toggle between the .git/config entry that defines the remote and the refs/remotes/ directory that stores its branch snapshots.

.git/config

[core]
repositoryformatversion = 0
filemode = true
 
[remote "origin"]
url = https://github.com/badu/myrepo.git
fetch = +refs/heads/*:refs/remotes/origin/*
 
[branch "main"]
remote = origin
merge = refs/heads/main

What it means

url = https://…

The remote is just a name ("origin") mapped to a URL. That's the entire definition. You can have multiple remotes pointing to different URLs.

fetch = +refs/heads/*:refs/remotes/origin/*

The refspec. On fetch, every branch on the remote (refs/heads/*) is mirrored locally as a remote-tracking branch (refs/remotes/origin/*).

remote = origin + merge = refs/heads/main

Tells git pull which remote and which branch to merge when you're on main. This is set up automatically by git clone.

Remote-Tracking Branches

origin/main, origin/develop — these are not branches you can commit to. They are bookmarks that record where the remote's branches were the last time Git communicated with the server.

They live in .git/refs/remotes/origin/ and are identical in structure to local branches — a 41-byte file containing a commit hash. The difference is that Git refuses to let you advance them with a commit. Only git fetch (and git push) update them.

This means they can get stale. If a colleague pushed five commits to main this morning, your origin/main still points at yesterday's commit until you run git fetch.

Multiple Remotes

A repo can have any number of remotes. The convention is to name the primary one origin (set automatically by git clone), but the name is arbitrary.

A common pattern in open-source development is to have two remotes: origin pointing to your personal fork, and upstream pointing to the original repo you forked from.

$ git remote -vorigin https://github.com/you/myrepo.git (fetch)origin https://github.com/you/myrepo.git (push)upstream https://github.com/org/myrepo.git (fetch)upstream https://github.com/org/myrepo.git (push)

Managing Remotes

Terminal
$# List all remotes:
$git remote -v
origin https://github.com/badu/myrepo.git (fetch)
origin https://github.com/badu/myrepo.git (push)
$# Add a second remote:
$git remote add upstream https://github.com/org/myrepo.git
$# Change a remote's URL:
$git remote set-url origin git@github.com:badu/myrepo.git
$# Remove a remote:
$git remote remove upstream