Skip to content

show-ref Git Command Guide

The git show-ref command lists references (branches, tags, remotes) in a Git repository and their corresponding commit hashes. It provides low-level access to Git’s reference database, making it useful for scripting, repository inspection, and reference validation.

Terminal window
git show-ref [<options>] [--] [<pattern>...]
git show-ref --verify [--quiet] [--] [<ref>...]
git show-ref --delete [--quiet] [--] <ref>...
OptionDescription
--headShow HEAD reference
--tagsShow tag references
--headsShow branch references
--remotesShow remote references
-d, --dereferenceDereference tags
--hash[=<n>]Show only hash (abbreviated)
--abbrev[=<n>]Abbreviate hashes
--verifyVerify references exist
--quietSuppress output
--deleteDelete references
OptionDescription
-s, --hash-onlyShow only hash
--heads-onlyShow only branches
--tags-onlyShow only tags
--remotes-onlyShow only remotes
--exclude-existing[=<pattern>]Exclude existing refs
ParameterDescription
<pattern>Pattern to match references
<ref>Specific reference to operate on
Reference Listing Format:
<hash> <ref-name>
<hash> <ref-name>
...
Example Output:
a1b2c3d4e5f6 refs/heads/main
f7e8d9c0b1a2 refs/heads/develop
b3c4d5e6f7a8 refs/tags/v1.0
c4d5e6f7a8b9 refs/remotes/origin/main
Git Reference Categories:
├── refs/heads/ = Local branches
├── refs/tags/ = Tags (annotated and lightweight)
├── refs/remotes/ = Remote tracking branches
├── HEAD = Current branch/commit pointer
├── refs/stash = Stash references
└── refs/notes/ = Notes references
Hash Display Options:
├── Full hash: a1b2c3d4e5f6f7e8d9c0b1a2b3c4d5e6
├── Abbreviated: a1b2c3d
├── Custom length: a1b2c3d4 (8 chars)
└── Minimum unique: Determined by repository
Terminal window
# List all references
git show-ref
# List branches only
git show-ref --heads
# List tags only
git show-ref --tags
# List remotes only
git show-ref --remotes
# List with abbreviated hashes
git show-ref --abbrev
Terminal window
# Match specific patterns
git show-ref refs/heads/feature/*
# Match multiple patterns
git show-ref refs/heads/main refs/tags/v*
# Exclude patterns
git show-ref --exclude-existing=refs/heads/main
# Show only hashes
git show-ref --hash-only
Terminal window
# Verify reference exists
git show-ref --verify refs/heads/main
# Verify quietly (for scripts)
git show-ref --verify --quiet refs/heads/main
# Check multiple references
git show-ref --verify refs/heads/main refs/tags/v1.0
Terminal window
# Show HEAD and its target
git show-ref --head
# Dereference tags to commits
git show-ref --dereference --tags
# Show all reference types
git show-ref --heads --tags --remotes
# Custom hash length
git show-ref --abbrev=12
Terminal window
# Get current branch hash
current_hash=$(git show-ref --hash --head)
# List all branch names
git show-ref --heads | cut -d' ' -f2 | sed 's|refs/heads/||'
# Find branches pointing to specific commit
commit="a1b2c3d4"
git show-ref | grep "^$commit" | cut -d' ' -f2
Terminal window
# Count references by type
echo "Branches: $(git show-ref --heads | wc -l)"
echo "Tags: $(git show-ref --tags | wc -l)"
echo "Remotes: $(git show-ref --remotes | wc -l)"
# Find orphaned references
git show-ref --heads | while read -r hash ref; do
if ! git cat-file -e "$hash" 2>/dev/null; then
echo "Broken ref: $ref"
fi
done
Terminal window
# Configure show-ref behavior
git config showref.abbrev 7 # Default abbreviation length
git config showref.verify true # Verify refs by default
# Configure reference handling
git config core.warnAmbiguousRefs true
git config core.logAllRefUpdates true
Terminal window
# Use for repository inspection
git show-ref | head -10
# Verify refs in scripts
if git show-ref --verify --quiet "refs/heads/$branch"; then
echo "Branch exists"
fi
# Get reference information
branch_hash=$(git show-ref --hash "refs/heads/main")
Terminal window
# Check repository state
git status >/dev/null 2>&1 || exit 1
# Handle missing references
git show-ref "refs/heads/$branch" 2>/dev/null || echo "Branch not found"
# Validate reference format
if [[ "$ref" =~ ^refs/(heads|tags|remotes)/ ]]; then
git show-ref --verify "$ref"
fi
#!/bin/bash
# Branch management with show-ref
list_branches() {
echo "=== Branch Listing ==="
# All branches with hashes
git show-ref --heads | while read -r hash ref; do
branch=$(basename "$ref")
echo "$hash $branch"
done
# Remote branches
echo ""
echo "Remote branches:"
git show-ref --remotes | while read -r hash ref; do
remote_branch=$(echo "$ref" | sed 's|refs/remotes/||')
echo "$hash $remote_branch"
done
}
# Find branches by commit
find_branches_by_commit() {
local commit="$1"
echo "Branches containing commit $commit:"
git show-ref | grep "^$commit" | cut -d' ' -f2 | sed 's|refs/heads/||'
}
# Check branch existence
branch_exists() {
local branch="$1"
if git show-ref --verify --quiet "refs/heads/$branch"; then
echo "Branch $branch exists"
return 0
else
echo "Branch $branch does not exist"
return 1
fi
}
list_branches
Terminal window
# Tag management with show-ref
tag_analysis() {
echo "=== Tag Analysis ==="
# List all tags with hashes
echo "All tags:"
git show-ref --tags | while read -r hash ref; do
tag=$(basename "$ref")
echo "$hash $tag"
done
# Dereference annotated tags
echo ""
echo "Annotated tags (dereferenced):"
git show-ref --dereference --tags | while read -r line; do
if [[ "$line" == *"^{}"* ]]; then
hash=$(echo "$line" | cut -d' ' -f1)
ref=$(echo "$line" | cut -d' ' -f2 | sed 's|^{\}$||')
tag=$(basename "$ref")
echo "$hash $tag (annotated)"
fi
done
# Find lightweight tags
echo ""
echo "Lightweight tags:"
git show-ref --tags | while read -r hash ref; do
tag=$(basename "$ref")
# Check if it's lightweight (no ^{} entry)
if ! git show-ref --dereference "$ref" >/dev/null 2>&1; then
echo "$hash $tag"
fi
done
}
tag_analysis
Terminal window
# Repository health checks with show-ref
health_check() {
echo "=== Repository Health Check ==="
# Check reference integrity
echo "Checking reference integrity..."
broken_refs=0
git show-ref | while read -r hash ref; do
if ! git cat-file -e "$hash" 2>/dev/null; then
echo "Broken reference: $ref -> $hash"
((broken_refs++))
fi
done
if [ "$broken_refs" -eq 0 ]; then
echo "✓ All references are valid"
else
echo "⚠ Found $broken_refs broken references"
fi
# Check for duplicate refs
echo ""
echo "Checking for duplicate references..."
duplicates=$(git show-ref | cut -d' ' -f1 | sort | uniq -d | wc -l)
if [ "$duplicates" -eq 0 ]; then
echo "✓ No duplicate references"
else
echo "⚠ Found duplicate references"
fi
# Reference statistics
echo ""
echo "Reference statistics:"
echo "Branches: $(git show-ref --heads | wc -l)"
echo "Tags: $(git show-ref --tags | wc -l)"
echo "Remotes: $(git show-ref --remotes | wc -l)"
echo "Total refs: $(git show-ref | wc -l)"
echo "Health check complete"
}
health_check
Terminal window
# Handle missing references
git show-ref "refs/heads/$branch" 2>/dev/null || echo "Branch not found"
# Check if repository has commits
git log --oneline | head -1 || echo "No commits in repository"
# Verify HEAD exists
git show-ref --head >/dev/null 2>&1 || echo "HEAD not found"
Terminal window
# Find broken references
git show-ref | while read -r hash ref; do
if ! git cat-file -e "$hash" 2>/dev/null; then
echo "Broken: $ref -> $hash"
fi
done
# Clean broken references
# Note: This requires manual intervention
git update-ref -d "refs/heads/broken-branch" 2>/dev/null
Terminal window
# Speed up operations in large repos
git show-ref --heads | head -20 # Limit output
# Use specific patterns
git show-ref "refs/heads/main" # Single ref
# Avoid expensive operations
git show-ref --verify "refs/heads/main" # Quick existence check
Terminal window
# Handle reference name encoding
git show-ref | iconv -f utf-8 -t utf-8 2>/dev/null
# Check for invalid characters
git show-ref | grep -v '^[0-9a-f]\{40\} refs/'
Terminal window
# Handle stale remote references
git remote prune origin
# Update remote references
git fetch --prune
# Check remote reference validity
git ls-remote origin 2>/dev/null | head -5
Terminal window
# Fix pattern matching
git show-ref "refs/heads/feature/*"
# Use proper globbing
git show-ref --heads | grep "^refs/heads/feature/"
# Escape special characters
git show-ref "refs/heads/bugfix/ISSUE-123"
#!/bin/bash
# Development workflow with show-ref
dev_workflow_refs() {
echo "=== Development Reference Analysis ==="
# Current branch info
current_branch=$(git symbolic-ref --short HEAD 2>/dev/null || echo "detached")
echo "Current branch: $current_branch"
if [ "$current_branch" != "detached" ]; then
current_hash=$(git show-ref --hash "refs/heads/$current_branch")
echo "Current hash: $current_hash"
fi
# Branch overview
echo ""
echo "Branch overview:"
git show-ref --heads | while read -r hash ref; do
branch=$(basename "$ref")
marker=" "
if [ "$branch" = "$current_branch" ]; then
marker=""
fi
echo "$marker$branch: $hash"
done
# Remote tracking status
echo ""
echo "Remote tracking:"
git show-ref --heads | while read -r hash ref; do
branch=$(basename "$ref")
remote_ref="refs/remotes/origin/$branch"
if git show-ref --verify --quiet "$remote_ref" 2>/dev/null; then
remote_hash=$(git show-ref --hash "$remote_ref")
if [ "$hash" = "$remote_hash" ]; then
status="✓ synced"
else
status="⚠ diverged"
fi
else
status="no remote"
fi
echo " $branch: $status"
done
# Recent tag info
echo ""
echo "Recent tags:"
git show-ref --tags | sort -k1 | tail -5 | while read -r hash ref; do
tag=$(basename "$ref")
echo " $tag: $hash"
done
echo "Reference analysis complete"
}
dev_workflow_refs
Terminal window
# CI/CD pipeline with show-ref
ci_ref_validation() {
echo "=== CI/CD Reference Validation ==="
# Validate required branches exist
required_branches=("main" "develop")
for branch in "${required_branches[@]}"; do
if git show-ref --verify --quiet "refs/heads/$branch"; then
echo "✓ Required branch exists: $branch"
else
echo "✗ Missing required branch: $branch"
exit 1
fi
done
# Check branch protection
protected_branches=("main" "release")
for branch in "${protected_branches[@]}"; do
if git show-ref --verify --quiet "refs/heads/$branch"; then
# Additional validation could be added here
echo "✓ Protected branch present: $branch"
fi
done
# Validate tag format
echo ""
echo "Tag validation:"
git show-ref --tags | while read -r hash ref; do
tag=$(basename "$ref")
if [[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "✓ Valid tag format: $tag"
else
echo "⚠ Non-standard tag: $tag"
fi
done
# Check for force pushes (simplified)
echo ""
echo "Reference integrity:"
if git show-ref | wc -l | grep -q "^0$"; then
echo "✗ No references found"
exit 1
else
echo "✓ References present"
fi
# Validate HEAD
if git show-ref --head >/dev/null 2>&1; then
echo "✓ HEAD reference valid"
else
echo "✗ HEAD reference invalid"
exit 1
fi
echo "Reference validation complete"
}
ci_ref_validation
Terminal window
# Repository maintenance with show-ref
repo_maintenance() {
echo "=== Repository Maintenance ==="
# Clean stale remote references
echo "Cleaning stale remote references..."
git remote prune origin
# Find and report broken references
echo ""
echo "Checking for broken references..."
broken_found=0
git show-ref | while read -r hash ref; do
if ! git cat-file -e "$hash" 2>/dev/null; then
echo "Broken reference: $ref"
((broken_found++))
fi
done
if [ "$broken_found" -eq 0 ]; then
echo "✓ No broken references found"
else
echo "⚠ Found $broken_found broken references"
fi
# Archive old branches
echo ""
echo "Archiving old branches..."
archive_dir="branch-archive-$(date +%Y%m%d)"
mkdir -p "$archive_dir"
git show-ref --heads | while read -r hash ref; do
branch=$(basename "$ref")
# Archive branches not updated in 6 months
if ! git log -1 --since="6 months ago" "$ref" >/dev/null 2>&1; then
echo "Archiving branch: $branch"
git log --oneline "$ref" > "$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 "Archived branches: ${archive_dir}.tar.gz"
fi
# Reference statistics
echo ""
echo "Reference statistics:"
echo " Branches: $(git show-ref --heads | wc -l)"
echo " Tags: $(git show-ref --tags | wc -l)"
echo " Remotes: $(git show-ref --remotes | wc -l)"
echo " Total: $(git show-ref | wc -l)"
echo "Maintenance complete"
}
repo_maintenance
Terminal window
# Backup and recovery with show-ref
backup_refs() {
echo "=== Reference Backup ==="
backup_file="refs-backup-$(date +%Y%m%d-%H%M%S).txt"
# Create comprehensive backup
{
echo "# Git References Backup - $(date)"
echo "# Repository: $(git remote get-url origin 2>/dev/null || pwd)"
echo ""
echo "## HEAD"
git show-ref --head
echo ""
echo "## Branches"
git show-ref --heads
echo ""
echo "## Tags"
git show-ref --tags
echo ""
echo "## Remotes"
git show-ref --remotes
echo ""
echo "## All References"
git show-ref
} > "$backup_file"
echo "Reference backup created: $backup_file"
# Verify backup integrity
backup_lines=$(wc -l < "$backup_file")
actual_refs=$(git show-ref | wc -l)
if [ "$backup_lines" -gt "$actual_refs" ]; then
echo "✓ Backup created successfully ($backup_lines lines)"
else
echo "⚠ Backup may be incomplete"
fi
}
# Restore references from backup
restore_refs() {
local backup_file="$1"
if [ ! -f "$backup_file" ]; then
echo "Backup file not found: $backup_file"
return 1
fi
echo "Restoring references from: $backup_file"
# This is a simplified restoration - real restoration requires careful handling
echo "⚠ Reference restoration requires manual intervention"
echo "Please review the backup file and restore references manually"
# Show what would be restored
grep "^[0-9a-f]" "$backup_file" | head -10
}
backup_refs
Terminal window
# Security audit with show-ref
security_audit() {
echo "=== Security Reference Audit ==="
# Check for suspicious references
echo "Checking for suspicious references..."
suspicious_patterns=("password\|secret\|key\|token\|credential")
git show-ref | while read -r hash ref; do
ref_name=$(basename "$ref")
if [[ "$ref_name" =~ $suspicious_patterns ]]; then
echo "⚠ Suspicious reference name: $ref"
fi
done
# Check reference permissions
echo ""
echo "Checking reference permissions..."
find .git/refs -type f | while read -r ref_file; do
perms=$(stat -c "%a" "$ref_file" 2>/dev/null)
if [ "$perms" != "644" ] && [ "$perms" != "664" ]; then
echo "⚠ Unusual permissions on: $ref_file ($perms)"
fi
done
# Validate reference content
echo ""
echo "Validating reference content..."
invalid_refs=0
git show-ref | while read -r hash ref; do
if ! [[ "$hash" =~ ^[0-9a-f]{40}$ ]]; then
echo "⚠ Invalid hash format: $ref -> $hash"
((invalid_refs++))
fi
done
if [ "$invalid_refs" -eq 0 ]; then
echo "✓ All reference hashes are valid"
fi
# Check for unsigned tags
echo ""
echo "Checking tag signatures..."
git show-ref --tags | while read -r hash ref; do
tag=$(basename "$ref")
if git tag -v "$tag" >/dev/null 2>&1; then
echo "✓ Signed tag: $tag"
else
echo "⚠ Unsigned tag: $tag"
fi
done
echo "Security audit complete"
}
security_audit
Terminal window
# Performance monitoring with show-ref
performance_monitor() {
echo "=== Reference Performance Monitor ==="
# Measure show-ref performance
echo "Measuring show-ref performance..."
# Test different operations
operations=(
"git show-ref"
"git show-ref --heads"
"git show-ref --tags"
"git show-ref --remotes"
"git show-ref --verify refs/heads/main"
)
for op in "${operations[@]}"; do
start_time=$(date +%s.%3N)
$op >/dev/null 2>&1
end_time=$(date +%s.%3N)
elapsed=$(echo "$end_time - $start_time" | bc 2>/dev/null || echo "0")
echo "$(printf '%-35s' "$op"): ${elapsed}s"
done
# Reference count impact
echo ""
echo "Reference count analysis:"
total_refs=$(git show-ref | wc -l)
echo "Total references: $total_refs"
if [ "$total_refs" -gt 1000 ]; then
echo "⚠ High reference count may impact performance"
elif [ "$total_refs" -gt 100 ]; then
echo "✓ Moderate reference count"
else
echo "✓ Low reference count"
fi
# Packing status
echo ""
echo "Reference packing status:"
if [ -f .git/packed-refs ]; then
packed_lines=$(wc -l < .git/packed-refs)
echo "Packed references: $packed_lines"
else
echo "No packed references"
fi
loose_refs=$(find .git/refs -type f | wc -l)
echo "Loose references: $loose_refs"
echo "Performance monitoring complete"
}
performance_monitor

What’s the difference between git show-ref and git branch -a?

Section titled “What’s the difference between git show-ref and git branch -a?”

git show-ref shows raw reference information with hashes, while git branch -a shows formatted branch listing. show-ref is better for scripting and low-level operations.

How do I list all branches with their hashes?

Section titled “How do I list all branches with their hashes?”

Use git show-ref —heads to list all local branches with their commit hashes.

Can git show-ref verify if a reference exists?

Section titled “Can git show-ref verify if a reference exists?”

Yes, use git show-ref —verify to check if a reference exists, returning exit code 0 if it does.

How do I get just the hash of a specific reference?

Section titled “How do I get just the hash of a specific reference?”

Use git show-ref —hash or git show-ref —hash-only for just the hash.

What’s the difference between —heads, —tags, and —remotes?

Section titled “What’s the difference between —heads, —tags, and —remotes?”

—heads shows refs/heads/* (branches), —tags shows refs/tags/* (tags), —remotes shows refs/remotes/* (remote tracking branches).

Yes, you can use glob patterns like git show-ref refs/heads/feature/* to match multiple references.

How do I see abbreviated hashes with show-ref?

Section titled “How do I see abbreviated hashes with show-ref?”

Use git show-ref —abbrev or git show-ref —abbrev= to control abbreviation length.

Yes, use —dereference to show what annotated tags point to (shows both tag object and commit).

Use git show-ref —head to verify HEAD reference exists and points to something valid.

What’s the —exclude-existing option for?

Section titled “What’s the —exclude-existing option for?”

—exclude-existing filters out references that already exist, useful when creating new references.

Yes, use —delete to remove references, but this is dangerous and should be used carefully.

How do I count total references in a repository?

Section titled “How do I count total references in a repository?”

Use git show-ref | wc -l to count all references, or combine with specific options for filtered counts.

Can git show-ref work with packed references?

Section titled “Can git show-ref work with packed references?”

Yes, it automatically handles both loose and packed references transparently.

How do I find all references pointing to a specific commit?

Section titled “How do I find all references pointing to a specific commit?”

Use git show-ref | grep ”^” to find all references pointing to that commit.

What’s the performance impact of show-ref?

Section titled “What’s the performance impact of show-ref?”

Very fast as it only reads reference files, not repository content. Suitable for frequent use in scripts.

Can show-ref work with remote repositories?

Section titled “Can show-ref work with remote repositories?”

No, show-ref only works with local repository references. Use git ls-remote for remote repositories.

Combine show-ref with git cat-file -e to verify all references point to valid objects.

  1. Repository Inspection: Examining all references and their relationships
  2. Script Integration: Low-level reference access for automation scripts
  3. Reference Validation: Verifying reference existence and integrity
  4. Branch Management: Listing and analyzing branch references
  5. Tag Management: Working with tag references and validation
  6. Remote Management: Handling remote tracking branch references
  7. Repository Maintenance: Cleaning and organizing references
  8. Security Auditing: Validating reference integrity and permissions