CLI gets confused when api host has path prefix missing from ssh host

Checklist

  • I'm using the latest version of the extension (Run glab --version)
    • Extension version: glab 1.82.0 (b932a8d8)
  • Operating system and version: Darwin 24.6.0 arm64
  • Gitlab.com or self-managed instance? Self-managed instance
  • GitLab version (if self-managed): N/A for bug reproduction (applies to any self-managed with separate git SSH host)
  • I have performed glab auth status to check for authentication issues
  • Run the command in debug mode (like DEBUG=true glab mr list) and attach any useful output

Summary

Repository URL parsing fails when a self-managed GitLab instance uses an api_host containing a subdirectory (e.g., gitlab.example.com/gitlab) but the git SSH host is different (e.g., git.ssh.example.com). The parsed repository path incorrectly includes the subdirectory prefix.

Environment

  • OS: Darwin 24.6.0 arm64
  • SHELL: /bin/zsh
  • TERM: xterm-ghostty
  • GLAB: glab 1.82.0 (b932a8d8)

Other: Configuration uses separate git SSH host with api_host subdirectory pattern

Steps to reproduce

  1. Create a glab config for a self-managed instance with separate git and API hosts:
hosts:
  git.ssh.example.com:
    token: YOUR_TOKEN
    api_host: gitlab.example.com/subdir
  1. Clone a repository using the git SSH URL:
git clone ssh://git@git.ssh.example.com/group/project.git
cd project
  1. Run a glab command:
glab mr list
  1. Check git config to observe cached repository resolution:
git config --list | grep glab-resolved

What is the current bug behavior?

The repository path is parsed with the subdirectory incorrectly included in the final result.

Expected cached value:

remote.origin.glab-resolved=base:group/project

Actual buggy cached value:

remote.origin.glab-resolved=base:subdir/group/project

The code in internal/glrepo/repo.go:FromURL() attempts to strip the /subdir subdirectory from the git URL path, but since the subdirectory doesn't exist in the actual git remote URL (/group/project), the strip operation fails silently and the subdirectory prefix ends up in the final parsed path.

What is the expected _correct_behavior?

The repository information should be correctly extracted as:

  • Full name: group/project
  • Host: git.ssh.example.com
  • Cached config: remote.origin.glab-resolved=base:group/project

The api_host subdirectory should only be stripped from paths that actually contain it. When the git URL path doesn't contain the subdirectory (because git SSH host differs from API host), the path should be used as-is.

Relevant logs and/or screenshots

Configuration scenario:

  • api_host: gitlab.example.com/subdir (contains subdirectory /subdir)
  • Git SSH host: git.ssh.example.com (different from API host)
  • Git URL: ssh://git@git.ssh.example.com/group/project.git
  • URL path: /group/project (does NOT contain /subdir)

The buggy code incorrectly handles this case, resulting in the subdirectory appearing in the parsed path.

Possible fixes

In internal/glrepo/repo.go lines 181-187, change from strings.TrimSuffix() to strings.TrimPrefix():

if _, subdir, ok := strings.Cut(apiHost, "/"); ok {
    urlPath = strings.TrimPrefix(u.Path, "/"+subdir)
}

This safely handles both cases:

  • Path contains the subdirectory: strips it
  • Path doesn't contain the subdirectory: returns path unchanged
Assignee Loading
Time tracking Loading