$ shellfirm
Protection Coverage

Git

Protection patterns for git operations including force push, reset, clean, and branch deletion

shellfirm provides two groups of git checks: git (standard) for clearly dangerous operations and git-strict for broader coverage of history-modifying commands.

Standard git checks (git)

Force push

IDgit:force_push
SeverityHigh
FilterNotContains --force-with-lease
Alternativegit push --force-with-lease -- checks that your local ref is up-to-date before force pushing
Blast radiusCounts commits ahead of remote
# Triggers
git push --force origin main
git push -f origin feature

# Does NOT trigger (safe variant)
git push --force-with-lease origin main

Reset

IDgit:reset
SeverityHigh
FilterNotContains --soft
Alternativegit stash -- saves changes so you can recover them later
Blast radiusCounts modified files (staged + unstaged)
# Triggers
git reset --hard
git reset HEAD~5
git reset --mixed

# Does NOT trigger
git reset --soft HEAD~1

Clean (force)

IDgit:clean_force
SeverityHigh
FiltersNotContains --dry-run, NotContains -n
Alternativegit clean -fdn -- dry-run shows what would be deleted
Blast radiusCounts untracked files/directories
# Triggers
git clean -fd
git clean -fdx

# Does NOT trigger
git clean -fdn
git clean -fd --dry-run

Force delete branch

IDgit:force_delete_branch
SeverityHigh
Alternativegit branch -d <branch> -- safe delete refuses if branch has unmerged changes
Blast radiusNames the branch being deleted
# Triggers
git branch -D feature-old
git branch -D experiment

Force checkout

IDgit:force_checkout
SeverityHigh
Alternativegit stash && git checkout <branch> -- stash changes first
Blast radiusCounts files with uncommitted changes
# Triggers
git checkout -f main
git checkout -f feature

Checkout discard all

IDgit:checkout_discard_all
SeverityHigh
Alternativegit stash -- saves changes so you can recover them later
# Triggers
git checkout -- .
git checkout -- ./
git checkout -- *

# Does NOT trigger (specific file is fine)
git checkout -- file.txt
git checkout -- src/main.rs
git checkout -- .gitignore

Restore discard all

IDgit:restore_discard_all
SeverityHigh
Alternativegit stash -- saves changes so you can recover them later
# Triggers
git restore .
git restore ./
git restore *
git restore --staged .
git restore --source=HEAD .

# Does NOT trigger (specific file is fine)
git restore file.txt
git restore --staged file.txt
git restore src/main.rs
git restore .gitignore

Stash clear

IDgit:stash_clear
SeverityHigh
Alternativegit stash list -- review your stashes before clearing. Use git stash drop stash@{N} to remove individual entries
# Triggers
git stash clear

# Does NOT trigger
git stash list
git stash drop stash@{0}

Delete all tracked files

IDgit:delete_all
SeverityHigh
Blast radiusCounts all tracked files in the repository
# Triggers
git rm *
git rm .

Interactive rebase

IDgit:interactive_rebase
SeverityMedium
# Triggers
git rebase -i HEAD~5
git rebase -i main

Filter-branch

IDgit:filter_branch
SeverityHigh
Alternativegit-filter-repo -- faster, safer, and officially recommended
Blast radiusCounts total commits in history
# Triggers
git filter-branch --tree-filter 'rm -rf secrets' HEAD

Push mirror

IDgit:push_mirror
SeverityCritical

Mirror push overwrites the ENTIRE remote -- all branches, tags, and refs.

# Triggers
git push --mirror
git push --mirror origin
git push origin --mirror

Push delete branch

IDgit:push_delete_branch
SeverityHigh
# Triggers
git push origin --delete feature-branch
git push --delete origin feature
git push origin :feature-branch

Reflog expire

IDgit:reflog_expire
SeverityCritical

Expiring all reflog entries destroys the last recovery mechanism for lost commits.

# Triggers
git reflog expire --expire=now --all
git reflog expire --all --expire=now

# Does NOT trigger
git reflog show
git reflog expire --expire=90.days

Other standard checks

IDDescriptionSeverity
git:gc_prunegit gc --prune=now -- permanently deletes unreachable objectsHigh
git:delete_refgit update-ref -d -- deletes a Git referenceHigh
git:merge_no_ffgit merge --no-ff or git merge --abortMedium
git:cherry_pickgit cherry-pick -- applies changes from existing commitsMedium
git:bisectgit bisect -- starts binary search for bugsMedium
git:worktree_managementgit worktree add or git worktree removeMedium

Strict git checks (git-strict)

These checks cover broader operations. Useful for teams that want visibility into staging and committing.

IDDescriptionSeverity
git-strict:add_allgit add ., git add --all, git add -A -- stages all changesLow
git-strict:commit_allgit commit --all or git commit -a -- commits all changed filesLow
git-strict:rebasegit rebase -- rewrites commit historyMedium
git-strict:stash_pop_dropgit stash pop or git stash drop -- applies or removes stashed changesLow
git-strict:submodule_updategit submodule update or git submodule deinitLow
git-strict:create_taggit tag -a -- creates an annotated tagLow

The strict checks have blast radius support for git-strict:add_all and git-strict:commit_all, showing how many files would be staged or committed.