If you are within the context of a CI/CD tool, you may run into the scenario where a newly applied git tag has initiated a pipeline action.
Depending on the tool, the pipeline will provide you with either a SHA of the last commit and/or the tag name – but not the branch where the tag was applied. This is because a git tag is tied to a commit, not a specific branch.
However, if the tag was applied as the latest commit on a branch (a likely scenario for triggering a pipeline), then you can use the following commands to resolve back to a branch name.
# pipeline may already provide the git SHA # but if not, you can lookup by tag name tag_name=v1.0.0 tag_sha=$(git rev-list -1 $tag_name) # find branch name git for-each-ref | grep ^$tag_sha | grep origin | head -n1 | sed "s/.*\///"
This will NOT work if:
- There has been a more recent commit to this branch
- You have a shallow fetch/clone, that does not have the branch/tag history
GitLab pipeline
The CI_COMMIT_SHA and CI_COMMIT_TAG are part of the predefined variables. But you will need to set the variable GIT_DEPTH=0 or the project CI/CD settings to “git clone” to see the origin refs, because by default it only does a shallow git fetch.
simple-resolve-branch-on-tag: rules: - if: $CI_COMMIT_TAG stage: .pre # small alpine image that has git/grep/sed installed image: registry.gitlab.com/gitlab-pipeline-helpers/docker-alpine-with-envsubst:1.0.6 variables: GIT_DEPTH: 0 script: | echo "CI_COMMIT_TAG = $CI_COMMIT_TAG" echo "CI_COMMIT_SHA = $CI_COMMIT_SHA" echo "CI_COMMIT_SHORT_SHA = $CI_COMMIT_SHORT_SHA" echo "candidates for branch name" git for-each-ref | grep ^$CI_COMMIT_SHA | grep origin | grep -v HEAD | head -n1 | sed "s/.*\///" branch_name=$(git for-each-ref | grep ^$CI_COMMIT_SHA | grep origin | grep -v HEAD | head -n1 | sed "s/.*\///") echo tag $CI_COMMIT_TAG is on branch $branch_name
Here is a full example .gitlab-ci.yml.
The docker-alpine-with-envsubst image is one I built using an alpine-based image that ensures I have the git, grep, and sed utilties (~36Mb).
GitHub Action
The GITHUB_SHA and GITHUB_REF_NAME are part of the predefined variables. But you will need to set the ‘fetch-depth’ of actions/checkout to 0 to see the origin refs, because by default it only does a shallow git fetch.
... - name: Check out repository code uses: actions/checkout@v4 with: fetch-depth: 0 ... - name: calculate branch name IF tag if: github.ref_type == 'tag' run: | echo "GITHUB_REF_NAME = $GITHUB_REF_NAME" echo "GITHUB_SHA = $GITHUB_SHA" branch_name=`git for-each-ref | grep ^$GITHUB_SHA | grep origin | grep -v HEAD | head -n1 | sed "s/.*\///"` echo tag $GITHUB_REF_NAME is on branch $branch_name
Here is a full example, github-actions-buildOCI.yml
REFERENCES
stackoverflow, finding source branch when creating tag in gitlab using GitLab workflows
github, predefined GitHub Action variables
stackoverflow, exhaustive search on tags for every branch
Gitlab issue, checking for empty variables and non-existent variables in pipeline
GitLab source, docker-alpine-with-envsubst image
NOTES
‘show-ref’ only works for lightweight tags (not annotated)
lightweight_tag_name=v1.0.0 lightweight_tag_sha=$(git show-ref --dereference $tag_name | head -n1 | cut -d' ' -f1)