Skip to content

Rust .gitignore

Generate a Rust .gitignore — covers Cargo's target/ directory, *.rs.bk backup files, and Cargo.lock. VS Code, macOS, Windows, and Linux files preselected.

A ready-to-use Rust .gitignore. Excludes Cargo's target/ directory, *.rs.bk backup files, and Cargo.lock (typically excluded for libraries; commit it for binaries). All three OS templates are preselected since Rust is commonly developed cross-platform.

Languages

Operating systems

Editors

Tools

Pick at least one template

Download
 

Rust’s build tool, Cargo, puts everything in one place: target/. The .gitignore is correspondingly small — most of it is just that one directory. The list above is a known-good set; this page explains the entries and the Cargo.lock decision.

target/

target/

target/ holds compiled artifacts: dependency object files, your crate’s binaries, doc-generated output. Easily gigabytes for a non-trivial project. Always regenerable from cargo build.

If you compile in multiple modes (debug, release), each gets its own subdirectory in target/ — both ignored.

For workspace projects with multiple crates, the workspace root has one target/, not one per crate. The single target/ ignore at the workspace root covers everything.

Cargo.lock — the binary vs library question

This is the one Rust-specific decision worth understanding. The old rule was “commit Cargo.lock for binaries, ignore it for libraries”. In August 2023 the Cargo team changed that guidance: cargo new now tracks Cargo.lock for libraries too, and the Cargo FAQ leaves the choice to the project, with committing as the starting point.

Project typeCommit Cargo.lock?
Application / binary crateYes — reproducible builds and deployments
Library crateYes by default — ignoring it is still a legitimate choice
Mixed workspaceYes

The trade-offs:

  • Committing gives deterministic CI, lets git bisect reproduce old builds, and pins the dependency set you test your minimum supported Rust version against.
  • It doesn’t pin anything for your users. A library’s Cargo.lock doesn’t affect crates that depend on it — they resolve from Cargo.toml. So a library that commits its lockfile should also test against the latest dependencies in CI (for example a scheduled job that runs cargo update first).

That’s why the generator above leaves Cargo.lock as a commented-out line: uncomment it only if you’ve decided to ignore the lockfile.

Editor and OS

*.swp
*.swo
.idea/
.vscode/
.DS_Store
Thumbs.db

Standard. .idea/ for JetBrains IDEs (CLion, RustRover); .vscode/ for VS Code with rust-analyzer.

rust-analyzer cache

# rust-analyzer state
.rust-analyzer/

If using rust-analyzer (the standard LSP), it may write a .rust-analyzer/ directory for its own cache. Editor-specific; never useful to commit.

Backup and crash files

*.rs.bk

Some older versions of rustfmt left backup files when reformatting. Modern rustfmt doesn’t, but the pattern is harmless.

Build script outputs

If your crate uses a build script (build.rs) that generates files, those generated files might be committed (if they’re considered source) or might not be (if they’re considered build artifacts). Project-specific decision.

Rustup / per-project toolchain

# rust-toolchain.toml      ← commit this
# rust-toolchain           ← commit this (older form)

These files specify the Rust version the project uses. Commit them so contributors get the same toolchain via rustup.

Workspaces

In a Cargo workspace:

target/                  # workspace-level target — covers all member crates
**/target/               # if any member crate has its own target (rare)

The single workspace-level target/ covers all members. Sometimes a member crate generates a stray target/ for some reason (weird build script, mixed toolchain), so a glob form is sometimes added.

Profiling

flamegraph.svg
*.heaptrack.gz
*.dhat
massif.out.*

If you use profiling tools (cargo-flamegraph, dhat, valgrind), they produce per-run output files. Regenerable.

Common pitfalls

  • Ignoring Cargo.lock for a binary crate. Breaks reproducibility. Commit it.
  • Committing Cargo.lock for a library crate without testing newer dependencies. Your CI then only ever sees the locked versions, while your users get the latest ones. Keep the lockfile, but add a job that tests with cargo update.
  • Committing target/. It’s large, platform-specific, and regenerable. Always ignore.
  • Committing target/ once and not realizing it. git rm -rf --cached target then commit, after adding to .gitignore.
  • Ignoring Cargo.toml. Don’t. That’s your manifest — the most important file in the project.
  • Forgetting .cargo/ in CI configurations. Sometimes projects keep .cargo/config.toml for project-specific cargo settings. Commit that file (it’s source-of-truth configuration); only ignore generated cache directories.

For other stacks, see Python, Node.js, Java, Go, .NET, Ruby, or the general .gitignore generator.