---
title: "Your Code Needs to Live Somewhere Other Than Your Laptop"
description: "GitHub as Your Bridge to Production\r\n\r\nYou ever hear about the senior programmer who got hit by a bus?\r\n\r\nMetaphorically. He's fine. But the company wasn't.\r\n\r\nBack when I first started coding there were floppy disks or a CD burner if you wanted to be fancy. Git and GitHub weren't a thing until like 2008. FTP was cool, but it wasn't very secure; and if you had a lot of code it took forever to upload. God forbid you accidentally tried to drop your .obj files in too. We had SVN, but it was clunky and conflicts were a nightmare to resolve.\r\n\r\nToday we have Git and it's Microsoft-owned buddy GitHub - Git is a command line tool written by the dude who wrote and has a well-deserved deathgrip on Linux. It helps you keep track of all the changes you make to code and it forced you to commit - literally that's the command to make a change - to your changes. It also allows you to store your code somewhere secure (like GitHub) so it's not only on your computer. It also has this fancy merging feature so that multiple people can work on a project simultaneously and it has a way to handle conflict resolution (in code, not personally).\r\n\r\n## Connecting Replit to GitHub (Step-by-Step)\r\n\r\nGitHub will be your source of truth. Everything important lives in a GitHub repo. Here's how to connect your Replit project:\r\n\r\nIn Replit there's a Tool called \"Git\" and it will walk you through authenticating and creating a repository right in the Replit UI. But if you're crazy like me and want to do it by hand:\r\n\r\n### 1. Create a GitHub Repository\r\n\r\nGo to github.com, click \"New Repository\":\r\n\r\n- Name: Something descriptive, like `myapp-backend`\r\n- Public or Private: Your choice (private is fine for startups)\r\n- Initialize: Don't add README, .gitignore, or license - Replit will handle this\r\n- Click \"Create Repository\"\r\n\r\nGitHub will show you a URL: `https://github.com/yourusername/myapp-backend.git`\r\n\r\n### 2. Connect Replit to GitHub\r\n\r\nIn Replit, open the shell (bottom of the screen) and run:\r\n\r\n```bash\r\ngit init\r\ngit remote add origin https://github.com/yourusername/myapp-backend.git\r\ngit add .\r\ngit commit -m \"Initial commit\"\r\ngit branch -M main\r\ngit push -u origin main\r\n```\r\n\r\nYou'll need to authenticate. Replit will prompt you. Follow the instructions.\r\n\r\n### 3. Configure Git Identity\r\n\r\nTell git who you are:\r\n\r\n```bash\r\ngit config user.name \"Your Name\"\r\ngit config user.email \"your.email@example.com\"\r\n```\r\n\r\nThis ensures your commits are attributed correctly.\r\n\r\n### 4. Verify It Worked\r\n\r\nGo to your GitHub repo in a browser. You should see all your files. If you do, you're connected.\r\n\r\nFrom now on, changes you commit in Replit will push to GitHub. This is your backup, your history, and your path to production. Also any changes you make outside of Replit (hint hint) can be pulled back into Replit through GitHub.\r\n\r\n## Commit Practices That Save Your Sanity\r\n\r\nHere's how to use git without making your future self hate you:\r\n\r\n### Commit Often\r\n\r\nDon't wait until something is \"done.\" Commit when:\r\n\r\n- You finish a small feature\r\n- You fix a bug\r\n- You reach a good stopping point\r\n- You reach a bad stopping point\r\n- You're about to try something risky\r\n- It's been more than an hour since your last commit\r\n- Your gut says, \"I should commit right now\"\r\n\r\nThink of commits as save points in a video game. You want lots of them.\r\n\r\n### Write Decent Commit Messages\r\n\r\nYour commit messages should explain *why*, not *what*. The diff shows what changed. The message should explain why it changed.\r\n\r\n**Bad commit messages:**\r\n\r\n```\r\nUpdate code\r\nFix bug\r\nChanges\r\nWIP\r\nasdfasdf\r\n```\r\n\r\n**Good commit messages:**\r\n\r\n```\r\nAdd user authentication with JWT tokens\r\nFix race condition in payment processing\r\nRefactor database queries to reduce N+1 problems\r\nRemove unused dependencies to reduce bundle size\r\n```\r\n\r\nIf you're a grammar nerd you'll have noticed something. All of these messages are in the imperative mood. This is a best practice. I'm pretty sure Git's own documentation recommends it. \r\n\r\nYou can even have longer messages after the first line for added context!\r\n\r\nExample:\r\n\r\n```\r\nAdd password reset flow via email\r\n\r\nUsers were getting locked out frequently. This adds a \"forgot password\" \r\nlink that sends a reset token via email.\r\n```\r\n\r\n### When to Push\r\n\r\nPush to GitHub:\r\n\r\n- After every commit (if it's working)\r\n- Before you stop working for the day\r\n- Before you try something risky\r\n- When you want someone else to see your work\r\n\r\nDon't wait to push. Push early, push often. GitHub is your backup.\r\n\r\n### What NOT to Commit\r\n\r\nNever commit:\r\n\r\n- Passwords or API keys - remember the ants from chapter 4?\r\n- Database credentials - the ants will come\r\n- OAuth secrets - the ants will find you\r\n- Private keys - the ants will bite your private keys\r\n- Large binary files like videos - use S3\r\n- node_modules or venv directories - unnecessary junk\r\n- .env files with secrets - the ants again!\r\n\r\nUse `.gitignore` to prevent accidental commits:\r\n\r\n```\r\n# Python\r\n__pycache__/\r\n*.py[cod]\r\nvenv/\r\n.env\r\n\r\n# Node\r\nnode_modules/\r\n.env\r\n\r\n# IDE\r\n.vscode/\r\n.idea/\r\n\r\n# OS\r\n.DS_Store\r\nThumbs.db\r\n\r\n# Secrets\r\nconfig/secrets.yml\r\n*.pem\r\n*.key\r\n```\r\n\r\nPut this in `.gitignore` at the root of your repo.\r\n\r\n## Branch Strategy for Solo Founders vs Small Teams\r\n\r\nBranch strategies can get complicated. Don't let them.\r\n\r\n### Solo Founder (You)\r\n\r\nUse `main` for everything. That's it. One branch.\r\n\r\nWhy? Because complex branching strategies are overhead you don't need. You're not merging conflicting changes from 50 developers. You're building features and shipping them.\r\n\r\nWorkflow:\r\n\r\n1. Write code\r\n2. Commit to `main`\r\n3. Push to `main`\r\n4. Deploy from `main`\r\n\r\nWhen you need to try something risky, create a feature branch:\r\n\r\n```bash\r\ngit checkout -b experiment-with-websockets\r\n# ... work ...\r\ngit commit -m \"Add websocket support\"\r\n```\r\n\r\nIf it works:\r\n\r\n```bash\r\ngit checkout main\r\ngit merge experiment-with-websockets\r\ngit push\r\n```\r\n\r\nIf it doesn't work:\r\n\r\n```bash\r\ngit checkout main\r\ngit branch -D experiment-with-websockets  # Delete the failed experiment and it's like it never happened\r\n```\r\n\r\n### Small Team (2-5 People)\r\n\r\nStill mostly use `main`, but add feature branches when people are working on the same files:\r\n\r\n```bash\r\ngit checkout -b feature/user-profiles\r\n# ... work ...\r\ngit commit -m \"Add user profile page\"\r\ngit push origin feature/user-profiles\r\n```\r\n\r\nCreate a pull request on GitHub, have someone review it (even if it's just a quick glance), then merge.\r\n\r\nThis prevents conflicts and gives you a moment to catch obvious mistakes. And, if you're into more AI Copilot does an obnoxiously good job of nitpicking code, even AI-generated code.\r\n\r\n### What You Don't Need\r\n\r\nDon't use:\r\n\r\n- GitFlow (develop, release, hotfix branches) - too complex to start with\r\n- Separate staging branches - use tags instead\r\n- Long-lived feature branches - they create merge hell, I even prevent these on large development teams, baaaaad juju\r\n- Complicated rebase strategies - just merge\r\n\r\nKeep it simple. The goal is to ship features, not to impress other developers with your git expertise.\r\n\r\n## Writing Commit Messages Your Future Self Will Thank You For\r\n\r\nSix months from now, something will break. You'll need to figure out when it broke and why.\r\n\r\nGood commit messages make this easy. Bad commit messages make you want to quit programming again... for the fourth time.\r\n\r\n### The Format\r\n\r\n```\r\nShort imperative mood summary (42 chars or less)\r\n\r\nMore detailed explanation if needed. Wrap at 72 characters.\r\nExplain the problem this solves, why you chose this approach,\r\nand any tradeoffs you made.\r\n\r\n- Bullet points are fine\r\n- For listing multiple changes\r\n- But prefer one commit per logical change\r\n```\r\n\r\n### Examples\r\n\r\n**Bad:**\r\n\r\n```\r\nFixing it\r\n```\r\nWhat was \"it\"? Nobody knows. Not even you.\r\n\r\n**Good:**\r\n\r\n```\r\nFix race condition in payment processing\r\n\r\nMultiple simultaneous payments from the same user could result in\r\nduplicate charges. Added a transaction lock to prevent this.\r\n\r\nRelated to customer complaint #247.\r\n```\r\n\r\n**Bad:**\r\n\r\n```\r\nUpdates\r\n```\r\nEvery commit is an update. This tells us nothing.\r\n\r\n**Good:**\r\n\r\n```\r\nReduce database queries in user dashboard\r\n\r\nDashboard was making 42 queries per page load, causing slow responses.\r\nConsolidated into 3 queries using LEFT JOINs. Page load time reduced\r\nfrom 2.3s to 0.4s.\r\n```\r\n\r\n**Bad:**\r\n\r\n```\r\ngrraaaasdf\r\n```\r\nI get it. It's late. You're tired. But still, no.\r\n\r\n**Good:**\r\n\r\n```\r\nAdd error logging to payment webhook\r\n\r\nPayment webhook was crashing. Added logging to CloudWatch so we can\r\ndebug.\r\n```\r\n\r\nNotice how good commit messages:\r\n\r\n1. Explain what changed (briefly)\r\n2. Explain why it changed\r\n3. Sometimes include metrics or context\r\n4. Reference related issues/tickets\r\n\r\n### The Five-Second Rule\r\n\r\nCan you understand what this commit does in five seconds?\r\n\r\nIf yes, it's a good commit message.\r\nIf no, make it clearer.\r\n\r\n## GitHub as Your Backup System\r\n\r\nGitHub isn't just version control. It's your backup.\r\n\r\nYour laptop will die. Your Repl will get deleted. AWS will have an outage. GitHub is where your code survives.\r\n\r\n### What Should Live in GitHub\r\n\r\nEverything:\r\n\r\n- All source code\r\n- Configuration files (except secrets)\r\n- Database migrations\r\n- Documentation\r\n- Deployment scripts\r\n- README files\r\n- .gitignore\r\n\r\nIf it's text and it's important, it goes in GitHub.\r\n\r\n### What Should NOT Live in GitHub\r\n\r\n- Secrets (use AWS Secrets Manager)\r\n- Large files (use S3 or Git LFS)\r\n- Generated files (build outputs, compiled code)\r\n- Dependencies (node_modules, venv)\r\n- User-uploaded content\r\n\r\n### Making Sure You're Actually Backed Up\r\n\r\nRun this occasionally:\r\n```bash\r\ngit status\r\n```\r\n\r\nIf you see \"untracked files\" or \"changes not staged,\" you have work that isn't backed up. Commit and push it.\r\n\r\nGet in the habit of running `git status` before you stop working. If there are uncommitted changes, commit them.\r\n\r\n## Pull Requests for Code Review\r\n\r\nEven if you're solo, pull requests are useful:\r\n\r\n1. Create a feature branch\r\n2. Push it to GitHub\r\n3. Create a pull request\r\n4. Review your own changes\r\n5. Merge when satisfied\r\n\r\nThis forces you to look at all changes in one place. You catch mistakes you'd miss otherwise.\r\n\r\nI've found typos, logic errors, and debug code I forgot to remove - all by reviewing my own pull requests.\r\n\r\nWhen you have a team, pull requests become collaborative:\r\n\r\n- Someone reviews your code\r\n- They spot issues you missed\r\n- You fix them before merging\r\n- Code quality improves\r\n\r\nDon't skip this step. Your future self will thank you.\r\n\r\n## Setting Up GitHub Actions (Preview)\r\n\r\nWe'll cover GitHub Actions in detail in the next chapter, but here's the connection:\r\n\r\nGitHub is your source of truth. When you push a tag to GitHub, it triggers a GitHub Action that deploys your code.\r\n\r\nThe workflow:\r\n\r\n1. Code lives in Replit\r\n2. Commit and push to GitHub\r\n3. Create a tag: `git tag 202501201430`\r\n4. Push tag: `git push origin 202501201430`\r\n5. GitHub Action sees the tag and deploys\r\n\r\nGitHub is the bridge between development (Replit) and production (AWS Lightsail).\r\n\r\n## Common GitHub Gotchas\r\n\r\nHere are mistakes you or someone you love may or may not have already made:\r\n\r\n### Gotcha 1: Committing Secrets\r\n\r\nYou commit your `.env` file with all your API keys. Now they're in GitHub history forever.\r\n\r\n**Solution:** Add `.env` to `.gitignore` immediately. If you already committed secrets, rotate them (change the passwords/keys) and then purge from git history using `git filter-branch` or a tool like BFG Repo Cleaner. Also, remember the fire ants are coming for you.\r\n\r\n### Gotcha 2: Merge Conflicts\r\n\r\nYou edit the same file on two different machines. Push from one. Try to push from the other. Git complains.\r\n\r\n**Solution:**\r\n\r\n```bash\r\ngit pull --rebase\r\n# Fix conflicts if any\r\ngit push\r\n```\r\n\r\nBetter solution: Work in one place at a time. If you must work in multiple places, always pull before you start working.\r\n\r\n### Gotcha 3: Lost Commits\r\n\r\nMade commits, forgot to push, switched computers. Commits are gone.\r\n\r\n**Solution:** Always push before switching contexts. Make it a habit. There is no \"fix\" for this one.\r\n\r\n### Gotcha 4: Broken Main Branch\r\n\r\nPushed something that broke everything. Production is down. Panic.\r\n\r\n**Solution:**\r\n```bash\r\n# Revert to previous commit\r\ngit revert HEAD\r\ngit push\r\n\r\n# Or if you haven't pushed yet\r\ngit reset HEAD~1\r\n```\r\n\r\nThis is why we use tags for deployment. If main is broken, production still runs the last tagged version.\r\n\r\n### Gotcha 5: Accidentally Deleted Branch\r\n\r\nCreated a feature branch, decided you didn't need it, deleted it. Two days later realize you do need it.\r\n\r\n**Solution:** Deleted branches can be recovered:\r\n```bash\r\ngit reflog  # Find the commit SHA\r\ngit checkout -b recovered-branch <SHA>\r\n```\r\n\r\nGit keeps deleted branches for about 30 days. After that, they're really gone.\r\n\r\n## Real Example\r\n\r\nI'm going through my Git history for the past 30 days and here's what we've got:\r\n\r\n- 294 commits across 19 different repositories\r\n- Created 7 new repositories\r\n- Created a pull request that received 15 comments - we were \"discussing\"\r\n- Opened 6 other pull requests\r\n- Reviewed 3 pull requests\r\n\r\n---\r\n\r\n## Action Items\r\n\r\n- [ ] Create a GitHub account if you don't have one\r\n- [ ] Create a repository for your project\r\n- [ ] Connect your Replit project to GitHub\r\n- [ ] Add a .gitignore file with common excludes\r\n- [ ] Make your first commit with a good commit message\r\n- [ ] Practice: make a small change, commit, push\r\n- [ ] Set up GitHub Issues to track your TODOs\r\n\r\n## Red Flags You're Doing Git Wrong\r\n\r\n- Code only exists on your laptop\r\n- Days go by between commits\r\n- Commit messages are all \"update\" or \"fix\"\r\n- .env file is committed to the repo\r\n- You avoid committing because \"it's not ready yet\"\r\n- Only one person knows how git works on your team\r\n- Merge conflicts happen constantly\r\n\r\n## Key Takeaways\r\n\r\n- GitHub is your source of truth and backup\r\n- Commit often (multiple times per day)\r\n- Write commit messages that explain why, not just what\r\n- Push regularly - don't let work pile up uncommitted\r\n- Use .gitignore to prevent committing secrets\r\n- Keep branching simple - don't over-engineer it\r\n- Review your own code via pull requests\r\n\r\n## Resources\r\n\r\n- GitHub Docs: https://docs.github.com/\r\n- Git Basics: https://git-scm.com/book/en/v2/Getting-Started-Git-Basics\r\n- Writing Good Commit Messages: https://chris.beams.io/posts/git-commit/\r\n- .gitignore templates: https://github.com/github/gitignore\r\n\r\n\\newpage"
image: "https://cdn.sethserver.com/blog-images/github-your-bridge-from-replit-to-production-social-1769975080.webp"
---

