Git Workflows
Overview
Git version control patterns, branching strategies, and team collaboration best practices.
Branching Strategies
Git Flow
main ─────●────────────●─────────────●───────────
\ /
\ release/1.0 release/1.1
\ / \ /
develop ──────●───●──────●────●──────●────────────
\ / \ /
feature/ feature/ feature/
login payment search
Initialize git flow
git flow init
Start a new feature
git flow feature start user-authentication
Work on feature...
git flow feature finish user-authentication
Start a release
git flow release start 1.0.0
Bug fixes only...
git flow release finish 1.0.0
Hotfix for production
git flow hotfix start critical-bug git flow hotfix finish critical-bug
GitHub Flow (Simplified)
main ─────●──────●──────●──────●──────●───────
\ / \ /
feature/ feature/ feature/
add-auth fix-bug new-ui
1. Create branch from main
git checkout main git pull origin main git checkout -b feature/add-authentication
2. Make changes and commit
git add . git commit -m "feat: add user authentication"
3. Push and create PR
git push -u origin feature/add-authentication gh pr create --title "Add user authentication" --body "..."
4. After review, merge via GitHub
gh pr merge --squash
5. Delete branch
git checkout main git pull origin main git branch -d feature/add-authentication
Trunk-Based Development
main ────●──●──●──●──●──●──●──●──●──── │ │ │ └─────┴────────┴─── short-lived branches (< 1 day)
Small, frequent commits directly to main or via short-lived branches
git checkout main git pull git checkout -b fix/typo-in-readme
Make small change...
git commit -m "fix: typo in README" git push -u origin fix/typo-in-readme
PR, review, merge same day
Common Operations
Commits
Stage specific changes
git add -p # Interactive staging
Commit with message
git commit -m "feat(auth): add JWT token validation"
Amend last commit (not pushed)
git commit --amend -m "feat(auth): add JWT token validation and refresh"
Commit with co-author
git commit -m "feat: implement feature
Co-authored-by: Name <email@example.com>"
Empty commit (trigger CI)
git commit --allow-empty -m "chore: trigger CI build"
Conventional Commits
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
Type Description
feat New feature
fix Bug fix
docs Documentation only
style Formatting, no code change
refactor Code change, no new feature or fix
perf Performance improvement
test Adding tests
chore Build, CI, tooling
Examples
git commit -m "feat(api): add user registration endpoint" git commit -m "fix(auth): handle expired token refresh" git commit -m "docs: update API documentation" git commit -m "refactor(db): extract connection pool logic" git commit -m "test(user): add unit tests for validation"
Branching
Create and switch to branch
git checkout -b feature/new-feature
or
git switch -c feature/new-feature
List branches
git branch -a # All branches git branch -vv # With tracking info
Delete branch
git branch -d feature/merged-branch # Safe delete git branch -D feature/unmerged-branch # Force delete
Rename branch
git branch -m old-name new-name
Set upstream
git branch --set-upstream-to=origin/main main
Merging
Merge branch into current
git merge feature/branch
Merge with no fast-forward (always create merge commit)
git merge --no-ff feature/branch
Squash merge (combine all commits)
git merge --squash feature/branch git commit -m "feat: add feature (squashed)"
Abort merge
git merge --abort
Rebasing
Rebase current branch onto main
git fetch origin git rebase origin/main
Interactive rebase (last 3 commits)
git rebase -i HEAD~3
In editor, change 'pick' to:
- squash (s): combine with previous
- fixup (f): combine, discard message
- reword (r): change commit message
- edit (e): stop for amending
- drop (d): remove commit
Continue rebase after resolving conflicts
git add . git rebase --continue
Abort rebase
git rebase --abort
Stashing
Stash changes
git stash git stash push -m "work in progress"
Stash including untracked files
git stash -u
List stashes
git stash list
Apply stash
git stash pop # Apply and remove git stash apply # Apply and keep git stash apply stash@{2} # Apply specific
Show stash contents
git stash show -p stash@{0}
Drop stash
git stash drop stash@{0} git stash clear # Drop all
Undoing Changes
Discard changes in working directory
git checkout -- file.txt git restore file.txt # Git 2.23+
Unstage file
git reset HEAD file.txt git restore --staged file.txt # Git 2.23+
Reset to previous commit (keep changes staged)
git reset --soft HEAD~1
Reset to previous commit (keep changes unstaged)
git reset HEAD1
git reset --mixed HEAD1
Reset to previous commit (discard changes)
git reset --hard HEAD~1
Revert a commit (create new commit that undoes)
git revert <commit-hash>
Revert merge commit
git revert -m 1 <merge-commit-hash>
Git Hooks
Pre-commit Hook
#!/bin/sh
.git/hooks/pre-commit
Run linting
npm run lint if [ $? -ne 0 ]; then echo "Linting failed. Please fix errors before committing." exit 1 fi
Run type checking
npm run type-check if [ $? -ne 0 ]; then echo "Type checking failed. Please fix errors before committing." exit 1 fi
Check for console.log
if git diff --cached | grep -E '^+.*console.(log|debug|info)' > /dev/null; then echo "Warning: Found console.log statements. Remove before committing." exit 1 fi
Husky + lint-staged
// package.json { "scripts": { "prepare": "husky install" }, "lint-staged": { ".{js,ts,tsx}": [ "eslint --fix", "prettier --write" ], ".{json,md,yml}": [ "prettier --write" ] } }
.husky/pre-commit
#!/bin/sh . "$(dirname "$0")/_/husky.sh"
npx lint-staged
.husky/commit-msg
#!/bin/sh . "$(dirname "$0")/_/husky.sh"
npx --no -- commitlint --edit "$1"
Advanced Operations
Cherry-pick
Apply specific commit to current branch
git cherry-pick <commit-hash>
Cherry-pick multiple commits
git cherry-pick <commit1> <commit2> <commit3>
Cherry-pick without committing
git cherry-pick -n <commit-hash>
Cherry-pick merge commit
git cherry-pick -m 1 <merge-commit-hash>
Bisect (Find Bug Introduction)
Start bisect
git bisect start
Mark current as bad
git bisect bad
Mark known good commit
git bisect good v1.0.0
Git checks out middle commit, test and mark
git bisect good # or git bisect bad
Repeat until found
Git reports the first bad commit
End bisect
git bisect reset
Automated bisect
git bisect start HEAD v1.0.0 git bisect run npm test
Worktrees
Create worktree for parallel work
git worktree add ../project-hotfix hotfix/urgent-fix git worktree add ../project-feature feature/new-feature
List worktrees
git worktree list
Remove worktree
git worktree remove ../project-hotfix
Submodules
Add submodule
git submodule add https://github.com/org/repo.git libs/repo
Clone with submodules
git clone --recurse-submodules https://github.com/org/project.git
Update submodules
git submodule update --init --recursive
Pull submodule updates
git submodule update --remote
Git Configuration
User config
git config --global user.name "Your Name" git config --global user.email "you@example.com"
Default branch
git config --global init.defaultBranch main
Editor
git config --global core.editor "code --wait"
Aliases
git config --global alias.co checkout git config --global alias.br branch git config --global alias.ci commit git config --global alias.st status git config --global alias.lg "log --oneline --graph --all" git config --global alias.unstage "reset HEAD --" git config --global alias.last "log -1 HEAD"
Pull behavior
git config --global pull.rebase true
Auto-setup remote tracking
git config --global push.autoSetupRemote true
Credential caching
git config --global credential.helper cache git config --global credential.helper 'cache --timeout=3600'
Related Skills
-
[[devops-cicd]] - CI/CD with Git
-
[[code-quality]] - Code review practices
-
[[project-management]] - Agile workflows