@@ -430,3 +430,57 @@ class GitURL(GitPipURL, GitBaseURL, URLProtocol, SkipDefaultFieldsReprMixin):
430430 matchers = MatcherRegistry = MatcherRegistry (
431431 _matchers = {m .label : m for m in [* DEFAULT_MATCHERS , * PIP_DEFAULT_MATCHERS ]}
432432 )
433+
434+ def to_url (self ) -> str :
435+ """Return a ``git(1)``-compatible URL. Can be used with ``git clone``.
436+
437+ Examples
438+ --------
439+
440+ SSH style URL:
441+ >>> git_location = GitURL(url='git@github.com:vcs-python/libvcs.git')
442+
443+ >>> git_location.path = 'vcs-python/vcspull'
444+
445+ >>> git_location.to_url()
446+ 'git@github.com:vcs-python/vcspull.git'
447+
448+ HTTPs URL:
449+
450+ >>> git_location = GitURL(url='https://github.com/vcs-python/libvcs.git')
451+
452+ >>> git_location.path = 'vcs-python/vcspull'
453+
454+ >>> git_location.to_url()
455+ 'https://github.com/vcs-python/vcspull.git'
456+
457+ Switch them to gitlab:
458+
459+ >>> git_location.hostname = 'gitlab.com'
460+
461+ >>> git_location.to_url()
462+ 'https://gitlab.com/vcs-python/vcspull.git'
463+
464+ Pip style URL, thanks to this class implementing :class:`GitPipURL`:
465+
466+ >>> git_location = GitURL(url='git+ssh://git@github.com/vcs-python/libvcs')
467+
468+ >>> git_location.hostname = 'gitlab.com'
469+
470+ >>> git_location.to_url()
471+ 'git+ssh://gitlab.com/vcs-python/libvcs'
472+
473+ See also
474+ --------
475+
476+ :meth:`GitBaseURL.to_url`, :meth:`GitPipURL.to_url`
477+ """
478+ if self .scheme is not None :
479+ parts = [self .scheme , "://" , self .hostname , "/" , self .path ]
480+ else :
481+ parts = [self .user or "git" , "@" , self .hostname , ":" , self .path ]
482+
483+ if self .suffix :
484+ parts .append (self .suffix )
485+
486+ return "" .join (part for part in parts if isinstance (part , str ))
0 commit comments