# Your Code Needs to Live Somewhere Other Than Your Laptop

Let me tell you a story about a senior programmer who got hit by a bus.

Don't worry... he's fine. Metaphorically. His company wasn't, though. All of their code lived exclusively on his laptop. When he was out for three weeks recovering, the entire engineering team sat around contemplating their life choices. This is what we call "bus factor" in software development, and it's been a problem since before most of us were born.

I've been writing code since floppy disks were the backup solution. The fancy option back then was burning code to CDs. Then came FTP uploads that took forever, especially that one time I accidentally uploaded every single .obj file from a compiled project. If you don't know what that is, consider yourself lucky. If you do know, you're wincing right now because you've done it too.

Version control used to be a nightmare. Then Git came along.

## Git Is Your Safety Net (Not Your Enemy)

Git was created by Linus Torvalds, the "Linux guy." Microsoft bought GitHub, which is still strange to think about. But now it's the standard. You can't avoid it, and honestly, you shouldn't want to. Bitbucket and GitLab (thanks for the swag) exist too, but they're just not as mainstream.

Here's what Git actually does in plain English: it tracks every change you make to your code. It forces you to "commit" (literally the command) to those changes. It stores everything somewhere secure that isn't just your laptop. And it lets multiple people work on the same codebase without everyone's changes turning into a pile of conflict-ridden garbage.

