unrot

[![CI](https://github.com/cachebag/unrot/actions/workflows/ci.yml/badge.svg)](https://github.com/cachebag/unrot/actions/workflows/ci.yml) [![crates.io](https://img.shields.io/crates/v/unrot.svg)](https://crates.io/crates/unrot) [![Downloads](https://img.shields.io/crates/d/unrot.svg)](https://crates.io/crates/unrot) [![Rust 1.94+](https://img.shields.io/badge/rust-1.94%2B-orange)](https://blog.rust-lang.org/2025/05/15/Rust-1.94.0.html) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE-MIT.md) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](./LICENSE-APACHE.md)
A symlink is _[broken](https://en.wikipedia.org/wiki/Symbolic_link#:~:text=Its%20target%20path%20would%20point%20to%20nothing%20and%20might%20be%20described%20as%20broken%2C%20orphaned%2C%20dead%2C%20or%20dangling)_ when its target no longer exists. `unrot` finds these, reports the dead target path, and attempts to locate where it moved by fuzzy matching the target filename against the real filesystem. You decide whether to re-link, skip, or remove. ## Install ``` cargo install unrot ``` ## Usage ```bash # Scans current directory for broken symlinks and interactively allows you to fix them (default) unrot # Scans a specific directory unrot /path/to/project # Scan only — report broken links (link -> target) unrot scan /path/to/project # List broken symlink paths only, no candidates unrot list /path/to/project # Search for candidates in a wider directory tree unrot ~/project -s ~/ # Preview what would happen without modifying anything unrot /path/to/project --dry-run # Add extra directories to skip (on top of .git, node_modules, target, etc.) unrot /path/to/project -I vendor -I dist # Run a command without terminal coloring enabled unrot [OPTIONS] [PATH] --no-color ``` ### Commands | Command | Description | |---------|-------------| | *(default)* | Interactive fix mode — scan, show candidates, let you re-link/skip/remove | | `scan [PATH]` | Scan only, report broken links (link -> target) | | `fix [PATH]` | Interactive fix mode (explicit) | | `list [PATH]` | List broken link paths only, no candidates, exit | ### Interactive commands When prompted for each broken symlink: | Input | Action | |-------|--------| | `1`, `2`, ... | Re-link to the numbered candidate | | `c` | Enter a custom path to re-link to | | `s` | Skip this symlink | | `r` | Remove this symlink (asks for confirmation) | ### Options | Option | Short | Description | |--------|-------|-------------| | `[PATH]` | — | Directory to scan (default: `.`) | | `--search-root ` | `-s` | Search for candidates here instead of the scan path | | `--dry-run` | — | Preview changes without modifying the filesystem | | `--batch-confirm` | — | Collect all decisions, show summary, then confirm before applying | | `--ignore ` | `-I` | Additional directory names to skip (repeatable) | | `--no-color` | -- | Disables terminal coloring for a given command | ## License Licensed under either of * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) * MIT license ([LICENSE-MIT](LICENSE-MIT)) at your option.