Git Commands & Workflows

Essential Git commands and workflows for modern development. From basic commits to advanced rebasing, branch management, and collaboration patterns.

Setup & Configuration

Initial Git setup and configuration for your development environment

Configure User Identity

Set your name and email for commits. Use --global for all repos or omit for current repo only.

BeginnersetupconfigurationidentityDocs
# Global configuration (all repositories)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# Repository-specific configuration
git config user.name "Work Name"
git config user.email "work@company.com"

# View configuration
git config --list
git config user.name

Essential Aliases for Productivity

Save time with Git aliases. These are the most useful shortcuts for daily work.

IntermediatealiasesproductivityshortcutsDocs
# Status shortcuts
git config --global alias.st status
git config --global alias.s "status -s"

# Branch shortcuts
git config --global alias.br branch
git config --global alias.co checkout
git config --global alias.cob "checkout -b"

# Commit shortcuts
git config --global alias.ci commit
git config --global alias.cam "commit -am"
git config --global alias.amend "commit --amend --no-edit"

# Log shortcuts
git config --global alias.lg "log --graph --oneline --decorate --all"
git config --global alias.last "log -1 HEAD"
git config --global alias.ll "log --pretty=format:'%C(yellow)%h%C(red)%d %C(reset)%s %C(green)[%cn] %C(blue)%cr' --decorate --numstat"

# Diff shortcuts
git config --global alias.d diff
git config --global alias.ds "diff --staged"

# Undo shortcuts
git config --global alias.unstage "reset HEAD --"
git config --global alias.undo "reset --soft HEAD~1"

# Now use them like: git st, git cob feature-branch, git lg

Configure Line Endings & Editor

Prevent line ending issues across platforms and set your preferred editor.

Beginnerconfigurationeditorline-endingscross-platform
# Line endings (prevents Windows/Unix conflicts)
# Windows:
git config --global core.autocrlf true
# Mac/Linux:
git config --global core.autocrlf input

# Default editor
git config --global core.editor "code --wait"  # VS Code
git config --global core.editor "vim"          # Vim
git config --global core.editor "nano"         # Nano

# Default branch name
git config --global init.defaultBranch main

# Pull strategy (rebase instead of merge)
git config --global pull.rebase true

Basic Workflow

Everyday Git commands for committing and managing changes

Initialize & Clone Repositories

Start a new repository or clone an existing one.

Beginnerinitializationclonerepository
# Create new repository
git init
git init my-project  # Creates directory and initializes

# Clone existing repository
git clone https://github.com/user/repo.git
git clone https://github.com/user/repo.git my-folder
git clone --depth 1 https://github.com/user/repo.git  # Shallow clone (faster)

# Clone specific branch
git clone -b develop https://github.com/user/repo.git

Check Status & Diff

View what's changed, staged, or needs attention in your working directory.

Beginnerstatusdiffchanges
# Detailed status
git status

# Short status (cleaner output)
git status -s

# View unstaged changes
git diff

# View staged changes
git diff --staged
git diff --cached  # Same as --staged

# View changes in specific file
git diff path/to/file.js

# Compare branches
git diff main..feature-branch
git diff main...feature-branch  # Shows changes since branch diverged

# Word-level diff (better for prose)
git diff --word-diff

# View changed file names only
git diff --name-only
git diff --stat

Stage & Commit Changes

The bread and butter of Git - staging and committing your work.

BeginnerstagingcommitaddDocs
# Stage specific files
git add file1.js file2.js

# Stage all changes
git add .
git add -A  # Includes deletions

# Stage interactively (choose what to stage)
git add -p

# Commit staged changes
git commit -m "Add user authentication"

# Stage and commit in one command
git commit -am "Fix bug in login form"

# Commit with detailed message
git commit
# Opens editor for multi-line message:
# First line: Short summary (50 chars or less)
#
# Longer description explaining why this change
# was necessary and what it accomplishes.

# Amend last commit (change message or add files)
git add forgotten-file.js
git commit --amend --no-edit  # Keep same message
git commit --amend -m "New commit message"

# Sign commits (if configured)
git commit -S -m "Signed commit"

View History & Logs

Explore your commit history with various formatting options.

Intermediateloghistorysearchblame
# Basic log
git log

# Compact one-line format
git log --oneline

