Private Branches in Public Repos
-
-
-
3 min read
Something that’s semi-frequently bugged me about having this site be statically generated from flat files in a public GitHub repository is how to deal with drafts of posts. I want to be able to save my progress “in the cloud” so that I can pick it up on other machines without making anything half-baked publicly accessible.
The way I have been dealing with this is to use a persistent GitHub Codespace where changes can just sit untracked. But this means waiting for the Codespace to initialize when I start working on something, dealing with it pausing after inactivity, or even paying a bit for it if I go over GitHub’s free allotment. Without increasing the number of vCPUs on the Codespace, it’s also significantly slower than any machine I would use.
So a few times I’ve gone looking for a better solution to this problem and I’ve come up empty. But last night I decided to try again, and I gave this prompt to Claude:
I wish I could have encrypted WIP branches in public GitHub repos. Does such a thing exist?
The response told me a bit about encryption options, but the first two alternatives it gave hints at something better:
- Private branches - Just use a private repo for WIP, then move to public when ready
- Fork workflow - Keep your fork private while the upstream is public
This made something click for me. If I created a private fork that only exists to store branches of work-in-progress, then I could add it as a remote to clones of the public repo. This would effectively let me have “private branches”! Finally!
I’ve implemented this by creating an empty private GitHub repo, added
it as a remote named private
, pushed up everything from
the original, and renamed the origin
remote to
public
. This rename makes sure I will need to explicitly
specify a remote when pushing new branches, preventing accidental
pushes to the public repo.
git remote add private https://github.com/limulus/limulus-dot-net-private.git
git push private --all
git remote rename origin public
git checkout -b my-wip
git push -u private my-wip
When it comes time to merge my work into the public
main
branch, I can do this easily with plain old
git merge
. If there’s intermediate commits in the branch
that I don’t want to be public I can always rebase or squash.
GitHub unfortunately does not track this separate private repo as a
fork. That (plus the public/private dichotomy) means I can’t directly
make PRs from the private repo. If I were using a PR based workflow, I
expect that would have to reset the upstream of the branch to
public
and then make a PR. But that’s not something I’m
planning on doing with this project.
This is one of those things where I feel a little silly for not realizing this was possible. It’s obvious in retrospect that the ability to have multiple remotes in a repository would allow for this. But it’s a git feature I’ve used at most once before.