Complete Git guide for freelance developers

In short: As of September 5, 2026, use a simplified GitHub Flow for most freelance projects: keep main deployable, give each task a short-lived branch, and merge through a pull request. Add Conventional Commits to clarify history. Reserve GitFlow for projects with planned releases or several versions maintained in parallel.
Git becomes demanding when you switch among several projects, clients, and teams. A consistent branching strategy, explicit commits, and a few checks before every push prevent costly mistakes.
Which branching strategy should you choose?
Your choice of branch strategy depends on project size, deployment frequency, and the number of contributors.
GitFlow: the classic method
The GitFlow model, presented by Vincent Driessen in 2010, uses long-lived branches and a strict hierarchy. Its author now recommends a simpler workflow for continuous delivery, while retaining GitFlow for explicitly versioned software or products that support several versions.
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
The official GitHub Flow documentation, consulted on September 5, 2026 describes a lightweight workflow: one branch per change, explicit commits, a pull request, and then a merge into the default branch.
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 feedback or validation.
- Merge into
mainwhen the change is ready. - Delete the branch when it is no longer needed.
Trunk-based development: expert mode
Trunk-based development pushes the idea further: work joins the main branch frequently, either directly or from short-lived branches.
# Ephemeral branch
git checkout -b quick-fix
# Changes...
git commit -am "fix: quick fix"
git push origin quick-fix
# Prompt review and merge
# Or directly on main (for small changes)
git checkout main
# Changes...
git commit -am "docs: update README"
git push origin main
In this example, incomplete features are hidden behind feature flags:
if (featureFlag.isEnabled('new-payment-flow')) {
// New payment logic
} else {
// Legacy logic
}
My choice as a freelancer
For most freelance projects, my recommendation is an adapted GitHub Flow:
- Solo project: keep
maindeployable and create a short-lived branch for each meaningful task. - Team project: add a pull request, automated checks, and the validation environment required by the client.
- Planned releases or versions maintained in parallel: consider GitFlow, without adding any branch that the release process does not justify.
Why adopt Conventional Commits?
The Conventional Commits 1.0.0 specification, consulted on September 5, 2026 defines a lightweight convention that adds human-readable and machine-readable meaning to commit messages:
<type>[optional scope]: <description>
[optional body]
[optional footer]
Common types:
feat:new feature defined by the specificationfix:bug fix defined by the specificationdocs:documentation, an allowed complementary typestyle:formatting with no functional impactrefactor:refactoringtest:addition or modification of testschore:maintenance taskperf: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"
This convention makes history easier to read and lets tools generate changelogs or determine a semantic version change. Types other than feat and fix remain team conventions, so document them.
Which Git practices should you apply daily?
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 reapplies your commits onto a new base and can preserve a linear history. Use it on your working branch, but avoid rewriting a branch that others already use unless the team has agreed to it:
# 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
How do you collaborate across several clients?
Case 1: you join 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: you manage 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: you collaborate 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"
Which tools complement this Git workflow?
Git hooks with Husky
The Husky getting-started documentation, consulted on September 5, 2026 says that husky init creates a pre-commit hook in .husky/ and updates the prepare script. You can then run the checks appropriate to the project:
# 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 the offending commit
# 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
Start simple: an adapted GitHub Flow, consistent Conventional Commits, and one branch per task. Add rules only when a client, team, or release cycle justifies them.
When handling several clients, keep repositories strictly separate and check the remote, branch, and active Git identity before every push. Document each team’s choices in its CONTRIBUTING.md.
Sources
Frequently asked questions
Which Git workflow should you use when working solo?
Use a simplified GitHub Flow: keep `main` deployable, create a short-lived branch for each task, then open a pull request before merging. Add GitFlow only when the project requires planned releases or support for multiple versions.
Should freelancers use Conventional Commits?
Yes, if you apply the convention consistently. Prefixes such as `feat`, `fix`, and `docs` make history easier to read and can support changelog and release automation.
How do you manage several clients with Git without mixing projects?
Keep a separate repository and configuration for each client, follow their conventions, and use one branch per task. Always check the repository, branch, and Git identity before pushing.
Is GitFlow still recommended for freelancers?
Not by default. GitFlow remains relevant for explicitly versioned software or when several versions must be supported, but a simpler flow is usually a better fit for continuous delivery.