Skip to content

branch Git Command Guide

The git branch command creates, lists, deletes, and manages branches in Git repositories. Branches enable parallel development workflows, feature isolation, and collaborative development patterns essential for modern software development.

Terminal window
git branch [(-c | -C) [<commit>]] [(-d | -D) [<commit>]] [(-m | -M) [<commit>]]
[(-r | --remotes)] [(-a | --all)] [--list] [--show-current]
[(-v | --verbose)] [(-q | --quiet)] [--abbrev=<n>] [--no-abbrev]
[--column[=<options>] | --no-column] [--sort=<key>]
[--merged[=<commit>]] [--no-merged[=<commit>]]
[--contains[=<commit>]] [--no-contains[=<commit>]]
[--points-at=<object>] [--format=<format>]
[(--set-upstream-to=<upstream> | -u <upstream>) [<branch>]]
[--unset-upstream [<branch>]] [--edit-description [<branch>]]
[<branch-name>] [<start-point>]
OptionDescription
(no option)Create new branch
-c <branch>Copy branch
-C <branch>Copy branch (force)
--trackSet up tracking
--no-trackDon’t set up tracking
-u <upstream>, --set-upstream-to=<upstream>Set upstream
OptionDescription
-d, --deleteDelete merged branches
-DDelete branches (force)
--unset-upstreamRemove upstream
OptionDescription
-m, --moveRename branch
-MRename branch (force)
OptionDescription
--listList branches
-v, --verboseShow commit and upstream
-a, --allList all branches
-r, --remotesList remote branches
--show-currentShow current branch
--column[=<options>]Display in columns
--no-columnDon’t display in columns
--sort=<key>Sort branches
--abbrev=<n>Abbreviate commits
--no-abbrevDon’t abbreviate
OptionDescription
--merged[=<commit>]Show merged branches
--no-merged[=<commit>]Show unmerged branches
--contains[=<commit>]Show branches containing commit
--no-contains[=<commit>]Show branches not containing commit
--points-at=<object>Show branches pointing to object
OptionDescription
--format=<format>Custom output format
--edit-descriptionEdit branch description
-q, --quietSuppress messages
ParameterDescription
<branch-name>Name of branch to operate on
<start-point>Commit to start branch from
<commit>Commit for filtering operations
Git Branch Categories:
├── Local Branches: Exist only in local repository
├── Remote Tracking Branches: Track remote branches (origin/main)
├── Current Branch: Currently checked out branch (HEAD points here)
├── Orphan Branches: Created without parent history
└── Detached HEAD: HEAD points to commit, not branch
Branch Relationships:
├── Upstream Branch: Remote branch being tracked
├── Tracking Branch: Local branch with upstream set
├── Ahead/Behind: Commits ahead/behind upstream
└── Merge Base: Common ancestor with other branches
Common Branch Naming Patterns:
├── main/master: Default branch
├── develop: Integration branch
├── feature/*: Feature development
├── bugfix/*: Bug fixes
├── hotfix/*: Critical fixes
├── release/*: Release preparation
└── experiment/*: Experimental work
Branch Name Best Practices:
├── Use lowercase with hyphens
├── Include issue numbers when applicable
├── Use descriptive names
├── Follow team conventions
└── Avoid special characters
Terminal window
# Create branch from current HEAD
git branch feature-branch
# Create branch from specific commit
git branch bugfix-123 abc123
# Create branch from another branch
git branch new-feature develop
# Create and switch immediately
git checkout -b feature-branch
git switch -c feature-branch
# Copy existing branch
git branch -c existing-branch new-branch
Terminal window
# List local branches
git branch
# List all branches (local + remote)
git branch -a
# List remote branches only
git branch -r
# Verbose listing with commit info
git branch -v
# Very verbose with upstream info
git branch -vv
# Show current branch
git branch --show-current
Terminal window
# Switch to existing branch
git checkout feature-branch
git switch feature-branch
# Create and switch
git checkout -b new-branch
git switch -c new-branch
# Switch with tracking
git checkout --track origin/feature
git switch --track origin/feature
Terminal window
# Delete merged branch
git branch -d feature-branch
# Force delete unmerged branch
git branch -D feature-branch
# Delete remote branch
git push origin --delete feature-branch
# Delete multiple branches
git branch -D branch1 branch2 branch3
Terminal window
# Set upstream for existing branch
git branch --set-upstream-to=origin/main main
git branch -u origin/main main
# Unset upstream
git branch --unset-upstream
# Create tracking branch
git branch --track feature origin/feature
# Show tracking info
git branch -vv
Terminal window
# Rename current branch
git branch -m new-name
# Rename specific branch
git branch -m old-name new-name
# Force rename (overwrite existing)
git branch -M old-name new-name
# Move branch to different commit
git branch -f branch-name new-commit
Terminal window
# Show merged branches
git branch --merged
# Show merged into specific commit
git branch --merged v1.0
# Show unmerged branches
git branch --no-merged
# Show branches containing commit
git branch --contains abc123
# Show branches not containing commit
git branch --no-contains abc123
Terminal window
# Sort branches by date
git branch --sort=-committerdate
# Sort by author
git branch --sort=author
# Group by pattern
git branch | grep "feature/"
git branch | grep "bugfix/"
Terminal window
# Configure branch defaults
git config branch.autosetupmerge true # Auto setup merge
git config branch.autosetuprebase always # Auto setup rebase
# Configure branch sorting
git config branch.sort -committerdate # Sort by date
# Configure branch colors
git config color.branch.current yellow
git config color.branch.local green
git config color.branch.remote red
# Configure branch descriptions
git config branch.description true
Terminal window
# Use descriptive names
git branch feature/user-authentication
git branch bugfix/login-validation
# Keep branches focused
# One feature or fix per branch
# Regular cleanup
git branch --merged | grep -v main | xargs git branch -d
# Track remote branches
git branch --track feature origin/feature
# Use branch descriptions
git branch --edit-description feature-branch
Terminal window
# Check before deleting
git branch -d branch-name # Fails if unmerged
git branch -D branch-name # Force delete
# Backup before major operations
git branch backup-$(date +%Y%m%d)
# Verify branch state
git status
git log --oneline -5
#!/bin/bash
# Feature branch workflow management
create_feature_branch() {
local feature_name="$1"
local base_branch="${2:-develop}"
echo "Creating feature branch: $feature_name"
# Switch to base branch
git checkout "$base_branch"
git pull origin "$base_branch"
# Create feature branch
git checkout -b "feature/$feature_name"
# Set upstream
git push -u origin "feature/$feature_name"
echo "Feature branch created and pushed"
}
# Usage
create_feature_branch "user-dashboard" "develop"
Terminal window
# Automated branch cleanup
cleanup_branches() {
echo "Cleaning up merged branches"
# Get current branch
current_branch=$(git branch --show-current)
# Find merged branches (excluding main/master and current)
merged_branches=$(git branch --merged | grep -v "main\|master\|develop" | grep -v "^\*" | sed 's/^ //')
if [ -z "$merged_branches" ]; then
echo "No merged branches to clean up"
return 0
fi
echo "Merged branches to delete:"
echo "$merged_branches"
echo ""
read -p "Delete these branches? (y/N): " confirm
if [[ "$confirm" == "y" ]]; then
echo "$merged_branches" | xargs git branch -d
echo "Branches cleaned up"
else
echo "Cleanup cancelled"
fi
}
cleanup_branches
Terminal window
# Branch status dashboard
branch_dashboard() {
echo "=== Branch Dashboard ==="
echo ""
# Current branch
current=$(git branch --show-current)
echo "Current branch: $current"
# Branch counts
local_branches=$(git branch | wc -l)
remote_branches=$(git branch -r | wc -l)
echo "Local branches: $local_branches"
echo "Remote branches: $remote_branches"
# Branch status
echo ""
echo "Branch Status:"
git branch -vv | head -10
# Unmerged branches
unmerged=$(git branch --no-merged 2>/dev/null | wc -l)
if [ "$unmerged" -gt 0 ]; then
echo ""
echo "Unmerged branches: $unmerged"
git branch --no-merged | head -5
fi
# Stale branches (no commits in 30 days)
echo ""
echo "Potentially stale branches:"
git branch -v | while read -r branch; do
# Extract last commit date
last_commit=$(echo "$branch" | awk '{print $3}')
if [ -n "$last_commit" ]; then
# Check if older than 30 days
if git log -1 --since="30 days ago" "$last_commit" >/dev/null 2>&1; then
continue
else
echo "$branch"
fi
fi
done | head -5
echo ""
echo "Dashboard complete"
}
branch_dashboard
Terminal window
# Branch already exists
git branch -f existing-branch new-start # Force recreate
# Invalid branch name
git branch "feature/user-auth" # Use valid characters
# No commits to branch from
git log --oneline -1 # Check HEAD exists
Terminal window
# Branch not fully merged
git branch -D unmerged-branch # Force delete
# Branch checked out
git checkout main # Switch away first
git branch -d feature-branch
# Remote branch deletion
git push origin --delete feature-branch
Terminal window
# Upstream not set
git branch --set-upstream-to=origin/main main
# Upstream branch deleted
git branch --unset-upstream
git branch --set-upstream-to=origin/new-main main
# Tracking info incorrect
git branch -vv # Check tracking
git remote -v # Check remotes
Terminal window
# Uncommitted changes
git stash push -m "work in progress"
git checkout feature-branch
git stash pop
# Branch doesn't exist locally
git checkout --track origin/feature-branch
# Detached HEAD state
git checkout main # Return to branch
Terminal window
# Fix invalid branch names
git branch -m "old name" "new-name" # Rename to valid name
# Handle special characters
git branch "feature/user@domain" # Avoid @ in names
git branch "feature/user-domain" # Use valid alternative
Terminal window
# Remote branch not visible
git fetch --all # Fetch all remotes
git branch -r # List remote branches
# Remote branch deleted
git remote prune origin # Clean deleted remotes
git branch -d -r origin/deleted-branch # Delete local tracking
Terminal window
# Speed up branch operations
git branch --no-merged | head -10 # Limit output
# Use local operations when possible
git branch -l # Local only
git branch --no-contains HEAD | wc -l # Count efficiently
#!/bin/bash
# Git Flow branch management
git_flow_branches() {
echo "=== Git Flow Branch Management ==="
# Create develop branch if not exists
if ! git show-ref --verify --quiet refs/heads/develop; then
git branch develop main
git push -u origin develop
fi
# Create release branch
create_release() {
local version="$1"
git checkout develop
git pull origin develop
git checkout -b "release/$version"
git push -u origin "release/$version"
}
# Create hotfix branch
create_hotfix() {
local version="$1"
git checkout main
git pull origin main
git checkout -b "hotfix/$version"
git push -u origin "hotfix/$version"
}
# Finish release
finish_release() {
local version="$1"
git checkout main
git merge --no-ff "release/$version"
git tag -a "$version" -m "Release $version"
git push origin main --tags
git checkout develop
git merge --no-ff "release/$version"
git push origin develop
git branch -d "release/$version"
git push origin --delete "release/$version"
}
# Show available operations
echo "Available operations:"
echo " create_release <version>"
echo " create_hotfix <version>"
echo " finish_release <version>"
}
git_flow_branches
Terminal window
# Branch protection and validation
validate_branches() {
echo "=== Branch Validation ==="
# Check protected branches
protected_branches=("main" "master" "develop" "production")
for branch in "${protected_branches[@]}"; do
if git show-ref --verify --quiet "refs/heads/$branch"; then
# Check if branch has required protection
echo "✓ Protected branch exists: $branch"
# Check recent commits
recent_commits=$(git log --oneline -10 "$branch" | wc -l)
echo " Recent commits: $recent_commits"
else
echo "⚠ Missing protected branch: $branch"
fi
done
# Check branch naming conventions
echo ""
echo "Branch naming validation:"
git branch | while read -r branch; do
branch=$(echo "$branch" | sed 's/^* //')
if [[ ! "$branch" =~ ^(main|master|develop|feature/|bugfix/|hotfix/|release/) ]]; then
echo "⚠ Non-standard branch name: $branch"
fi
done
# Check for orphaned branches
echo ""
echo "Orphaned branches (no recent commits):"
git branch -v | while read -r branch commit rest; do
branch=$(echo "$branch" | sed 's/^* //')
# Check if last commit > 90 days ago
if ! git log -1 --since="90 days ago" "$commit" >/dev/null 2>&1; then
echo " $branch (last commit: $(git log -1 --format='%ci' "$commit"))"
fi
done
echo ""
echo "Validation complete"
}
validate_branches
Terminal window
# Automated branch maintenance
branch_maintenance() {
echo "=== Branch Maintenance ==="
# Update tracking branches
echo "Updating tracking branches..."
git fetch --all --prune
# Remove stale remote tracking branches
echo "Removing stale remote branches..."
git branch -r | while read -r remote_branch; do
# Check if remote branch still exists
if ! git ls-remote --exit-code origin "${remote_branch#origin/}" >/dev/null 2>&1; then
echo "Removing stale branch: $remote_branch"
git branch -d -r "$remote_branch" 2>/dev/null || true
fi
done
# Clean up merged local branches
echo "Cleaning merged local branches..."
git branch --merged | grep -v "main\|master\|develop" | grep -v "^\*" | while read -r branch; do
echo "Deleting merged branch: $branch"
git branch -d "$branch"
done
# Archive old branches
echo "Archiving old branches..."
archive_dir="branch-archive-$(date +%Y%m%d)"
mkdir -p "$archive_dir"
git branch -v | while read -r branch commit rest; do
branch=$(echo "$branch" | sed 's/^* //')
# Archive branches older than 6 months
if ! git log -1 --since="6 months ago" "$commit" >/dev/null 2>&1; then
echo "Archiving branch: $branch"
git log --oneline "$branch" > "$archive_dir/$branch.log"
fi
done
if [ -d "$archive_dir" ] && [ "$(ls -A "$archive_dir")" ]; then
tar czf "${archive_dir}.tar.gz" "$archive_dir"
rm -rf "$archive_dir"
echo "Branches archived to: ${archive_dir}.tar.gz"
fi
echo "Maintenance complete"
}
branch_maintenance
Terminal window
# Branch analytics and reporting
branch_analytics() {
echo "=== Branch Analytics Report ==="
echo "Generated: $(date)"
echo ""
# Branch statistics
total_branches=$(git branch | wc -l)
remote_branches=$(git branch -r | wc -l)
local_only=$(($total_branches - $remote_branches))
echo "Branch Statistics:"
echo " Total branches: $total_branches"
echo " Remote branches: $remote_branches"
echo " Local-only branches: $local_only"
# Branch age analysis
echo ""
echo "Branch Age Distribution:"
git branch -v | while read -r branch commit rest; do
branch=$(echo "$branch" | sed 's/^* //')
# Calculate age in days
commit_date=$(git log -1 --format='%ct' "$commit")
current_date=$(date +%s)
age_days=$(( ($current_date - $commit_date) / 86400 ))
if [ $age_days -le 7 ]; then
echo "7d: $branch"
elif [ $age_days -le 30 ]; then
echo "30d: $branch"
elif [ $age_days -le 90 ]; then
echo "90d: $branch"
else
echo "90d+: $branch"
fi
done | sort | uniq -c | sort -nr
# Most active branches
echo ""
echo "Most Active Branches (by commits):"
git branch | sed 's/^* //' | while read -r branch; do
commit_count=$(git rev-list --count "$branch" 2>/dev/null || echo "0")
echo "$commit_count $branch"
done | sort -nr | head -10
# Branch naming patterns
echo ""
echo "Branch Naming Patterns:"
git branch | sed 's/^* //' | sed 's/\/.*//' | sort | uniq -c | sort -nr | head -10
# Upstream tracking status
echo ""
echo "Upstream Tracking Status:"
tracked=$(git branch -vv | grep -c "\[.*\]")
untracked=$(git branch -vv | grep -c "\[.*\]" | wc -l)
untracked=$(( $total_branches - $tracked ))
echo " Tracked branches: $tracked"
echo " Untracked branches: $untracked"
echo ""
echo "Analytics complete"
}
branch_analytics
Terminal window
# Collaborative branch management
collaborative_branches() {
echo "=== Collaborative Branch Management ==="
# Sync with remote
echo "Syncing with remote..."
git fetch --all --prune
# Show branch ownership
echo "Branch ownership:"
git branch -v | while read -r branch commit rest; do
branch=$(echo "$branch" | sed 's/^* //')
author=$(git log -1 --format='%an' "$commit")
echo "$branch: $author"
done
# Check for branches needing review
echo ""
echo "Branches that may need review:"
git branch -v | while read -r branch commit rest; do
branch=$(echo "$branch" | sed 's/^* //')
# Check if branch has recent commits not in main
if git rev-list --count main.."$branch" 2>/dev/null | grep -q "^[1-9]"; then
commit_count=$(git rev-list --count main.."$branch")
last_commit=$(git log -1 --format='%ci' "$branch")
echo "$branch: $commit_count commits, last: $last_commit"
fi
done
# Suggest branch cleanup
echo ""
echo "Suggested cleanup:"
git branch --merged | grep -v "main\|master\|develop" | grep -v "^\*" | while read -r branch; do
echo " Merged: $branch"
done
git branch --no-merged | while read -r branch; do
echo " Unmerged: $branch"
done
echo ""
echo "Collaborative management complete"
}
collaborative_branches

What’s the difference between git branch and git checkout -b?

Section titled “What’s the difference between git branch and git checkout -b?”

git branch creates a branch without switching; git checkout -b creates and switches to the branch immediately.

How do I see all branches including remote ones?

Section titled “How do I see all branches including remote ones?”

Use git branch -a to list all local and remote branches, or git branch -r for remote branches only.

No, you must switch to another branch first before deleting the current branch.

What’s the difference between -d and -D for deleting branches?

Section titled “What’s the difference between -d and -D for deleting branches?”

-d deletes only if the branch is fully merged; -D force deletes regardless of merge status.

Use git branch -m to rename the current branch, or git branch -m for any branch.

How do I see which branches contain a specific commit?

Section titled “How do I see which branches contain a specific commit?”

Use git branch —contains to show branches containing that commit.

Can I set up tracking for an existing branch?

Section titled “Can I set up tracking for an existing branch?”

Yes, use git branch —set-upstream-to=/ to set tracking.

How do I see branches that are merged vs not merged?

Section titled “How do I see branches that are merged vs not merged?”

Use git branch —merged to see merged branches, git branch —no-merged for unmerged ones.

A local branch that tracks a remote branch, automatically knowing which remote branch to push/pull from.

How do I create a branch from a specific commit?

Section titled “How do I create a branch from a specific commit?”

