Git Best Practices: Commit Messages, Branching and Collaboration
Best practices include writing meaningful commits, using branches properly, and avoiding risky commands.
Git Best Practices: Commit Messages, Branching and Collaboration
Git is a powerful tool, but using it effectively requires discipline and consistency. Best practices are not arbitrary rules; they are proven techniques that prevent common mistakes, make collaboration smoother, and keep your repository history readable and useful. Teams that follow Git best practices spend less time resolving conflicts, debugging history, and explaining past decisions. Teams that do not struggle with messy commit logs, lost work, and constant merge headaches.
These best practices apply whether you are working alone on a personal project or contributing to a large team codebase. They cover every aspect of Git usage from writing commit messages to structuring branches to collaborating with others. To understand these practices fully, it is helpful to be familiar with Git core concepts, branching fundamentals, and basic Git workflow.
Commit Messages → Write meaningful, structured messages
Branching → Use feature branches, keep main stable
Merging → Rebase before merging, avoid merge commits when possible
Collaboration → Pull before push, communicate large changes
History → Keep history clean, squash related commits
Security → Never commit secrets, use .gitignore
Writing Good Commit Messages
A commit message is the only documentation for why a change was made. Future developers, including your future self, will read these messages to understand the evolution of the codebase. Good commit messages tell a story. Bad commit messages create confusion.
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat - New feature
fix - Bug fix
docs - Documentation only
style - Code style changes (formatting, semicolons, etc.)
refactor - Code change that neither fixes a bug nor adds a feature
perf - Performance improvement
test - Adding or fixing tests
chore - Maintenance tasks (build process, dependencies)
feat(auth): add password reset functionality
- Add reset token generation endpoint
- Implement email sending via SMTP
- Create password reset form page
- Add token validation and expiration
feat(api): add rate limiting to public endpoints
Implements token bucket algorithm for rate limiting.
Limits are 100 requests per minute per IP address.
Returns 429 status code when limit exceeded.
fix(cart): prevent duplicate items when adding same product
Previously, adding the same product twice created duplicate
cart items. Now increments quantity instead.
Closes #456
fix
Update
WIP
stuff
Fixed stuff
Changed things
Bug fix
asdf
temp
working on it
Branching Best Practices
Branching is one of Git's most powerful features, but poor branch management leads to confusion and integration problems. Following branching best practices keeps your repository organized and your team productive.
- Keep main branch stable: The main branch should always contain production-ready code. Never commit directly to main. Always use pull requests or merge requests.
- Use feature branches: Create a new branch for every feature, bug fix, or experiment. Name branches descriptively:
feature/user-authentication,bugfix/login-error,hotfix/critical-patch. - Delete branches after merging: Merged branches are clutter. Delete them locally and remotely after integration. Git tracks the merge, so the branch is not needed.
- Keep branches short-lived: Long-running branches accumulate drift and create painful merges. Aim to merge feature branches within a few days. If a feature takes longer, merge main into your branch regularly.
- Use consistent naming conventions: Agree on a branch naming convention with your team. Common patterns include prefixing with feature/, bugfix/, hotfix/, release/, and using kebab-case.
feature/add-login-page
feature/user-authentication
bugfix/fix-navigation-error
hotfix/security-patch-2.1.1
release/v2.0.0
docs/update-readme
chore/update-dependencies
Commit Best Practices
How you commit changes affects the readability of your history and the ease of debugging. Small, focused commits are easier to understand, revert, and cherry-pick than large, sweeping changes.
- Commit early and often: Small commits are easier to understand, revert, and debug. Aim for commits that represent one logical change. If you are writing "and" in your commit message, consider splitting the commit.
- Each commit should do one thing: A commit should fix one bug, add one feature, or refactor one component. Mixing unrelated changes makes history harder to navigate and revert.
- Do not commit half-done work: Only commit code that works. Half-finished features belong in your working directory or a stash, not in the permanent history.
- Test before you commit: Run your tests locally before committing. A commit that breaks the build disrupts everyone who pulls your changes.
- Review your changes before committing: Use
git diffto review what you are about to commit. Catching mistakes before they enter history saves time and prevents confusion.
# Instead of one large commit:
Commit: "Add user authentication and profile editing and password reset"
# Do multiple focused commits:
Commit 1: feat(auth): add user registration endpoint
Commit 2: feat(auth): add login endpoint with JWT
Commit 3: feat(profile): add profile view endpoint
Commit 4: feat(profile): add profile edit endpoint
Commit 5: feat(auth): add password reset flow
Collaboration Best Practices
Git is designed for collaboration, but smooth collaboration requires discipline. Following these practices prevents conflicts and keeps everyone in sync.
- Pull before you push: Always pull the latest changes from the remote before pushing. If someone else pushed while you were working, you need to integrate their changes first.
- Push frequently: Push your commits to the remote regularly, even if your branch is not complete. This backs up your work and allows others to see your progress.
- Communicate large changes: If you are about to push a large refactoring or a change that affects many files, let your team know. This helps them prepare and avoid conflicts.
- Use pull requests for code review: Never merge your own code without review on team projects. Pull requests provide a forum for discussion, catching bugs and improving quality.
- Keep pull requests small: Small pull requests are easier to review and merge. Aim for changes under 400 lines. Large pull requests overwhelm reviewers and increase the chance of missed issues.
Merging and Rebasing Best Practices
Choosing between merge and rebase depends on your situation. Both have valid uses, and understanding when to use each is a mark of Git proficiency.
- Rebase feature branches before merging: Before merging your feature branch into main, rebase it onto the latest main. This creates a linear history without merge commits and resolves conflicts on your branch rather than in main.
- Never rebase shared branches: Do not rebase branches that others have already pulled. Rebasing rewrites history, causing divergence and confusion for anyone who has based work on the original commits.
- Merge shared branches: When integrating a feature branch that others have worked on, use merge instead of rebase. Merge preserves the true history of when branches were integrated.
- Use merge commits for releases: Merge commits clearly mark when a feature was integrated into a release branch, which is valuable for understanding release contents.
# Start a feature branch from latest main
git checkout main
git pull origin main
git checkout -b feature/new-feature
# Work on feature (multiple commits)
git add .
git commit -m "feat: add part one"
git add .
git commit -m "feat: add part two"
# Before merging, rebase onto latest main
git checkout main
git pull origin main
git checkout feature/new-feature
git rebase main
# Now merge (fast-forward possible)
git checkout main
git merge feature/new-feature
git push origin main
Repository Housekeeping Best Practices
A well-maintained repository is easier to work with and less prone to errors. Regular housekeeping prevents common problems before they happen.
- Use .gitignore properly: Never commit dependencies, build artifacts, environment files, or IDE configurations. These clutter the repository and cause unnecessary conflicts.
- Never commit secrets: API keys, passwords, tokens, and certificates do not belong in version control. Use environment variables or secrets management. If a secret is committed, rotate it immediately.
- Keep repository size small: Large files, binaries, and generated assets bloat the repository. Use Git LFS for large files or exclude them entirely.
- Run git gc periodically: Garbage collection optimizes repository storage by compressing objects and removing unreachable data. Git runs it automatically, but you can run
git gcmanually. - Remove stale branches: Delete local and remote branches that are no longer needed. Use
git branch -dfor local andgit push origin --deletefor remote branches.
Common Git Best Practices Mistakes to Avoid
- Writing vague commit messages: "Fix bug" or "Update" tells future developers nothing. Write messages that explain what changed and why.
- Committing directly to main: Direct commits to main bypass code review and can break the build for everyone. Always use feature branches and pull requests.
- Pushing before pulling: Pushing without pulling first causes rejected pushes and forces you to resolve conflicts after the fact.
- Not pulling before starting work: Starting work on an outdated main branch guarantees merge conflicts. Pull before creating your feature branch.
- Committing large, unrelated changes together: Mixed commits are hard to revert and understand. Keep commits focused on one logical change.
- Forgetting to push tags: Tags are local by default. Use
git push --tagsto share them with the team.
Team Agreement Essentials
Every team using Git should document and agree on these practices. Consistency across the team is more important than any single rule.
- Commit message format: Agree on a format like Conventional Commits and enforce it with commit-msg hooks.
- Branch naming convention: Decide on prefixes (feature/, bugfix/, hotfix/) and enforce them.
- Merge vs rebase policy: Agree on when to merge and when to rebase. Document the decision.
- Pull request process: Define how many approvals are required, who can merge, and how long PRs stay open.
- Main branch protection: Require pull requests, status checks, and approvals before merging to main.
- Release process: Define how releases are tagged and how release branches are managed.
□ Commit messages follow Conventional Commits format
□ Feature branches created from latest main
□ Pull requests require at least one approval
□ All CI checks must pass before merge
□ No direct commits to main
□ Branches deleted after merge
□ Rebasing used on feature branches before merge
□ Merge commits used for shared branches
□ .gitignore includes all build artifacts and secrets
□ Secrets never committed to repository
Frequently Asked Questions
- How long should a commit message be?
The subject line should be under 50 characters. The body should wrap at 72 characters. This ensures messages display properly in terminal and GUI tools. - How often should I commit?
Commit whenever you complete a small, logical unit of work. If you are about to try something risky, commit first. If you are switching tasks, commit first. Aim for multiple commits per day, not one giant commit at the end. - Should I use git pull --rebase?
Yes, for feature branches.git pull --rebaseapplies your local commits on top of remote changes, creating a linear history. Usegit pull(with merge) only on shared branches where you want to preserve the exact merge timeline. - What is the difference between git merge and git rebase?
Merge creates a merge commit and preserves the exact history. Rebase rewrites commits to create a linear history. Use rebase for cleaning up feature branches before merging. Use merge for integrating shared branches. - How do I enforce commit message format?
Use a commit-msg Git hook or a CI check. Tools like commitlint can validate commit messages automatically. - What should I learn next after Git best practices?
After mastering best practices, explore Git workflows, Git hooks for automation, advanced Git commands, and common Git mistakes for complete Git mastery.
