Git Workflow Best Practices
A structured approach to maintaining clean git history and effective branch management.
Purpose
Good git hygiene makes collaboration easier, debugging faster, and code history valuable. This skill establishes patterns for commits, branches, and pull requests that scale from solo projects to large teams.
Prerequisites
git --version)Steps
Step 1: Create a Feature Branch
Always branch from an up-to-date main branch.
Update main first
git checkout main
git pull origin mainCreate feature branch with descriptive name
git checkout -b feat/user-authentication
or for fixes: fix/login-validation-error
or for chores: chore/update-dependencies
Expected outcome: New branch created, isolated from main.
Step 2: Make Atomic Commits
Each commit should be a single logical change.
Stage specific files (not git add .)
git add src/auth/login.ts src/auth/login.test.tsWrite conventional commit message
git commit -m "feat(auth): implement login form validationAdd email format validation
Add password strength meter
Add error messages for invalid inputs Closes #123"
Expected outcome: Clean commit with clear message and scope.
Step 3: Keep Branch Updated
Regularly sync with main to avoid merge conflicts.
Fetch and rebase (preferred over merge)
git fetch origin
git rebase origin/mainIf conflicts occur, resolve them file by file
git add
git rebase --continue
Expected outcome: Branch includes latest changes from main.
Step 4: Push and Create PR
Push with upstream tracking
git push -u origin feat/user-authentication
Create PR with:
Expected outcome: PR ready for review.
Checks
Automated Checks
Verify commit message format
git log --oneline -5Check for merge conflicts
git diff --checkEnsure no accidental files staged
git status
Manual Checks
Failure Modes
git rebase origin/maingit reset HEAD~1, then branch and recommitgit reflog, recover commitsRollback
If you need to undo recent commits:
Undo last commit, keep changes staged
git reset --soft HEAD~1Undo last commit, discard changes (⚠️ destructive)
git reset --hard HEAD~1Revert a merged commit (creates new commit)
git revert
Variations
Squash Before Merge
For cleaner history, squash commits before merging:
Interactive rebase to squash
git rebase -i HEAD~5Mark commits to squash (s) or fixup (f)
Keep first commit as "pick"
Trunk-Based Development
For rapid iteration, skip feature branches:
Work directly on main with small commits
git checkout main
git pull
make small change
git commit -am "feat: add logout button"
git push
