Git Internals β How Git Actually Stores Data
Understanding Git's data model is the key to never being afraid of any Git command. Git stores everything as objects in a content-addressable store. There are 4 object types:
| Object | Content |
|---|---|
| blob | File contents (no filename) |
| tree | Directory listing (filenames + blob SHAs) |
| commit | tree SHA + parent SHA + author + message |
| tag | commit SHA + tagger + message |
A branch is just a file containing a commit SHA. git checkout main makes HEAD point to the main branch file. Git is beautifully simple at its core.
cat .git/HEAD # ref: refs/heads/main
cat .git/refs/heads/main # 9a1bc3d4e5f6...
git cat-file -p 9a1bc3 # content of any object by SHA
1. Interactive Rebase β Sculpting Perfect Commit Histories
Interactive rebase (git rebase -i) lets you rewrite the commit history of your branch before merging. At companies like Google and Meta, clean commit histories are enforced β each commit should be a logical unit that passes tests.
git log --oneline main..feature/payment
# f3c2a1b WIP checkpoint
# 9d8e7c6 fix typo in variable name
# 4b5a3d2 add tests
# 7e6f5a4 Add Stripe webhook handler
# 2c3d4e5 Add Subscription model
# 1a2b3c4 Add billing app scaffold
git rebase -i main # Opens editor
# In editor
pick 1a2b3c4 Add billing app scaffold
pick 2c3d4e5 Add Subscription model
pick 7e6f5a4 Add Stripe webhook handler
squash 4b5a3d2 add tests # Merge into previous commit
squash 9d8e7c6 fix typo # Merge into previous commit
drop f3c2a1b WIP checkpoint # Discard this commit
Available Actions
| Action | Short | What It Does |
|---|---|---|
| pick | p | Keep commit as-is |
| reword | r | Keep commit, edit message |
| edit | e | Pause to amend commit |
| squash | s | Merge into previous, edit combined message |
| fixup | f | Merge into previous, discard this message |
| drop | d | Delete commit entirely |
Golden rule: Never rebase commits that have been pushed to a shared branch. Rebasing rewrites SHAs, so anyone who based work on your original commits will have diverged histories.
2. git bisect β Binary Search for Bugs
git bisect uses binary search to find the exact commit that introduced a bug. With 10,000 commits, bisect finds the culprit in at most 14 steps.
git bisect start
git bisect bad # Current commit has the bug
git bisect good v2.0.0 # This version was fine
# Git checks out midpoint β test your app, then:
git bisect bad # Bug present
git bisect good # Bug not present
# Repeat until Git prints: "abc1234 is the first bad commit"
git bisect reset # End bisect
Automated Bisect
git bisect start
git bisect bad HEAD
git bisect good v2.0.0
# Let git run tests automatically β exit 0 = good, non-zero = bad
git bisect run python -m pytest billing/tests/test_webhook.py -x -q
3. git cherry-pick β Surgical Code Transplants
Cherry-pick copies the diff from one commit and applies it to another branch. Use it to backport a bug fix to a release branch without merging the entire feature.
git checkout release/2.x
git cherry-pick abc1234 # Apply single commit
git cherry-pick abc1234..def5678 # Apply range (exclusive..inclusive)
git cherry-pick -n abc1234 # Stage changes without committing
git cherry-pick --edit abc1234 # Apply and edit commit message
# Conflict resolution
git cherry-pick abc1234
# CONFLICT! Edit the files to resolve...
git add billing/views.py
git cherry-pick --continue # Finish
# OR
git cherry-pick --abort # Cancel
4. git worktree β Parallel Feature Development
Normally, switching branches interrupts your current work. git worktree lets you check out multiple branches simultaneously in separate directories.
# Add a second worktree for a hotfix
git worktree add ../kashii-hotfix hotfix/payment-crash
cd ../kashii-hotfix
# Fix the bug, run tests, push β without touching your feature branch
git worktree list
# /Users/kashinath/Desktop/updatezbykashi (main)
# /Users/kashinath/Desktop/kashii-hotfix (hotfix/payment-crash)
git worktree remove ../kashii-hotfix
5. When to Use Each Tool
| Scenario | Tool |
|---|---|
| Clean up messy commits before PR | Interactive rebase |
| Combine 5 WIP commits into 1 | git rebase -i + squash |
| "Something broke 3 weeks ago, which commit?" | git bisect |
| Backport fix to release branch | git cherry-pick |
| Work on hotfix while mid-feature | git worktree |
| Undo last commit (keep changes staged) | git reset --soft HEAD~1 |
| Undo pushed commit safely | git revert HEAD |