⟳ Git Data Flow
Git has four distinct zones where your code lives. Every command moves data between exactly two of them — once you see the map, every command clicks into place.
Click any command to see the exact path your data travels.
Your code always lives in one of these four places. Git commands are instructions to snapshot and move data between them.
add them.git add. Nothing is permanent yet..git folder. A permanent database of every commit on this machine. Entirely local — nothing is shared until you push.push, and others see them only after they fetch or pull.Three commands, always in this order. Every commit you've ever pushed followed this exact path.
unsaved to Git yet
the queue
saved in .git
to the team
git add is how you pick. If you changed 5 files but only want 2 in this commit, just git add those 2. The other 3 stay in Working Dir until you decide.# Typical save-and-share flow
git status # see what changed
git add src/login.ts # stage one specific file
git add src/auth/ # or stage a whole folder
git commit -m "fix: login redirect after password reset"
git push origin feature/login-fix
Three commands bring code from the remote. They stop at different zones — that's the key difference between them.
| Command | Downloads to Local Repo? | Updates your files? | Safe mid-feature? |
|---|---|---|---|
git fetch | Yes — updates origin/main | No — Working Dir untouched | Always safe |
git pull | Yes | Yes — merges into current branch | Safe on clean branch |
git clone | Yes — creates it from scratch | Yes — creates Working Dir | First time only |
git fetch is always safe — it never touches your Working Dir or Staging Area. After a fetch, run git log origin/main --oneline -5 to see what arrived, then consciously choose to merge or rebase.# Safe: see what the team pushed before touching your branch
git fetch origin
git log origin/main --oneline -8 # inspect incoming commits
# Then apply when ready
git rebase origin/main # replay your commits on top (cleaner)
# or
git merge origin/main
# Shortcut on a clean main branch
git switch main && git pull
Undo commands move data in the opposite direction. Knowing which zone you're targeting tells you exactly how destructive a command is.
| Command | Moves from | Moves to | Danger level |
|---|---|---|---|
git restore --staged <file> | Staging Area | Working Dir (unstages, keeps edits) | Safe — edits preserved |
git restore <file> | Last commit (Local Repo) | Working Dir (overwrites file) | Destructive — edits gone |
git reset --soft HEAD~1 | Local Repo (last commit) | Staging Area (commits unpacked) | Safe — changes queued |
git reset HEAD~1 (mixed) | Local Repo (last commit) | Working Dir (commits unstaged) | Safe — changes kept |
git reset --hard HEAD~1 | Local Repo (last commit) | Discarded — both zones overwritten | Destructive — gone permanently |
push, don't rewrite history. git reset is fine before pushing. After pushing, use git revert instead — it adds a new commit that undoes the change, leaving history intact for teammates.# Unstage a file (keep your edits, just remove from next commit)
git restore --staged src/config.ts
# Discard working-dir edits entirely (file goes back to last commit)
git restore src/config.ts
# Undo last commit — keep changes in Staging (ready to re-commit)
git reset --soft HEAD~1
# Undo last commit — keep changes in Working Dir (not staged)
git reset HEAD~1
# Nuclear: undo last commit and wipe all changes
git reset --hard HEAD~1
# Safe alternative after pushing: create an undo commit
git revert HEAD
Stash is a side-pocket inside your Local Repo. It temporarily holds work-in-progress so you can switch branches without committing half-done changes.
# Save everything and get a clean Working Dir
git stash push -m "login form WIP"
# Switch branch, fix bug, come back
git switch main
# ... fix + commit + push ...
git switch feature/login-form
# Restore stashed work
git stash pop # apply top entry and remove it
git stash apply stash@{1} # apply specific entry (keeps it in stash)
git stash list # see all saved entries
Every command listed by which zones it touches and whether it's safe to run mid-feature.
| Command | From zone | To zone | Safe mid-feature? |
|---|---|---|---|
git add <file> | Working Dir | Staging Area | Always safe |
git commit | Staging Area | Local Repo | Always safe |
git push | Local Repo | Remote | Safe if branch is yours |
git fetch | Remote | Local Repo only | Always safe |
git pull | Remote | Local Repo + Working Dir | Safe on clean branch |
git clone | Remote | Creates all local zones | First time only |
git restore --staged | Staging Area | Working Dir (unstage) | Safe — edits kept |
git restore <file> | Local Repo | Working Dir (overwrite) | Destructive |
git reset --soft | Local Repo | Staging Area | Safe (before push) |
git reset (mixed) | Local Repo | Working Dir | Safe (before push) |
git reset --hard | Local Repo | Discards both zones | Destructive |
git revert | Local Repo | New commit added | Always safe |
git stash | Working Dir + Staging | Stash shelf | Always safe |
git stash pop | Stash shelf | Working Dir | Always safe |