TIL: Git remotes
A git remote is (usually) just something called a “bare” repository.
I’ve never really appreciated
git’s distributed design up until this moment.
Say you’ve got a
git repository that has the
origin remote set to a GitHub URL.
You’ve probably seen it hundreds of times, it looks something like:
sdnts will be your GitHub username and
dietcode will be the name of
your repository). Let’s try creating a custom
git remote called
has nothing to do with GitHub, but one you can
git push to exactly the same way.
First thing you’ll need of course is a server running somewhere. I have one at
sdnts.dev that I can SSH into as the user
sid. I’ll run these commands on my
$ mkdir /home/sid/dietcode.git $ cd /home/sid/dietcode.git $ git init --bare -b main
and that’s… it. I can now add it as a custom remote on my local repository:
$ git remote add jupiter [email protected]:/home/sid/dietcode.git $ git push jupiter # Push to your remote just like you would to `origin`
Wait, what just happened?
What I just did was create a “bare”
git repository. A bare repository is like
a “normal” repository that you get when you
git clone, except it doesn’t have a working
tree — as in, it doesn’t directly have the “files” you’ve created. Think of it
as just the
git push to a remote,
git literally SSHes into a server (pointed to
remote URL), and syncs your local working tree with the bare repository
on the server, making sure both of them have the exact same version history. If the
remote repository is “behind” your local working tree (i.e. you have commits that
it doesn’t have), your commits are copied to the remote repository. If the remote
repository is “ahead” of your local working tree (i.e. it has commits you don’t
git push is rejected. You are now responsible for figuring out what
to do with these extra commits. You can “rebase” your commits on top of the remote’s
git pull origin --rebase), or you can tell the remote to forcefully
discard any extra commits it has and blindly treat your commit history as canon
git push --force).
(Git is fantastic software with unfortunate DX, and it 100% worth it to understand what it is doing behind the scenes. You will never again mess up history!)
Anyway, if you now try and analyze a GitHub
remote URL, you should be able to roughly
predict what GitHub’s
git server is doing. Its remote URLs look like this:
- They have a server running on
- This server has a user called
- There’s a directory called
gituser’s home directory (
dietcode.gitdirectory hosts a “bare” git repository
Surely this is highly simplified, but it is still broadly what’s going on.
So what do you do with this information? I just think it’s neat, but you could
combine this with server-side Git hooks to build an old-school Heroku-style deploy
experience, where you push to a
heroku remote to deploy your website. I bet that’d
make for an interesting post.