Complete Git guide for freelance developers
Git is every developerβs essential tool. But for a freelancer juggling multiple projects, clients, and teams, mastering Git goes far beyond simple git add and git commit. A coherent branch strategy, clear commit conventions, and a workflow adapted to freelance collaboration make the difference between a project that runs smoothly and one that spirals into chaos. Hereβs a complete guide based on 16 years of experience.
Branch strategies
Your choice of branch strategy depends on project size, deployment frequency, and the number of contributors.
GitFlow: the classic method
GitFlow, popularized by Vincent Driessen in 2010, uses long-lived branches and a strict hierarchy:
main ββββββββββββββββββββββββββββββββββββββΊ (production)
β β²
βββ develop ββββββββββββββββββββββββββββββββ€ (integration)
β β β β β
β βββ feature/login βββ β
β βββ feature/api βββββ β
β β
β βββ release/1.0 βββββββββββββββββββββ
β
βββ hotfix/fix-bug βββββββββββββββββββββββΊβ
The branches:
main: production code, always stabledevelop: feature integrationfeature/*: new feature developmentrelease/*: version preparationhotfix/*: urgent production fixes
When to use it: projects with planned release cycles, mobile apps with App Store/Play Store versioning, regulated environments requiring strict deployment control.
GitHub Flow: simplicity
GitHub Flow simplifies the model with a single main branch and short feature branches:
main βββββββββββββββββββββββββββββββΊ (always deployable)
β² β²
β β
feature/A feature/B
(PR + review) (PR + review)
The principle is simple:
- Create a branch from
main - Work on the feature
- Open a Pull Request for review
- Merge into
mainafter approval - Deploy immediately
Trunk-based development: expert mode
Trunk-based development pushes the logic even further: ultra-short branches (a few hours to one day maximum) or direct commits to the main branch:
# Ephemeral branch
git checkout -b quick-fix
# Changes...
git commit -am "fix: quick fix"
git push origin quick-fix
# PR, review, merge within the hour
# Or directly on main (for small changes)
git checkout main
# Changes...
git commit -am "docs: update README"
git push origin main
Incomplete features are hidden behind feature flags:
if (featureFlag.isEnabled('new-payment-flow')) {
// New payment logic
} else {
// Legacy logic
}
My choice as a freelancer
After years of experience, my recommendation for freelancers is an adapted GitHub Flow:
- Solo projects: Pure GitHub Flow. A
mainbranch always deployable, short feature branches. - Teams of 2-5 people: GitHub Flow with staging environments.
- Teams > 5 people or planned releases: Lightened GitFlow (without the
developbranch if deployments are frequent).
Commit conventions: Conventional Commits
Well-structured commits are essential for maintenance and collaboration:
<type>[optional scope]: <description>
[optional body]
[optional footer]
Types:
feat:new featurefix:bug fixdocs:documentationstyle:formatting (no functional impact)refactor:refactoringtest:test addition/modificationchore:maintenance tasksperf:performance optimization
Examples:
git commit -m "feat(auth): add OAuth2 login with Google"
git commit -m "fix(cart): prevent duplicate items on rapid clicks"
git commit -m "docs: update API documentation for v2 endpoints"
git commit -m "perf(images): implement WebP conversion pipeline"
These conventions allow automatic changelog generation and at-a-glance project history understanding.
Daily best practices
The .gitignore from day one
Every project should start with a proper .gitignore:
# Dependencies
node_modules/
vendor/
# Environment
.env
.env.local
.env.*.local
# Build
dist/
build/
# IDE
.vscode/
.idea/
# OS
.DS_Store
Thumbs.db
# Logs
*.log
npm-debug.log*
Handling merge conflicts
Conflicts are inevitable. Hereβs a systematic method:
# Update main
git checkout main && git pull
# Rebase your feature branch onto main
git checkout feature/my-feature
git rebase main
# If conflict occurs, resolve and continue
git add <files>
git rebase --continue
# Or abort the rebase if needed
git rebase --abort
Rebase is preferred over merge for a cleaner, linear history:
# History with merge (less readable)
* Merge branch 'feature/login' into main
|\
| * feat: add login form
|/
* feat: add auth module
# History with rebase (cleaner)
* feat: add login form
* feat: add auth module
Git aliases to save time
# ~/.gitconfig
[alias]
st = status -sb
co = checkout
br = branch
cm = commit -m
lg = log --oneline --graph --all --decorate
unstage = reset HEAD --
last = log -1 HEAD --stat
undo = reset --soft HEAD~1
Freelance collaboration workflows
Case 1: Joining an existing project
# Clone the repo
git clone <url>
cd <project>
# Understand the branch structure
git branch -a
# Create your working branch
git checkout -b freelance/marc-feature main
# Follow existing conventions
git log --oneline -20
Case 2: Managing a project for a client
# Recommended structure
git init
git checkout -b main
# Protect main (on GitHub/GitLab)
# - Require pull request reviews
# - Require status checks
# - No force push
# Branch per task
git checkout -b feature/redesign-homepage
Case 3: Collaborating with in-house developers
# Sync regularly
git fetch origin
git rebase origin/main
# Clear PR with description
gh pr create --title "feat: redesign homepage" \
--body "## Changes
- New hero section
- Updated navigation
- Mobile responsive layout
## Testing
- [x] Desktop Chrome/FF/Safari
- [x] Mobile iOS/Android"
Complementary tools
Git hooks with Husky
Automate checks before each commit:
# Installation
npm install -D husky
npx husky init
# .husky/pre-commit
npx lint-staged
// package.json
{
"lint-staged": {
"*.{js,ts}": ["eslint --fix", "prettier --write"],
"*.{css,scss}": ["stylelint --fix", "prettier --write"],
"*.md": ["prettier --write"]
}
}
Git Bisect to find bugs
# Git bisect finds the commit that introduced a bug
git bisect start
git bisect bad # Current commit is broken
git bisect good v1.0 # This version worked
# Git automatically checks out intermediate commits
# Test and indicate good/bad
git bisect good # or git bisect bad
# Repeat until the offending commit is found
git bisect reset # Return to HEAD
Conclusion
As a freelancer, your Git mastery reflects your professionalism. A clean history, respected conventions, and a workflow adapted to the project context make a difference in collaboration with clients and their teams. Start simple β GitHub Flow with Conventional Commits β and add complexity only when the context demands it.
The best strategy is the one you apply consistently. Document your choices in a CONTRIBUTING.md shared with each team, and donβt hesitate to adjust across projects.