revisions Git Command Guide
The git revisions documentation explains how to specify commits, trees, blobs, and ranges using Git’s extended SHA-1 syntax. This comprehensive guide covers all revision specification methods used throughout Git commands.
Revision Specification Syntax:
Section titled “Revision Specification Syntax:”SHA-1 and Object Names:
Section titled “SHA-1 and Object Names:”# Full SHA-1 hashdae86e1950b1277e545cee180551750029cfe735
# Abbreviated SHA-1 (first 4+ characters)dae86e
# Full refsrefs/heads/mainrefs/tags/v1.0refs/remotes/origin/main
# Symbolic refsHEADORIG_HEADMERGE_HEADCHERRY_PICK_HEADBranch and Tag Names:
Section titled “Branch and Tag Names:”# Local branchesmaindevelopfeature/user-auth
# Remote tracking branchesorigin/mainupstream/develop
# Tagsv1.0v2.1.3stable
# Tag with branchv1.0^{} # Annotated tag objectv1.0^{tree} # Tree of lightweight tagRelative References:
Section titled “Relative References:”# Parent referencesHEAD^ # First parent of HEADHEAD^2 # Second parent of HEADHEAD^^ # Grandparent (HEAD^1^1)
# Tilde notationHEAD~ # First parent (same as HEAD^)HEAD~2 # GrandparentHEAD~3 # Great-grandparent
# Complex relativesHEAD^2~3 # Third parent of second parent of HEADmain~5^2 # Second parent of 5th ancestor of mainReflog References:
Section titled “Reflog References:”# Current reflog positionsHEAD@{0} # Current HEADHEAD@{1} # Previous HEAD positionmain@{2} # Two steps ago for main branch
# Time-based reflogHEAD@{yesterday}HEAD@{1.day.ago}HEAD@{2.weeks.ago}HEAD@{3.months.ago}
# Date specificationsHEAD@{2023-01-01}HEAD@{2023-01-01 12:00:00}
# Relative timeHEAD@{5.minutes.ago}HEAD@{2.hours.ago}Revision Ranges:
Section titled “Revision Ranges:”# Two-dot range (symmetric difference)A..B # Commits in B but not in Amain..feature # Commits in feature since main
# Three-dot range (symmetric)A...B # Commits in A or B but not bothmain...feature # Commits unique to each branch
# Multiple pointsA B ^C # Commits reachable from A or B but not C--not A # Exclude commits reachable from ASpecial Symbols:
Section titled “Special Symbols:”# Special refsHEAD # Current branch tipORIG_HEAD # HEAD before merge/resetMERGE_HEAD # Merge commit being mergedCHERRY_PICK_HEAD # Commit being cherry-pickedREVERT_HEAD # Commit being reverted
# Empty tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty tree SHA-1Advanced Revision Specifications:
Section titled “Advanced Revision Specifications:”Tree and Blob References:
Section titled “Tree and Blob References:”# Tree objectsHEAD: # Root tree of HEADHEAD:src # src directory in HEADmain:docs/README.md # Specific file tree
# Blob objectsHEAD:README.md # README.md content in HEADv1.0:LICENSE # LICENSE content in v1.0main^{blob} # Blob pointed to by main
# Tree from commitabc123^{tree} # Tree object of commit abc123Complex Range Expressions:
Section titled “Complex Range Expressions:”# Complex exclusions--not main --not develop # Exclude main and develop branches
# Branch-specific rangesorigin/main..origin/feature # Remote branch range
# Tag-based rangesv1.0..v2.0 # Between tagsv1.0...v2.0 # Symmetric tag range
# Mixed referencesHEAD origin/main ^origin/develop # Complex inclusion/exclusionTime-Based Selections:
Section titled “Time-Based Selections:”# Since/until dates--since="2 weeks ago"--until="2023-01-01"--after="1 month ago"--before="yesterday"
# Author/date filters (with commands)--author="John Doe"--committer="jane@example.com"--grep="bug fix"Path-Based Filtering:
Section titled “Path-Based Filtering:”# File-specific history-- src/main.c # Commits affecting src/main.c--follow -- README.md # Follow renames
# Directory filtering-- src/ # Commits affecting src directory-- Documentation/ # Documentation changesRevision Resolution Process:
Section titled “Revision Resolution Process:”Name Resolution Algorithm:
Section titled “Name Resolution Algorithm:”Resolution Steps:1. Check for exact SHA-1 match2. Check local refs (heads, tags, remotes)3. Check reflog references4. Check abbreviated SHA-15. Check ancestry references (^ ~)6. Apply range operators (.. ...)7. Resolve special symbolsDisambiguation Rules:
Section titled “Disambiguation Rules:”When Multiple Matches Exist:├── Prefer local branches over remote├── Prefer tags over branches├── Use full SHA-1 for uniqueness├── Use ^0 for commit vs tag disambiguation└── Use ^{type} for object type specificationError Handling:
Section titled “Error Handling:”Common Resolution Errors:├── 'ambiguous argument' - Multiple possible matches├── 'unknown revision' - No matches found├── 'bad revision' - Invalid syntax├── 'needed a single revision' - Range where single rev expected
Resolution Strategies:├── Use longer SHA-1 abbreviations├── Specify full ref paths├── Use ^{type} disambiguators├── Check reflog with git reflogPractical Usage Examples:
Section titled “Practical Usage Examples:”Basic Commit References:
Section titled “Basic Commit References:”# Show specific commitgit show abc123
# Show commit relative to HEADgit show HEAD~3
# Show merge commit parentsgit show HEAD^1 # First parentgit show HEAD^2 # Second parentBranch and Tag Operations:
Section titled “Branch and Tag Operations:”# Compare branchesgit log main..feature
# Show commits since taggit log v1.0..HEAD
# Cherry-pick from another branchgit cherry-pick feature~2Reflog Navigation:
Section titled “Reflog Navigation:”# Recover from mistakegit reset --hard HEAD@{1} # Go back one step
# See what changed yesterdaygit diff HEAD@{yesterday}
# Find when bug was introducedgit bisect start HEAD@{1.week.ago} HEADComplex Range Queries:
Section titled “Complex Range Queries:”# Find commits in feature but not in main or developgit log --oneline feature ^main ^develop
# Show merge commitsgit log --merges main..feature
# Find commits by author in rangegit log --author="John" main..featureTree and Blob Access:
Section titled “Tree and Blob Access:”# Show file at specific revisiongit show v1.0:README.md
# Compare file versionsgit diff HEAD:src/main.c HEAD~1:src/main.c
# Extract old versiongit show HEAD~5:Makefile > old-makefileConfiguration and Best Practices:
Section titled “Configuration and Best Practices:”Git Configuration for Revisions:
Section titled “Git Configuration for Revisions:”# Configure abbreviation lengthgit config core.abbrev 7
# Configure refloggit config core.logAllRefUpdates truegit config gc.reflogExpire 90.days
# Configure date formatsgit config log.date relative
# Configure default refsgit config core.defaultRef HEADBest Practices for Revision Specification:
Section titled “Best Practices for Revision Specification:”# Use descriptive namesgit checkout feature/user-authentication # Goodgit checkout abc123 # Less clear
# Prefer relative refs for scriptsHEAD~1 # Better than hardcoded SHA-1main^ # Clear parent relationship
# Use ranges consistentlymain..feature # Commits in feature since mainfeature..main # Usually empty
# Validate before usinggit rev-parse --verify <ref> # Check existencegit rev-parse --disambiguate=<prefix> # Test disambiguationScript Integration:
Section titled “Script Integration:”# Safe revision handling in scriptsvalidate_revision() { local rev="$1"
if ! git rev-parse --verify "$rev" >/dev/null 2>&1; then echo "Invalid revision: $rev" exit 1 fi
# Get canonical form canonical=$(git rev-parse "$rev") echo "Using revision: $canonical"}
# Usagevalidate_revision "HEAD~2"Integration with Git Commands:
Section titled “Integration with Git Commands:”Log and Show Commands:
Section titled “Log and Show Commands:”# Log with complex rangesgit log --oneline main...feature --author="John" --since="1 week ago"
# Show with refloggit show HEAD@{2.days.ago}
# Bisect with rangesgit bisect start HEAD HEAD~20git bisect run test-script.shDiff and Merge Operations:
Section titled “Diff and Merge Operations:”# Diff with complex refsgit diff HEAD~5 HEAD -- src/
# Merge with specific basegit merge --no-ff -m "Merge feature" feature main
# Cherry-pick rangegit cherry-pick main..featureBranch Management:
Section titled “Branch Management:”# Create branch from complex refgit checkout -b new-branch HEAD~10
# Reset to reflog positiongit reset --hard main@{yesterday}
# Rebase onto specific commitgit rebase --onto v2.0 v1.5 feature-branchTroubleshooting Common Issues:
Section titled “Troubleshooting Common Issues:”Ambiguous Revisions:
Section titled “Ambiguous Revisions:”# Resolve ambiguous refsgit rev-parse --disambiguate=abc # See possible matches
# Use full SHA-1git show abc123def456 # Instead of short abc123
# Specify ref typegit show v1.0^{commit} # Force commit interpretationgit show v1.0^{tag} # Force tag interpretationInvalid Revision Syntax:
Section titled “Invalid Revision Syntax:”# Fix syntax errorsHEAD^^^ # Invalid - use HEAD~3HEAD^1^2 # Invalid - use HEAD~2^2 or HEAD^^2main..feature..bugfix # Invalid - use main feature ^bugfix
# Correct syntaxHEAD~3 # Third ancestorHEAD^2~2 # Second ancestor of second parentmain feature ^bugfix # Commits in main/feature but not bugfixReflog Issues:
Section titled “Reflog Issues:”# Fix reflog problemsgit reflog expire --expire=now --all # Clear refloggit reflog --all # Check current reflog
# Recover lost refsgit fsck --unreachable | grep commit # Find dangling commitsgit update-ref refs/heads/recovered <commit-sha>Time-Based Reference Issues:
Section titled “Time-Based Reference Issues:”# Fix time reference problemsgit reflog --since="1 week ago" # Check available entries
# Use specific datesHEAD@{2023-01-01 10:00:00} # Specific timestamp
# Check timezone settingsgit config log.datedate # Verify system timePath-Based Resolution Issues:
Section titled “Path-Based Resolution Issues:”# Debug path resolutiongit ls-tree HEAD # See tree structuregit ls-tree HEAD:src # Check subdirectory
# Fix path issuesgit show HEAD:src/main.c # Correct pathgit show HEAD:src/main.c # Wrong - no leading slash neededRange Specification Problems:
Section titled “Range Specification Problems:”# Debug range issuesgit rev-list main..feature | head -5 # Check range contentsgit rev-list --count main..feature # Count commits in range
# Verify branch relationshipsgit log --oneline --graph --decorate main feature # Visualizegit merge-base main feature # Find common ancestorReal-World Usage Examples:
Section titled “Real-World Usage Examples:”Release Management:
Section titled “Release Management:”# Release preparation with revision rangesprepare_release() { local version="$1" local base_tag="${2:-v$(($version-1))}"
echo "Preparing release $version from $base_tag"
# Check commits since last release commit_count=$(git rev-list --count "$base_tag..HEAD") echo "Commits since $base_tag: $commit_count"
# Check for breaking changes breaking_changes=$(git log --grep="BREAKING" --oneline "$base_tag..HEAD") if [ -n "$breaking_changes" ]; then echo "⚠ Breaking changes detected:" echo "$breaking_changes" fi
# Generate changelog echo "# Release $version" > CHANGELOG.md echo "" >> CHANGELOG.md git log --pretty=format:"* %s (%h)" "$base_tag..HEAD" >> CHANGELOG.md
# Create release tag git tag -a "v$version" -m "Release version $version"}
prepare_release "2.1.0" "v2.0.0"Code Review Workflow:
Section titled “Code Review Workflow:”# Code review with revision rangescode_review_session() { local branch="$1" local base="${2:-main}"
echo "Code review session for $branch vs $base"
# Get commit range commits=$(git rev-list "$base..$branch")
echo "Commits to review: $(echo "$commits" | wc -l)"
# Show summary git log --oneline --stat "$base..$branch" | head -30
# Check for large commits for commit in $commits; do changes=$(git show --stat "$commit" | tail -1 | awk '{print $4+$6}') if [ "$changes" -gt 500 ]; then echo "⚠ Large commit: $(git show -s --format='%h %s' "$commit")" fi done
# Interactive review echo "Starting interactive review..." git log --patch --reverse "$base..$branch" | less}
code_review_session "feature/new-api" "develop"Repository Analysis:
Section titled “Repository Analysis:”# Analyze repository structure with revisionsanalyze_repository() { echo "Repository Analysis Report" echo "========================="
# Branch analysis echo "Branch Information:" git branch -v | while read -r branch commit message; do branch=${branch#* } echo " $branch: $commit - $message" done
# Tag analysis echo -e "\nTag Information:" git tag | while read -r tag; do commit=$(git rev-parse "$tag") date=$(git show -s --format=%ci "$tag") echo " $tag: $commit ($date)" done
# Reflog summary echo -e "\nReflog Activity:" git reflog --all --pretty=format:"%gd %gs %s" | head -10
# Revision statistics total_commits=$(git rev-list --all --count) total_refs=$(git rev-parse --all | wc -l) echo -e "\nStatistics:" echo " Total commits: $total_commits" echo " Total refs: $total_refs"}
analyze_repositoryAutomated Testing with Revisions:
Section titled “Automated Testing with Revisions:”# Test different revisions automaticallyautomated_revision_testing() { local test_script="$1" local revisions="${2:-HEAD~5..HEAD}"
echo "Testing revisions: $revisions"
# Get commits to test commits=$(git rev-list "$revisions")
failed_tests=0 for commit in $commits; do echo "Testing commit: $(git log --oneline -1 "$commit")"
# Checkout commit if git checkout -q "$commit"; then # Run tests if ! $test_script; then echo "✗ Tests failed for $commit" failed_tests=$((failed_tests + 1)) else echo "✓ Tests passed for $commit" fi else echo "✗ Could not checkout $commit" failed_tests=$((failed_tests + 1)) fi done
# Return to original state git checkout -q -
if [ "$failed_tests" -gt 0 ]; then echo "✗ $failed_tests commits failed testing" return 1 else echo "✓ All tested commits passed" return 0 fi}
automated_revision_testing "npm test" "main..feature"Git Hook Integration:
Section titled “Git Hook Integration:”# Pre-commit hook with revision validationcat > .git/hooks/pre-commit << 'EOF'#!/bin/bash# Validate commits using revision specifications
# Check if commit is on main branchcurrent_branch=$(git rev-parse --abbrev-ref HEAD)if [ "$current_branch" = "main" ]; then echo "Direct commits to main branch not allowed" echo "Please create a feature branch" exit 1fi
# Check commit message formatcommit_msg=$(git show -s --format=%s HEAD)if [[ ! "$commit_msg" =~ ^(feat|fix|docs|style|refactor|test|chore): ]]; then echo "Commit message must follow conventional format:" echo " type(scope): description" echo "" echo "Valid types: feat, fix, docs, style, refactor, test, chore" exit 1fi
# Check file size limitsgit diff --cached --name-only | while read -r file; do size=$(git ls-files --stage "$file" | awk '{print $3}') if [ "$size" -gt 1048576 ]; then # 1MB echo "File too large: $file ($(numfmt --to=iec $size))" exit 1 fidone
echo "✓ Pre-commit validation passed"EOF
chmod +x .git/hooks/pre-commitBisect Automation:
Section titled “Bisect Automation:”# Automated bisect with revision rangesautomated_bisect() { local good_rev="$1" local bad_rev="${2:-HEAD}" local test_command="$3"
echo "Starting automated bisect" echo "Good revision: $good_rev" echo "Bad revision: $bad_rev"
# Start bisect git bisect start "$bad_rev" "$good_rev"
# Run bisect git bisect run bash -c "$test_command"
# Show result if git bisect log | grep -q "first bad commit"; then bad_commit=$(git bisect view --format=%H | head -1) echo "Found bad commit: $(git show -s --format='%h %s' "$bad_commit")" else echo "Bisect completed without finding bad commit" fi
# Clean up git bisect reset}
automated_bisect "v1.0" "HEAD" "make test"Repository Migration Validation:
Section titled “Repository Migration Validation:”# Validate repository migration with revision checkingvalidate_migration() { local source_repo="$1" local target_repo="$2"
echo "Validating repository migration"
# Compare commit counts source_commits=$(GIT_DIR="$source_repo" git rev-list --all --count) target_commits=$(GIT_DIR="$target_repo" git rev-list --all --count)
echo "Source commits: $source_commits" echo "Target commits: $target_commits"
if [ "$source_commits" != "$target_commits" ]; then echo "⚠ Commit count mismatch" return 1 fi
# Compare refs source_refs=$(GIT_DIR="$source_repo" git rev-parse --all | sort) target_refs=$(GIT_DIR="$target_repo" git rev-parse --all | sort)
if ! diff <(echo "$source_refs") <(echo "$target_refs") >/dev/null; then echo "⚠ Reference mismatch" diff <(echo "$source_refs") <(echo "$target_refs") return 1 fi
# Compare recent commits source_recent=$(GIT_DIR="$source_repo" git log --oneline -5) target_recent=$(GIT_DIR="$target_repo" git log --oneline -5)
if [ "$source_recent" != "$target_recent" ]; then echo "⚠ Recent commit mismatch" return 1 fi
echo "✓ Migration validation passed" return 0}
validate_migration "/path/to/source.git" "/path/to/target.git"What are the different ways to specify a commit?
Section titled “What are the different ways to specify a commit?”SHA-1 hash (full or abbreviated), branch names, tag names, HEAD, relative refs (^ ~), reflog (@{ }), and symbolic refs.
How do I specify a range of commits?
Section titled “How do I specify a range of commits?”Use A..B for commits in B but not A, or A…B for symmetric difference. Multiple refs with ^ for complex ranges.
What’s the difference between HEAD^ and HEAD~?
Section titled “What’s the difference between HEAD^ and HEAD~?”HEAD^ is the first parent, HEAD~ is equivalent but allows chaining (HEAD~2). For merge commits, HEAD^2 is the second parent.
How do I reference yesterday’s HEAD?
Section titled “How do I reference yesterday’s HEAD?”Use HEAD@{yesterday} or HEAD@{1.day.ago}. Requires reflog to be enabled.
Can I reference commits by date?
Section titled “Can I reference commits by date?”Use reflog syntax like HEAD@{2023-01-01} or relative dates. For commit dates, use —since/—until with commands.
How do I specify a file at a specific revision?
Section titled “How do I specify a file at a specific revision?”Use revision:path syntax like HEAD:README.md or v1.0:src/main.c.
What’s the difference between .. and …?
Section titled “What’s the difference between .. and …?”A..B shows commits reachable from B but not A. A…B shows commits reachable from A or B but not both (symmetric difference).
How do I find the common ancestor of two branches?
Section titled “How do I find the common ancestor of two branches?”Use git merge-base branch1 branch2 to find the common ancestor commit.
Can I use wildcards in revision specifications?
Section titled “Can I use wildcards in revision specifications?”Limited support through reflog and some commands. Generally use explicit refs or SHA-1s.
How do I specify all branches except one?
Section titled “How do I specify all branches except one?”Use —all ^excluded-branch or —branches ^excluded-branch.
What’s ORIG_HEAD and when is it set?
Section titled “What’s ORIG_HEAD and when is it set?”ORIG_HEAD stores the previous HEAD position before operations like merge, reset, or rebase that change HEAD.
Can I reference commits by author or message?
Section titled “Can I reference commits by author or message?”Use —author, —grep, etc. with commands like git log, but not directly in revision specs.
How do I disambiguate between refs with same name?
Section titled “How do I disambiguate between refs with same name?”Use full ref paths (refs/heads/main) or ^{type} syntax (main^{commit}).
What’s the safest way to specify revisions in scripts?
Section titled “What’s the safest way to specify revisions in scripts?”Use git rev-parse to validate and canonicalize revisions before use. Prefer symbolic refs over hardcoded SHA-1s.
Can revision specs include time-based filtering?
Section titled “Can revision specs include time-based filtering?”Time filtering is done by commands (—since, —until), not in the revision spec itself.
How do I reference the empty tree?
Section titled “How do I reference the empty tree?”Use the special SHA-1 4b825dc642cb6eb9a060e54bf8d69288fbee4904 for the empty tree.
What’s the difference between lightweight and annotated tags?
Section titled “What’s the difference between lightweight and annotated tags?”Annotated tags are objects with metadata; use tag^{} to get the commit, tag^{tree} for the tree.
Can I use revision specs in git config?
Section titled “Can I use revision specs in git config?”Limited support. Generally use explicit refs or SHA-1s in configuration.
Applications of the git revisions command
Section titled “Applications of the git revisions command”- Script Automation: Reliable revision parsing and validation in Git scripts
- Complex Range Queries: Advanced commit range specifications for analysis
- Reflog Navigation: Time-based reference access using reflog
- Cross-Reference Operations: Working with multiple branches and tags
- Repository Analysis: Comprehensive repository structure examination
- Automated Workflows: Revision-based automation in CI/CD and hooks