Use git branch to create a branch starting from that commit.

Yes, use git branch -c to copy an existing branch.

How do I see the current branch name in scripts?

Section titled “How do I see the current branch name in scripts?”

Use git branch —show-current or git rev-parse —abbrev-ref HEAD.

What’s the difference between local and remote branches?

Section titled “What’s the difference between local and remote branches?”

Local branches exist only in your repository; remote branches track branches on remote repositories.

Use git push —delete to delete a remote branch.

If recently deleted, check git reflog to find the commit hash and recreate the branch.

Use git log —oneline —all —simplify-by-decoration to see when branches were created.

—orphan creates a new branch with no history, useful for completely separate development lines.

Use git diff .. or git log —oneline ...

Can I have multiple branches pointing to the same commit?

Section titled “Can I have multiple branches pointing to the same commit?”

Yes, multiple branches can point to the same commit - that’s how branching works.

How do I find the merge base of two branches?

Section titled “How do I find the merge base of two branches?”

Use git merge-base to find the common ancestor commit.

When merging a branch where all commits are already in the target branch history, Git just moves the pointer forward.

Use git log —oneline —graph —all to visualize the branch structure and relationships.

  1. Feature Development: Creating isolated branches for new features
  2. Bug Fixes: Setting up branches for bug fixes from stable commits
  3. Release Management: Managing release branches and hotfixes
  4. Code Review: Organizing branches for pull request workflows
  5. Experimentation: Creating branches for experimental features
  6. Collaboration: Managing team branches and tracking contributions
  7. Repository Organization: Maintaining clean branch hierarchies
  8. Workflow Automation: Scripting branch creation and cleanup