Skip to content

Git Commit Forensics Quick Reference

At-a-glance commands for git log querying, blame, and forensics.

Goal Command
Find when a string appeared git log -S "redis://" -p --oneline
Regex content search git log -G "password.*=" --oneline -p
Search all branches git log --all -S "TOKEN" --oneline
Show full diff per match git log -S "v1.2.3" --pickaxe-all -p
Restrict to a file git log -S "JWT_SECRET" -- config/app.ts

Clean mainline history

git log --oneline --first-parent main        # only merge-boundary commits
git log --oneline --first-parent --merges    # only merge commits
git shortlog --first-parent v1.0..HEAD       # release notes by author

File lifecycle tracking

git log --diff-filter=A --oneline -- README.md          # when added
git log --diff-filter=D --oneline -- config.yaml        # when deleted
git log --follow --diff-filter=R --oneline -- src/util   # renames
git log --diff-filter=M --name-only v1..v2              # modified files
git diff-tree --no-commit-id -r --name-status SHA1 SHA2  # fast CI diff

Function tracking

git log -L :functionName:src/file.ts -p        # track through refactors
git log -L 50,80:src/file.ts                   # track line range

Clean blame

git blame --ignore-revs-file=.git-blame-ignore-revs file.ts
git blame --ignore-rev abc1234 file.ts
git blame --porcelain file.ts | grep "^author " | sort -u

Release notes from structured commits

git log --oneline --first-parent --grep="^feat" v1.0..HEAD
git log --oneline --first-parent --grep="^fix"  v1.0..HEAD
git log --oneline --first-parent --grep="BREAKING" v1.0..HEAD

Build stamping

git describe --tags --always --dirty          # v2.4.0-12-gabc1234
git describe --tags --abbrev=0                # just the tag name

Branch and tag governance

git for-each-ref --sort=-committerdate refs/heads/ --format="%(committerdate:short) | %(ref)"
git for-each-ref --sort=-creatordate refs/tags/ --format="%(creatordate:short) | %(ref) | %(subject)"
git rev-list --count branch --not main       # commits ahead of main

Topology-aware history

git log --oneline --ancestry-path v1.0..HEAD       # direct DAG path only
git log --oneline --first-parent --ancestry-path    # clean mainline only

CI preflight checks

# Skip CI if only docs changed
git diff-tree --no-commit-id -r --name-only HEAD~1 HEAD \
  | grep -q -v "^docs/" || echo "skip CI"

# Detect if package.json changed in a PR
base=$(git merge-base origin/main HEAD)
git diff-tree --no-commit-id -r --name-only "$base" HEAD \
  | grep -q "package.json" && echo "deps changed"

See docs/devops-workflows/git-commit-forensics-querying.md for full guide and scripts/commit-forensics.sh for the automation script.