// blog /
Flipping a Repo Public Publishes Your Whole History.
- #git
- #security
- #open_source
- #solo_dev
Five of my repos are public on GitHub right now. GlowUpFinder, ReligionCompare, BuilderAI.tools, ClickSolveTools, and MiniGamePlanet all have a view source link on my work page, because for a freelancer the code itself is the best proof the projects are real. Getting them public took an afternoon. Getting them safe to make public took longer, and the reason is something most people never think about until it bites them.
The visibility toggle doesn’t publish your code. It publishes your code and every commit you have ever made to it.
That distinction matters more than it sounds. A repo that has been private since day one accumulates the kind of history you’d never put in a readme. Early commits where a config file had a real key in it before you learned better. A .env that got committed in week one and deleted in week two, still sitting in the history, fully recoverable by anyone who clones and checks out the old commit. Half-finished experiments. Angry commit messages. And on every single commit, an author line with the name and email git was configured with at the time, which for me meant personal details I keep off this site on purpose.
Deleting a file does nothing here. Git’s whole job is remembering. The file is gone from the current tree and alive in the history, and git log --all plus a checkout brings it right back. Same for a key you overwrote. Same for that author identity. History is append-only unless you go out of your way to rewrite it, and rewriting published history creates its own mess.
So none of my five repos went public with their real history. Each one got the same treatment while it was still private. I created a fresh orphan branch, which is git’s way of starting a branch with no parent commits at all, committed the current state of the code as one clean snapshot, and made that the entire history. One commit. No archaeology available, because there’s nothing buried.
The author identity on that snapshot matters too. GitHub gives every account a noreply address, the one that looks like a number followed by [email protected], and you can set your commit author to it. That means the public commits carry my GitHub username and nothing else. No personal email harvestable by every scraper that crawls public repos, and they do crawl.
Then, and this is the part I’d actually insist on, verify before you flip the switch, because after is too late. The check for each repo was mechanical. Commit count equals one. Author on that commit is the noreply identity and nothing else. A pattern grep across the tree for anything shaped like a secret, the sk_live prefixes, the private key blocks, the stray .env. Zero hits on all of it or the repo stays private. Only after all five passed did any of them go public.
Was anything actually dangerous in those old histories? I never did a full inventory, and that’s the point. Auditing eighteen months of private commits across five projects for every possible leak would have taken days and I still couldn’t be sure. Replacing the history with a snapshot took minutes per repo and made the question irrelevant. When checking a thing is expensive and replacing it is cheap, replace it.
There’s a cost. The public repos show no development history, so nobody can watch the code evolve, and a rich commit graph is its own kind of credibility. I get why big open source projects would never do this. For a portfolio, the tradeoff runs the other way. A buyer clicking view source wants to see how the code is built today. Nobody is reading commit 212 from last spring, and if they are, they’re probably not shopping for a website.
The habit that came out of this stuck with me. Anything that has ever been in a repo should be treated as part of the repo, and the time to think about what your history contains is before it’s public, while you can still choose what it says.