Skip to content
ExponaBLOG
GIT & GITHUB FOR PROFESSIONAL DEVELOPERS · DAY 082 / 100

Common Git mistakes: a Git & GitHub guide for developers

Habits that cause pain.

Expona Admin6 min read

Common Git mistakes: a Git & GitHub guide for developers

We've all been there: a commit that should've taken five minutes somehow rewrites your team's history, or a secret key ends up in production. Common Git mistakes: a Git & GitHub guide for developers aren't just annoyances—they compound over time, turning workflow friction into genuine risk. Learning to recognize and avoid these patterns early saves your team hours of recovery work and keeps your codebase healthier.

Huge commits mixing many changes

One of the most damaging habits we see is bundling unrelated changes into a single commit. You're refactoring the payment module, fixing a typo in the readme, updating dependencies, and changing the logging strategy—all in one 200-line commit. When something breaks in production three weeks later, you can't isolate which change caused it.

Let's say you're working on a checkout flow. You touch the payment handler, the order database schema, the email notification template, and the analytics tracker. You finish everything at 5 PM and commit it all together:

bash
git add .
git commit -m "checkout improvements"

Two weeks later, conversion rates drop. Was it the payment logic? The schema change? The analytics? You're forced to revert the entire commit and lose all that work, or spend hours bisecting to find the culprit. A better approach:

bash
git add src/payment/handler.ts src/payment/handler.spec.ts
git commit -m "refactor: extract payment processor validation logic"

git add src/order/schema.ts src/order/migrations/
git commit -m "feat: add order metadata field for tracking source"

git add src/email/templates/order-confirmation.html
git commit -m "fix: correct order total display in confirmation email"

git add src/analytics/tracker.ts
git commit -m "feat: track checkout step completion metrics"

Now when something breaks, you can bisect to a specific commit in seconds. Code review becomes meaningful—reviewers can actually understand what changed and why. And if one change needs to be reverted, the others stay intact.

The rule: one logical concern per commit. If your commit message uses the word "and", split it into multiple commits.

Force-pushing shared branches

Force-pushing is a powerful tool, but on a shared branch it's a grenade. Picture this: your teammate pulls main at 2 PM and starts building a feature. You realize main has a bad commit, so at 2:15 PM you do:

bash
git reset --hard HEAD~1
git push --force origin main

Your teammate's local main is now out of sync with the remote. Their next pull creates a confusing merge conflict that looks like their code disappeared. They panic. They force-push their changes back. You're now in a destructive rebase loop.

If you need to undo a commit on a shared branch, use revert instead:

bash
git revert HEAD
git push origin main

This creates a new commit that undoes the changes, preserving history. Everyone else pulls and gets a clean forward-moving timeline.

Force-push is fine on your own feature branches—that's expected workflow. But once code is on a shared branch (main, develop, release, etc.), treat it as immutable. If you absolutely must force-push to a shared branch because of a security incident or corrupted history, warn your entire team synchronously via Slack or a standup, not asynchronously in a commit message.

Committing secrets or build output

Accidentally committing an AWS key, database password, or API token is shockingly common. Even if you delete it in the next commit, the secret lives in your repository history forever. An attacker cloning your repo sees the exposed key. Rotating it everywhere it's used becomes a emergency.

Worse, many teams commit build artifacts: node_modules, dist, build, .jar files, or compiled binaries. Your repository balloons to gigabytes. Cloning becomes painfully slow. Merging becomes a nightmare because unrelated branch changes both modified thousands of generated files.

Start with a proper .gitignore:

bash
# Secrets and environment
.env
.env.local
.env.*.local

# Build output
dist/
build/
*.jar
*.war
node_modules/

# IDE and OS
.idea/
.vscode/
.DS_Store
*.swp

# Logs
logs/
*.log

For secrets that your application genuinely needs, use environment variables or a secret manager (AWS Secrets Manager, HashiCorp Vault, 1Password, etc.). Never put them in code.

If you've already committed a secret, it's not enough to delete it and push. The secret is still in history. Use git-filter-repo to rewrite history:

bash
pip install git-filter-repo
git filter-repo --path .env --invert-paths

Then force-push and have everyone on your team rebase their local branches. It's painful, which is why prevention through proper .gitignore is so much better.

Long-lived feature branches

A feature branch that stays open for three weeks accumulates painful merge conflicts. Your teammate rebased main five times while you've been in parallel work. When you finally open a pull request, there are 50 merge conflicts in files you didn't even touch.

Worse, the longer a branch lives, the more context you lose. By day 14, you've half-forgotten why you made certain decisions. Code review comments feel stale. The changes have drifted further from the original requirements. And if two long-lived branches both touch the same code, integration becomes a nightmare.

Aim to keep feature branches alive for 2–5 days maximum. Break your work into smaller chunks:

  • Instead of a two-week branch implementing a full payment system, break it into: database schema changes (one PR), payment processor integration (another PR), refund handling (another PR).
  • Open PRs for work-in-progress code if it helps. Use draft PRs in GitHub so reviewers know it's not ready, but your teammates can give early feedback.
  • Keep pulling main into your feature branch every day or two, so you're never far out of sync.
bash
# Stay synced while developing
git fetch origin
git rebase origin/main

If a rebase conflict occurs, you catch it early when the code is fresh in your head. Your teammates are merging small, focused changes instead of massive ones. Everyone's code review gets faster and more thorough.

Common mistakes summary

These four habits show up on almost every team we've worked with. The pain they cause scales with team size—what's annoying for two developers becomes paralyzing for ten. The good news: they're all preventable with discipline and the right defaults.

Mistake Impact Prevention
Huge commits mixing changes Impossible to debug, complex reviews, painful reverts One logical concern per commit; use git add to stage pieces
Force-pushing shared branches Broken local clones, lost work, team friction Use revert instead; force-push only feature branches
Committing secrets or build output Security breach, huge repository size, slow clones Proper .gitignore, environment variables for secrets, secret manager
Long-lived feature branches Merge conflicts, stale context, delayed integration Keep branches under 5 days; rebase on main daily

Key takeaways

  • Atomic commits: Each commit should represent one logical unit of work. If you're tempted to say "and" in your commit message, split it.
  • Revert, don't force-push: On shared branches, use git revert to undo changes. Reserve force-push for your own feature branches.
  • Gitignore and secrets managers: Build artifacts and secrets never belong in version control. Use .gitignore proactively and store sensitive data in environment variables or a dedicated secret manager.
  • Short-lived branches: Keep feature branches open for days, not weeks. Pull main frequently and open PRs early to reduce merge pain and keep context fresh.
  • History matters: Your commit history is documentation. Treat it as a narrative that helps future developers (and future you) understand why code changed, not just what changed.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles