A new feature was added to VSTS Build recently called Path Filters (look under Git filters). Path filters allow the build definition author to decide whether to trigger a build based on paths of modified files in any given commit.

Path filters are specified as part of a continuous integration trigger. By default there are no path filters explicitly configured, however there is an implicit include of all files in the repository.

When entering a path you need to provide a leading forward slash (e.g. /docs) (this has tripped a few folks up).

The screenshot above actually reveals another trap that some people fall into when they first start using path filters. As soon as you specify an explicit path filter (include or exclude) the implicit include of the entire repository no longer applies to the trigger.

Let's work through a scenario with the code structure below. This is a simple repository with a /docs folder and a /src folder. There is a README.md file hanging off the root, and an app.js file in the /src folder along with an index.md file in the /docs folder.

First, I commit a change to the file src/app.js in the repository and push it to the remote in VSTS.

Because I've added an Exclude rule on /docs in the path filters in the continuous integration trigger you might think that the commit will kick-off a build (since the change was to src/app.js). But remember that as soon as you add a rule, the implicit Include on the root of the repository is removed. Therefore no build is queued.

If I wanted to exclude changes from a single path, I would have to include the root, and also exclude /docs.

With the new path filter rules in place, performing the same commit results in a build occurring.

Any commit in the /docs folder will not trigger a build. The order of the rules are not significant, so if you specify a trailing include of the root directory it will not override excludes added higher in the list. However, rules with a more specific path override less specific rules.

To illustrate how the rules are interpreted consider the following table. Here we are excluding all files in the /docs folder plus the README.md file off the root.

Exclude /README.md
Exclude /docs
Include /

The explicit Include rule is also added so that other file changes in a commit trigger a build. The order of the rules does not matter, and the earlier rules are applied because they are more specific than the Include at the root.

Path filters are such a useful feature, especially if you have a single repository containing source files for multiple components that build separately, or where you simply want to change files that don't require a rebuild.

Hopefully this helps some people trying to understand the way the Include/Exclude rules for path filters are processed by VSTS Build.