Suresh Rajamani
Suresh Rajamani

Reputation: 17

Get Pull Request File Content DIFF using Azure Devops REST Api

I am developing a service hook for Azure Devops Pull Request created event. In this service hook i want to get the files modified in this Pull Request and get the DIFF content details about each file against target branch. It would be better if can able to get raw DIFF of each file similar to github provided or at least which are the lines modified/added/removed using Azure Devops rest api. Currently i used Iteration Changes Api and used the last iteration to get the files list for changes, but the changes response does not have any details about which lines are modified/added/removed in each file. Can you suggest me the api with sample which can use for this requirement.

Upvotes: -2

Views: 97

Answers (1)

Miao Tian-MSFT
Miao Tian-MSFT

Reputation: 5642

There is currently no officially documented Azure Dev API to get a detailed diff of the contents of files modified in a pull request. The current documented Azure DevOps REST API Diffs - Get can only get the list of all modified files on a pull request.

If your projects really need this feature, you can request the feature on Developer Community. This will make it more convenient for the Azure DevOps engineer teams to receive and understand your ideas. And your feedback also could be helpful for improving the Azure DevOps products.

The following is a Workaround for your reference:

We can get the REST API commands that Azure DevOps actually uses by checking the network trace in Developer tools of Microsoft Edge. Please note that since this REST API is not yet documented, it may change one day without notice. It only works with the full permission personal access token.

network trace

The actual API used in Azure DevOps:

POST https://dev.azure.com/{organization}/_apis/Contribution/HierarchyQuery/project/{project}?api-version=5.0-preview.1

Body:

{
    "contributionIds": [
        "ms.vss-code-web.file-diff-data-provider"
    ],
    "dataProviderContext": {
        "properties": {
            "repositoryId": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            "diffParameters": {
                "includeCharDiffs": true,
                "modifiedPath": "$filePath",
                "modifiedVersion": "GC$baseCommitId",
                "originalPath": "$filePath",
                "originalVersion": "GC$targetCommitId",
                "partialDiff": true,
                "forceLoad": false
            }
        }
    }
}

Here is my full test PowerShell script for your reference:

# Replace these variables with your actual values 
$organization = ''
$project = ''
$repositoryId = 'xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
$pullRequestId = '110'
$pat = ''

# Encode PAT for authentication
$encodedPat = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($pat)"))
$headers = @{
    Authorization = "Basic $encodedPat"
}
# Step 1: Get the commits in the Pull Request
$commitsUrl = "https://dev.azure.com/$organization/$project/_apis/git/repositories/$repositoryId/pullRequests/$pullRequestId/commits?api-version=7.1"
$commitsResponse = Invoke-RestMethod -Uri $commitsUrl -Headers $headers
$commits = $commitsResponse.value

# Step 2: Extract the base and target commits
$baseCommitId = $commits[-1].commitId
$targetCommitId = $commits[0].commitId


# Step 3: Get the changes between the base and target commits
$difffilesUrl = "https://dev.azure.com/$organization/$project/_apis/git/repositories/$repositoryId/diffs/commits?baseVersion=$baseCommitId&baseVersionType=commit&targetVersion=$targetCommitId&targetVersionType=commit&api-version=7.1"
$difffilesResponse = Invoke-RestMethod -Uri $diffUrl -Headers $headers
$changes = $diffResponse.changes

# Step 4: Output the difference for each file in the changes
foreach ($change in $changes) {
$filePath = $change.item.path

$body = @"
{
    "contributionIds": [
        "ms.vss-code-web.file-diff-data-provider"
    ],
    "dataProviderContext": {
        "properties": {
            "repositoryId": "$repositoryId",
            "diffParameters": {
                "includeCharDiffs": true,
                "modifiedPath": "$filePath",
                "modifiedVersion": "GC$baseCommitId",
                "originalPath": "$filePath",
                "originalVersion": "GC$targetCommitId",
                "partialDiff": true,
                "forceLoad": false
            }
        }
    }
}
"@

$differUri ="https://dev.azure.com/$organization/_apis/Contribution/HierarchyQuery/project/$($project)?api-version=5.0-preview.1"

$result =Invoke-RestMethod -Uri $differUri -Method "POST" -Headers $headers -ContentType "application/json" -Body $body
$difference=$result.dataProviders.'ms.vss-code-web.file-diff-data-provider'.blocks | ConvertTo-Json -Depth 8

Write-Output "filePath: $filePath : "
Write-Output "$difference"


}


Test result:

ui

result

Upvotes: 0

Related Questions