This matters because your laptop *will* die. Replit *will* occasionally delete things. AWS *will* have an outage. GitHub is where your code survives all of that.

## The Commit-Often Philosophy

I looked at my Git history from the past 30 days: 294 commits across 19 repositories. About 10 commits per day. Some days hit 30+. Some days are zero, but those are rare.

This isn't because I'm particularly disciplined. It's because I've lost work before, and it sucked. Hours of work, gone, because I thought "I'll commit when I'm done." I wasn't done. I had to rewrite everything from memory.

Now I commit obsessively. When do you commit? Finished a small feature? Commit. Fixed a bug? Commit. Reached a stopping point, working or not? Commit. About to try something risky? Definitely commit. Been more than ten minutes? Commit. Going to lunch? Commit. I'm going to keep saying this until you go commit your code.

Think of commits like video game save points. You want lots of them. You never know when you'll need to get hit by a bus.

## Write Commit Messages Your Future Self Won't Hate

Bad commit messages I've seen (and written):
- "Update code"
- "Fix bug"
- "Changes"
- "WIP"
- "asdfasdf"
- "grraaaasdf" (it's late, you're tired, but still no)

These tell you nothing. Six months from now when something breaks, you'll curse past-you for being so lazy.

Good commit messages look like this:

```
Add user authentication with JWT
```

