treefmt icon indicating copy to clipboard operation
treefmt copied to clipboard

Support for `--staged-only` Flag

Open hsjobeki opened this issue 5 months ago • 9 comments

Feature Request: Support for --staged-only Flag

Is your feature request related to a problem? Please describe.

Yes. When running treefmt natively on a project with partially staged changes, the formatter operates on both staged and unstaged content. For example:

  • Staged: foo.nix (lines 10–20) — has formatting issues
  • Unstaged: foo.nix (lines 80–81) — contains the formatting fix, but is unstaged

Because treefmt formats the entire file, it may end up accepting files with unstages formatting fixes as well. Which makes it unsutable as a pre-commit tool on its own.

This becomes an issue when using treefmt as part of a pre-commit hook. Tools like [git-hooks.nix](https://github.com/cachix/git-hooks.nix) are capable of extracting only staged changes, but they bring their own ecosystem. This adds overhead, complexity, and potential integration friction.

Describe the solution you'd like

I'd like treefmt to support a native --staged-only flag, which restricts formatting to only the staged portions of files. This would enable native use of treefmt in pre-commit workflows without (mentioned) external wrappers.

Describe alternatives you've considered

  • Using [git-hooks.nix](https://github.com/cachix/git-hooks.nix) with custom eslint formatter derivations scripts to restrict treefmt to staged changes. However, this approach introduces:

    • Additional dependencies
    • Complexity in setup and maintenance
    • Friction when dealing with frontend tooling (e.g., aligning eslint plugins with the project)

Running treefmt directly is far simpler — if it supported "staged-only" formatting that would be awesome.

Example of interactions

# Initial state
$ git status

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   foo.nix

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   foo.nix
  1. Run
treefmt . --staged-only

Expected:

=> treefmt fails because it checks the staged change only.

  1. Stage the formatted files This makes sense, since we want to build a pre-commit check. Which should check the content of the commit, not local files.
git add foo.nix
treefmt . --staged-only

Expected:

treefmt runs fine. Because we have staged the formatting changes.

EDIT: Maybe we should call this --check-staged-only which fails on change

hsjobeki avatar Jul 21 '25 17:07 hsjobeki