# Graph view with branches
git log --graph --oneline --all

# Detailed log with stats
git log --stat

# Show last N commits
git log -3
git log -n 5

# Search commits
git log --grep="bug fix"
git log --author="John"
git log --since="2 weeks ago"
git log --until="2023-12-31"

# Show commits affecting specific file
git log -- path/to/file.js
git log -p path/to/file.js  # Include diffs

# Pretty format
git log --pretty=format:"%h - %an, %ar : %s"
# %h  = short hash
# %an = author name
# %ar = author date, relative
# %s  = subject

# Show what changed in each commit
git log -p
git log -p -2  # Last 2 commits with diffs

# Find who changed each line (blame)
git blame file.js
git blame -L 10,20 file.js  # Specific lines

Branching & Merging

Create, switch, and manage branches for parallel development

Branch Operations

Create, list, switch, and delete branches effectively.

Beginnerbranchcheckoutswitch
# List branches
git branch           # Local branches
git branch -a        # All branches (including remote)
git branch -r        # Remote branches only

# Create new branch
git branch feature-login

# Create and switch to new branch
git checkout -b feature-login
git switch -c feature-login  # Modern alternative

# Switch branches
git checkout main
git switch main  # Modern alternative

# Rename branch
git branch -m old-name new-name
git branch -m new-name  # Rename current branch

# Delete branch
git branch -d feature-completed  # Safe delete (merged only)
git branch -D feature-broken     # Force delete

# Delete remote branch
git push origin --delete feature-old

# Track remote branch
git checkout -b feature origin/feature
git branch --set-upstream-to=origin/feature feature

Merging Strategies

Different ways to integrate changes from one branch into another.

Intermediatemergecherry-pickintegrationDocs
# Fast-forward merge (when possible)
git checkout main
git merge feature-branch

# No fast-forward (always create merge commit)
git merge --no-ff feature-branch

# Squash merge (combine all commits into one)
git merge --squash feature-branch
git commit -m "Add complete feature X"

# Abort merge if conflicts arise
git merge --abort

# Continue merge after resolving conflicts
git add resolved-file.js
git commit  # Completes merge

# View merged branches
git branch --merged
git branch --no-merged

# Merge specific commit
git cherry-pick abc123def

# Cherry-pick without committing (stage only)
git cherry-pick -n abc123def

Rebase for Clean History

Rebase commits for a linear history. Use with caution on shared branches!

AdvancedrebasehistoryinteractiveDocs
# Basic rebase
git checkout feature
git rebase main

# Abort rebase if things go wrong
git rebase --abort

# Continue after resolving conflicts
git add resolved-file.js
git rebase --continue

# Skip problematic commit
git rebase --skip

# Interactive rebase (edit commit history)
git rebase -i HEAD~3  # Last 3 commits
git rebase -i main    # All commits since branching from main

# In interactive mode, you can:
# pick   = keep commit as-is
# reword = change commit message
# edit   = pause to amend commit
# squash = merge with previous commit
# fixup  = like squash but discard message
# drop   = remove commit

# Example interactive rebase:
# pick abc123 Add login
# squash def456 Fix typo
# reword ghi789 Add tests
# drop jkl012 Debug logging

# Update feature branch with latest main
git checkout feature
git rebase main

# Keep "theirs" during rebase conflicts
git checkout --theirs file.js
git add file.js
git rebase --continue

Remote Repositories

Work with remote repositories, push, pull, and fetch changes

Remote Management

Add, list, and manage remote repository connections.

Beginnerremoteoriginupstream
# List remotes
git remote
git remote -v  # Show URLs

# Add remote
git remote add origin https://github.com/user/repo.git
git remote add upstream https://github.com/original/repo.git

# Change remote URL
git remote set-url origin https://github.com/user/new-repo.git

# Remove remote
git remote remove upstream

# Rename remote
git remote rename origin main-remote

# Show remote details
git remote show origin

# Prune deleted remote branches
git remote prune origin

Push, Pull & Fetch

Sync your local repository with remotes.

IntermediatepushpullfetchsyncDocs
# Push to remote
git push origin main
git push origin feature-branch

# Push and set upstream (first time)
git push -u origin feature-branch

# Push all branches
git push origin --all

# Push tags
git push origin --tags

