Function: projectile--normalize-repo-url

projectile--normalize-repo-url is a byte-compiled function defined in projectile.el.

Signature

(projectile--normalize-repo-url URL)

Documentation

Return a canonical identity for the remote URL, or nil when there's none.

One repository can be addressed in several ways - git@host:owner/repo.git, https://host/owner/repo, ssh://git@host:22/owner/repo/ - and all of them have to compare equal for two clones of it to be recognized as checkouts of the same thing. The identity is HOST/PATH without the user, port, trailing slashes or .git suffix, downcased because hosts are case-insensitive and so, in practice, are the forges' paths.

A URL that addresses a local repository (a bare path, or a file:// URL) normalizes to that path, left in its original case since local file systems are not reliably case-insensitive.

Source Code

;; Defined in ~/.emacs.d/elpa/projectile-20260820.1509/projectile.el
(defun projectile--normalize-repo-url (url)
  "Return a canonical identity for the remote URL, or nil when there's none.

One repository can be addressed in several ways - `git@host:owner/repo.git',
`https://host/owner/repo', `ssh://git@host:22/owner/repo/' - and all of
them have to compare equal for two clones of it to be recognized as
checkouts of the same thing.  The identity is `HOST/PATH' without the
user, port, trailing slashes or `.git' suffix, downcased because hosts
are case-insensitive and so, in practice, are the forges' paths.

A URL that addresses a local repository (a bare path, or a `file://'
URL) normalizes to that path, left in its original case since local file
systems are not reliably case-insensitive."
  (when (and url (not (string-blank-p url)))
    (let ((url (string-trim url)))
      (cond
       ;; A `file://' URL addresses a local repository, same as a bare path.
       ((string-prefix-p "file:///" url)
        (projectile--normalize-repo-path (string-remove-prefix "file://" url)))
       ((or (string-match projectile--repo-url-scheme-regexp url)
            ;; The scp-like syntax has no scheme, so anything carrying one
            ;; has already had its chance above and isn't a host:path.
            (and (not (string-match-p "://" url))
                 (string-match projectile--repo-url-scp-regexp url)))
        (downcase (concat (match-string 1 url) "/"
                          (projectile--normalize-repo-path
                           (replace-regexp-in-string "\\`/+" "" (match-string 2 url))))))
       (t (projectile--normalize-repo-path (expand-file-name url)))))))