mroberts 70188eb4ea fix(git): use jj as diff source in jujutsu repos
In a colocated jj repo, jj does not maintain git's index for git's own
consumption. git can therefore report an unmodified tracked file as a
whole-file add: for tests/integration/test_texttoentities_endpoint.py in
the IO repo, `git ls-tree HEAD` and `git ls-files -s` both showed the same
blob, yet `git status` reported `AM` and `git diff --cached --unified=0`
emitted a single `@@ -0,0 +1,330 @@` hunk.

shush treats every line in that hunk as agent-changed, so `--changes-only`
stripped all six comments from a file the agent had never touched (`jj diff`
confirmed 0 insertions). Diffing against HEAD instead of the index does not
help: it is poisoned the same way.

jj is authoritative when present, so DetectRepo now prefers `jj root` and
the three change queries route to `jj diff --git --context=0`. jj has no
staging area, so --staged, --unstaged and --changes-only all resolve to the
working-copy change; GetChangesOnly short-circuits so files are not
duplicated across the staged and unstaged passes.

Empty line ranges are overloaded to mean "process the whole file" (untracked
semantics). A deletion-only change parses to zero ranges, which would have
made shush strip an entire file whose only edit removed lines, so such files
are now skipped. New files still get correct full-file ranges from jj's
`@@ -0,0 +1,N @@` hunk, so they do not need the fallback.

Pagers are disabled explicitly on every git and jj invocation so output
stays machine-parseable regardless of the user's config.
2026-07-21 15:07:46 -05:00
2026-07-08 13:24:29 -05:00
2025-07-09 09:13:33 -03:00
2025-07-09 09:13:33 -03:00

shush 🤫

Sloppily Hushing Unwanted Source-code Heavy (comments)

Remove comments from source code files blazingly fast. Features Claude Code integration, smart comment preservation, and git-aware processing. Supports 40+ file extensions across most popular programming languages.

Installation

Quick Install (Linux/macOS)

curl -sSf https://raw.githubusercontent.com/carlosarraes/shush/main/install.sh | sh

Manual Download

Download the binary for your platform from the releases page.

🤖 Claude Code Integration

Automatic comment cleanup whenever Claude Code modifies files:

# Install hooks
shush --install-hook              # User-wide (all projects)
shush --install-hook --project    # Project-specific only

# Manage hooks
shush --hook-status               # Check installation status
shush --list-hooks                # Show all configured hooks
shush --uninstall-hook            # Remove hooks

Once installed, comments are automatically cleaned whenever Claude Code uses Write, Edit, or MultiEdit tools. Respects your .shush.toml configuration for comment preservation.

⚙️ Configuration (.shush.toml)

Smart comment preservation through configuration:

shush --create-config    # Create example configuration
shush --config          # Show current configuration

Configuration File Example

# Patterns to preserve in comments (supports wildcards with *)
preserve = [
    "TODO:",
    "FIXME:",
    "@ts-ignore",
    "eslint-",
    "*IMPORTANT*",   # Wildcard: preserves any comment containing IMPORTANT
    "*DEBUG*",       # Wildcard: preserves any comment containing DEBUG
]

# Number of context lines to show in preview mode (default: 3)
context_lines = 3

Configuration Discovery

Shush searches for configuration in this order:

  1. .shush.toml (current directory)
  2. .shush.toml (git repository root)
  3. ~/.config/.shush.toml (global user config)

🚫 File Exclusion (.shushignore)

Exclude files and directories from processing:

# Create .shushignore file
echo "*.tmp" > .shushignore       # Ignore all .tmp files
echo "build/" >> .shushignore     # Ignore build directory
echo "test*.js" >> .shushignore   # Ignore test files
echo "!important.js" >> .shushignore  # But keep important.js

Ignore File Locations:

  • .shushignore (project root or current directory)
  • ~/.config/.shushignore (global user ignore patterns)

Usage

Basic Operations

# Remove comments from file/directory
shush file.py
shush src/ --recursive

# Preview changes
shush script.sh --dry-run
shush script.sh --dry-run --context-lines 5

# Comment type filtering
shush file.js --inline          # Only line comments
shush file.c --block            # Only block comments

# Backup and preserve options
shush config.lua --backup
shush script.py --preserve-lines  # Keep comment-only lines as empty

Git-Aware Processing

# Process only changed lines
shush --staged                   # Clean staged changes
shush --unstaged                 # Clean unstaged changes  
shush --changes-only             # Clean all changes (staged + unstaged + untracked)

Options

# Comment filtering
--inline       Remove only line comments
--block        Remove only block comments

# Processing modes
-r, --recursive    Process directories recursively
--dry-run          Show what would be removed without making changes
--backup           Create backup files before modification
--verbose          Show detailed output
--preserve-lines   Keep comment-only lines as empty lines
-c, --context-lines Number of context lines to show in preview mode

# Git-aware flags
--changes-only Remove comments only from git changes
--staged       Remove comments only from staged git changes
--unstaged     Remove comments only from unstaged git changes

# Configuration
--config       Show current configuration and location
--create-config Create example .shush.toml configuration file

# Claude Code hooks
--install-hook   Install Claude Code hooks for automatic comment cleanup
--uninstall-hook Uninstall Claude Code hooks  
--list-hooks     List current Claude Code hooks configuration
--hook-status    Check if shush hooks are installed
--project        Use project scope for hook operations (default: user-wide)

# Utility
--version      Show version information
--llm          Show LLM-friendly usage guide
--help         Show help message

Examples

Python

# Before
# This is a comment
def hello():
    # Comment-only line
    print("Hello")  # Inline comment

# After: shush example.py
def hello():
    print("Hello")

# After: shush example.py --preserve-lines
def hello():
    
    print("Hello")

Git Workflow

# Preview and clean staged changes
shush --staged --dry-run          # 1. Review what will be cleaned  
shush --staged                    # 2. Clean staged changes
git commit -m "Clean code"        # 3. Commit cleaned code

How It Works

  • Language Detection: Auto-detects language from file extension
  • String-Aware Parsing: Preserves URLs and strings containing comment markers
  • Git-Aware Processing: Only processes changed lines for surgical precision
  • Smart Preservation: Configurable comment preservation via .shush.toml patterns
  • Claude Code Integration: Automatic cleanup via PostToolUse hooks

Requirements

  • Linux or macOS (x86_64 or ARM64)

License

MIT

S
Description
Strip AI generated comments from code
Readme
231 KiB
v0.6.2
Latest
2026-07-21 20:23:29 +00:00
Languages
Go 94.2%
Makefile 3%
Shell 2.8%