Skip to content

Relative submodule link to a nested project fails to resolve

Summary

A submodule with a relative link to a project in a nested group does not resolve correctly.

Steps to reproduce

  1. Create groups A and A/B and projects A/B/project1 and A/B/project2
  2. Add project1 as a submodule to project2 with a relative link as described in the documentation
  3. Open project2 in the web interface and try to navigate to project1

Example Project

bugtestA/bugtestB/project2 links to bugtestA/bugtestB/project1 but the relative link fails to resolve correctly.

bugtestA/project2 is a fork one level higher that suggests the issue occurs whether the containing project is nested or not.

What is the current bug behavior?

The submodule link points to the current page instead of the page for the submodule's project and the commit contains no link at all, which is the usual behavior for a bad submodule link.

Relative links to a non-nested group appears to still be functional (ex: A/project2 -> A/project1), on our 9.5.1-ee instances, at least.

What is the expected correct behavior?

The link for the submodule should point to the submoudle's project and the commit should point to the specific commit in the subproject.

Relevant logs and/or screenshots

Submodule configuration from documentation:

[submodule "project"]
  path = project
  url = ../../group/project.git

.gitmodules contents from test project:

[submodule "project1"]
	path = project1
	url = ../../bugtestA/bugtestB/project1.git

Snippet from submodule_helper.rb that seems to suggest this is the correct format:

  def relative_self_links(url, commit)
    url.rstrip!
    # Map relative links to a namespace and project
    # For example:
    # ../bar.git -> same namespace, repo bar
    # ../foo/bar.git -> namespace foo, repo bar
    # ../../foo/bar/baz.git -> namespace bar, repo baz
    components = url.split('/')
    base = components.pop.gsub(/.git$/, '')
    namespace = components.pop.gsub(/^\.\.$/, '')

    if namespace.empty?
      namespace = @project.namespace.full_path
    end

    [
      namespace_project_path(namespace, base),
      namespace_project_tree_path(namespace, base, commit)
    ]
  end

Output of checks

N/A

This bug happens on GitLab.com (and our 9.5.1-ee instances)

Possible fixes

submodule_helper.rb is probably a good place to start. It may be the namespace resolution in relative_self_links, I'm not sure how namespace_project_path and namespace_project_path_tree function, but the namespace and base for ../../bugtestA/bugtestB/project1.git come out to project1 and bugtestB, and I'm not how or if bugtestA/bugtestB can be resolved from only bugtestB.