azure-devopsazure-devops-rest-api

Get the branch name from tag using Azure DevOps api


Using the Azure DevOps API, can someone help me get the actual branch name if I have the tag associated with it?

Thanks in advance.

So far, I get the API that gives all the tags for a particular repo, but this does not give me any branch information associated with it:

https://dev.azure.com/{{organization}}/{{project}}/_apis/git/repositories/{{repository_id}}/refs?filter=tags/&api-version=6.0

Solution

  • There isn’t such REST API to get branch name by a tag or commit. In the Azure DevOps, Tags are created based on the commit id, and a commit or tag can belong more than one branches. Let’s illustrate by below graph:

    A---B---E---F master
         \     /
          C---D   dev
    

    This is a branch structure with master and dev branch. And dev branch merge into master with commit F. If you want to get the branch name based on commit D, you will get two branch names. Commit D belongs to two branch: dev (first parent) and master (second parent).

    We can get the branch name via condition and multiple REST APIs, also we could get the branch name via git cmd.

    a. List all tags and get the objectId.

    GET https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories/{repo ID}/refs?filter=tags/&api-version=6.0
    

    b. Get the tag info and commit ID via objectId

    Note: the field taggedObject.objectId is commit ID

    GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/annotatedtags/{objectId}?api-version=6.0-preview.1
    

    Workaround 1

    Now we could get the commit details and get the branch name(s) contain the given commit, we can use git command:

    git branch --contains <commit>
    

    Workaround 2

    We could list all commits info on a branch via this API

    GET https://dev.azure.com/{Org name}/_apis/git/repositories/{repositoryId}/commits?searchCriteria.itemVersion.version={branch name}&api-version=6.0
    

    And now, we get commit id which contain the tag and all commit ID on a branch, add if{} or eq() to check it, if it return True, we could know this branch contain the tag

    Update1

    My test repo contains branch main and test01, the branch main contains the tag Tag01, the branch test01 contains the tag Tag01 and tag02

    Power shell script:

    $ListAllTagsURL="https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories/{Repo ID}/refs?filter=tags/&api-version=6.0"
    $PAT="{PAT}"
    $base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($PAT)"))
    
    $ListAllTags = Invoke-RestMethod -Uri $ListAllTagsURL -Headers @{Authorization = "Basic {0}" -f $base64AuthInfo} -Method get
    
    #List all tags name
    #write-host $ListAllTags.value.name
    foreach($Tag in $ListAllTags.value){
        if($Tag.name -eq "{tag name such as refs/tags/Tag01}"){
            $objectId = $Tag.objectId
            $TagName = $Tag.name
        }
    }
    
    #Get tag details and commit ID
    $TagURL="https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories/{Repo ID}/annotatedtags/$($objectId)?api-version=6.0-preview.1"
    $TagInfo = Invoke-RestMethod -Uri $TagURL -Headers @{Authorization = "Basic {0}" -f $base64AuthInfo} -Method get
    $TagCommitID = $TagInfo.taggedObject.objectId
    #write-host $TagCommitID 
    
    
    #List all branch
    $url="https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories/{Repo ID}/refs?filter=heads&api-version=6.1-preview.1"
    $BranchInfo = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic {0}" -f $base64AuthInfo} -Method get
    foreach($Branch in $BranchInfo.value){
    #write-host $Branch.name
    $BranchName = $Branch.name.split("/",3)[-1]
    #write-host $BranchName
    
    #List all commit ID via Branch Name
    $BranchDetailUrl="https://dev.azure.com/v-viliu/_apis/git/repositories/{Repo ID}/commits?searchCriteria.itemVersion.version=$($BranchName)&api-version=6.0"
    $BranchDetailInfo = Invoke-RestMethod -Uri $BranchDetailUrl -Headers @{Authorization = "Basic {0}" -f $base64AuthInfo} -Method get
    #write-host $BranchDetailInfo.value.commitId
    
    foreach($CommitID in $BranchDetailInfo.value.commitId){
        If($CommitID -eq $TagCommitID){
            write-host $BranchName "Contain this tag" $TagName
        }
    
    }
    
    }
    

    Result:

    enter image description here