💡 Practical Experience
Never Force Push main/master
git push --force origin main is the most common mistake beginners make. You rewrite history, your colleagues pull code that doesn't match yours, and conflicts fly everywhere. Force push on personal branches all you want — never on shared branches. If you truly need to change shared branch history, use --force-with-lease — it checks whether someone else has pushed new commits to the remote.
Write .gitignore Before the First Commit
Committing node_modules/, .env, __pycache__/ and trying to delete them later? Too late — they'll live in history forever. The first thing after creating a repository is to write a proper .gitignore before making your first commit. Don't forget .env might contain database passwords.
Write Commit Messages for Humans
Three months from now, you'll be digging through git log trying to find a bug, and you'll see a row of fix, update, wip — you'll want to scream. Be clear: fix: resolve case-insensitive password validation during user login. Five seconds of effort now saves half an hour of debugging later.
git add -p is a Superpower
You changed 3 files, but only 1 is a bugfix — the other 2 are formatting tweaks. Don't git add . and make one giant commit. git add -p lets you select changes chunk by chunk for staging, so each commit only contains related modifications.
Don't Overcomplicate Your Branch Strategy
Git Flow, GitHub Flow, GitLab Flow... Many teams spend enormous time debating branch strategies. Most projects only need main + feature branches. Develop a feature, merge it. Found a bug, hotfix it. Overly complex branch strategies only increase the probability of merge conflicts.