Git Workflow Cheatsheet
gitGit branching strategies and common workflow patterns.
Feature Branch Workflow
git checkout -b feature/<name> mainCreate a new branch from main for isolated feature development
git checkout -b feature/user-auth maingit push -u origin feature/<name>Push branch to remote and set upstream tracking
git push -u origin feature/user-authgit pull origin main --rebaseKeep feature branch updated with latest main changes
git checkout feature/user-auth
git pull origin main --rebasegh pr create --base main --head feature/<name>Open a pull request for code review using GitHub CLI
gh pr create --base main --head feature/user-auth --title "Add auth"git branch -d feature/<name>Clean up local branch after merge to main
git branch -d feature/user-auth
git push origin --delete feature/user-authGit Flow Workflow
git flow initSet up repository with git flow branch structure
git flow init -dgit flow feature start <name>Create feature branch from develop branch
git flow feature start payment-gatewaygit flow feature finish <name>Merge feature into develop and delete feature branch
git flow feature finish payment-gatewaygit flow release start <version>Create release branch from develop for final testing
git flow release start 1.2.0git flow release finish <version>Merge release into main and develop with version tag
git flow release finish 1.2.0git flow hotfix start <name>Create hotfix branch from main for urgent production fixes
git flow hotfix start critical-security-patchgit flow hotfix finish <name>Merge hotfix into both main and develop branches
git flow hotfix finish critical-security-patchgit checkout -b release/<version> developCreate release branch manually without git-flow extension
git checkout -b release/1.2.0 develop
git checkout main
git merge release/1.2.0Trunk-Based Development
git checkout -b <initials>/<task> mainCreate small branch that lives max 1-2 days before merging
git checkout -b jd/fix-login maingit fetch origin && git rebase origin/mainFrequently rebase on main to minimize merge conflicts
git fetch origin
git rebase origin/mainif (featureFlags.isEnabled('newUI')) { ... }Use feature flags to merge incomplete features safely to main
git commit -m "Add new UI behind feature flag"git commit -m "<message>" && git push origin mainFor small trusted teams commit directly to trunk
git add .
git commit -m "Fix typo"
git push origin maingit push origin main --push-option=ci.skipEnsure all commits pass CI before integration
git push origin mainMerge Strategies
git merge <branch> --no-ffCreates merge commit preserving complete branch history
git checkout main
git merge feature/auth --no-ffgit merge --squash <branch>Combine all branch commits into single commit on target
git checkout main
git merge --squash feature/auth
git commit -m "Add authentication"git rebase main && git checkout main && git merge <branch>Replay commits on main for linear history then fast-forward
git checkout feature/auth
git rebase main
git checkout main
git merge feature/authgit merge --ff-only <branch>Only merge if fast-forward is possible without merge commit
git checkout main
git merge --ff-only feature/authgit merge <branch>Use when preserving feature branch context and history matters
# Good for long-running features, team collaborationgit merge --squash <branch>Use for messy branch history or WIP commits you want to hide
# Good for small features, clean main historygit rebase mainUse for linear history when branch has no shared commits
# Good for personal branches, before PRInteractive Rebase Commands
git rebase -i HEAD~<n>Open editor to modify last n commits interactively
git rebase -i HEAD~5pick <commit-hash>Keep commit as-is without changes
pick abc1234 Add login featurereword <commit-hash>Keep commit but edit the commit message
reword abc1234 Add login featureedit <commit-hash>Pause at commit to amend changes or split it
edit abc1234 Add login feature
# Then: git commit --amendsquash <commit-hash>Combine commit with previous and merge commit messages
pick abc1234 Add login
squash def5678 Fix login typofixup <commit-hash>Combine with previous commit but discard this message
pick abc1234 Add login
fixup def5678 Fix typodrop <commit-hash>Remove commit entirely from history
drop abc1234 WIP commit# Rearrange lines in editorChange commit order by moving lines in the rebase editor
pick def5678 Second commit
pick abc1234 First commitgit rebase --abortCancel rebase and return to original state
git rebase --abortgit rebase --continueContinue rebase after resolving conflicts or amending
git add .
git rebase --continuegit rebase -i --autosquash HEAD~<n>Auto-arrange fixup! and squash! prefixed commits
git commit --fixup=abc1234
git rebase -i --autosquash HEAD~3Resolving Merge Conflicts
git statusShow files with merge conflicts needing resolution
git status
# both modified: src/app.jsgit diffShow detailed conflict markers in affected files
git diff --name-only --diff-filter=Ugit checkout --ours <file>Keep your branch version and discard incoming changes
git checkout --ours src/app.js
git add src/app.jsgit checkout --theirs <file>Accept the other branch version and discard yours
git checkout --theirs src/app.js
git add src/app.js# Edit file, remove <<<<<<< ======= >>>>>>>Manually edit file to combine both changes as needed
# Edit src/app.js
git add src/app.jsgit mergetoolOpen configured visual merge tool for conflict resolution
git config merge.tool vscode
git mergetoolgit add <files> && git commitStage resolved files and commit to complete merge
git add .
git commit -m "Resolve merge conflicts"git merge --abortCancel merge and return to pre-merge state
git merge --abortUndoing Changes
git reset --soft HEAD~<n>Undo commits keeping changes staged for recommit
git reset --soft HEAD~1
# Changes remain stagedgit reset HEAD~<n>Undo commits keeping changes in working directory unstaged
git reset HEAD~2
# Changes remain but unstagedgit reset --hard HEAD~<n>Completely remove commits and all changes permanently
git reset --hard HEAD~1
# All changes lost!git reset --hard <commit-hash>Reset branch to exact state of specified commit
git reset --hard abc1234git revert <commit-hash>Create new commit that undoes changes without rewriting history
git revert abc1234
# Safe for shared branchesgit revert <oldest>^..<newest>Revert a range of commits creating individual revert commits
git revert abc1234^..def5678git revert -n <commit-hash>Apply revert changes to working directory without committing
git revert -n abc1234
git revert -n def5678
git commit -m "Revert features"git restore --source=<commit> <file>Restore specific file to state from any commit
git restore --source=HEAD~2 src/app.jsgit restore --staged <file>Unstage file keeping working directory changes
git restore --staged src/app.jsgit restore <file>Discard working directory changes reverting to staged or HEAD
git restore src/app.jsgit restore . && git clean -fdRemove all uncommitted changes and untracked files
git restore .
git clean -fdReflog Recovery
git reflogShow history of all HEAD movements including deleted commits
git reflog
# abc1234 HEAD@{0}: commit: Add featuregit reflog show <branch>Show reflog for specific branch only
git reflog show maingit reset --hard <reflog-hash>Restore branch to state captured in reflog entry
git reflog
git reset --hard HEAD@{2}git checkout -b <branch> <reflog-hash>Recreate deleted branch from its last known commit
git reflog
git checkout -b feature/recovered HEAD@{5}git cherry-pick <reflog-hash>Apply specific lost commit to current branch
git reflog
git cherry-pick abc1234git reset --hard ORIG_HEADReturn to state before last rebase or merge operation
git reset --hard ORIG_HEADgit fsck --unreachable | grep commitFind orphaned commits including dropped stashes
git fsck --unreachable | grep commit
git show <hash>git reflog expire --expire=<time> --allRemove reflog entries older than specified time
git reflog expire --expire=30.days --all