DVC: Versioning Data
The churn model was trained on June's data. It is now August, and a user complaint makes you want to rerun June's training exactly. The code is in Git — but the June snapshot of subscriptions.csv was overwritten weeks ago. DVC (Data Version Control) makes that snapshot one command away.
The rule
Git holds the pointer; storage holds the bytes.
DVC works next to Git. When you add a data file, DVC moves the real bytes into a cache, and writes a tiny pointer file that Git tracks:
dvc init # once per repository
dvc add data/subscriptions.csv # creates data/subscriptions.csv.dvc
git add data/subscriptions.csv.dvc data/.gitignore
git commit -m "Data: June snapshot"
dvc remote add -d storage s3://tunebox-ml/dvc
dvc push # upload the bytes to the remoteThe pointer file is a few lines of YAML:
outs:
- md5: 3f9a1c0e7b2d4a6f8e1c2b3a4d5e6f70
size: 4194304000
path: subscriptions.csvThe md5 is a content hash: a fingerprint computed from the file's bytes. Change one row and the hash changes. So the pointer names exactly one version of the data, and DVC's .gitignore entry keeps the real CSV out of Git.
A teammate who clones the repo runs dvc pull and receives the bytes that match the hash. Because the pointer lives in Git, going back in time works the same way as for code:
git checkout v2026-06 # old pointer file comes back
dvc checkout # swap the workspace data to match itIf that old version is not in the local cache yet, dvc pull fetches it from the remote instead.
The shortcut
Think of every DVC command as "Git moves the pointer, DVC moves the bytes."
Move the pointer
git checkout v2026-06restores June'ssubscriptions.csv.dvc, with June's hash.
The classic mistake is running only the Git half. After git checkout, the pointer says "June" but the CSV on disk is still August's until DVC moves the bytes.
Drills
Answer fast — trust the rule.
What does Git store after dvc add data/subscriptions.csv?
A teammate clones the repo and the CSV is missing. Which command fetches it?
One row in the CSV changes and you run dvc add again. What happens to the pointer's md5?
After git checkout v2026-06 you train immediately and get August's results. Why?
Remember
- Git holds the pointer; storage holds the bytes.
- Every move has two halves: Git moves the pointer, DVC moves the bytes.
- Trap: checking out old code and forgetting
dvc checkout, so old code meets new data.