```
Add forgot password link to login page
```

The format is simple: short summary (under 50 characters), then a longer explanation if needed. The message should explain *why* you made the change, not just *what* changed. The code diff shows what changed.

Use imperative mood: "Add feature" not "Added feature." This matches Git's own convention and keeps everything consistent.

## Keep Your Branching Strategy Stupid Simple

Most branching strategies you'll read about online are designed for 50+ person teams. You're not that yet. Don't pretend you are.

If you're solo: use `main` for everything. One branch. Ship features and move on. Only create a feature branch when you're trying something risky and want to preserve `main` as "known good."

Small team (2-5 people): still mostly use `main`. Add feature branches when multiple people are working on the same files or when you want someone to review before merging.

Long-lived feature branches are bad juju even on large teams. Keep it simple. Your goal is to ship features, not to impress other programmers with your Git expertise.

## GitHub Is Your Backup System

I'll say it again: your laptop will die. GitHub is where your code survives.

What should live in GitHub? Everything that's text. Source code, configuration files (except secrets), database migrations, documentation, deployment scripts, README files. If it's text and it's important, it goes in GitHub.

What should NOT live in GitHub? Secrets (use AWS Secrets Manager), large files like videos or images (use S3), generated files, dependencies like node\_modules. And for the love of all that is holy, never commit your .env file with API keys. Remember the fire ants from my security post? Same principle.

