Open-Source Wikis

/

fd

/

Lore

sharkdp/fd

Lore

How fd grew from a one-file Rust experiment in May 2017 into the 10.x line shipped today. Dates are derived from git log, tag timestamps, CHANGELOG.md, and module creation dates.

Eras

The first commits — May 2017

The repository starts on 2017-05-09 with three commits from David Peter (sharkdp):

2145973  Initial commit
aab0a2d  Add initial code
8acb30b  Build instructions

The "Add initial code" commit dropped the bones of what is still recognisable today: a clap-based CLI, the parallel walk, color output, and an ignore-aware default. fd was conceived as an opinionated alternative to GNU find and the README's "13 times faster than find" framing has been there from the start.

Growing into a serious tool — 2017–2019

Through the rest of 2017 and 2018, the codebase picked up the user-facing features that define the modern fd:

  • -x/--exec and -X/--exec-batch (one-by-one and batched command execution).
  • The placeholder syntax ({}, {/}, {//}, {.}, {/.}) inspired by GNU Parallel, modeled by the Token enum in src/fmt/mod.rs.
  • The .fdignore file format, mirroring .gitignore but specific to fd.
  • Smart case (pattern_has_uppercase_char in src/regex_helper.rs).
  • The size, time, and owner filters under src/filter/.

The 7.x line settled on the buffer-then-stream output pattern (MAX_BUFFER_LENGTH = 1000, DEFAULT_MAX_BUFFER_TIME = 100ms) that ReceiverBuffer still implements in src/walk.rs.

9.0.0 and the gitignore-of-.git debate — early 2024

Version 9.0.0 (early 2024) shipped a controversial change: when --hidden was used together with VCS-ignore handling, fd would automatically ignore .git directories. Several existing workflows broke around it, and there was no clean opt-out. Issue #1457 captured the fallout. 10.0.0 reverted the behaviour and the CHANGELOG explicitly notes the revert. Users who liked the old behaviour can still opt in by adding .git/ to their global fdignore file.

The jiff migration — late 2024 (10.3.0)

Version 10.3.0 replaced two date-handling crates with a single one:

  • humantime and chrono were removed.
  • jiff was added (#1690, @sorairolake).

This changed two user-visible behaviours of --changed-within / --changed-before:

  1. The single-letter M no longer means "month" (it would clash with minutes). Users now write mo, mos, month, or months.
  2. Months and years respect the actual calendar instead of being a hard-coded number of seconds.

The TimeFilter::from_str implementation in src/filter/time.rs reflects this: it tries Span, then Timestamp, then DateTime, then a @<unix-seconds> fallback.

10.4.x and the Rust 1.90 / Edition 2024 step-up — early 2026

The 10.4.0 release pushed the MSRV to 1.90.0, dropped support for 32-bit Intel Mac and Windows 7 (!), switched the crate to Rust edition 2024, and added two notable features:

  • --ignore-contain for skipping directories that hold a marker file like CACHEDIR.TAG (#1727, @fischman).

  • OSC 8 hyperlink output via --hyperlink (10.2.0 originally, refined in 10.4.x).

    10.4.1 was a re-release fix; 10.4.2 patched a performance regression introduced by --ignore-contain (#1913).

The current "Unreleased" section of the CHANGELOG (as of 2250bb0) tracks two additions:

  • --ignore-parent to override --no-ignore-parent (#1958, @tmccombs).
  • A friendlier error when the search pattern itself contains a / path separator (#1873, #1975).

Longest-standing code

These pieces have weathered multiple rewrites and still ship:

Subsystem First seen Today
Smart case in regex_helper.rs early 2017 Still the small pattern_has_uppercase_char recursion over a parsed regex_syntax::Hir. The neighbouring pattern_matches_strings_with_leading_dot was added later, but the smart-case core is original.
--exec placeholder tokens 2017 Same five tokens: {}, {/}, {//}, {.}, {/.}. Now expressed as the Token enum in src/fmt/mod.rs and shared with --format.
Buffer-then-stream output 2017–18 ReceiverBuffer in src/walk.rs still uses the same 1000-entry / 100 ms switch-over.
ExitCode enum 2017–18 Four variants: Success, HasResults, GeneralError, KilledBySigint (src/exit_codes.rs).

Deprecated or removed features

  • Auto-ignoring .git with --hidden — added in 9.0.0, removed in 10.0.0 (see above).
  • humantime and chrono — replaced by jiff in 10.3.0.
  • M as a month suffix in time filters — removed in 10.3.0 in favour of unambiguous mo/mos.
  • x86_64 macOS as a tier-1 target — the 10.3.0 changelog notes that this was likely the last release tested on Intel Mac, since GitHub dropped the runner.
  • Windows 7 / 32-bit Intel Mac — dropped in 10.4.0 with the MSRV bump.

Major rewrites and migrations

When What Rationale
~2018 Switch to crossbeam-channel for sender→receiver coordination Bounded, lock-free MPMC channel; fits the "many senders, one (or N) receivers" topology.
~2018 Adoption of the ignore crate for traversal Reuse the well-tested implementation that backs ripgrep instead of rolling a custom walker.
~2020 Migration to clap derive macros Replaces hand-rolled clap builder code; concentrates flags in Opts in src/cli.rs.
2024 (10.3.0) humantime + chronojiff Single, modern, calendar-aware time crate.
2026 (10.4.0) Edition 2024, MSRV 1.90 Use modern Rust language features and standard-library APIs.

Growth trajectory

  • 2017 — repository created, single contributor (sharkdp).
  • 2018–2020 — David Peter remained the primary author; community contributions began arriving steadily.
  • 2021–2023 — Thayne McCombs (tmccombs) and Tavian Barnes (tavianator) joined as co-maintainers. Together with sharkdp they account for ~57% of all commits.
  • 2024–2026 — Maintenance-leaning era: many small bugfixes and dependency bumps, with substantial dependabot activity (~12% of all commits).
  • Total: 1,894 commits from 230 unique authors over nine calendar years; ~480 commits in the trailing twelve months.

For who works where today, see maintainers.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Lore – fd wiki | Factory