{ ILoveJS }

Git Workflow Cheatsheet

git

Git branching strategies and common workflow patterns.

8 sections · 63 items

Feature Branch Workflow

Create Feature Branch
git checkout -b feature/<name> main

Create a new branch from main for isolated feature development

bash
git checkout -b feature/user-auth main
Push Feature Branch
git push -u origin feature/<name>

Push branch to remote and set upstream tracking

bash
git push -u origin feature/user-auth
Update Feature Branch
git pull origin main --rebase

Keep feature branch updated with latest main changes

bash
git checkout feature/user-auth
git pull origin main --rebase
Create Pull Request
gh pr create --base main --head feature/<name>

Open a pull request for code review using GitHub CLI

bash
gh pr create --base main --head feature/user-auth --title "Add auth"
Delete Merged Branch
git branch -d feature/<name>

Clean up local branch after merge to main

bash
git branch -d feature/user-auth
git push origin --delete feature/user-auth

Git Flow Workflow

Initialize Git Flow
git flow init

Set up repository with git flow branch structure

bash
git flow init -d
Start Feature
git flow feature start <name>

Create feature branch from develop branch

bash
git flow feature start payment-gateway
Finish Feature
git flow feature finish <name>

Merge feature into develop and delete feature branch

bash
git flow feature finish payment-gateway
Start Release
git flow release start <version>

Create release branch from develop for final testing

bash
git flow release start 1.2.0
Finish Release
git flow release finish <version>

Merge release into main and develop with version tag

bash
git flow release finish 1.2.0
Start Hotfix
git flow hotfix start <name>

Create hotfix branch from main for urgent production fixes

bash
git flow hotfix start critical-security-patch
Finish Hotfix
git flow hotfix finish <name>

Merge hotfix into both main and develop branches

bash
git flow hotfix finish critical-security-patch
Manual Git Flow - Release
git checkout -b release/<version> develop

Create release branch manually without git-flow extension

bash
git checkout -b release/1.2.0 develop
git checkout main
git merge release/1.2.0

Trunk-Based Development

Short-Lived Branch
git checkout -b <initials>/<task> main

Create small branch that lives max 1-2 days before merging

bash
git checkout -b jd/fix-login main
Sync with Trunk
git fetch origin && git rebase origin/main

Frequently rebase on main to minimize merge conflicts

bash
git fetch origin
git rebase origin/main
Feature Flags Integration
if (featureFlags.isEnabled('newUI')) { ... }

Use feature flags to merge incomplete features safely to main

bash
git commit -m "Add new UI behind feature flag"
Direct Commit to Main
git commit -m "<message>" && git push origin main

For small trusted teams commit directly to trunk

bash
git add .
git commit -m "Fix typo"
git push origin main
CI Verification
git push origin main --push-option=ci.skip

Ensure all commits pass CI before integration

bash
git push origin main

Merge Strategies

Merge Commit
git merge <branch> --no-ff

Creates merge commit preserving complete branch history

bash
git checkout main
git merge feature/auth --no-ff
Squash Merge
git merge --squash <branch>

Combine all branch commits into single commit on target

bash
git checkout main
git merge --squash feature/auth
git commit -m "Add authentication"
Rebase and Merge
git rebase main && git checkout main && git merge <branch>

Replay commits on main for linear history then fast-forward

bash
git checkout feature/auth
git rebase main
git checkout main
git merge feature/auth
Fast-Forward Merge
git merge --ff-only <branch>

Only merge if fast-forward is possible without merge commit

bash
git checkout main
git merge --ff-only feature/auth
When: Merge Commit
git merge <branch>

Use when preserving feature branch context and history matters

bash
# Good for long-running features, team collaboration
When: Squash Merge
git merge --squash <branch>

Use for messy branch history or WIP commits you want to hide

bash
# Good for small features, clean main history
When: Rebase
git rebase main

Use for linear history when branch has no shared commits

bash
# Good for personal branches, before PR

Interactive Rebase Commands

Start Interactive Rebase
git rebase -i HEAD~<n>

Open editor to modify last n commits interactively

bash
git rebase -i HEAD~5
Pick (p)
pick <commit-hash>

Keep commit as-is without changes

bash
pick abc1234 Add login feature
Reword (r)
reword <commit-hash>

Keep commit but edit the commit message

bash
reword abc1234 Add login feature
Edit (e)
edit <commit-hash>

Pause at commit to amend changes or split it

bash
edit abc1234 Add login feature
# Then: git commit --amend
Squash (s)
squash <commit-hash>

Combine commit with previous and merge commit messages

bash
pick abc1234 Add login
squash def5678 Fix login typo
Fixup (f)
fixup <commit-hash>

Combine with previous commit but discard this message