# Force push (DANGEROUS - overwrites remote history)
git push --force origin feature-branch
git push --force-with-lease origin feature-branch  # Safer

# Fetch from remote (doesn't merge)
git fetch origin
git fetch --all  # All remotes

# Pull (fetch + merge)
git pull origin main
git pull --rebase origin main  # Rebase instead of merge

# Pull with autostash
git pull --rebase --autostash

# Clone specific depth (faster for large repos)
git clone --depth 1 https://github.com/user/repo.git

Syncing Forks

Keep your fork up-to-date with the original repository.

Intermediateforkupstreamsynccollaboration
# Add upstream remote (original repo)
git remote add upstream https://github.com/original/repo.git

# Fetch upstream changes
git fetch upstream

# Merge upstream/main into your main
git checkout main
git merge upstream/main

# Or rebase your changes on top of upstream
git checkout main
git rebase upstream/main

# Push updated main to your fork
git push origin main

# Complete workflow for fork sync
git fetch upstream
git checkout main
git rebase upstream/main
git push origin main --force-with-lease

Undoing Changes

Fix mistakes, revert commits, and recover lost work. Every developer's lifesaver!

Undo Unstaged Changes

Discard changes in your working directory that haven't been staged.

Beginnerundodiscardrestoreclean
# Discard changes in specific file
git checkout -- file.js
git restore file.js  # Modern alternative

# Discard all unstaged changes
git checkout -- .
git restore .

# Discard changes in specific directory
git restore src/

# Show what would be removed (dry run)
git clean -n

# Remove untracked files
git clean -f

# Remove untracked files and directories
git clean -fd

# Remove ignored files too
git clean -fdx

Unstage Files

Remove files from staging area without losing the changes.

Beginnerunstageresetstaging
# Unstage specific file
git reset HEAD file.js
git restore --staged file.js  # Modern alternative

# Unstage all files
git reset HEAD
git restore --staged .

# Unstage and discard changes
git reset --hard HEAD

Undo Commits

Various ways to undo commits depending on what you need.

IntermediateundoresetrevertcommitsDocs
# Undo last commit but keep changes staged
git reset --soft HEAD~1

# Undo last commit and unstage changes
git reset HEAD~1
git reset --mixed HEAD~1  # Same as above

# Undo last commit and discard changes (DANGEROUS)
git reset --hard HEAD~1

# Undo multiple commits
git reset --soft HEAD~3  # Last 3 commits

# Undo to specific commit
git reset --soft abc123def

# Create new commit that undoes a previous commit
git revert abc123def

# Revert multiple commits
git revert abc123..def456

# Revert without committing (stage changes only)
git revert -n abc123def

# Revert merge commit
git revert -m 1 merge-commit-hash

Fix Last Commit

Change the last commit message or add forgotten files.

Intermediateamendfixcommit
# Change last commit message
git commit --amend -m "Better commit message"

# Add forgotten files to last commit
git add forgotten-file.js
git commit --amend --no-edit

# Change author of last commit
git commit --amend --author="Name <email@example.com>"

# Change timestamp of last commit
git commit --amend --date="now"

# WARNING: Never amend commits that have been pushed!
# If you must, force push:
git push --force-with-lease origin branch-name

Recover Lost Commits

Use reflog to recover commits that seem lost. Git rarely loses data!

Advancedreflogrecoverylost-commitsDocs
# View reflog (history of HEAD movements)
git reflog

# Reflog shows:
# abc123 HEAD@{0}: commit: Add feature
# def456 HEAD@{1}: checkout: moving from main to feature
# ghi789 HEAD@{2}: reset: moving to HEAD~1

# Recover lost commit
git checkout abc123
git cherry-pick abc123
git reset --hard abc123

# Recover deleted branch
git reflog
git checkout -b recovered-branch HEAD@{2}

# Reflog for specific branch
git reflog show feature-branch

# Reflog with dates
git reflog --date=iso

Stashing Work

Temporarily save uncommitted changes to switch contexts quickly

Basic Stashing

Save your work in progress without committing when you need to switch branches.

Beginnerstashtemporarysave
# Stash current changes
git stash
git stash push  # Same as above

# Stash with descriptive message
git stash push -m "Work in progress on login form"

