GitShield
Permanently protect specific local files from ever being committed to git — regardless of which tool commits (terminal, VS Code SCM, GitHub Desktop, etc.).
Features
- Visual file panel — see all workspace files in one place with checkboxes
- Bulletproof protection — a three-tier pre-commit hook intercepts every commit from any tool
- Remote cleanup — protecting an already-pushed file commits and pushes its removal, so it actually disappears from GitHub
- Branch-aware — protection is re-applied automatically when you switch branches (and on startup), so files stay untracked on every branch you work on
- New file alerts — get notified when new files are created, with a one-click protect option
- Non-destructive — files stay on disk; only removed from git's tracking index
- Theme-aware UI — panel matches your VS Code color theme automatically
- Compatible with existing hooks — appends to husky/lint-staged without overwriting
How It Works
Checkbox Meaning
Checked = allow commits · Unchecked = protect (never commit)
- Click the
🛡️ GitShield button in the status bar
- Uncheck any file you want to permanently protect
- Changes save automatically — there is no Save button
Three-Tier Protection
| Tier |
Mechanism |
Action |
| 1 |
Hardcoded system blocklist (.env, *.pem, id_rsa, .ssh/, .aws/, secrets.json) |
Blocks commit, exits 1 |
| 2 |
.gitignore awareness |
Warns, does not block |
| 3 |
User-selected protected files (from protected.json) |
Unstages the file with a notice; if that empties the commit, fails with a clear message |
All tiers ignore staged deletions — removing a secret from git history forward must always be possible, otherwise a leaked file could never be taken off the remote.
System-protected files (.env, *.pem, etc.) are locked — they appear in the panel with a 🔒 icon and cannot be re-enabled through the UI. This protection survives manual edits to .gitshield/protected.json.
Removing an Already-Pushed File
When you protect a file that was previously committed and pushed, GitShield:
- Untracks it locally (
git rm --cached — the file stays on disk)
- Creates a removal commit containing only that deletion (your other staged changes are untouched)
- Pushes the commit, so the file disappears from the remote
This affects the current branch only. If the file was also pushed on other branches, check out each branch — GitShield re-applies protection on branch switch, and the file's removal rides along with your next commit there. Note that the file remains visible in past commits; rewriting history requires git filter-repo.
Branches
Protection follows you across branches:
- The protected list (
.gitshield/protected.json), the exclude entries, and the pre-commit hook are all repo-level — they apply no matter which branch is checked out.
- Untracking (
git rm --cached) is per-branch index state, so GitShield watches .git/HEAD and re-applies protection automatically after every checkout (and on VS Code startup).
- A protected file that doesn't exist on the current branch keeps its protection — it is not dropped from the config.
Installation
Install from the VS Code Marketplace by searching GitShield, or press Ctrl+P and run:
ext install HadeedAhmad711.gitshield
Requirements
- VS Code 1.85 or newer
- A workspace with a
.git folder (extension is inactive outside git repos)
- Git for Windows (Git Bash) or WSL on Windows (for the pre-commit shell script)
Protection Details
Protected files are stored in .gitshield/protected.json — local only, never committed. The config file itself is also excluded from git automatically.
Re-enabling a File
- Open the panel → re-check the file (saves automatically)
- Run
git add <file> to start tracking it again
Known Limitations
| Bypass |
Notes |
git commit --no-verify |
Skips all hooks. This is a git built-in; cannot be prevented locally. |
git -c core.hooksPath=... commit |
Redirects hook lookup. Requires deliberate effort. |
| Existing history |
GitShield does not rewrite past commits. Use git filter-repo for that. |
GitShield protects against accidents. A developer deliberately using --no-verify to commit a secret is making an intentional choice. For enforcement that cannot be bypassed, use server-side push protection (e.g. GitHub Advanced Security secret scanning).
How Protection Is Applied
.git/info/exclude — machine-local equivalent of .gitignore; never committed or shared. Hides protected files from git status. Entries are anchored to the repo root so protecting notes.md doesn't hide every notes.md in the tree.
git rm --cached — removes already-tracked files from git's index. File stays on disk. Re-applied automatically after branch switches.
- Pre-commit hook — shell script at
.git/hooks/pre-commit that fires before every commit from any tool.
Multi-Root Workspaces
GitShield protects the primary workspace folder only. A banner in the panel notes this limitation when multiple folders are open.
Documentation
A full walkthrough with troubleshooting and FAQ ships with the extension as USER-GUIDE.md (in the extension's install folder, or in the source repository).