Back to blog

Complete Git guide for freelance developers

October 1, 2024 β€’ Dedimarco
git development freelance productivity
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 stable
  • develop: feature integration
  • feature/*: new feature development
  • release/*: version preparation
  • hotfix/*: 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:

  1. Create a branch from main
  2. Work on the feature
  3. Open a Pull Request for review
  4. Merge into main after approval
  5. 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 main branch 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 develop branch 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 feature
  • fix: bug fix
  • docs: documentation
  • style: formatting (no functional impact)
  • refactor: refactoring
  • test: test addition/modification
  • chore: maintenance tasks
  • perf: 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.