skip to content

When you request multiple tasks like `gradle clean build`, how does Gradle build one combined graph, and what does `--exclude-task` (-x) do to it?

level: seniorimportance: should knowfreq 30%

answer

  1. merged union of closures
  2. dedup -> each task runs once
  3. CLI order = soft hint, edges win
  4. -x prunes task + its exclusive deps
  5. verify pruned plan with --dry-run

basics

~20 s

Gradle merges all requested tasks into a single DAG, deduplicates shared dependencies (each task runs once), and topologically sorts the whole thing. -x <task> removes that task and any edge into it from the plan, so it and its now-unneeded dependencies are excluded.

solid answer

~50 s

Multiple requested tasks (`clean build`) do not run as independent sub-builds; Gradle computes the **transitive closure of all of them into one merged DAG**, **deduplicates** shared dependencies so each task instance runs exactly **once**, and topologically sorts the combined graph. Command-line order influences which valid topo order is chosen (Gradle honors the requested order as an ordering hint), but real dependency edges always win. `--exclude-task` (`-x`) **removes a task from the resolved graph** along with the edges that would have pulled it in; dependencies that exist *solely* to support the excluded task are dropped too, while dependencies still needed by other selected tasks remain. Excluding a task does not error if it isn't in the graph. Use `--dry-run` together with `-x` to confirm the pruned plan before committing to it — a common pattern is `gradle build -x test --dry-run` to verify test is gone but compilation stays.

code

bash · 8 lines
bash
# One merged, deduplicated, topo-sorted graph for both tasks
gradle clean build

# Prune the test task (and test-only deps) from the plan
gradle build -x test

# Confirm the pruned plan before running it
gradle build -x test --dry-run

go deeper

for a junior

Know multiple tasks combine into one run and -x skips a task.

for a middle

Explain dedup (each task once) and that -x also drops dependencies only needed by the excluded task.

for a senior

Discuss CLI order as a soft hint vs. hard edges, and verifying pruned plans with --dry-run.

for a principal

Standardize exclusion patterns in CI scripts and reason about plan stability/determinism when composing task requests.

## Merging multiple requested tasks When you pass several tasks, Gradle does **not** run them as separate graphs back to back. It: 1. Selects all requested tasks. 2. Computes the **union of their transitive closures** into a single graph. 3. **Deduplicates** — a task depended on by several requested tasks appears (and runs) exactly **once**. 4. **Topologically sorts** the merged graph. ### Command-line order as a hint The order you list tasks is treated as a soft ordering preference: where the graph leaves freedom, Gradle tries to honor the requested order (so `clean` is generally scheduled before `build`). But **hard dependency edges override** any requested order — you cannot reorder past a real dependency. ## `--exclude-task` / `-x` `-x <name>` **prunes** a task from the resolved plan: - The named task is removed. - Edges that exist *only* to satisfy it are removed, so its exclusive dependencies are also dropped. - Dependencies that other surviving tasks still need are **kept**. - Excluding a task not present in the plan is a no-op, not an error. A classic use is skipping slow verification: `gradle build -x test` builds and assembles but does not run tests (and skips test-only compilation that nothing else needs). ## Verify with dry-run Because pruning interacts with shared dependencies in non-obvious ways, pair it with `--dry-run`: ``` > gradle build -x test --dry-run :compileJava SKIPPED :processResources SKIPPED :classes SKIPPED :jar SKIPPED :assemble SKIPPED :check SKIPPED :build SKIPPED # note: :test and :compileTestJava are absent ``` This confirms the excluded subtree is gone while the rest of the plan is intact.

  • If both `clean` and `build` depend on the same task, how many times does that shared task run?
    Once. Gradle deduplicates the merged graph so each task instance executes exactly once regardless of how many requested tasks reach it.
  • Does command-line task order guarantee execution order?
    No — it is a soft hint honored only where the graph allows; real dependency edges always take precedence.
  • What happens if you exclude a task that isn't in the graph?
    Nothing — it is a no-op and does not fail the build.

saying these in an interview costs you the question

  • Saying `clean build` runs two separate independent graphs
  • Claiming a shared dependency runs once per requesting task
  • Believing CLI order can override a real dependency edge
  • Thinking -x only hides the task but still runs it

context