skip to content

What is the difference between `--write-locks` and `--update-locks`, and when do you use each?

level: middleimportance: should knowfreq 42%

answer

  1. write-locks = recompute all
  2. update-locks g:m = only named change
  3. wildcards in update-locks
  4. targeted CVE bump → update-locks
  5. small reviewable diff

basics

~10 s

--write-locks re-resolves freely and rewrites all lock entries for the configurations it resolves. --update-locks group:module re-resolves but only lets the named modules change, keeping every other locked version pinned.

solid answer

~40 s

Both flags regenerate lock state, but with different blast radius. `--write-locks` ignores existing locks during resolution and **overwrites** the lockfile entries for whatever configurations the run resolves — it's the 'recompute everything' option, used after you've intentionally changed many dependencies or want a fresh snapshot. `--update-locks group:module[,group:module...]` is **surgical**: it keeps all currently locked versions pinned *except* the modules you name, which are allowed to move to whatever the current constraints resolve to. It accepts wildcards (e.g. `org.apache.*:*`). Use `--update-locks` to bump one library (e.g. patch a CVE in `jackson-databind`) without churning the rest of the graph, which keeps the lockfile diff small and reviewable. Use `--write-locks` when adding/removing dependencies or doing a wholesale refresh. Both leave the build verifying against the new lockfile afterward.

code

bash · 8 lines
bash
# Full refresh after changing several dependencies:
./gradlew dependencies --write-locks

# Bump only one module (e.g. security patch), keep the rest pinned:
./gradlew dependencies --update-locks com.fasterxml.jackson.core:jackson-databind

# Bump a whole group with a wildcard:
./gradlew dependencies --update-locks 'org.apache.commons:*'

go deeper

for a junior

Know --write-locks regenerates locks; --update-locks targets specific modules.

for a middle

Explain blast radius: write = recompute all resolved configs, update = constrain change to named modules (with wildcards).

for a senior

Discuss reviewability of diffs, transitive fallout from update-locks, and choosing the flag per change type.

for a principal

Standardize an upgrade workflow (targeted update-locks for patches, write-locks for dependency changes) and bake it into the release/CI process.

## Why two flags A lockfile freezes the whole resolved graph. There are two distinct reasons to regenerate it: 1. **You changed your declared dependencies** (added, removed, or re-versioned several), so the whole graph should be recomputed. 2. **You want to bump one or a few modules** (e.g. a security patch) while keeping everything else exactly as pinned, to minimize risk and review noise. ## `--write-locks` ```bash ./gradlew dependencies --write-locks ``` - During this run, existing lock state is **ignored** for the configurations being resolved. - Resolution proceeds against the *current* constraints (so dynamic versions pick today's highest match). - The resulting versions are written back, **overwriting** the prior entries for those configurations. - Net effect: a fresh snapshot. Other configurations not resolved in this run keep their old entries. ## `--update-locks` ```bash ./gradlew dependencies --update-locks com.fasterxml.jackson.core:jackson-databind ``` - Acts like a **constrained** write: all existing locks stay in force *except* the named modules. - The named modules are temporarily unlocked, re-resolved, and their new versions (plus any newly-pulled or dropped transitives caused by that change) are written. - Supports comma-separated lists and `*` wildcards: `--update-locks org.apache.*:*`. - Keeps the diff focused, which is the whole point for targeted upgrades. ## Choosing | Situation | Flag | |---|---| | Added/removed/changed many deps | `--write-locks` | | First-time generation | `--write-locks` | | Patch one library (CVE, bugfix) | `--update-locks g:m` | | Bump a family of modules | `--update-locks org.x.*:*` | ## Gotcha `--update-locks` still re-resolves the full graph; it just *constrains* what may change. If bumping the named module forces a transitive elsewhere to move, that downstream change is also written — locking can't pin a version that no longer satisfies the constraints. After either command, commit the updated `gradle.lockfile` and let normal builds verify.

  • If `--update-locks` only names one module, can other lines in the lockfile still change?
    Yes — if bumping that module changes its transitive closure, the affected transitives are re-resolved and rewritten too. Locking can't keep a pin that the new constraints no longer satisfy.
  • Which flag would you use for a routine security patch of a single library?
    `--update-locks group:module` for that library, so the lockfile diff stays minimal and reviewable.

saying these in an interview costs you the question

  • Saying --update-locks guarantees only one line changes — transitive fallout can change more.
  • Using --write-locks for a single-library bump and producing a noisy, hard-to-review diff.

context