bash
pick abc1234 Add login
fixup def5678 Fix typo
Drop (d)
drop <commit-hash>

Remove commit entirely from history

bash
drop abc1234 WIP commit
Reorder Commits
# Rearrange lines in editor

Change commit order by moving lines in the rebase editor

bash
pick def5678 Second commit
pick abc1234 First commit
Abort Rebase
git rebase --abort

Cancel rebase and return to original state

bash
git rebase --abort
Continue Rebase
git rebase --continue

Continue rebase after resolving conflicts or amending

bash
git add .
git rebase --continue
Autosquash Fixups
git rebase -i --autosquash HEAD~<n>

Auto-arrange fixup! and squash! prefixed commits

bash
git commit --fixup=abc1234
git rebase -i --autosquash HEAD~3

Resolving Merge Conflicts

View Conflict Status
git status

Show files with merge conflicts needing resolution

bash
git status
# both modified: src/app.js
View Conflict Diff
git diff

Show detailed conflict markers in affected files

bash
git diff --name-only --diff-filter=U
Accept Current Changes
git checkout --ours <file>

Keep your branch version and discard incoming changes

bash
git checkout --ours src/app.js
git add src/app.js
Accept Incoming Changes
git checkout --theirs <file>

Accept the other branch version and discard yours

bash
git checkout --theirs src/app.js
git add src/app.js
Manual Resolution
# Edit file, remove <<<<<<< ======= >>>>>>>

Manually edit file to combine both changes as needed

bash
# Edit src/app.js
git add src/app.js
Use Merge Tool
git mergetool

Open configured visual merge tool for conflict resolution

bash
git config merge.tool vscode
git mergetool
Complete Merge
git add <files> && git commit

Stage resolved files and commit to complete merge

bash
git add .
git commit -m "Resolve merge conflicts"
Abort Merge
git merge --abort

Cancel merge and return to pre-merge state

bash
git merge --abort

Undoing Changes

Reset Soft
git reset --soft HEAD~<n>

Undo commits keeping changes staged for recommit

bash
git reset --soft HEAD~1
# Changes remain staged
Reset Mixed (Default)
git reset HEAD~<n>

Undo commits keeping changes in working directory unstaged

bash
git reset HEAD~2
# Changes remain but unstaged
Reset Hard
git reset --hard HEAD~<n>

Completely remove commits and all changes permanently

bash
git reset --hard HEAD~1
# All changes lost!
Reset to Specific Commit
git reset --hard <commit-hash>

Reset branch to exact state of specified commit

bash
git reset --hard abc1234
Revert Commit
git revert <commit-hash>

Create new commit that undoes changes without rewriting history

bash
git revert abc1234
# Safe for shared branches
Revert Multiple Commits
git revert <oldest>^..<newest>

Revert a range of commits creating individual revert commits

bash
git revert abc1234^..def5678
Revert Without Commit
git revert -n <commit-hash>

Apply revert changes to working directory without committing

bash
git revert -n abc1234
git revert -n def5678
git commit -m "Revert features"
Restore File from Commit
git restore --source=<commit> <file>

Restore specific file to state from any commit

bash
git restore --source=HEAD~2 src/app.js
Restore Staged File
git restore --staged <file>

Unstage file keeping working directory changes

bash
git restore --staged src/app.js
Restore Working Directory
git restore <file>

Discard working directory changes reverting to staged or HEAD

bash
git restore src/app.js
Discard All Local Changes
git restore . && git clean -fd

Remove all uncommitted changes and untracked files

bash
git restore .
git clean -fd

Reflog Recovery

View Reflog
git reflog

Show history of all HEAD movements including deleted commits

bash
git reflog
# abc1234 HEAD@{0}: commit: Add feature
View Branch Reflog
git reflog show <branch>

Show reflog for specific branch only

bash
git reflog show main
Recover Deleted Commit
git reset --hard <reflog-hash>

Restore branch to state captured in reflog entry

bash
git reflog
git reset --hard HEAD@{2}
Recover Deleted Branch
git checkout -b <branch> <reflog-hash>

Recreate deleted branch from its last known commit

bash
git reflog
git checkout -b feature/recovered HEAD@{5}
Cherry-Pick Lost Commit
git cherry-pick <reflog-hash>

Apply specific lost commit to current branch

bash
git reflog
git cherry-pick abc1234
Recover After Bad Rebase
git reset --hard ORIG_HEAD

Return to state before last rebase or merge operation

bash
git reset --hard ORIG_HEAD
Find Lost Stash
git fsck --unreachable | grep commit

Find orphaned commits including dropped stashes

bash
git fsck --unreachable | grep commit
git show <hash>
Expire Reflog
git reflog expire --expire=<time> --all

Remove reflog entries older than specified time

bash
git reflog expire --expire=30.days --all

Related Content