# Include untracked files
git stash -u
git stash --include-untracked

# Stash everything (including ignored files)
git stash -a
git stash --all

# List stashes
git stash list

# Show stash contents
git stash show
git stash show -p  # Show full diff
git stash show stash@{1}  # Specific stash

Apply & Manage Stashes

Restore stashed work and manage multiple stashes.

IntermediatestashapplypopmanagementDocs
# Apply most recent stash
git stash apply

# Apply specific stash
git stash apply stash@{2}

# Apply and remove from stash list (pop)
git stash pop

# Apply stash to new branch
git stash branch new-branch-name

# Remove specific stash
git stash drop stash@{1}

# Clear all stashes
git stash clear

# Create stash of specific files only
git stash push -m "Stash utils only" -- src/utils/

# Stash only staged changes
git stash push --staged

Resolving Conflicts

Handle merge conflicts like a pro

Identify & Resolve Conflicts

When Git can't automatically merge changes, you'll need to resolve conflicts manually.

Intermediateconflictsmergeresolution
# Check which files have conflicts
git status

# View conflict markers in file:
<<<<<<< HEAD
Your current changes
=======
Incoming changes
>>>>>>> branch-name

# Choose version to keep:
# Option 1: Keep your version
git checkout --ours conflicted-file.js

# Option 2: Keep their version
git checkout --theirs conflicted-file.js

# Option 3: Edit manually, then:
git add conflicted-file.js

# After resolving all conflicts:
git commit  # For merge
git rebase --continue  # For rebase

# Abort if you want to start over:
git merge --abort
git rebase --abort

# View conflict diff
git diff
git diff --name-only --diff-filter=U  # List conflicted files

Merge Tools

Use visual merge tools for easier conflict resolution.

Intermediatemergetoolvisualconflicts
# Configure merge tool
git config --global merge.tool vimdiff
git config --global merge.tool vscode
git config --global merge.tool kdiff3

# VS Code merge tool configuration
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait --merge $REMOTE $LOCAL $BASE $MERGED'

# Launch merge tool
git mergetool

# After resolving with tool
git commit

# Don't create .orig backup files
git config --global mergetool.keepBackup false

Advanced Techniques

Power user commands for complex scenarios and workflow optimization

Submodules

Include other Git repositories as subdirectories within your project.

Advancedsubmodulesdependenciesnested
# Add submodule
git submodule add https://github.com/user/library.git lib/library

# Clone repo with submodules
git clone --recursive https://github.com/user/repo.git

# Initialize submodules after cloning
git submodule init
git submodule update

# Update all submodules
git submodule update --remote

# Update specific submodule
git submodule update --remote lib/library

# Remove submodule
git submodule deinit lib/library
git rm lib/library
rm -rf .git/modules/lib/library

Bisect - Find Bug Introduction

Binary search through commit history to find when a bug was introduced.

Advancedbisectdebuggingbinary-searchDocs
# Start bisecting
git bisect start

# Mark current commit as bad
git bisect bad

# Mark known good commit
git bisect good abc123

# Git checks out middle commit, test it, then:
git bisect good  # If this commit is fine
git bisect bad   # If this commit has the bug

# Git will continue binary search automatically
# Repeat until you find the problematic commit

# View bisect log
git bisect log

# Finish bisecting
git bisect reset

# Automated bisect with test script
git bisect start HEAD abc123
git bisect run npm test

Worktrees - Multiple Branches Simultaneously

Work on multiple branches at once without stashing or losing context.

Advancedworktreemultiple-branchesparallel
# Create worktree for feature branch
git worktree add ../feature-branch feature-branch

# Create new branch in worktree
git worktree add -b hotfix ../hotfix

# List worktrees
git worktree list

# Remove worktree
git worktree remove ../feature-branch

# Prune deleted worktrees
git worktree prune

# Use case example:
# Main project in ~/project
# Feature work in ~/project-feature
# Hotfix in ~/project-hotfix
# All sharing same .git directory!

Sparse Checkout - Partial Clone

Clone only specific directories from large repositories.

Advancedsparse-checkoutpartialperformance
# Initialize repo without checking out files
git clone --no-checkout https://github.com/user/large-repo.git
cd large-repo

# Enable sparse checkout
git sparse-checkout init --cone