Make it a habit: run `git status` before you stop working. If you see uncommitted changes, commit them. Then push. Every single time.

## The Bridge to Production

Here's how this all connects to deployment: GitHub is the bridge between your development environment (usually Replit these days) and production (like AWS or GCP). When you push a tag to GitHub, a GitHub Action triggers and deploys your code automatically. This ensures you never deploy code that isn't in version control, and you can always roll back to a previous version.

If you zoned out there for a minute, just remember that GitHub sits in the middle of everything. Pull it out and the whole pipeline falls apart.

-Sethers


```json
{"@context": "https://schema.org", "@type": "BlogPosting", "headline": "Your Code Needs to Live Somewhere Other Than Your Laptop", "datePublished": "2026-02-01T20:12:25", "dateModified": "2026-09-17T19:48:17", "image": {"@type": "ImageObject", "url": "https://cdn.sethserver.com/blog-images/github-your-bridge-from-replit-to-production-social-1769975080.webp", "width": 400, "height": 400}, "url": "https://www.sethserver.com/programming/your-code-needs-to-live-somewhere-other-than-your-laptop.html", "author": {"@type": "Person", "name": "Seth Black", "url": "https://www.linkedin.com/in/seth-black-tx"}, "publisher": {"@type": "Organization", "name": "Sethserver", "logo": {"@type": "ImageObject", "url": "https://www.sethserver.com/static/images/PaperAirplane512.png"}}, "description": "GitHub as Your Bridge to Production\r\n\r\nYou ever hear about the senior programmer who got hit by a bus?\r\n\r\nMetaphorically. He's fine. But the company wasn't.\r\n\r\nBack when I first started coding there were floppy disks or a CD burner if you wanted to be fancy. Git and GitHub weren't a thing until like 2008. FTP was cool, but it wasn't very secure; and if you had a lot of code it took forever to upload. God forbid you accidentally tried to drop your .obj files in too. We had SVN, but it was clunky and conflicts were a nightmare to resolve.\r\n\r\nToday we have Git and it's Microsoft-owned buddy GitHub - Git is a command line tool written by the dude who wrote and has a well-deserved deathgrip on Linux. It helps you keep track of all the changes you make to code and it forced you to commit - literally that's the command to make a change - to your changes. It also allows you to store your code somewhere secure (like GitHub) so it's not only on your computer. It also has this fancy merging feature so that multiple people can work on a project simultaneously and it has a way to handle conflict resolution (in code, not personally).\r\n\r\n## Connecting Replit to GitHub (Step-by-Step)\r\n\r\nGitHub will be your source of truth. Everything important lives in a GitHub repo. Here's how to connect your Replit project:\r\n\r\nIn Replit there's a Tool called \"Git\" and it will walk you through authenticating and creating a repository right in the Replit UI. But if you're crazy like me and want to do it by hand:\r\n\r\n### 1. Create a GitHub Repository\r\n\r\nGo to github.com, click \"New Repository\":\r\n\r\n- Name: Something descriptive, like `myapp-backend`\r\n- Public or Private: Your choice (private is fine for startups)\r\n- Initialize: Don't add README, .gitignore, or license - Replit will handle this\r\n- Click \"Create Repository\"\r\n\r\nGitHub will show you a URL: `https://github.com/yourusername/myapp-backend.git`\r\n\r\n### 2. Connect Replit to GitHub\r\n\r\nIn Replit, open the shell (bottom of the screen) and run:\r\n\r\n```bash\r\ngit init\r\ngit remote add origin https://github.com/yourusername/myapp-backend.git\r\ngit add .\r\ngit commit -m \"Initial commit\"\r\ngit branch -M main\r\ngit push -u origin main\r\n```\r\n\r\nYou'll need to authenticate. Replit will prompt you. Follow the instructions.\r\n\r\n### 3. Configure Git Identity\r\n\r\nTell git who you are:\r\n\r\n```bash\r\ngit config user.name \"Your Name\"\r\ngit config user.email \"your.email@example.com\"\r\n```\r\n\r\nThis ensures your commits are attributed correctly.\r\n\r\n### 4. Verify It Worked\r\n\r\nGo to your GitHub repo in a browser. You should see all your files. If you do, you're connected.\r\n\r\nFrom now on, changes you commit in Replit will push to GitHub. This is your backup, your history, and your path to production. Also any changes you make outside of Replit (hint hint) can be pulled back into Replit through GitHub.\r\n\r\n## Commit Practices That Save Your Sanity\r\n\r\nHere's how to use git without making your future self hate you:\r\n\r\n### Commit Often\r\n\r\nDon't wait until something is \"done.\" Commit when:\r\n\r\n- You finish a small feature\r\n- You fix a bug\r\n- You reach a good stopping point\r\n- You reach a bad stopping point\r\n- You're about to try something risky\r\n- It's been more than an hour since your last commit\r\n- Your gut says, \"I should commit right now\"\r\n\r\nThink of commits as save points in a video game. You want lots of them.\r\n\r\n### Write Decent Commit Messages\r\n\r\nYour commit messages should explain *why*, not *what*. The diff shows what changed. The message should explain why it changed.\r\n\r\n**Bad commit messages:**\r\n\r\n```\r\nUpdate code\r\nFix bug\r\nChanges\r\nWIP\r\nasdfasdf\r\n```\r\n\r\n**Good commit messages:**\r\n\r\n```\r\nAdd user authentication with JWT tokens\r\nFix race condition in payment processing\r\nRefactor database queries to reduce N+1 problems\r\nRemove unused dependencies to reduce bundle size\r\n```\r\n\r\nIf you're a grammar nerd you'll have noticed something. All of these messages are in the imperative mood. This is a best practice. I'm pretty sure Git's own documentation recommends it. \r\n\r\nYou can even have longer messages after the first line for added context!\r\n\r\nExample:\r\n\r\n```\r\nAdd password reset flow via email\r\n\r\nUsers were getting locked out frequently. This adds a \"forgot password\" \r\nlink that sends a reset token via email.\r\n```\r\n\r\n### When to Push\r\n\r\nPush to GitHub:\r\n\r\n- After every commit (if it's working)\r\n- Before you stop working for the day\r\n- Before you try something risky\r\n- When you want someone else to see your work\r\n\r\nDon't wait to push. Push early, push often. GitHub is your backup.\r\n\r\n### What NOT to Commit\r\n\r\nNever commit:\r\n\r\n- Passwords or API keys - remember the ants from chapter 4?\r\n- Database credentials - the ants will come\r\n- OAuth secrets - the ants will find you\r\n- Private keys - the ants will bite your private keys\r\n- Large binary files like videos - use S3\r\n- node_modules or venv directories - unnecessary junk\r\n- .env files with secrets - the ants again!\r\n\r\nUse `.gitignore` to prevent accidental commits:\r\n\r\n```\r\n# Python\r\n__pycache__/\r\n*.py[cod]\r\nvenv/\r\n.env\r\n\r\n# Node\r\nnode_modules/\r\n.env\r\n\r\n# IDE\r\n.vscode/\r\n.idea/\r\n\r\n# OS\r\n.DS_Store\r\nThumbs.db\r\n\r\n# Secrets\r\nconfig/secrets.yml\r\n*.pem\r\n*.key\r\n```\r\n\r\nPut this in `.gitignore` at the root of your repo.\r\n\r\n## Branch Strategy for Solo Founders vs Small Teams\r\n\r\nBranch strategies can get complicated. Don't let them.\r\n\r\n### Solo Founder (You)\r\n\r\nUse `main` for everything. That's it. One branch.\r\n\r\nWhy? Because complex branching strategies are overhead you don't need. You're not merging conflicting changes from 50 developers. You're building features and shipping them.\r\n\r\nWorkflow:\r\n\r\n1. Write code\r\n2. Commit to `main`\r\n3. Push to `main`\r\n4. Deploy from `main`\r\n\r\nWhen you need to try something risky, create a feature branch:\r\n\r\n```bash\r\ngit checkout -b experiment-with-websockets\r\n# ... work ...\r\ngit commit -m \"Add websocket support\"\r\n```\r\n\r\nIf it works:\r\n\r\n```bash\r\ngit checkout main\r\ngit merge experiment-with-websockets\r\ngit push\r\n```\r\n\r\nIf it doesn't work:\r\n\r\n```bash\r\ngit checkout main\r\ngit branch -D experiment-with-websockets  # Delete the failed experiment and it's like it never happened\r\n```\r\n\r\n### Small Team (2-5 People)\r\n\r\nStill mostly use `main`, but add feature branches when people are working on the same files:\r\n\r\n```bash\r\ngit checkout -b feature/user-profiles\r\n# ... work ...\r\ngit commit -m \"Add user profile page\"\r\ngit push origin feature/user-profiles\r\n```\r\n\r\nCreate a pull request on GitHub, have someone review it (even if it's just a quick glance), then merge.\r\n\r\nThis prevents conflicts and gives you a moment to catch obvious mistakes. And, if you're into more AI Copilot does an obnoxiously good job of nitpicking code, even AI-generated code.\r\n\r\n### What You Don't Need\r\n\r\nDon't use:\r\n\r\n- GitFlow (develop, release, hotfix branches) - too complex to start with\r\n- Separate staging branches - use tags instead\r\n- Long-lived feature branches - they create merge hell, I even prevent these on large development teams, baaaaad juju\r\n- Complicated rebase strategies - just merge\r\n\r\nKeep it simple. The goal is to ship features, not to impress other developers with your git expertise.\r\n\r\n## Writing Commit Messages Your Future Self Will Thank You For\r\n\r\nSix months from now, something will break. You'll need to figure out when it broke and why.\r\n\r\nGood commit messages make this easy. Bad commit messages make you want to quit programming again... for the fourth time.\r\n\r\n### The Format\r\n\r\n```\r\nShort imperative mood summary (42 chars or less)\r\n\r\nMore detailed explanation if needed. Wrap at 72 characters.\r\nExplain the problem this solves, why you chose this approach,\r\nand any tradeoffs you made.\r\n\r\n- Bullet points are fine\r\n- For listing multiple changes\r\n- But prefer one commit per logical change\r\n```\r\n\r\n### Examples\r\n\r\n**Bad:**\r\n\r\n```\r\nFixing it\r\n```\r\nWhat was \"it\"? Nobody knows. Not even you.\r\n\r\n**Good:**\r\n\r\n```\r\nFix race condition in payment processing\r\n\r\nMultiple simultaneous payments from the same user could result in\r\nduplicate charges. Added a transaction lock to prevent this.\r\n\r\nRelated to customer complaint #247.\r\n```\r\n\r\n**Bad:**\r\n\r\n```\r\nUpdates\r\n```\r\nEvery commit is an update. This tells us nothing.\r\n\r\n**Good:**\r\n\r\n```\r\nReduce database queries in user dashboard\r\n\r\nDashboard was making 42 queries per page load, causing slow responses.\r\nConsolidated into 3 queries using LEFT JOINs. Page load time reduced\r\nfrom 2.3s to 0.4s.\r\n```\r\n\r\n**Bad:**\r\n\r\n```\r\ngrraaaasdf\r\n```\r\nI get it. It's late. You're tired. But still, no.\r\n\r\n**Good:**\r\n\r\n```\r\nAdd error logging to payment webhook\r\n\r\nPayment webhook was crashing. Added logging to CloudWatch so we can\r\ndebug.\r\n```\r\n\r\nNotice how good commit messages:\r\n\r\n1. Explain what changed (briefly)\r\n2. Explain why it changed\r\n3. Sometimes include metrics or context\r\n4. Reference related issues/tickets\r\n\r\n### The Five-Second Rule\r\n\r\nCan you understand what this commit does in five seconds?\r\n\r\nIf yes, it's a good commit message.\r\nIf no, make it clearer.\r\n\r\n## GitHub as Your Backup System\r\n\r\nGitHub isn't just version control. It's your backup.\r\n\r\nYour laptop will die. Your Repl will get deleted. AWS will have an outage. GitHub is where your code survives.\r\n\r\n### What Should Live in GitHub\r\n\r\nEverything:\r\n\r\n- All source code\r\n- Configuration files (except secrets)\r\n- Database migrations\r\n- Documentation\r\n- Deployment scripts\r\n- README files\r\n- .gitignore\r\n\r\nIf it's text and it's important, it goes in GitHub.\r\n\r\n### What Should NOT Live in GitHub\r\n\r\n- Secrets (use AWS Secrets Manager)\r\n- Large files (use S3 or Git LFS)\r\n- Generated files (build outputs, compiled code)\r\n- Dependencies (node_modules, venv)\r\n- User-uploaded content\r\n\r\n### Making Sure You're Actually Backed Up\r\n\r\nRun this occasionally:\r\n```bash\r\ngit status\r\n```\r\n\r\nIf you see \"untracked files\" or \"changes not staged,\" you have work that isn't backed up. Commit and push it.\r\n\r\nGet in the habit of running `git status` before you stop working. If there are uncommitted changes, commit them.\r\n\r\n## Pull Requests for Code Review\r\n\r\nEven if you're solo, pull requests are useful:\r\n\r\n1. Create a feature branch\r\n2. Push it to GitHub\r\n3. Create a pull request\r\n4. Review your own changes\r\n5. Merge when satisfied\r\n\r\nThis forces you to look at all changes in one place. You catch mistakes you'd miss otherwise.\r\n\r\nI've found typos, logic errors, and debug code I forgot to remove - all by reviewing my own pull requests.\r\n\r\nWhen you have a team, pull requests become collaborative:\r\n\r\n- Someone reviews your code\r\n- They spot issues you missed\r\n- You fix them before merging\r\n- Code quality improves\r\n\r\nDon't skip this step. Your future self will thank you.\r\n\r\n## Setting Up GitHub Actions (Preview)\r\n\r\nWe'll cover GitHub Actions in detail in the next chapter, but here's the connection:\r\n\r\nGitHub is your source of truth. When you push a tag to GitHub, it triggers a GitHub Action that deploys your code.\r\n\r\nThe workflow:\r\n\r\n1. Code lives in Replit\r\n2. Commit and push to GitHub\r\n3. Create a tag: `git tag 202501201430`\r\n4. Push tag: `git push origin 202501201430`\r\n5. GitHub Action sees the tag and deploys\r\n\r\nGitHub is the bridge between development (Replit) and production (AWS Lightsail).\r\n\r\n## Common GitHub Gotchas\r\n\r\nHere are mistakes you or someone you love may or may not have already made:\r\n\r\n### Gotcha 1: Committing Secrets\r\n\r\nYou commit your `.env` file with all your API keys. Now they're in GitHub history forever.\r\n\r\n**Solution:** Add `.env` to `.gitignore` immediately. If you already committed secrets, rotate them (change the passwords/keys) and then purge from git history using `git filter-branch` or a tool like BFG Repo Cleaner. Also, remember the fire ants are coming for you.\r\n\r\n### Gotcha 2: Merge Conflicts\r\n\r\nYou edit the same file on two different machines. Push from one. Try to push from the other. Git complains.\r\n\r\n**Solution:**\r\n\r\n```bash\r\ngit pull --rebase\r\n# Fix conflicts if any\r\ngit push\r\n```\r\n\r\nBetter solution: Work in one place at a time. If you must work in multiple places, always pull before you start working.\r\n\r\n### Gotcha 3: Lost Commits\r\n\r\nMade commits, forgot to push, switched computers. Commits are gone.\r\n\r\n**Solution:** Always push before switching contexts. Make it a habit. There is no \"fix\" for this one.\r\n\r\n### Gotcha 4: Broken Main Branch\r\n\r\nPushed something that broke everything. Production is down. Panic.\r\n\r\n**Solution:**\r\n```bash\r\n# Revert to previous commit\r\ngit revert HEAD\r\ngit push\r\n\r\n# Or if you haven't pushed yet\r\ngit reset HEAD~1\r\n```\r\n\r\nThis is why we use tags for deployment. If main is broken, production still runs the last tagged version.\r\n\r\n### Gotcha 5: Accidentally Deleted Branch\r\n\r\nCreated a feature branch, decided you didn't need it, deleted it. Two days later realize you do need it.\r\n\r\n**Solution:** Deleted branches can be recovered:\r\n```bash\r\ngit reflog  # Find the commit SHA\r\ngit checkout -b recovered-branch <SHA>\r\n```\r\n\r\nGit keeps deleted branches for about 30 days. After that, they're really gone.\r\n\r\n## Real Example\r\n\r\nI'm going through my Git history for the past 30 days and here's what we've got:\r\n\r\n- 294 commits across 19 different repositories\r\n- Created 7 new repositories\r\n- Created a pull request that received 15 comments - we were \"discussing\"\r\n- Opened 6 other pull requests\r\n- Reviewed 3 pull requests\r\n\r\n---\r\n\r\n## Action Items\r\n\r\n- [ ] Create a GitHub account if you don't have one\r\n- [ ] Create a repository for your project\r\n- [ ] Connect your Replit project to GitHub\r\n- [ ] Add a .gitignore file with common excludes\r\n- [ ] Make your first commit with a good commit message\r\n- [ ] Practice: make a small change, commit, push\r\n- [ ] Set up GitHub Issues to track your TODOs\r\n\r\n## Red Flags You're Doing Git Wrong\r\n\r\n- Code only exists on your laptop\r\n- Days go by between commits\r\n- Commit messages are all \"update\" or \"fix\"\r\n- .env file is committed to the repo\r\n- You avoid committing because \"it's not ready yet\"\r\n- Only one person knows how git works on your team\r\n- Merge conflicts happen constantly\r\n\r\n## Key Takeaways\r\n\r\n- GitHub is your source of truth and backup\r\n- Commit often (multiple times per day)\r\n- Write commit messages that explain why, not just what\r\n- Push regularly - don't let work pile up uncommitted\r\n- Use .gitignore to prevent committing secrets\r\n- Keep branching simple - don't over-engineer it\r\n- Review your own code via pull requests\r\n\r\n## Resources\r\n\r\n- GitHub Docs: https://docs.github.com/\r\n- Git Basics: https://git-scm.com/book/en/v2/Getting-Started-Git-Basics\r\n- Writing Good Commit Messages: https://chris.beams.io/posts/git-commit/\r\n- .gitignore templates: https://github.com/github/gitignore\r\n\r\n\\newpage\r\n", "articleSection": "Technology"}
{"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "sethserver", "item": "https://www.sethserver.com/"}, {"@type": "ListItem", "position": 2, "name": "Programming", "item": "https://www.sethserver.com/programming/"}, {"@type": "ListItem", "position": 3, "name": "Your Code Needs to Live Somewhere Other Than Your Laptop", "item": "https://www.sethserver.com/programming/your-code-needs-to-live-somewhere-other-than-your-laptop.html"}]}
```
