One issue with the solution provided by Shamrai Aleksander is that the set of changes that you would collect by running GetChangesAsync()
in a loop would include changes that have been merged into your pull request from merge commits. As a result, the set of changed files would be much larger than the true set of files changed within the pull request you are analyzing.
You can retrieve the set of files that have been changed only by the selected pull request by using the GetCommitDiffsAsync() method in the .NET client library (this maps to the Get Diff REST API). What's unique about this method/API is that if diffCommonCommit
is true
, it will perform a diff from the "merge base" of the target branch. This avoids the problem of extra files showing up due to merge commits in your pull request.
You will need the commit IDs for the latest commits both your pull request branch and the branch your pull request is targeting. Here is an example of a method that detects if a file with a certain path has been changed in a pull request.
public static async Task<bool> DoesPullRequestChangelistContainPath(
string repositoryId,
GitPullRequest pullRequest,
string path)
{
// Get commit ID for production branch
var productionBranch = await GitClient.GetBranchAsync(
Constants.ProjectName,
repositoryId,
Constants.ProductionBranchName);
var productionBranchCommitId = productionBranch.Commit.CommitId;
// Get commit ID for PR branch
var pullRequestSourceBranchNameWithoutPrefix = pullRequest.SourceRefName.Replace(Constants.AdoBranchPrefix, string.Empty);
var pullRequestBranch = await GitClient.GetBranchAsync(
Constants.ProjectName,
repositoryId,
pullRequestSourceBranchNameWithoutPrefix);
var pullRequestBranchCommitId = pullRequestBranch.Commit.CommitId;
// Get the diff between the merge base of the two branches and the latest commit of the pull request branch.
// This gets us the set of changes between the "squashed" commits of the pull request and the production branch.
var response = await GitClient.GetCommitDiffsAsync(
repositoryId,
diffCommonCommit: true,
baseVersionDescriptor: new GitBaseVersionDescriptor() { Version = productionBranchCommitId, VersionType = GitVersionType.Commit},
targetVersionDescriptor: new GitTargetVersionDescriptor { Version = pullRequestBranchCommitId, VersionType = GitVersionType.Commit });
return response.Changes.Any(change => change?.Item?.Path?.Contains(path) == true);
}