Getting a Branch Name Containing a Slash in Azure DevOps: Tips and Tricks

If you are examining several repositories, you can access certain information about the self repository through Predefined variables. However, when utilizing multi-repo triggers, some of these variables contain data about the repository that initiated the trigger. To resolve this, you can generate a bash script that assigns a brief branch name to a variable.

Question:

There are two variables provided by
Azure Devops
that give details about the name of the current git branch. These variables are identified as

$(Build.SourceBranchName)

and

$(Build.SourceBranch)

.

The complete branch reference can be found in

SourceBranch

, whereas

SourceBranchName

should only have the abbreviated branch name.

Regrettably, the behavior becomes unpredictable when a slash (

/

) is present in the branch name.

+---------------------------------------------------------------------------------------------------------+
| Situation                     | Git branch name  | Build.SourceBranch          | Build.SourceBranchName |
|---------------------------------------------------------------------------------------------------------|
| branch name contains no slash | mybranch         | refs/heads/mybranch         | mybranch               |
| branch name contains slash    | release/mybranch | refs/heads/release/mybranch | mybranch               |
+---------------------------------------------------------------------------------------------------------+

According to Azure DevOps documentation, the section of the branch name preceding the slash is not included in the name of the branch. This was confirmed by a colleague.

The final segment of the ref indicates the Git repo branch or
pull request
. For instance, if the ref is refs/heads/master, then the final segment is master. Similarly, if the ref is refs/heads/feature/tools, then the final segment is tools.

I am uncertain about the usefulness of this behavior. The branch name needs to contain a slash for me to checkout the branch. However, removing the part before the slash could lead to confusion about the actual path, as the name might be ambiguous.

Is there an easy way to obtain the branch name with a slash included, or should I always use the full ref for safety?


Solution 1:

My scripts invariably incorporate

Build.SourceBranch

. By assigning it to a new variable and eliminating

refs/heads/

from the outset, I solely employ it for CI and PR.

  1. When working with PowerShell, I utilize the

    Build.SourceBranch

    variable, excluding

    refs/heads

    .

The first line assigns the value of “$(Build.SourceBranch)” to the variable $branchSource. Then, the second line removes the “refs/heads/” prefix from the string stored in $branchSource variable, and saves the result in $branchSourcePath.

  1. To create PRs, I utilize the

    System.PullRequest.SourceBranch

    variable instead of

    refs/heads

    as

    Build.SourceBranch

    already stores the remote PR’s path. The process of substitution remains unchanged, only the appropriate variable needs to be used.

The value of the variable “$branchSource” is determined by “$(System.PullRequest.SourceBranch)”.
“$branchSourcePath” is created by removing the “refs/heads/” substring from the value of “$branchSource”.


Solution 2:


Utilize the

System.PullRequest.SourceBranch

and

System.PullRequest.TargetBranch

variables when constructing on a PR.

The branch that the pull request is targeting can be accessed through System.PullRequest.TargetBranch.

The pull request’s intended branch, illustrated by

refs/heads/master

, initializes the variable only in cases where the build is triggered by a Git PR impacted by a branch policy.

Use Predefined
Build Variables

Additionally, if you require the use of a full or abbreviated path, it is possible to create a personalized variable that suits your specific needs.

Generate an
Bash script
statement to assign the variable with the name of the shorter branch.

# Bash script
BRANCH_NAME=$(echo "$(System.PullRequest.TargetBranch)" | awk -F/ '{print $NF}')
echo "##vso[task.setvariable variable=PullRequest_Target_Branch;]$BRANCH_NAME"

Later in your pipeline, you can make a reference to $(PullRequest_Target_Branch).


Solution 3:

Use this bro

variables:
  BRANCH_NAME: $[replace(variables['Build.SourceBranchName'], 'refs/heads/', '')]

Here’s an example of how to utilize this.

$(BRANCH_NAME)


Solution 4:

There seems to be no adequate solution to this problem.

After conducting some online research, I have compiled information regarding branches and pull requests.

variables:
  ${{ if startsWith(variables['Build.SourceBranch'], 'refs/heads/') }}:
    BRANCH_NAME: $[ replace(variables['Build.SourceBranch'], 'refs/heads/', '') ]
    DOCKER_IMAGE_TAG: $[ replace(replace(variables['Build.SourceBranch'], 'refs/heads/', ''), '/', '_') ]
  ${{ if startsWith(variables['Build.SourceBranch'], 'refs/pull/') }}:
    BRANCH_NAME: $[ replace(variables['System.PullRequest.SourceBranch'], 'refs/heads/', '') ]
    DOCKER_IMAGE_TAG: $[ replace(replace(variables['System.PullRequest.SourceBranch'], 'refs/heads/', ''), '/', '_') ]


BRANCH_NAME

will incorporate the forward slash, resulting in

refs/heads/mybranch

equating to

mybranch

, while

refs/heads/feature/mybranch

will represent

feature/mybranch

.

The reason for including

DOCKER_IMAGE_TAG

was to substitute

/

with

_

for the tags of docker images.

Frequently Asked Questions

Posted in Git