Skip to content

Git Plumbing Cheat Sheet for CI/CD

Quick reference for low-level Git object manipulation, synthetic commits, and fast metadata querying without working tree checkouts.


Object Inspection

# Get SHA-1/SHA-256 hash of string or file without staging
echo "content" | git hash-object -w --stdin
git hash-object -w path/to/file.json

# Check object type (blob, tree, commit, tag)
git cat-file -t <OBJECT_OR_REF>

# Check object byte size
git cat-file -s <OBJECT_OR_REF>

# Print raw object content directly to stdout
git cat-file -p <OBJECT_OR_REF>
git cat-file -p origin/main:helm/values.yaml

# Extract file from any branch/tag to local file
git cat-file -p origin/main:package.json > /tmp/package.json

Tree & Ref Operations

# List tree contents recursively
git ls-tree -r --name-only <COMMIT_OR_TREE>

# List only files in a specific directory at ref
git ls-tree <REF> src/components/

# Resolve human-readable ref or relative notation to full SHA
git rev-parse HEAD
git rev-parse origin/main^{tree}
git rev-parse refs/tags/v1.0.0^{commit}

# Check if commit A is ancestor of commit B (exit 0=true, 1=false)
git merge-base --is-ancestor <ANCESTOR_COMMIT> <DESCENDANT_COMMIT>

# High-speed file change detection between commits
git diff-tree -r --no-commit-id --name-only <BASE_SHA> <HEAD_SHA>

Synthetic Commits & Atomic Ref Updates

# Create isolated index file for concurrency
export GIT_INDEX_FILE=$(mktemp)

# Load existing tree into isolated index
git read-tree origin/main

# Inject new or updated file blob into isolated index
BLOB=$(echo '{"build": 42}' | git hash-object -w --stdin)
git update-index --add --cacheinfo 100644 "$BLOB" build-metadata.json

# Write index to new tree object
NEW_TREE=$(git write-tree)

# Create synthetic commit
PARENT=$(git rev-parse origin/main)
NEW_COMMIT=$(git commit-tree "$NEW_TREE" -p "$PARENT" -m "chore: automated ci build 42")

# Atomically update ref with optimistic concurrency lock
git update-ref refs/heads/main "$NEW_COMMIT" "$PARENT"

# Cleanup isolated index
rm -f "$GIT_INDEX_FILE"

Annotated Tags via Plumbing

# Create annotated tag object and point ref
TAG_SHA=$(git mktag <<EOF
object $(git rev-parse HEAD)
type commit
tag v1.0.0-ci
tagger CI Bot <ci@local> $(date +%s) +0000

Automated Release Tag
EOF
)
git update-ref refs/tags/v1.0.0-ci "$TAG_SHA"