Research Report — April 2026

Git Best Practices
for Modern Development

A comprehensive guide covering branching strategies, commit conventions, security, performance, AI-assisted workflows, and everything in between.

15 Topics Covered
40+ Sources
4 Skill Levels
Beginner
Intermediate
Advanced
Expert

Click a level to toggle visibility. All levels shown by default.

01

Branching Strategies

Your branching strategy defines how your team collaborates. There is no universal best choice — the right strategy depends on team size, release cadence, and deployment model.

Which Strategy Should You Use? Intermediate

How often do you deploy to production?
Continuously
Team size?
< 10 devs
GitHub Flow
10+ devs
Strong CI + Feature Flags?
Yes
Trunk-Based
No
GitHub Flow
Scheduled Releases
GitFlow

Strategy Comparison Beginner

Strategy Branches Best For Complexity Used By
GitFlow main, develop, feature/*, release/*, hotfix/* Versioned software, scheduled releases High Enterprise, mobile apps
GitHub Flow main + short-lived feature branches Web apps, continuous deployment Low Startups, SaaS teams
Trunk-Based main only (branches < 1 day) Mature teams, strong CI/CD Medium Google, Meta, Netflix
Release Flow main + release branches Large-scale services Medium Microsoft

GitHub Flow in Action Beginner

1
Create Branch
2
Commit Changes
3
Open PR
4
Code Review
5
Merge to Main
6
Deploy

GitFlow Branch Model Intermediate

main ————————————————————————— (tagged releases) \ / / release \ —— / \ / \ / develop —————————————— \ / \ / feature hotfix (emergency fix)
Deep Dive: Trunk-Based Development Requirements Advanced

Trunk-Based Development (TBD) is the gold standard for high-performing teams, but it demands infrastructure maturity:

  • Feature flags: Every incomplete feature must be toggleable at runtime. Tools: LaunchDarkly, Unleash, Flipt, or homegrown.
  • Comprehensive CI: Every commit to main must pass the full test suite in under 10 minutes. Flaky tests are blockers, not nuisances.
  • Short-lived branches: If you use branches at all, they must merge within 24 hours. Long-lived branches defeat the purpose.
  • Code review speed: PRs must be reviewed within hours, not days. Consider pair programming as an alternative to async review.
  • Observability: You need instant rollback capability and real-time monitoring to catch regressions deployed to production.
Warning: TBD without feature flags is just "everyone commits to main and prays." The flags are not optional.
02

Commit Message Conventions

Good commit messages are a love letter to your future self. They make git log, git blame, and git bisect infinitely more useful.

The Seven Rules Beginner

1

Separate subject from body

Leave a blank line between the subject and body. This makes git log --oneline work beautifully.

2

Limit subject to 50 chars

Forces clarity. GitHub truncates at 72, so 50 keeps you safely visible everywhere.

3

Capitalize the subject

Start with an uppercase letter. "Fix bug" not "fix bug".

4

No trailing period

The subject line is a title, not a sentence. Drop the period.

5

Imperative mood

"Add feature" not "Added feature" or "Adds feature". Match Git's own style: "Merge branch..."

6

Wrap body at 72 chars

Git doesn't auto-wrap. You must do it. Keeps git log readable in any terminal.

7

Explain what and why

The body should explain what changed and why, not how. The diff shows how.

Conventional Commits Intermediate

Format
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
TypePurposeExample
featNew featurefeat(auth): add OAuth2 login flow
fixBug fixfix(api): handle null response from /users
docsDocumentation onlydocs: update API migration guide
styleFormatting, whitespacestyle: fix indentation in auth module
refactorCode restructuringrefactor(db): extract query builder
perfPerformance improvementperf: cache user lookups in memory
testAdding/fixing teststest(auth): add edge cases for token refresh
buildBuild system changesbuild: upgrade webpack to v6
ciCI configurationci: add Node 22 to test matrix
choreMaintenance taskschore: update dependencies
revertRevert a previous commitrevert: feat(auth): add OAuth2 login flow

Anatomy of a Great Commit Message Beginner

Example: well-structured commit message
fix(auth): prevent token refresh race condition
When multiple API calls expire simultaneously, each
would trigger its own token refresh. This caused 401
errors when the second refresh invalidated the first.
Add a mutex around the refresh flow so only one call
performs the refresh while others wait for the result.
Closes #1234
Pro tip: Enable Conventional Commits enforcement with commitlint + a commit-msg hook. This automates CHANGELOG generation and semantic versioning via tools like semantic-release or standard-version.
03

Merge vs Rebase

The merge vs rebase debate is the "tabs vs spaces" of Git. Both have valid use cases. The key is understanding when each shines.

git merge

  • Preserves complete history
  • Non-destructive operation
  • Creates clear merge points
  • Safe for shared branches
  • Easy to understand
  • Clutters history with merge commits
  • Harder to read git log
  • Can obscure feature boundaries
VS

git rebase

  • Clean, linear history
  • Easy to follow with git log
  • No unnecessary merge commits
  • Cleaner git bisect
  • Makes cherry-pick easier
  • Rewrites commit history
  • Dangerous on shared branches
  • Harder to resolve conflicts

The Golden Rule Beginner

Never rebase shared/public branches. If other people have based work on those commits, rebasing rewrites the SHAs and forces everyone to reconcile divergent histories. Rebase only your own local feature branches.

The Recommended Workflow Intermediate

bash
# 1. Work on your feature branch
git checkout -b feat/new-widget

# 2. Make commits...
git commit -m "feat(widget): add base component"
git commit -m "feat(widget): add click handler"

# 3. Before merging, rebase onto latest main
git fetch origin
git rebase origin/main

# 4. Resolve any conflicts, then force-push your branch
git push --force-with-lease

# 5. Create PR and merge (squash or merge commit)

Squash Merge Intermediate

Squash merge combines all commits from a feature branch into a single commit on main. Popular with GitHub Flow because it keeps main history ultra-clean.

bash
# Squash merge a feature branch
git merge --squash feat/new-widget
git commit # Write a single summary commit message

# On GitHub: use the "Squash and merge" button on PRs
Advanced tip: Use --force-with-lease instead of --force when pushing after a rebase. It refuses to overwrite the remote if someone else pushed to the same branch, preventing you from destroying their work.
04

Git Hooks

Hooks automate quality checks at key points in your workflow. They catch issues before they reach CI, saving time and keeping your repository clean.

Hook Lifecycle Beginner

pre-commit
prepare-commit-msg
commit-msg
post-commit
pre-push

Tool Comparison Intermediate

ToolLanguageSpeedParallelConfig FormatBest For
Husky Node.js Medium No Shell scripts in .husky/ JS/TS projects
lint-staged Node.js Fast Yes JSON/JS in package.json Running linters on staged files only
Lefthook Go Fast Yes YAML (lefthook.yml) Polyglot projects, speed-critical
pre-commit Python Medium Yes YAML (.pre-commit-config.yaml) Python projects, polyglot

Husky + lint-staged Setup Beginner

bash
# Install Husky and lint-staged
npm install --save-dev husky lint-staged

# Initialize Husky
npx husky init

# Create pre-commit hook
echo "npx lint-staged" > .husky/pre-commit
json — package.json
{
  "lint-staged": {
    "*.{js,ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{json,md,yml}": ["prettier --write"],
    "*.css": ["stylelint --fix", "prettier --write"]
  }
}

Lefthook Alternative Advanced

yaml — lefthook.yml
pre-commit:
  parallel: true
  commands:
    lint:
      glob: "*.{js,ts,tsx}"
      run: npx eslint --fix {staged_files}
    format:
      glob: "*.{js,ts,tsx,json,md}"
      run: npx prettier --write {staged_files}
    typecheck:
      run: npx tsc --noEmit

commit-msg:
  commands:
    validate:
      run: npx commitlint --edit {1}
Why Lefthook? Go binary — no Node dependency. Parallel execution by default. YAML config is cleaner than shell scripts. Growing fast among teams tired of Husky's npm dependency chain.
05

Code Review Best Practices

Code review is the highest-leverage activity in a development team. Done well, it catches bugs, shares knowledge, and improves design. Done poorly, it blocks progress and breeds resentment.

Google's Standard Beginner

The core principle: "Approve if the code improves overall code health, even if it's not perfect." Don't block on style preferences if a style guide exists. A PR doesn't have to be flawless — it has to be better than what was there before.

The Magic Number: 400 LOC Beginner

Small PRs (<400 LOC)

Higher review quality. Faster merge time. Fewer bugs escape. Easier to revert if something breaks. Reviewers actually read the code.

Large PRs (>400 LOC)

Reviewers skim or rubber-stamp. Merge conflicts increase. Harder to understand context. Higher cognitive load leads to missed issues.

Review Checklist Intermediate

CategoryCheckPriority
CorrectnessDoes the code do what it claims?Critical
DesignIs the architecture appropriate? Any over-engineering?Critical
TestsAre edge cases covered? Do tests actually assert behavior?Critical
SecurityAny injection vectors, leaked secrets, or auth bypasses?Critical
ComplexityCan a reader understand it quickly? Could it be simpler?High
NamingAre variables, functions, classes clearly named?High
CommentsDo comments explain why, not what?Medium
Edge CasesNull checks, empty arrays, boundary conditions?High
PerformanceAny N+1 queries, unnecessary re-renders, memory leaks?Medium
Expert: Making Code Review Scale Expert
  • CODEOWNERS file: Automatically assign reviewers based on file paths. Ensures domain experts review their area.
  • Stacked PRs: Break large features into a chain of small, dependent PRs. Each can be reviewed and merged independently. Tools: ghstack, graphite, spr.
  • AI-assisted review: Use AI tools (GitHub Copilot, Claude) for first-pass review — catching typos, style issues, simple bugs. Human reviewers focus on design and business logic.
  • Review SLAs: Set team expectations. E.g., "First review within 4 hours." Track metrics. Review latency kills velocity.
  • Praise: Call out good code, not just problems. "Nice abstraction here" builds culture.
06

Git Security

Security in Git goes beyond just keeping secrets out of commits. It encompasses identity verification, access control, and automated scanning.

Essential .gitignore Beginner

.gitignore
# Environment & secrets
.env
.env.*
!.env.example
*.pem
*.key
credentials.json
service-account.json

# Dependencies
node_modules/
vendor/
.venv/

# Build output
dist/
build/
.next/
out/

# IDE & OS
.DS_Store
.idea/
.vscode/settings.json
*.swp

Commit Signing with SSH Intermediate

Since Git 2.34, you can sign commits with SSH keys — no GPG setup required. This proves commits come from the key owner, not just someone who configured user.name.

bash
# Configure SSH signing
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true

# Verify a signed commit
git log --show-signature -1

Secret Scanning Advanced

bash — Gitleaks
# Install gitleaks
brew install gitleaks

# Scan current state
gitleaks detect --source .

# Scan full history
gitleaks detect --source . --log-opts="--all"

# Use as pre-commit hook
gitleaks protect --staged

Branch Protection Rules Intermediate

Required Reviews

Minimum 1-2 approving reviews before merge. Dismiss stale reviews on new pushes.

Status Checks

Require CI to pass. Block merge on test failure, lint errors, or type check violations.

Signed Commits

Require commit signing to verify author identity. Prevents impersonation.

Linear History

Require squash or rebase merges. No merge commits = cleaner history.

07

Git Worktrees

Worktrees let you check out multiple branches simultaneously in separate directories, all sharing the same .git database. Essential for parallel development, especially with AI coding assistants.

Basic Usage Intermediate

bash
# Create a new worktree for a feature branch
git worktree add ../my-project-feat feat/new-feature

# Create worktree with a new branch
git worktree add -b feat/auth ../my-project-auth

# List all worktrees
git worktree list

# Remove a worktree when done
git worktree remove ../my-project-feat

# Prune stale worktree metadata
git worktree prune

AI-Assisted Development with Worktrees Advanced

Claude Code integration: Worktrees shine when running multiple AI agents in parallel. Each agent gets its own worktree and branch, preventing conflicts. Use .worktreeinclude to copy .env and secrets into new worktrees automatically.
bash — Parallel AI development
# Set up parallel worktrees for multiple features
git worktree add -b feat/auth   ../project-auth
git worktree add -b feat/search ../project-search
git worktree add -b fix/perf    ../project-perf

# Launch separate Claude Code sessions in each
cd ../project-auth   && claude "implement OAuth2 flow" &
cd ../project-search && claude "add full-text search" &
cd ../project-perf   && claude "optimize database queries" &

# Each agent works in isolation, no merge conflicts

Shared .git

All worktrees share the same objects, refs, and config. No duplicate clones eating disk space.

Branch Isolation

Each worktree checks out a different branch. You can't have two worktrees on the same branch.

.worktreeinclude

List files (like .env) to copy into new worktrees. Keeps secrets available without committing them.

08

Interactive Rebase Mastery

Interactive rebase (git rebase -i) is the power tool for crafting clean, logical commit histories before merging.

Rebase Operations Intermediate

CommandShortEffect
pickpUse commit as-is
rewordrUse commit but edit the message
editeStop at commit for amending
squashsMeld into previous commit, combine messages
fixupfMeld into previous commit, discard this message
dropdRemove commit entirely

The Autosquash Workflow Advanced

Autosquash is the cleanest way to fix up commits during development. Create fixup commits as you go, then squash them all at once before merging.

bash
# Enable autosquash globally (recommended)
git config --global rebase.autosquash true

# Make your initial commits
git commit -m "feat: add user profile page"     # abc1234
git commit -m "feat: add avatar upload"          # def5678

# Later, realize you need to fix the profile page commit
git commit --fixup=abc1234  # Creates "fixup! feat: add user profile page"

# When ready to clean up, autosquash reorders and fixups
git rebase -i --autosquash main
# The fixup commit is auto-placed after its target
Remember: Only rebase commits that haven't been pushed to a shared branch. Once commits are public, rebasing rewrites history and causes problems for everyone else.
09

Monorepo Strategies

Managing multiple packages, apps, or services in a single repository requires specialized Git strategies to keep things manageable.

Approach Comparison Intermediate

ApproachProsConsVerdict
True Monorepo Atomic commits, shared tooling, easy refactoring Requires build orchestration (Nx, Turborepo) Recommended
Git Submodules Independent version control per module Complex workflow, nested repos, easy to break Avoid
Git Subtrees Simpler than submodules, no nested .git History gets messy, push/pull syntax complex Situational
Sparse Checkout Clone only what you need from huge repos Requires Git 2.25+, team coordination Recommended

Sparse Checkout for Large Monorepos Advanced

bash
# Clone with sparse checkout (only root files)
git clone --sparse https://github.com/org/monorepo.git
cd monorepo

# Add only the directories you need
git sparse-checkout add packages/auth
git sparse-checkout add packages/shared
git sparse-checkout add infra/terraform

# List current sparse-checkout patterns
git sparse-checkout list

# Combine with partial clone for maximum speed
git clone --sparse --filter=blob:none https://github.com/org/monorepo.git
Avoid submodules unless you have a strong reason. They add cognitive overhead to every git operation, confuse new team members, and create "submodule hell" — a state where the parent and child repos are out of sync and nobody knows which version is correct.
10

Git Performance Optimization

As repositories grow, Git operations slow down. These techniques keep things fast even for large codebases.

Clone Strategies Intermediate

StrategyCommandWhat It SkipsUse Case
Full Clone git clone <url> Nothing Primary development
Shallow Clone git clone --depth=1 All history except latest commit CI/CD pipelines
Partial Clone (blobless) git clone --filter=blob:none File contents until checkout Large repos, fast initial clone
Partial Clone (treeless) git clone --filter=tree:0 Trees and blobs until needed Fastest clone, limited local ops
Sparse + Partial git clone --sparse --filter=blob:none Files outside sparse-checkout set Monorepo focused development

Background Maintenance Advanced

bash
# Enable background maintenance (Git 2.31+)
git maintenance start
# Runs hourly: prefetch, commit-graph, loose-objects, incremental-repack

# Manual optimization
git gc --aggressive           # Deep garbage collection
git repack -a -d --depth=250   # Optimal pack file
git commit-graph write --reachable  # Speed up log/rev-list

# Check repo stats
git count-objects -vH          # Size and object counts
Expert: Sparse Index & Filesystem Monitor Expert

For repos with millions of files, even git status can take seconds. Two features help:

bash
# Sparse index: shrink the index to only tracked paths
git config core.sparseCheckoutCone true
git sparse-checkout init --cone
git config index.sparse true

# Filesystem monitor (macOS/Windows/Linux)
git config core.fsmonitor true
git config core.untrackedcache true
# Uses OS-level file system events instead of scanning

With both enabled, git status on a 3M-file repo drops from ~10s to <200ms.

11

Large File Handling

Git was designed for text files. Binary assets (images, videos, datasets, models) require specialized handling to keep your repository lean.

Solution Comparison Intermediate

ToolHow It WorksMax File SizeBest For
Git LFS Pointer files in repo, content on LFS server ~5 GB (GitHub limit) Binary assets, design files, media
git-annex Decentralized, multiple backends (S3, rsync) Unlimited Research datasets, scientific data
DVC Data version control, ML-focused Unlimited ML models, training datasets
External storage Don't track in Git at all Unlimited Large media, build artifacts

Git LFS Setup Beginner

bash
# Install and initialize LFS
brew install git-lfs
git lfs install

# Track file patterns
git lfs track "*.psd"
git lfs track "*.mp4"
git lfs track "*.zip"
git lfs track "models/**"

# Verify what's tracked
git lfs ls-files

# Don't forget to commit .gitattributes
git add .gitattributes
git commit -m "chore: configure LFS tracking"
12

Git Recovery & Debugging

Git almost never loses data. If you can find the SHA, you can recover the commit. The reflog is your safety net.

The Reflog: Your Safety Net Intermediate

bash
# View the reflog (all HEAD movements)
git reflog
# abc1234 HEAD@{0}: commit: feat: add search
# def5678 HEAD@{1}: rebase: squash
# 789abcd HEAD@{2}: checkout: moving from main to feat/search

# Recover a "lost" commit after bad rebase
git reset --hard HEAD@{2}

# Cherry-pick a specific lost commit
git cherry-pick abc1234

# Create a branch from a reflog entry
git branch recovery-branch HEAD@{5}

Git Bisect: Binary Search for Bugs Advanced

bash
# Start bisecting
git bisect start

# Mark current commit as bad (has the bug)
git bisect bad

# Mark a known good commit (before the bug)
git bisect good v2.1.0

# Git checks out the midpoint. Test it, then:
git bisect good   # if this commit is OK
git bisect bad    # if this commit has the bug

# Repeat until Git identifies the exact commit

# Automate with a test script
git bisect run npm test

# Clean up when done
git bisect reset

Emergency Recovery Cheat Sheet Intermediate

git reset --soft HEAD~1 Undo last commit, keep changes staged
git reset --mixed HEAD~1 Undo last commit, keep changes unstaged
git checkout -- <file> Discard unstaged changes to a file
git stash Temporarily shelve working directory changes
git reflog && git reset --hard <SHA> Recover from bad rebase/reset
git fsck --unreachable Find orphaned/dangling objects
13

CI/CD Integration

Git and CI/CD are inseparable in modern development. Branch protection, automated testing, and deployment pipelines all hinge on Git events.

CI Pipeline Stages Beginner

Commit
Lint & Format
Test
Build
Deploy

GitHub Actions Workflow Intermediate

yaml — .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm run lint
      - run: npm run typecheck
      - run: npm test

Reusable Workflows Advanced

yaml — Calling a reusable workflow
jobs:
  lint-and-test:
    uses: ./.github/workflows/shared-ci.yml
    with:
      node-version: '22'
    secrets: inherit

  deploy:
    needs: lint-and-test
    if: github.ref == 'refs/heads/main'
    uses: ./.github/workflows/deploy.yml
    with:
      environment: production
Performance tip: Cache aggressively. Use actions/cache for node_modules, .next/cache, Docker layers, and package manager lock files. A cache hit can cut CI time by 60-80%.
14

Git Aliases & Productivity

Git aliases eliminate repetitive typing and encode best practices into muscle memory. A well-configured .gitconfig is a productivity multiplier.

Essential Aliases Beginner

gitconfig — ~/.gitconfig
[alias]
  # Status & logging
  st     = status -sb
  lg     = log --oneline --graph --decorate --all
  last   = log -1 HEAD --stat

  # Branching
  co     = checkout
  br     = branch
  brd    = branch -d
  sw     = switch

  # Committing
  ci     = commit
  amend  = commit --amend --no-edit
  wip    = !git add -A && git commit -m 'WIP'

  # Undoing
  undo   = reset --soft HEAD~1
  unstage = reset HEAD --

  # Syncing
  sync   = !git fetch origin && git rebase origin/main
  pf     = push --force-with-lease

Power Aliases Advanced

gitconfig
[alias]
  # Show branches sorted by last commit date
  recent = branch --sort=-committerdate --format='%(committerdate:relative)\t%(refname:short)'

  # Delete all merged branches (except main/develop)
  cleanup = !git branch --merged | grep -v '\\*\\|main\\|develop' | xargs -n 1 git branch -d

  # Show which files changed between two branches
  changed = diff --name-only

  # Interactive fixup (select commit to fix with fzf)
  fixup  = !git log --oneline -20 | fzf | awk '{print $1}' | xargs git commit --fixup

  # Who changed this file the most?
  authors = !git log --format='%aN' -- \"$1\" | sort | uniq -c | sort -rn

  # Today's commits
  today  = log --since=midnight --oneline --no-merges

Useful Git Config Settings Intermediate

gitconfig — ~/.gitconfig
[init]
  defaultBranch = main

[pull]
  rebase = true           # Rebase instead of merge on pull

[push]
  autoSetupRemote = true  # Auto-create upstream on first push
  default = current       # Push current branch by default

[fetch]
  prune = true             # Auto-remove dead remote branches

[rebase]
  autosquash = true        # Auto-fixup on interactive rebase
  autostash = true         # Auto-stash before rebase

[merge]
  conflictstyle = zdiff3   # Show base in conflict markers

[diff]
  algorithm = histogram    # Better diff output
  colorMoved = default     # Highlight moved lines

[rerere]
  enabled = true           # Remember conflict resolutions
rerere stands for "reuse recorded resolution." Once you resolve a conflict, Git remembers and auto-applies the same resolution next time. Essential for teams that rebase frequently.

fzf Integration Expert

Interactive Branch Switching, Log Browsing, and Stash Management
shell — ~/.zshrc
# Interactive branch switcher
fbr() {
  local branch
  branch=$(git branch --all --sort=-committerdate | \
    fzf --height 40% --preview 'git log --oneline -10 {1}' | \
    sed 's/remotes\/origin\///' | xargs)
  git checkout "$branch"
}

# Interactive log browser with diff preview
flog() {
  git log --oneline --color=always | \
    fzf --ansi --preview 'git show --stat --color=always {1}'
}

# Interactive stash manager
fstash() {
  local stash
  stash=$(git stash list | fzf --preview 'git stash show -p {1}' | \
    cut -d: -f1)
  git stash apply "$stash"
}
15

AI-Assisted Git Workflows

AI coding assistants are reshaping how developers interact with Git. The key insight: AI generates, humans verify. Never auto-push AI-generated code without review.

The AI + Git Workflow Intermediate

1
AI Drafts Code
2
Human Reviews
3
AI Commits
4
Human Approves PR
5
CI Validates

Claude Code Patterns Advanced

Worktree Isolation

Each Claude agent gets its own worktree and branch. Parallel development without merge conflicts. Use --worktree flag.

Commit Generation

Claude writes conventional commit messages from diffs. Add Co-Authored-By trailers to track AI contributions.

PR Creation

Claude drafts PR descriptions from commit history. Human reviews and approves. Never auto-merge.

Code Review

AI handles first-pass review: style, typos, simple bugs. Humans focus on design, business logic, and architecture.

GitClear Findings (2025) Intermediate

Data point: GitClear's 2025 analysis shows AI-assisted code has 4x growth in "moved" and "copy/pasted" code patterns compared to pre-AI baselines. This means: AI duplicates more than it should. Always review AI code for unnecessary duplication, extract shared functions, and maintain DRY principles manually.
bash — AI commit attribution
# Always attribute AI contributions in commits
git commit -m "feat(search): add full-text search API

Implements Elasticsearch-backed search with fuzzy matching
and relevance scoring. Includes rate limiting and caching.

Co-Authored-By: Claude <noreply@anthropic.com>"
>_

Quick Reference Cheat Sheet

Daily Operations Beginner

git status -sb Short status with branch info
git add -p Stage changes interactively, hunk by hunk
git diff --cached Show what's staged for the next commit
git log --oneline --graph -20 Visual commit history, last 20 commits
git stash push -m "description" Stash changes with a descriptive name
git switch -c feat/my-feature Create and switch to a new branch

Branch Management Intermediate

git branch --sort=-committerdate List branches by most recent commit
git push -u origin HEAD Push current branch and set upstream
git fetch --prune Fetch and remove dead remote tracking branches
git branch --merged | xargs git branch -d Delete all locally merged branches
git cherry-pick <SHA> Apply a specific commit to current branch
git rebase --onto main feat/old feat/new Transplant a branch to a new base

Investigation Advanced

git log -S "functionName" --oneline Find commits that added/removed a string
git log --all --follow -- path/to/file Full history of a file, including renames
git blame -w -C -C -C <file> Blame ignoring whitespace and detecting moves
git diff main...HEAD --stat Files changed on this branch vs main
git shortlog -sn --no-merges Commit count by author (leaderboard)
git rev-list --count main..HEAD Number of commits ahead of main

The Complete .gitconfig Expert

Production-Ready .gitconfig (Copy and Use)
gitconfig — ~/.gitconfig
[user]
  name = Your Name
  email = you@example.com

[init]
  defaultBranch = main

[core]
  editor = code --wait
  autocrlf = input
  pager = delta

[interactive]
  diffFilter = delta --color-only

[delta]
  navigate = true
  side-by-side = true
  line-numbers = true

[pull]
  rebase = true

[push]
  autoSetupRemote = true
  default = current

[fetch]
  prune = true
  pruneTags = true

[rebase]
  autosquash = true
  autostash = true
  updateRefs = true

[merge]
  conflictstyle = zdiff3

[diff]
  algorithm = histogram
  colorMoved = default
  mnemonicPrefix = true

[rerere]
  enabled = true

[branch]
  sort = -committerdate

[tag]
  sort = -version:refname

[gpg]
  format = ssh

[commit]
  gpgsign = true

[alias]
  st      = status -sb
  lg      = log --oneline --graph --decorate --all
  last    = log -1 HEAD --stat
  co      = checkout
  sw      = switch
  br      = branch
  ci      = commit
  amend   = commit --amend --no-edit
  undo    = reset --soft HEAD~1
  unstage = reset HEAD --
  wip     = !git add -A && git commit -m 'WIP'
  sync    = !git fetch origin && git rebase origin/main
  pf      = push --force-with-lease
  recent  = branch --sort=-committerdate --format='%(committerdate:relative)\t%(refname:short)'
  cleanup = !git branch --merged | grep -v '\\*\\|main\\|develop' | xargs -n 1 git branch -d
  today   = log --since=midnight --oneline --no-merges
  fixup   = !git log --oneline -20 | fzf | awk '{print $1}' | xargs git commit --fixup