rev-parse Git Command Guide
The git rev-parse command picks out and massages parameters, primarily used to parse revision names and convert them to SHA-1 hashes. It can also provide information about the repository state and is essential for Git scripting and automation.
git rev-parse Syntax:
Section titled “git rev-parse Syntax:”git rev-parse [<options>] <arg>...Operation Modes:
Section titled “Operation Modes:”| Mode | Description |
|---|---|
--parseopt | Use option parsing mode |
--sq-quote | Use single-quote mode for shell |
--not | Negate revisions |
--verify | Verify revisions exist |
--quiet | Suppress error messages |
--short | Show short SHA-1 |
--abbrev-ref | Show abbreviated ref name |
Information Options:
Section titled “Information Options:”| Option | Description |
|---|---|
--git-dir | Show .git directory path |
--is-inside-git-dir | Check if inside .git directory |
--is-inside-work-tree | Check if inside work tree |
--is-bare-repository | Check if repository is bare |
--local-env-vars | Show local environment variables |
--show-cdup | Show path to repository root |
--show-prefix | Show path from repository root |
--show-toplevel | Show top-level directory |
Revision Parsing Options:
Section titled “Revision Parsing Options:”| Option | Description |
|---|---|
--revs-only | Show only revision arguments |
--no-revs | Show only non-revision arguments |
--flags | Show parsed flags |
--no-flags | Show non-flag arguments |
--default <ref> | Default revision if none given |
--prefix <dir> | Prepend prefix to arguments |
--resolve-git-dir <path> | Resolve .git directory path |
Output Formatting Options:
Section titled “Output Formatting Options:”| Option | Description |
|---|---|
--symbolic | Show symbolic refs |
--symbolic-full-name | Show full symbolic names |
--disambiguate=<prefix> | Disambiguate truncated SHA-1 |
--all | Show all refs |
--branches | Show branch refs |
--tags | Show tag refs |
--remotes | Show remote refs |
Parameters:
Section titled “Parameters:”| Parameter | Description |
|---|---|
<arg> | Revisions, refs, or paths to parse |
<prefix> | Path prefix for resolution |
<ref> | Default reference |
Understanding Revision Parsing:
Section titled “Understanding Revision Parsing:”Revision Specifiers:
Section titled “Revision Specifiers:”Common Revision Formats:├── SHA-1: Full or abbreviated commit hash├── Branch: main, develop, feature/branch├── Tag: v1.0.0, stable├── Relative: HEAD~1, HEAD^2, HEAD@{1}├── Range: main..feature, main...develop└── Symbolic: HEAD, ORIG_HEAD, MERGE_HEAD
Resolution Process:1. Parse revision specifier2. Resolve to full SHA-1 hash3. Validate object exists4. Return canonical formRepository Information:
Section titled “Repository Information:”Repository State Queries:├── git rev-parse --git-dir # .git directory path├── git rev-parse --is-inside-work-tree # In work tree?├── git rev-parse --show-toplevel # Repository root├── git rev-parse --show-prefix # Current subdirectory├── git rev-parse --show-cdup # Path to root└── git rev-parse --is-bare-repository # Bare repository?Reference Resolution:
Section titled “Reference Resolution:”Reference Types:├── Branches: refs/heads/main├── Tags: refs/tags/v1.0├── Remotes: refs/remotes/origin/main├── Stash: refs/stash├── Special: HEAD, ORIG_HEAD, MERGE_HEAD└── Reflog: HEAD@{1}, main@{yesterday}Basic Rev-Parse Operations:
Section titled “Basic Rev-Parse Operations:”SHA-1 Resolution:
Section titled “SHA-1 Resolution:”# Get full SHA-1 for HEADgit rev-parse HEAD
# Get abbreviated SHA-1git rev-parse --short HEAD
# Resolve branch to SHA-1git rev-parse main
# Resolve tag to SHA-1git rev-parse v1.0.0
# Resolve relative refsgit rev-parse HEAD~1 HEAD^2Repository Information:
Section titled “Repository Information:”# Get repository rootgit rev-parse --show-toplevel
# Get .git directory pathgit rev-parse --git-dir
# Check repository typegit rev-parse --is-bare-repository
# Get current subdirectorygit rev-parse --show-prefix
# Check if in work treegit rev-parse --is-inside-work-treeReference Listing:
Section titled “Reference Listing:”# List all branchesgit rev-parse --branches
# List all tagsgit rev-parse --tags
# List all remotesgit rev-parse --remotes
# List all referencesgit rev-parse --all
# Show symbolic refsgit rev-parse --symbolic --branchesAdvanced Parsing Scenarios:
Section titled “Advanced Parsing Scenarios:”Revision Validation:
Section titled “Revision Validation:”# Verify revision existsgit rev-parse --verify HEAD
# Verify and quiet errorsgit rev-parse --verify --quiet abc123
# Disambiguate short SHA-1git rev-parse --disambiguate=abc
# Default revision if none givengit rev-parse --default HEADPath Resolution:
Section titled “Path Resolution:”# Resolve paths relative to repository rootgit rev-parse --prefix="$(git rev-parse --show-prefix)" -- src/file.txt
# Show path from repository rootgit rev-parse --show-prefix
# Combine with other commandsrepo_root=$(git rev-parse --show-toplevel)echo "Repository root: $repo_root"Script Integration:
Section titled “Script Integration:”# Parse command line argumentsgit rev-parse --parseopt -- "--all" "--" "$@"
# Extract revisions onlygit rev-parse --revs-only HEAD --stat
# Extract non-revisionsgit rev-parse --no-revs HEAD --stat
# Parse flagsgit rev-parse --flags --all --oneline HEADEnvironment Information:
Section titled “Environment Information:”# Show Git environment variablesgit rev-parse --local-env-vars
# Get Git directory resolutiongit rev-parse --resolve-git-dir .git
# Check Git directory statusgit rev-parse --is-inside-git-dirConfiguration and Best Practices:
Section titled “Configuration and Best Practices:”Git Configuration for Rev-Parse:
Section titled “Git Configuration for Rev-Parse:”# Configure abbreviation lengthgit config core.abbrev 7 # 7-character abbreviations
# Configure reflog referencesgit config core.logAllRefUpdates true # Enable reflog
# Configure symbolic ref displaygit config log.abbrevCommit true # Abbreviate commits
# Configure default behaviorgit config core.disambiguate tip # Disambiguation preferenceSafe Rev-Parse Usage:
Section titled “Safe Rev-Parse Usage:”# Always verify before usingif git rev-parse --verify "$ref" >/dev/null 2>&1; then sha=$(git rev-parse "$ref") echo "Valid ref: $sha"else echo "Invalid ref: $ref" exit 1fi
# Handle errors gracefullysha=$(git rev-parse --verify --quiet "$ref" || echo "")if [ -z "$sha" ]; then echo "Could not resolve: $ref" exit 1fiPerformance Optimization:
Section titled “Performance Optimization:”# Cache repository informationrepo_root=$(git rev-parse --show-toplevel)git_dir=$(git rev-parse --git-dir)
# Use short hashes when possibleshort_sha=$(git rev-parse --short HEAD)
# Batch operationsrefs=$(git rev-parse --all | tr '\n' ' ')for ref in $refs; do sha=$(git rev-parse "$ref") echo "$ref -> $sha"doneIntegration with Development Workflows:
Section titled “Integration with Development Workflows:”Build System Integration:
Section titled “Build System Integration:”#!/bin/bash# Build system integration with rev-parse
get_build_info() { # Get current commit commit_sha=$(git rev-parse HEAD) short_sha=$(git rev-parse --short HEAD)
# Get branch name branch=$(git rev-parse --abbrev-ref HEAD)
# Get repository info repo_root=$(git rev-parse --show-toplevel) is_dirty=$(git diff --quiet || echo "dirty")
# Get build timestamp build_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# Export for build system export GIT_COMMIT="$commit_sha" export GIT_SHORT_COMMIT="$short_sha" export GIT_BRANCH="$branch" export GIT_REPO_ROOT="$repo_root" export GIT_DIRTY="$is_dirty" export BUILD_TIME="$build_time"
echo "Build Info:" echo " Commit: $short_sha" echo " Branch: $branch" echo " Dirty: $is_dirty" echo " Time: $build_time"}
get_build_infoCI/CD Pipeline Integration:
Section titled “CI/CD Pipeline Integration:”# CI/CD pipeline commit informationci_commit_info() { echo "CI/CD Commit Information"
# Basic commit info commit_sha=$(git rev-parse HEAD) short_sha=$(git rev-parse --short HEAD) branch=$(git rev-parse --abbrev-ref HEAD)
# Repository info repo_url=$(git config --get remote.origin.url) repo_name=$(basename "$repo_url" .git)
# Author info author_name=$(git show -s --format='%an' HEAD) author_email=$(git show -s --format='%ae' HEAD)
# Commit details commit_message=$(git show -s --format='%s' HEAD) commit_date=$(git show -s --format='%ci' HEAD)
# Export for CI export CI_COMMIT_SHA="$commit_sha" export CI_COMMIT_SHORT_SHA="$short_sha" export CI_COMMIT_BRANCH="$branch" export CI_REPO_NAME="$repo_name" export CI_COMMIT_AUTHOR="$author_name" export CI_COMMIT_MESSAGE="$commit_message" export CI_COMMIT_DATE="$commit_date"
# Output for logging cat <<EOFCommit: $short_shaBranch: $branchAuthor: $author_name <$author_email>Message: $commit_messageDate: $commit_dateRepository: $repo_nameEOF}
ci_commit_infoVersion Information Extraction:
Section titled “Version Information Extraction:”# Extract version information from Gitget_version_info() { # Get latest tag latest_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
# Get commit count since tag commits_since_tag=$(git rev-parse --short HEAD)
# Get branch info branch=$(git rev-parse --abbrev-ref HEAD) is_main_branch=$(git rev-parse --verify main >/dev/null 2>&1 && echo "true" || echo "false")
# Get build info build_sha=$(git rev-parse --short HEAD) build_time=$(date -u +"%Y%m%d%H%M%S")
# Construct version if [ "$is_main_branch" = "true" ] && [ "$branch" = "main" ]; then version="$latest_tag" else version="$latest_tag-$branch-$build_sha" fi
# Export version info export VERSION="$version" export BUILD_SHA="$build_sha" export BUILD_TIME="$build_time" export BRANCH="$branch"
echo "Version: $version" echo "Build SHA: $build_sha" echo "Branch: $branch" echo "Build Time: $build_time"}
get_version_infoTroubleshooting Common Issues:
Section titled “Troubleshooting Common Issues:”Revision Resolution Failures:
Section titled “Revision Resolution Failures:”# Debug revision resolutiondebug_revision() { local rev="$1"
echo "Debugging revision: $rev"
# Try to resolve if git rev-parse "$rev" >/dev/null 2>&1; then sha=$(git rev-parse "$rev") echo "Resolved to: $sha"
# Check object type type=$(git cat-file -t "$sha") echo "Object type: $type"
# Show object info case "$type" in "commit") git show --no-patch --format="Author: %an <%ae>%nDate: %ad%nSubject: %s" "$sha" ;; "tree") echo "Tree object" ;; "blob") echo "Blob object" ;; esac else echo "Could not resolve: $rev"
# Check if it's a valid ref if git show-ref "$rev" >/dev/null 2>&1; then echo "Valid ref, but resolution failed" else echo "Not a valid ref" fi fi}
debug_revision "HEAD~1"Repository Detection Issues:
Section titled “Repository Detection Issues:”# Debug repository detectiondebug_repo_detection() { echo "Repository Detection Debug"
# Check if in Git repository if git rev-parse --git-dir >/dev/null 2>&1; then git_dir=$(git rev-parse --git-dir) echo "Git directory: $git_dir" else echo "Not in a Git repository" return 1 fi
# Check repository type if git rev-parse --is-bare-repository >/dev/null 2>&1; then echo "Bare repository" else echo "Working tree repository" fi
# Check work tree status if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then work_tree=$(git rev-parse --show-toplevel) echo "Work tree: $work_tree"
current_dir=$(pwd) prefix=$(git rev-parse --show-prefix) echo "Current directory: $current_dir" echo "Prefix from root: $prefix" else echo "Not in work tree" fi}
debug_repo_detectionPath Resolution Issues:
Section titled “Path Resolution Issues:”# Debug path resolutiondebug_path_resolution() { local path="$1"
echo "Debugging path resolution: $path"
# Check if path exists if [ -e "$path" ]; then echo "Path exists on filesystem" else echo "Path does not exist on filesystem" fi
# Check repository root repo_root=$(git rev-parse --show-toplevel 2>/dev/null) if [ -n "$repo_root" ]; then echo "Repository root: $repo_root"
# Get absolute path abs_path=$(cd "$repo_root" && realpath "$path" 2>/dev/null || echo "N/A") echo "Absolute path: $abs_path"
# Get relative path from root rel_path=$(git rev-parse --show-prefix)"$path" echo "Relative path: $rel_path" else echo "Not in a Git repository" fi}
debug_path_resolution "src/main.js"Environment Variable Issues:
Section titled “Environment Variable Issues:”# Debug environment issuesdebug_environment() { echo "Git Environment Debug"
# Show Git environment variables git rev-parse --local-env-vars
# Check Git configuration echo "Git config:" git config --list | grep -E "(user|core|remote)" | head -10
# Check current directory echo "Current directory: $(pwd)" echo "Home directory: $HOME"
# Check Git version git --version
# Check repository status if git status >/dev/null 2>&1; then echo "Repository status: OK" else echo "Repository status: ERROR" fi}
debug_environmentPerformance Issues:
Section titled “Performance Issues:”# Optimize rev-parse performanceoptimize_revparse_performance() { echo "Optimizing rev-parse performance"
# Cache frequently used values export GIT_REPO_ROOT=$(git rev-parse --show-toplevel) export GIT_COMMIT_SHA=$(git rev-parse HEAD) export GIT_SHORT_SHA=$(git rev-parse --short HEAD)
# Use short hashes when possible echo "Using short SHA: $GIT_SHORT_SHA"
# Batch operations all_refs=$(git rev-parse --all | tr '\n' ' ') echo "Found $(echo "$all_refs" | wc -w) refs"
# Avoid repeated calls for ref in $all_refs; do sha=$(git rev-parse "$ref" 2>/dev/null || echo "ERROR") echo "$ref -> $sha" done}
optimize_revparse_performanceReal-World Usage Examples:
Section titled “Real-World Usage Examples:”Git Hook Integration:
Section titled “Git Hook Integration:”#!/bin/bash# Pre-commit hook using rev-parse
# Get commit informationcommit_sha=$(git rev-parse HEAD)author_name=$(git show -s --format='%an' HEAD)author_email=$(git show -s --format='%ae' HEAD)
# Validate commitif [[ "$author_email" != *@company.com ]]; then echo "Error: Commits must use company email address" echo "Current email: $author_email" exit 1fi
# Check branchbranch=$(git rev-parse --abbrev-ref HEAD)if [[ "$branch" = "main" ]]; then echo "Error: Direct commits to main branch not allowed" exit 1fi
# Validate commit messagecommit_msg=$(git show -s --format='%s' HEAD)if [[ ${#commit_msg} -lt 10 ]]; then echo "Error: Commit message too short (minimum 10 characters)" exit 1fi
echo "✓ Pre-commit validation passed"echo "Commit: $commit_sha"echo "Author: $author_name <$author_email>"echo "Branch: $branch"Release Automation:
Section titled “Release Automation:”# Release automation with rev-parsecreate_release() { local version="$1" local branch="${2:-main}"
echo "Creating release $version from branch $branch"
# Validate branch exists if ! git rev-parse --verify "$branch" >/dev/null 2>&1; then echo "Error: Branch $branch does not exist" exit 1 fi
# Get commit information release_commit=$(git rev-parse "$branch") short_commit=$(git rev-parse --short "$branch")
# Check if tag already exists if git rev-parse --verify "refs/tags/v$version" >/dev/null 2>&1; then echo "Error: Tag v$version already exists" exit 1 fi
# Create annotated tag git tag -a "v$version" -m "Release version $version
Commit: $short_commitBranch: $branchDate: $(date -u +"%Y-%m-%dT%H:%M:%SZ")"
# Verify tag tag_sha=$(git rev-parse "v$version") if [ "$tag_sha" = "$release_commit" ]; then echo "✓ Release tag created: v$version" echo " Commit: $short_commit" echo " SHA: $tag_sha" else echo "Error: Tag creation failed" exit 1 fi
# Push tag git push origin "v$version" echo "✓ Tag pushed to remote"}
create_release "1.2.3" "release"Repository Analysis Tools:
Section titled “Repository Analysis Tools:”# Repository analysis using rev-parseanalyze_repository() { echo "Repository Analysis Report" echo "========================="
# Basic repository info repo_root=$(git rev-parse --show-toplevel) git_dir=$(git rev-parse --git-dir) is_bare=$(git rev-parse --is-bare-repository && echo "Yes" || echo "No")
echo "Repository Root: $repo_root" echo "Git Directory: $git_dir" echo "Bare Repository: $is_bare"
# Reference counts branch_count=$(git rev-parse --branches | wc -l) tag_count=$(git rev-parse --tags | wc -l) remote_count=$(git rev-parse --remotes | wc -l)
echo "Branches: $branch_count" echo "Tags: $tag_count" echo "Remotes: $remote_count"
# Current state current_branch=$(git rev-parse --abbrev-ref HEAD) current_commit=$(git rev-parse HEAD) short_commit=$(git rev-parse --short HEAD)
echo "Current Branch: $current_branch" echo "Current Commit: $short_commit ($current_commit)"
# Repository health if git rev-parse --verify HEAD >/dev/null 2>&1; then echo "HEAD Status: Valid" else echo "HEAD Status: Invalid" fi
# Check for uncommitted changes if git diff --quiet && git diff --staged --quiet; then echo "Working Tree: Clean" else echo "Working Tree: Modified" fi}
analyze_repositoryBranch Management Automation:
Section titled “Branch Management Automation:”# Automated branch managementmanage_branches() { echo "Branch Management Report"
# Get all branches all_branches=$(git rev-parse --branches)
# Analyze each branch for branch in $all_branches; do echo "Branch: $branch"
# Get branch commit branch_commit=$(git rev-parse "$branch") short_commit=$(git rev-parse --short "$branch")
# Check if merged if git merge-base --is-ancestor "$branch" main 2>/dev/null; then status="Merged" else status="Not merged" fi
# Get last commit date last_commit_date=$(git show -s --format='%ci' "$branch")
# Get author author=$(git show -s --format='%an' "$branch")
echo " Commit: $short_commit" echo " Status: $status" echo " Last Commit: $last_commit_date" echo " Author: $author" echo "" done
# Suggest cleanup echo "Branches that could be deleted:" for branch in $all_branches; do if [[ "$branch" != "main" ]] && git merge-base --is-ancestor "$branch" main 2>/dev/null; then echo " $branch (merged)" fi done}
manage_branchesCommit Message Validation:
Section titled “Commit Message Validation:”# Commit message validation using rev-parsevalidate_commit_message() { local commit="$1"
if [ -z "$commit" ]; then commit="HEAD" fi
# Get commit message subject=$(git show -s --format='%s' "$commit") body=$(git show -s --format='%b' "$commit")
echo "Validating commit: $(git rev-parse --short "$commit")" echo "Subject: $subject"
issues=0
# Check subject length if [ ${#subject} -gt 72 ]; then echo "⚠ Subject too long (${#subject} chars, max 72)" issues=$((issues + 1)) fi
# Check for period at end if [[ "$subject" =~ \.$ ]]; then echo "⚠ Subject ends with period" issues=$((issues + 1)) fi
# Check imperative mood if [[ ! "$subject" =~ ^(Add|Fix|Update|Remove|Refactor|Merge|Revert) ]]; then echo "⚠ Subject should start with imperative verb" issues=$((issues + 1)) fi
# Check body if [ -n "$body" ]; then # Check body line length while IFS= read -r line; do if [ ${#line} -gt 72 ]; then echo "⚠ Body line too long: ${line:0:50}..." issues=$((issues + 1)) break fi done <<< "$body" fi
if [ $issues -eq 0 ]; then echo "✓ Commit message validation passed" return 0 else echo "✗ Found $issues validation issues" return 1 fi}
validate_commit_message "HEAD"What’s the difference between rev-parse and rev-list?
Section titled “What’s the difference between rev-parse and rev-list?”rev-parse resolves individual revisions to SHA-1s and provides repository info; rev-list lists multiple commits in ranges and performs set operations.
How do I get the current commit SHA?
Section titled “How do I get the current commit SHA?”Use git rev-parse HEAD for full SHA-1, or git rev-parse —short HEAD for abbreviated version.
Can rev-parse resolve branch names?
Section titled “Can rev-parse resolve branch names?”Yes, git rev-parse main resolves the branch name to its current commit SHA-1.
How do I check if I’m in a Git repository?
Section titled “How do I check if I’m in a Git repository?”Use git rev-parse —git-dir to get the .git directory path, or check the exit code - success means you’re in a repository.
What’s the difference between —show-toplevel and —show-cdup?
Section titled “What’s the difference between —show-toplevel and —show-cdup?”—show-toplevel shows the absolute path to repository root; —show-cdup shows relative path from current directory to root (useful for scripts).
How do I get the current branch name?
Section titled “How do I get the current branch name?”Use git rev-parse —abbrev-ref HEAD for the branch name, or git symbolic-ref —short HEAD.
Can rev-parse work with relative refs?
Section titled “Can rev-parse work with relative refs?”Yes, git rev-parse HEAD~1 resolves to the parent commit, HEAD^2 to the second parent of a merge commit.
How do I list all branches with rev-parse?
Section titled “How do I list all branches with rev-parse?”Use git rev-parse —branches to list all local branches, —remotes for remote branches, —all for everything.
What’s —disambiguate for?
Section titled “What’s —disambiguate for?”—disambiguate=
Can rev-parse validate if a ref exists?
Section titled “Can rev-parse validate if a ref exists?”Yes, git rev-parse —verify returns success if the ref exists and can be resolved, failure otherwise.
How do I get repository information in scripts?
Section titled “How do I get repository information in scripts?”Use —show-toplevel for repo root, —git-dir for .git path, —is-inside-work-tree to check if in working directory.
What’s the —symbolic option for?
Section titled “What’s the —symbolic option for?”—symbolic shows the symbolic names of refs instead of resolving to SHA-1s, useful for seeing what refs point to.
Can rev-parse handle reflog references?
Section titled “Can rev-parse handle reflog references?”Yes, git rev-parse HEAD@{1} resolves reflog entries to their corresponding commits.
How do I get the short hash for a commit?
Section titled “How do I get the short hash for a commit?”Use git rev-parse —short
What’s —local-env-vars for?
Section titled “What’s —local-env-vars for?”—local-env-vars shows Git-related environment variables that are set locally, useful for debugging Git configuration.
Can rev-parse be used outside a repository?
Section titled “Can rev-parse be used outside a repository?”Some options like —parseopt work outside repositories, but most require being in a Git repository.
Applications of the git rev-parse command
Section titled “Applications of the git rev-parse command”- Script Integration: Resolve revisions and get repository information for automation
- Build Systems: Extract commit information for version strings and build metadata
- CI/CD Pipelines: Get branch names, commit SHAs, and repository state for pipelines
- Hook Development: Validate commits and repository state in Git hooks
- Repository Analysis: Extract statistics and information about repository structure
- Reference Validation: Verify that branches, tags, and commits exist and are valid