# Specify directories to checkout
git sparse-checkout set src/components tests/unit

# Add more directories
git sparse-checkout add docs

# List sparse checkout patterns
git sparse-checkout list

# Disable sparse checkout
git sparse-checkout disable

Filter-Branch - Rewrite History

Powerful but dangerous - rewrite commit history across entire repository.

Expertfilter-branchhistory-rewritingdangerous
# Remove file from all history (e.g., committed secrets)
git filter-branch --tree-filter 'rm -f secrets.txt' HEAD

# Modern alternative: git filter-repo (faster, safer)
# Install: pip install git-filter-repo
git filter-repo --path secrets.txt --invert-paths

# Change author email in all commits
git filter-branch --commit-filter '
  if [ "$GIT_AUTHOR_EMAIL" = "old@email.com" ];
  then
    GIT_AUTHOR_EMAIL="new@email.com";
    GIT_COMMITTER_EMAIL="new@email.com";
    git commit-tree "$@";
  else
    git commit-tree "$@";
  fi' HEAD

# WARNING: These commands rewrite history!
# Only use on repositories you haven't shared yet
# Or coordinate with your team and force-push

Tips & Tricks

Pro tips, shortcuts, and lesser-known features to boost productivity

Search & Find Commits

Powerful ways to find specific changes in your history.

Intermediatesearchfindhistory
# Find commits that added/removed specific text
git log -S "function_name"
git log -G "regex.*pattern"

# Find commits affecting specific line range
git log -L 10,20:path/to/file.js

# Search commit messages
git log --grep="bug"
git log --grep="feature" --grep="fix" --all-match

# Find commits by date
git log --since="2 weeks ago"
git log --after="2024-01-01" --before="2024-12-31"

# Find who deleted a file
git log --full-history -- path/to/deleted/file.js

# Find dangling commits
git fsck --lost-found

Ignore Files (gitignore)

Prevent specific files from being tracked by Git.

Beginnergitignoreignoretracking
# Create .gitignore file
cat > .gitignore << EOF
# Dependencies
node_modules/
vendor/

# Build outputs
dist/
build/
*.min.js

# Environment files
.env
.env.local
*.env.*

# IDE files
.vscode/
.idea/
*.swp

# OS files
.DS_Store
Thumbs.db

# Logs
*.log
logs/
EOF

# Ignore files globally
git config --global core.excludesfile ~/.gitignore_global

# Stop tracking already tracked file
git rm --cached file-to-ignore.txt
git rm -r --cached node_modules/

# View ignored files
git status --ignored

# Check if file is ignored
git check-ignore -v file.txt

Git Hooks - Automate Workflows

Run scripts automatically on Git events like commit or push.

Advancedhooksautomationworkflow
# Hooks are in .git/hooks/
cd .git/hooks

# Common hooks:
# pre-commit    - Before commit is created
# pre-push      - Before push to remote
# commit-msg    - Edit/validate commit message

# Example: pre-commit hook to run tests
cat > pre-commit << 'EOF'
#!/bin/bash
npm test
if [ $? -ne 0 ]; then
  echo "Tests failed! Commit aborted."
  exit 1
fi
EOF
chmod +x pre-commit

# Example: commit-msg hook to enforce format
cat > commit-msg << 'EOF'
#!/bin/bash
commit_msg=$(cat $1)
if ! echo "$commit_msg" | grep -qE "^(feat|fix|docs|style|refactor|test|chore):"; then
  echo "Commit message must start with: feat:|fix:|docs:|style:|refactor:|test:|chore:"
  exit 1
fi
EOF
chmod +x commit-msg

# Skip hooks (use sparingly)
git commit --no-verify
git push --no-verify

Optimize Repository

Speed up your repository and reduce its size.

Advancedoptimizationperformancecleanup
# Garbage collection
git gc

# Aggressive garbage collection
git gc --aggressive --prune=now

# Verify repository integrity
git fsck

# Count objects in repository
git count-objects -v

# Find large files in history
git rev-list --objects --all |   git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' |   sed -n 's/^blob //p' |   sort --numeric-sort --key=2 |   tail -10

# Prune remote tracking branches that no longer exist
git fetch --prune

# Optimize fetch/push performance
git config --global feature.manyFiles true
git config --global index.threads true