LibraLibra
LibraLibra
DocsBlogLibra
Getting Started
Architecture
Design
Commands
libra addlibra agentlibra alternateslibra applylibra archivelibra authlibra automationlibra bisectlibra blamelibra branchlibra bundlelibra cachelibra cat-filelibra check-attrlibra check-ignorelibra check-mailmaplibra checkoutlibra cherry-picklibra cleanlibra clonelibra cloudlibra code-controllibra codelibra commit-treelibra commitlibra completionslibra configlibra credentiallibra depslibra describelibra diff-fileslibra diff-indexlibra diff-treelibra difflibra dirtylibra fast-exportlibra fast-importlibra fetchlibra filelibra for-each-reflibra format-patchlibra fscklibra gclibra graphlibra greplibra hash-objectlibra hookslibra hydratelibra index-packlibra initlibra investigatelibra layerlibra lfslibra loglibra logfilelibra loginlibra logoutlibra ls-fileslibra ls-remotelibra ls-treelibra maintenancelibra medialibra merge-baselibra merge-filelibra mergelibra metadatalibra mvlibra noteslibra oplibra openlibra pack-objectslibra packagelibra prunelibra publishlibra pulllibra pushlibra read-treelibra rebaselibra refloglibra remotelibra repacklibra replacelibra rererelibra resetlibra restorelibra rev-listlibra rev-parselibra revertlibra reviewlibra revisionlibra rmlibra sandboxlibra servicelibra shortloglibra show-reflibra showlibra sparse-viewlibra stashlibra statslibra statuslibra switchlibra symbolic-reflibra taglibra update-indexlibra update-reflibra usagelibra verify-packlibra whoamilibra worktreelibra write-tree
API Reference
Policy
Commands

libra rm

Command reference for `libra rm`

Remove files from the working tree and/or the index.

Aliases: remove, delete

Synopsis

libra rm [--json|--machine] <pathspec>...
libra rm [--json|--machine] --cached <pathspec>...
libra rm [--json|--machine] -r <pathspec>...
libra rm [--json|--machine] --dry-run <pathspec>...

Description

libra rm removes files from the working tree and the index. By default it deletes the file from disk and unstages it so the removal is recorded in the next commit. With --cached, only the index entry is removed and the file remains on disk -- useful for untracking a file that was added by mistake without losing local changes.

Removing a directory requires the -r (recursive) flag. Without it, specifying a directory path produces an error. This mirrors Git's behavior and prevents accidental recursive deletion.

Before removing a file, Libra checks for uncommitted changes (both staged and unstaged). If the file has local modifications relative to the index, or the index differs from HEAD, the command refuses to proceed unless --force is passed or --cached is used. This safety check prevents silent data loss when a file has unsaved work.

Aliases: remove, delete. All three names invoke the same command.

Options

FlagShortLongDescription
PathspecpositionalOne or more files or directories to remove. Required unless --pathspec-from-file is used.
Cached--cachedOnly remove from the index; keep the working tree file intact.
Recursive-r--recursiveAllow recursive removal when a directory is specified.
Force-f--forceForce removal, bypassing the uncommitted-changes safety check.
Dry run--dry-runShow what would be removed without actually deleting anything.
Ignore unmatch--ignore-unmatchExit with zero status even if no pathspec matched any file.
Pathspec from file--pathspec-from-file <FILE>Read pathspecs from a file, one per line.
NUL separator--pathspec-file-nulPathspec file entries are separated by NUL bytes instead of newlines.
Sparse--sparseAccepted for Git compatibility as a no-op. Git uses it to allow removing index entries outside the sparse-checkout cone; Libra has no sparse-checkout state, so it changes nothing.

Option Details

--cached

Unstages the file but leaves the working tree copy in place. After running libra rm --cached secret.env, the file disappears from the index (and will show as "deleted" in the next commit), but the file remains on disk. This is the standard way to stop tracking a file without deleting it.

$ libra rm --cached config/local.toml
rm 'config/local.toml'

-f / --force

Bypasses safety checks for files with uncommitted changes. Normally Libra refuses to remove a file when:

  1. The working tree version differs from the index (local modifications).
  2. The index version differs from HEAD (staged changes).
  3. Both conditions are true simultaneously.

With --force, the file is removed regardless.

--dry-run

Shows what would be removed without touching the filesystem or index:

$ libra rm --dry-run src/old_module.rs tests/old_test.rs
rm 'src/old_module.rs'
rm 'tests/old_test.rs'

--pathspec-from-file

Reads pathspecs from a file instead of command-line arguments. Combined with --pathspec-file-nul, this supports filenames containing newlines or other special characters:

