AboutBlogMediaTags

What Is .ipynb_checkpoints? Deleting It, and the Git Commands That Actually Untrack It

Runcell Team,

What Is .ipynb_checkpoints?

The .ipynb_checkpoints folder is a hidden directory that Jupyter Notebook creates automatically next to your .ipynb files. It stores checkpoint snapshots that let you revert to a previous saved state. These folders are safe to delete and should be added to .gitignore to keep your repositories clean.

If the rule is already in .gitignore and Git still shows the files, that is expected behaviour rather than a bug, and the fix is not another ignore pattern. Skip to Already committed? .gitignore will not help, which walks a throwaway repository through what each untracking command does to your index.

TL;DR


What is .ipynb_checkpoints?

When you open and save a Jupyter Notebook, Jupyter keeps lightweight snapshots (checkpoints) of your work. These are stored in a hidden directory named .ipynb_checkpoints in the same folder as your notebook(s).

A typical structure looks like this:

project/ ├─ data/ ├─ analysis/ │ ├─ exploration.ipynb │ ├─ model.ipynb │ └─ .ipynb_checkpoints/ │ ├─ exploration-checkpoint.ipynb │ └─ model-checkpoint.ipynb └─ README.md

Each *-checkpoint.ipynb is a JSON notebook file, just like your main .ipynb, but captured at a previous point in time.

Are checkpoints the same as autosave?

Not exactly.

Front‑end behavior varies slightly:


Why do they keep reappearing?

Because they’re part of Jupyter’s safety net. Even if you delete the folder, Jupyter will recreate it the next time it saves a checkpoint for that directory. That’s by design.


Is it safe to delete them?

Yes. Deleting .ipynb_checkpoints does not remove your main notebook; it only removes the snapshots. You’ll lose the quick “revert” option for those notebooks until new checkpoints are created.

Good times to delete:


Keep them out of Git (and friends)

Checkpoints don’t belong in version control—Git already provides version history. Add these rules to your ignore files:

.gitignore

# Jupyter Notebook checkpoints .ipynb_checkpoints/ **/.ipynb_checkpoints/ *-checkpoint.ipynb

.dockerignore

.ipynb_checkpoints/ **/.ipynb_checkpoints/ *-checkpoint.ipynb

The double‑star ensures nested directories are covered. The file pattern is a belt‑and‑suspenders to catch any stray checkpoint files that may have been copied out of the folder.

If you use pre‑commit, you can also enforce cleanup:

# .pre-commit-config.yaml repos: - repo: local hooks: - id: clean-ipynb-checkpoints name: Remove Jupyter checkpoints language: system pass_filenames: false entry: bash -c 'find . -name "*-checkpoint.ipynb" -delete && find . -type d -name ".ipynb_checkpoints" -empty -delete'

Already committed? .gitignore will not help

This is the most common .ipynb_checkpoints problem, and the cause is a Git rule with nothing to do with Jupyter: .gitignore applies to untracked paths only. Once a file is in the index, Git keeps tracking it whatever the ignore rules say.

Everything below came from a script run against Git 2.50.1 (Apple Git-155). It builds a throwaway repository in a temp directory (three files, one of them a checkpoint committed by mistake), then tries each fix in turn. The blocks are pasted as they came out; the == headings are the script’s own.

Step 1 - the mistake

== 1. what is tracked before we do anything == analysis/.ipynb_checkpoints/model-checkpoint.ipynb analysis/model.ipynb train.py

Step 2 - adding the ignore rule changes nothing

== 2. add the ignore rule, then check again == .gitignore analysis/.ipynb_checkpoints/model-checkpoint.ipynb analysis/model.ipynb train.py

The checkpoint is still in git ls-files. It is not dormant either - edit it and Git notices at once:

== 3. prove it is still live: edit it and see Git notice == M analysis/.ipynb_checkpoints/model-checkpoint.ipynb

Step 3 - the targeted fix

Untrack the checkpoints and nothing else:

