ยปGit Tricks
How to interact with a repo on an untrusted machine
Let's say you have a Git repo that you use on a machine you don't trust particularly well, where "untrusted" in particular means you don't want the machine to have any credentials for accessing your master repo. This means that the typical SSH workflow for pulling/pushing from the client is unavailable.
There is a non-hacky way of doing this: set up a bare repo on that remote machine that you push changes to from your trusted machine (outbound SSH) and pull changes from on your untrusted machine (local file access).
But let's say you don't want this extra bare repo. It turns out there is a hacky way of doing this by specifying a different-than-usual set of refspecs in a few configurations.
Assume:
- The untrusted machine is called
untrusted
and the repo is located at/path/to/untrusted/repo
. - The trusted machine's repo lives at
/path/to/trusted/repo
.
Then:
-
On the trusted machine, edit
/path/to/trusted/repo/.git/config
to add a remoteuntrusted
that both pushes to and pulls from a set of remote refs. I use remoteself
for this:[remote "untrusted"] url = untrusted:/path/to/untrusted/repo fetch = +refs/heads/self/*:refs/remotes/untrusted/* push = +refs/heads/*:refs/remotes/self/*
-
On the untrusted machine, edit
/path/to/untrusted/repo/.git/config
to add a remote that is actually the same repo, and which pushes to and pulls from the same remote ref:[remote "self"] url = . fetch = +refs/remotes/self/*:refs/remotes/self/* push = +refs/heads/*:refs/remotes/self/*
-
Set up local branch(es) on the untrusted repo to track the corresponding
self
heads:[branch "master"] remote = self merge = refs/remotes/self/master
Now when you git push
on the untrusted machine, the self
remote heads in the local repo will be updated to take the new commits; and when you git fetch untrusted
on the trusted machine, it will SSH over and pull down whatever you pushed to those heads. Similarly, when you git push untrusted
from the trusted machine, it will SSH over and (depending on your push.default
settings) push the latest state for your local heads into the self
remote heads; and when you git pull
on the untrusted machine, it will update the local branch with whatever you pushed.
It's like having a separate bare repository on the untrusted machine without the clutter.