gitslip
Find files that slipped past .gitignore but are still tracked by git. You
add *.log or .env to .gitignore, but the file that was committed before
the rule existed keeps getting tracked — git only ignores files it isn't
already following. gitslip finds those leftovers and hands you the exact fix.
pipx run gitslip
# 2 tracked files are ignored by your rules but still committed:
#
# config/secrets.env
# ↳ .gitignore:7 *.env
# logs/app.log
# ↳ .gitignore:2 *.log
#
# Fix — stop tracking them (keeps your local copy):
# git rm --cached -- config/secrets.env
# git rm --cached -- logs/app.log
Zero dependencies, pure standard library. Also available for Node:
npx gitslip — byte-for-byte identical behaviour.
Why
Adding a path to .gitignore does nothing to a file git already tracks.
That's by design — but it means secrets, build artifacts and logs routinely sit
in repos long after someone "gitignored" them. The usual git rm --cached
fix-up is only run once someone notices, and a raw grep over .gitignore
can't tell a still-tracked leftover from a file that's correctly excluded.
gitslip answers one question precisely: which tracked files do my own ignore
rules say should be excluded? It then prints the git rm --cached commands to
untrack them (your working copy stays put).
How it works
It defers all the matching to git, so negation rules (!keep.log), directory
rules (build/), nested .gitignore files, .git/info/exclude and your global
core.excludesFile are all handled correctly:
- Detect —
git ls-files -i -c --exclude-standardlists files that are both tracked and ignored. That's the authoritative slipped set. - Attribute — for each one,
gitslipnames the rule that catches it (.gitignore:7 *.env) by askinggit check-ignoreagainst an empty index (tracked files are otherwise reported as "not ignored").
No file matching logic of our own = no subtle disagreements with git.
Usage
gitslip # audit the whole repo (exit 1 if anything slipped)
gitslip src/ config/ # limit the audit to pathspecs
gitslip --json # machine-readable, for CI
gitslip --apply # run the git rm --cached for you (keeps files on disk)
--apply only un-tracks; it never deletes your files. Review the diff and
commit when you're happy:
gitslip --apply
git commit -m "stop tracking ignored files"
In CI
- run: pipx run gitslip # fails the job if a tracked file is gitignored
Exit codes: 0 clean · 1 slipped files found · 2 error (not a repo, git
missing).
Install
pip install gitslip # or `pipx run gitslip`
npm i -g gitslip # Node build, identical behaviour
Requires git on PATH and Python ≥ 3.8 (or Node ≥ 18).
License
MIT
Release files for gitslip 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gitslip-0.1.0.tar.gz | 10.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gitslip-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.9 kB
Release files / gitslip-0.1.0.tar.gz
| Download URL | gitslip-0.1.0.tar.gz |
|---|---|
| Size | 10.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c701a9651a71e1d81c1effb3e20fadfa4a3e2f73beaadf555e512c9d7c2fd7dc
|
|
BLAKE2b-256 checksum How to use checksums |
d294518768efa1a75346dc06298f21274e43cefc9d0ada2b9809c33e3e16716f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|
Release files / gitslip-0.1.0-py3-none-any.whl
| Download URL | gitslip-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cb6f0979cf622b4011579cec080948a4fd3737554a6e0de3f2f7a7b5d67c4bb9
|
|
BLAKE2b-256 checksum How to use checksums |
4b4f816a4d21ffe073a5bc7729b61a7183aedebc416e760828e26c77fc732e2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|