Git Habits That Keep Solo Projects Recoverable

git-habits-that-keep-solo-projects-recoverable

Git Habits That Keep Solo Projects Recoverable. A Build Next Stack field guide for learners shipping small projects.

The three-commit floor before you walk away

Solo projects die in messy working trees, not in missing features. Before you close the laptop, leave the repo in one of three states: clean main, one WIP branch pushed, or stash with a sentence. Anything else—half-merged files, untracked config experiments, a broken test on main—becomes archaeology within a week.

Jordan, who ships a CLI tool and a static docs site on nights and weekends, runs a literal checklist in the commit message template:

  1. Does main build? Run the one command that proves it—npm test, cargo check, python -m pytest -q.
  2. Is WIP named? Branch names like fix/upload-timeout beat temp2 when you return on a tired Sunday.
  3. Is context in the message? WIP: multipart upload stalls at 8MB—repro in fixtures/large.bin saves twenty minutes of re-grepping.

The habit is not perfection; it is recoverability. You are the only person who will answer why this file changed at 11:47 p.m. three months from now.

Commit size that matches your memory span

Large solo commits feel efficient until you need to revert one bad idea inside them. Jordan targets commits that change one intention: add validation, fix typo in README, extract upload helper. Mixed commits (refactor + new feature + lockfile bump) force an all-or-nothing rollback when production hiccups on a Tuesday you forgot the details.

Practical rule: if the commit message needs and twice, split it. Git does not charge per commit. A side project with four hundred small commits is easier to bisect than forty heroic ones.

When you truly must batch—end of a hackathon block—use a temporary branch, squash locally before merge, and keep the branch until the squashed commit passes CI. Never squash away the only copy of a failing experiment you might revisit.

Tags and notes for releases you will forget

Solo devs skip tags because nobody asks for a changelog. Future you asks when a regression appeared. Jordan tags every user-visible deploy: v0.3.1-upload-fix, not semantic pedantry for its own sake but a pointer you can diff against.

Pair each tag with a one-line note in the README section Recent releases or a CHANGELOG.md entry written in sixty seconds:

  • Date — 2026-05-12
  • What shipped — multipart resume after network drop
  • Known rough edge — progress bar lies above 90%

That note is not marketing. It is a breadcrumb when a user emails you a screenshot and you cannot remember which deploy introduced the bug.

.gitignore and the secrets you almost committed

Recovery also means never needing to rotate keys because they hit GitHub. Jordan maintains a project-level .gitignore copied from a personal template: .env, .env.local, *.pem, dist/, node_modules/, OS junk, IDE folders. Before the first push, run git status with paranoid eyes—if a file has ever held a secret, assume it still does.

When a secret slips through once, treat the repo as compromised: rotate the key, use git filter-repo or BFG if it reached remote, and add a pre-commit hook that rejects obvious patterns. Solo does not mean casual about credentials; it means you are the entire security team.

Keep a .env.example with fake values and comments explaining where to get real ones. Future you should copy-paste without reading Slack history.

Branches: one active, one experimental

Branch sprawl kills solo repos faster than missing tests. Jordan caps active branches at two: main (always deployable or one fix away) and one experiment (feature or spike). Finished work merges or deletes within seven days. Stale branches become false options—you merge the wrong one at midnight.

Name experiments with an expiry hint: spike/redis-cache-may reminds you May is the decision month. When the spike dies, delete the branch on remote too; local-only cleanup is how origin accumulates ghosts.

If you need parallel ideas—UI rewrite while a bugfix must ship—bugfix branches from main, merge fast, then rebase the rewrite. Long-lived divergence without merges is a merge conflict invoice dated for when you are busiest.

Recovery drills worth ten minutes monthly

Once a month Jordan runs a tiny disaster drill on a copy of the repo or a scratch clone:

  1. Check out an old tag and confirm the documented build command still works or update the README honestly.
  2. Revert the last commit on a throwaway branch and verify tests catch what broke.
  3. Clone fresh to a new folder—if setup takes more than fifteen minutes, fix the README before adding features.

These drills surface broken docs, missing env notes, and scripts that only work on one machine. Solo projects rarely fail from lack of Git features; they fail because nobody practiced undo until production was on fire.

Log drill outcomes in an issue titled recovery drill YYYY-MM. One checkbox per month is enough accountability without a Jira cosplay.

When to rewrite history—and when to leave scars

Interactive rebase before the first push to your remote is fine. Rewriting public history on a side project others star is rude; on a private solo repo it is a judgment call. Jordan rebases WIP branches freely before merge, never force-pushes main, and documents force-push events in the changelog when collaborators exist.

Prefer git revert for mistakes already deployed. Revert commits are readable history: this release broke uploads; this commit undid it. A hidden rewrite forces you to trust your memory of what happened.

Scars in history—an reverted experiment, a hotfix with an embarrassing message—are cheaper than a pristine log that lies about how the bug was found.

When Jordan returns after a two-week vacation, the first command is git fetch –all –prune, then read the last three commit messages on main. That ritual replaces anxiety about what changed while away.

Tonight: one clean stopping point

Before you stop coding tonight, pick one recovery habit: push the WIP branch, tag if you shipped, or write the sixty-second changelog line. Do not aim for a perfect Git workflow chart—aim for a repo you can re-enter blindfolded in six weeks.

Solo Git wins when main always means buildable and every tag means something a future you can diff. Small commits and honest messages beat any GUI theme.

Run the monthly ten-minute drill on calendar repeat. Recovery practiced on a quiet evening beats recovery invented during a demo.