Skip to content

Branch and tag with same name cause multiple problems

Summary

Pushing a branch with the same name as a tag causes multiple problems throughout the GitLab application. I will list them here, and we can open additional, specific issues, as needed.

Some of these are simple ambiguity problems, where the UI isn't expecting the possibility of a branch and a tag with the same name, and the application simply has to "pick one":

  • commits view (example): It chose the tag, but check out the branch/tag dropdown: Commits view branch/tag dropdown

CI concerns

But there are bigger problems in CI:

  • GitLab CI thinks a job is for a tag, when it is triggered for a branch with the same name as a tag (on a non-tagged commit!):
    • The icon in the jobs view is wrong:
      Non-tagged job showing as tag
    • CI_COMMIT_TAG is set in the job environment (example) when it should not be. (Look carefully, c8af1faf is not a tagged commit, and never was)
    • In the response of the get single pipeline API, the tag attribute is set to true when it should be false
    • The list pipelines API, when called with scope=tags, is horribly wrong: It only returns these "false-tag" pipelines and omits correct "tag" pipelines
    • only: tags #20526 (comment 322819828)

      Worth noting, CI pipelines marked as only: tags are also triggered when pushing to the branch with the same name (GitLab 12.10.0-pre).

Steps to reproduce

Set up a repository:

#!/bin/bash
set -e
set -v

repo="ambiguous-ref-test"
file="foo.txt"
ref="v1.0"

# Create git repo
git init $repo
cd $repo

# Setup CI
cat >.gitlab-ci.yml <<EOF
image: debian:latest
build:
  script:
    - 'echo "CI_COMMIT_REF_NAME: \$CI_COMMIT_REF_NAME"'
    - 'echo "CI_COMMIT_SHA:      \$CI_COMMIT_SHA"'
    - 'echo "CI_COMMIT_TAG:      \$CI_COMMIT_TAG"'
    - 'echo "CI_COMMIT_TITLE:    \$CI_COMMIT_TITLE"'
EOF
git add .gitlab-ci.yml
git commit -m 'Setup CI'

# Create and tag a commit with some name
echo 'first' > $file
git add $file
git commit -m 'First commit'
git tag $ref

# Create a branch with the same name and switch to it
git branch $ref
git checkout $ref

# Add a commit to that branch, to distinguish
echo 'second' > $file
git add $file
git commit -m 'Second commit'

# Done
git log --oneline

Then:

  • git push origin master
    • Creates a "normal" job, as expected
  • git push origin tags/v1.0
    • Creates a "tag" job as expected
  • git push origin refs/heads/v1.0
    • Creates a "false tag" job

You can run this script (which uses python-gitlab) to see the bad API results:

#!/usr/bin/env python3
# Setup:
# - Create a project
# - Push a commit to master
# - Tag that commit as v1.0
# - Push another commit to master
# - Create a branch named v1.0 off of master (via the web UI, if that matters)
# - Run this script and see incorrect results
from gitlab import Gitlab

PROJ_NAME = 'JonathonReinhart/ambiguous-ref-test'
AMBIGUOUS_REF = 'v1.0'

g = Gitlab.from_config()
prj = g.projects.get(PROJ_NAME)

def dump(pipelines):
    # Ugh, pipelines.list() returns a ProjectPipeline but with some attributes missing
    for p in [prj.pipelines.get(p.id) for p in pipelines]:
        print(f"  id={p.id}, commit={p.sha}, tag={p.tag}")

###
# Get pipelines for ambiguous ref (tag and branch with same name)
testref = AMBIGUOUS_REF
print(f"Pipelines for ref={testref!r}:")
dump(prj.pipelines.list(ref=testref))

###
# Get pipelines of scope 'tags'
testscope = 'tags'
print(f"Pipelines for scope={testscope!r}:")
dump(prj.pipelines.list(scope=testscope))

Output:

Pipelines for ref='v1.0':
  id=151107863, commit=c8af1faf3d62c7f95da93f93c1885385cd3cf604, tag=True
  id=151107664, commit=aa5e3925d362db3d3ae69d6ed5f80326e6105f73, tag=True
Pipelines for scope='tags':
  id=151107863, commit=c8af1faf3d62c7f95da93f93c1885385cd3cf604, tag=True

Example Project

https://gitlab.com/JonathonReinhart/ambiguous-ref-test

Edited by Mark Nuzzo