$ libra rm --pathspec-from-file files-to-remove.txt
$ libra rm --pathspec-from-file files.txt --pathspec-file-nul

Common Commands

# Remove a single file from both index and disk
libra rm src/deprecated.rs

# Untrack a file but keep it on disk
libra rm --cached .env

# Recursively remove a directory
libra rm -r old_module/

# Preview what would be removed
libra rm --dry-run -r build/
libra --json rm --dry-run -r build/

# Force remove a file with local modifications
libra rm -f src/experimental.rs

# Remove files listed in a manifest
libra rm --pathspec-from-file cleanup-list.txt

# Remove from index, ignore if file is not tracked
libra rm --cached --ignore-unmatch generated.rs

Human Output

Each removed file is reported on its own line:

rm 'src/deprecated.rs'
rm 'old_module/foo.rs'
rm 'old_module/bar.rs'

In --dry-run mode, the same output is produced but no files are modified.

Global --quiet suppresses this primary human output while keeping warnings and errors on stderr.

JSON Output

--json and --machine use the rm command envelope. paths contains every tracked file matched for index removal. directories contains recursive directory pathspecs that were removed from disk. In --dry-run, the same candidate paths are reported, but removed_from_index and removed_from_disk are false.

{
  "ok": true,
  "command": "rm",
  "data": {
    "pathspecs": ["src/deprecated.rs"],
    "paths": [
      {
        "path": "src/deprecated.rs",
        "removed_from_index": true,
        "removed_from_disk": true
      }
    ],
    "directories": [],
    "cached": false,
    "recursive": false,
    "forced": false,
    "dry_run": false
  }
}

--machine emits the same envelope as compact single-line JSON.

Design Rationale

Why aliases remove and delete?

rm is terse and familiar to Git users, but not self-documenting. remove reads naturally in scripts and documentation. delete matches the vocabulary many developers reach for first. Supporting all three names reduces friction without adding any implementation complexity -- they are clap aliases that map to the same handler.

Why --pathspec-from-file?

When removing many files programmatically (e.g., a CI cleanup step or a migration script), command-line argument limits can be hit. --pathspec-from-file avoids this by reading paths from a file. The --pathspec-file-nul variant handles pathnames with spaces or newlines safely, following the same convention as git rm --pathspec-from-file.

Why safety checks on uncommitted changes?

Removing a file that has local modifications silently destroys work. Git requires --force in the same scenario. Libra follows this convention exactly: if the working tree differs from the index or the index differs from HEAD, the command errors with a message explaining which flag to use (--cached to keep the file, -f to force deletion). This two-flag escape hatch lets users express intent clearly.

Why no per-command --quiet flag?

Unlike libra clean, the rm command does not have a command-specific quiet flag. Use the global --quiet flag to suppress primary stdout while preserving warnings and errors.

Parameter Comparison: Libra vs Git vs jj

ParameterLibraGitjj
Basic removelibra rm <path>git rm <path>jj file untrack <path>
Cache only--cached--cachedDefault (jj untrack only affects tracking)
Recursive-r / --recursive-r / --recursiveImplicit (jj untrack handles dirs)
Force-f / --force-f / --forceNot needed (no safety check)
Dry run--dry-run--dry-run / -nNot available
Ignore unmatch--ignore-unmatch--ignore-unmatchNot available
Pathspec from file--pathspec-from-file--pathspec-from-fileNot available
NUL separator--pathspec-file-nul--pathspec-file-nulNot available
Sparse--sparse (accepted no-op)--sparseNot available
QuietGlobal --quiet-q / --quietNot available
Aliasesrm, remove, deleterm onlyfile untrack

Note: jj's file untrack is conceptually similar to libra rm --cached -- it stops tracking a file without deleting it. jj does not have a command that both untracks and deletes a file in one step.

Error Handling

ScenarioBehaviorExit
No pathspecs providedError: nothing specified for removalnon-zero
Path not found in indexError (or zero with --ignore-unmatch)non-zero / 0
Directory without -rError: not removing directory recursively without -rnon-zero
Uncommitted local modificationsError: file has local modifications, use --cached or -fnon-zero
Staged changes differ from HEADError: file has staged changes, use --cached or -fnon-zero
Both staged and local changesError: file has staged content different from both the file and HEAD, use -fnon-zero
Not inside a repositoryError: repository not foundnon-zero

libra revision

Command reference for `libra revision`

libra sandbox

Command reference for `libra sandbox`

On this page

SynopsisDescriptionOptionsOption DetailsCommon CommandsHuman OutputJSON OutputDesign RationaleWhy aliases remove and delete?Why --pathspec-from-file?Why safety checks on uncommitted changes?Why no per-command --quiet flag?Parameter Comparison: Libra vs Git vs jjError Handling