unModified()

Break stuff. Now.

Git Remote Add... USB stick?

You don't need a remote git repository to move your work around

September 8, 2020

I have two machines: The powerful but stationary desktop and the portable but weak laptop. Sometimes I need the portability of the notebook, but other times I need the power of the desktop. And so, it's not uncommon for me to move code between the two machines.

Except it's not that simple.

I don't want my files on Github or anyone else's servers unnecessarily. I'm also not confident installing and configuring SSH servers on either machine as I'm not an expert in that area. And working directly on networked/external drives is a no go because I/O performance tanks when working with a lot of small files (cough node_modules cough).

If only there was a way...

One day, while helping someone sort out their Git problems, I discovered that Git remote "urls" don't necessarily have to be SSH or HTTPS endpoints. They can also be paths to directories that contain Git repositories. For example, using a relative path to another directory is totally legit:

git remote add that-other-repo ../../path/to/directory/with/repo.git

Then it hit me.

If Git supports directories as remotes, anything that looks like a directory can be a remote. This directory could be on the current drive, on a removable drive, on a RAM drive, on a virtual drive, or even on a network-attached drive! And so I picked up an old USB drive to test the theory aaand... booom! It worked!

# cd into the intended storage.
# I use Windows and Git Bash, and my USB drive is E:\. To get to E:\, I did:
cd /e

# Create the "remote" project directory.
# It's customary for git repo directories to have names end with .git.
mkdir my-project.git

# Create a "bare" repository.
# A bare repository is essentially just like a regular local repo, except
# it only contains what normally goes in .git (the history-tracking stuff).
git init --bare

# cd back to the project directory.
# In my case, I put all my projects in ~/Projects.
cd ~/Projects/my-project

# Add the "remote" location to the repo.
# But instead of a url, it's a path to the directory in the USB drive.
git remote add my-usb /e/my-project.git

# Done!
git push my-usb my-local-branch

Set-up is very simple. Since I don't work off the USB drive directly, all I needed on that USB drive is a "bare" repo. Then I just add a remote on the local repo pointing to the project directory on the USB drive. From there, everything is just a push and fetch away.

It's not very different from working directly on the USB drive. The USB drive is still storing code, but it's only storing source code. Work and all its by-products (downloaded dependencies, compiled output, temporary files, etc.) stay on the local machine. Thus, the I/O problems mentioned earlier do not exist.

However, drive letters/mount points can change, and I deal with this in two ways. One is configuring the remote location to always use the same drive letter/mount point. The other is to just update the local repo's remote location with git remote set-url. I usually go with the latter since it doesn't deal with OS-specific things.

And that's it! I can now share code between two machines. When I want to share work, I just plug in the USB drive an push my work onto it. When I want to fetch any updated work, I just plug in the USB drive and fetch updated work from it. The workflow isn't any different from using a dedicated third-party Git repo, it's still the usual add-commit-push-fetch-rebase. The only difference is that there is no third-party Git repo.


PS: I do get a feeling that this approach is very "Goldbergian" and that there might actually be a simpler way to do this.