# Filtering Repository Content

version 9.4.0-20260219075125+0000

Gradle exposes an API to declare what a repository may or may not contain. There are different use cases for it:

- Performance when you know a dependency will never be found in a specific repository

- Security by avoiding leaking what dependencies are used in a private project

- Reliability when some repositories contain invalid or incorrect metadata or artifacts

It’s even more important when considering that the declared order of repositories matter.

## Declaring a repository filter

build.gradle.kts

    repositories {
        maven {
            url = uri("https://repo.mycompany.com/maven2")
            content {
                // this repository *only* contains artifacts with group "my.company"
                includeGroup("my.company")
            }
        }
        mavenCentral {
            content {
                // this repository contains everything BUT artifacts with group starting with "my.company"
                excludeGroupByRegex("my\\.company.*")
            }
        }
    }

build.gradle

    repositories {
        maven {
            url = "https://repo.mycompany.com/maven2"
            content {
                // this repository *only* contains artifacts with group "my.company"
                includeGroup "my.company"
            }
        }
        mavenCentral {
            content {
                // this repository contains everything BUT artifacts with group starting with "my.company"
                excludeGroupByRegex "my\\.company.*"
            }
        }
    }

By default, repositories include everything and exclude nothing:

- If you declare an include, then it excludes everything but what is included.

- If you declare an exclude, then it includes everything but what is excluded.

- If you declare both includes and excludes, then it includes only what is explicitly included and not excluded.

It is possible to filter either by explicit group, module or version, either strictly or using regular expressions. When using a strict version, it is possible to use a version range, using the format supported by Gradle. In addition, there are filtering options by resolution context: configuration name or even configuration attributes. See RepositoryContentDescriptor for details.

## Declaring content exclusively found in one repository

Filters declared using the repository-level content filter are not exclusive. This means that declaring that a repository includes an artifact doesn’t mean that the other repositories can’t have it either: you must declare what every repository contains in extension.

Alternatively, Gradle provides an API which lets you declare that a repository exclusively includes an artifact. If you do so:

- an artifact declared in a repository can’t be found in any other

- exclusive repository content must be declared in extension (just like for repository-level content)

| Using exclusive repository content filters is a Gradle Best Practice.

build.gradle.kts

    repositories {
        // This repository will _not_ be searched for artifacts in my.company
        // despite being declared first
        mavenCentral()
        exclusiveContent {
            forRepository {
                maven {
                    url = uri("https://repo.mycompany.com/maven2")
                }
            }
            filter {
                // this repository *only* contains artifacts with group "my.company"
                includeGroup("my.company")
            }
        }
    }

build.gradle

    repositories {
        // This repository will _not_ be searched for artifacts in my.company
        // despite being declared first
        mavenCentral()
        exclusiveContent {
            forRepository {
                maven {
                    url = "https://repo.mycompany.com/maven2"
                }
            }
            filter {
                // this repository *only* contains artifacts with group "my.company"
                includeGroup "my.company"
            }
        }
    }

It is possible to filter either by explicit group, module or version, either strictly or using regular expressions. See InclusiveRepositoryContentDescriptor for details.

When setting up exclusive content filters be sure to also consider what repository will contain the transitives dependencies your build will resolve.

| If you leverage exclusive content filtering in the `pluginManagement` section of the `settings.gradle(.kts)`, it becomes illegal to add more repositories through the project `buildscript.repositories`. In that case, the build configuration will fail. Your options are either to declare all repositories in settings or to use non-exclusive content filtering.

### Maven repository filtering

For Maven repositories, it’s often the case that a repository would either contain releases or snapshots. Gradle lets you declare what kind of artifacts are found in a repository using this DSL:

build.gradle.kts

    repositories {
        maven {
            url = uri("https://repo.mycompany.com/releases")
            mavenContent {
                releasesOnly()
            }
        }
        maven {
            url = uri("https://repo.mycompany.com/snapshots")
            mavenContent {
                snapshotsOnly()
            }
        }
    }

build.gradle

    repositories {
        maven {
            url = "https://repo.mycompany.com/releases"
            mavenContent {
                releasesOnly()
            }
        }
        maven {
            url = "https://repo.mycompany.com/snapshots"
            mavenContent {
                snapshotsOnly()
            }
        }
    }

## Enabling Ivy dynamic resolve mode

Normally, in an Ivy repository, dependencies are specified using the `rev` (revision) attribute in `ivy.xml`. However, dynamic resolve mode allows Gradle to prefer the `revConstraint` attribute over `rev`:

- If `revConstraint` is present in `ivy.xml`, Gradle will use it instead of `rev`.

- If `revConstraint` is not present, Gradle falls back to `rev`.

This provides more flexibility in dependency resolution, particularly when working with Ivy repositories that define constraints on acceptable versions.

You need to explicitly enable dynamic resolve mode when declaring an Ivy repository:

build.gradle.kts

    // Can enable dynamic resolve mode when you define the repository
    repositories {
        ivy {
            url = uri("http://repo.mycompany.com/repo")
            resolve.isDynamicMode = true
        }
    }

    // Can use a rule instead to enable (or disable) dynamic resolve mode for all repositories
    repositories.withType<IvyArtifactRepository> {
        resolve.isDynamicMode = true
    }

build.gradle

    // Can enable dynamic resolve mode when you define the repository
    repositories {
        ivy {
            url = "http://repo.mycompany.com/repo"
            resolve.dynamicMode = true
        }
    }

    // Can use a rule instead to enable (or disable) dynamic resolve mode for all repositories
    repositories.withType(IvyArtifactRepository) {
        resolve.dynamicMode = true
    }

| Dynamic resolve mode is only available for Gradle’s Ivy repositories. It is not available for Maven repositories, or custom Ivy `DependencyResolver` implementations.