git rm -r --cached --ignore-unmatch '*.ipynb_checkpoints/*' git commit -m "Stop tracking Jupyter checkpoints"
== 5. the targeted command, from a clean index == .gitignore analysis/.ipynb_checkpoints/model-checkpoint.ipynb analysis/model.ipynb train.py -- run it -- -- files left in the index -- .gitignore analysis/model.ipynb train.py -- git status --short -- D analysis/.ipynb_checkpoints/model-checkpoint.ipynb

One staged deletion, nothing else touched. --cached means the index only, so the file stays on disk; the script’s last step confirms model-checkpoint.ipynb is still there after the commit. --ignore-unmatch stops the command failing on a repository that has no checkpoints, which matters if it lives in a script.

Step 4 - the broad recipe, and the state it passes through

The widely repeated version is git rm -r --cached . then git add .. It works, and it is the right tool when you have just added several ignore rules at once. It is still worth seeing the index between the two commands:

== 4. what 'git rm -r --cached .' does to the index == -- files left in the index -- (empty: the index now lists nothing. Every path has a STAGED DELETION, and its working-tree copy shows up as untracked -- see status below.) -- git status --short -- D .gitignore D analysis/.ipynb_checkpoints/model-checkpoint.ipynb D analysis/model.ipynb D train.py ?? .gitignore ?? analysis/ ?? train.py

Every tracked path is staged for deletion. Committing at that point - an interrupted terminal, a reflexive git commit -am, a script that does not stop on error - commits the removal of the whole repository. git add . restores it correctly:

== 4b. the same recipe finished properly: git add . after it == -- files left in the index -- .gitignore analysis/model.ipynb train.py -- git status --short -- D analysis/.ipynb_checkpoints/model-checkpoint.ipynb

Same end state as the targeted command. What differs is the blast radius on the way there, and that the resulting diff touches every path your ignore rules now cover rather than only the checkpoints.

Prefer the targeted command unless you specifically want to re-apply every ignore rule in the repository at once.

What neither command does

Untracking keeps the file out of future commits. It does not remove it from history: whatever a checkpoint captured is still in earlier commits and still reachable. If one recorded a token or customer data, untracking is not the remedy - rewriting history with git filter-repo and rotating the secret is.


Clean up checkpoints safely

Linux/macOS (bash)

Delete only checkpoint files:

find . -name "*-checkpoint.ipynb" -delete

Remove empty .ipynb_checkpoints folders afterward:

find . -type d -name ".ipynb_checkpoints" -empty -delete

Windows (PowerShell)

Get-ChildItem -Recurse -Filter *-checkpoint.ipynb | Remove-Item Get-ChildItem -Recurse -Directory -Filter .ipynb_checkpoints | Remove-Item -Recurse -Force

Tip: Prefer deleting files first, then removing now‑empty directories. This minimizes the chance of deleting unrelated content if paths were nested in unexpected ways.


Reverting to a checkpoint

If you haven’t deleted them yet:

If the option is disabled or empty, there are no checkpoints yet for that notebook.


Autosave and configuration tips

There isn’t a universally supported, single “disable checkpoints forever” switch. The safest pattern is to ignore and clean them rather than trying to disable the mechanism.


CI/CD & packaging


Security & privacy notes


FAQ

Q: My repo keeps showing new *-checkpoint.ipynb files even with .gitignore. Why? A: They were committed before the ignore rule existed, and .gitignore has no effect on files Git already tracks. See Already committed? .gitignore will not help for the two commands that fix it, and what each does to the rest of your index.

Q: Can I use checkpoints as ‘real’ versioning? A: They’re best for local, short‑term rollback, not for collaboration history. Use Git (optionally with tools like nbdime) for meaningful diffs and merges.

Q: Do other notebook tools create the same folder? A: Not all. Behavior depends on the front‑end. Jupyter’s classic UI and JupyterLab commonly do; others may rely on different backup systems.


That balance gives you fast local safety with clean, lightweight repositories.


Before you export or share a notebook

Clearing checkpoints is usually one step of a larger “make this notebook presentable” job. Two things worth doing in the same pass:

© Runcell.RSS