From c08b60b5641d7b8bdb39a4048d1456cba52023a3 Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Wed, 6 May 2026 17:33:38 +0000 Subject: [PATCH] [F] Fix git-switch --- scripts/bin/git-switch | 94 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 11 deletions(-) diff --git a/scripts/bin/git-switch b/scripts/bin/git-switch index 53c444e..9ea1273 100755 --- a/scripts/bin/git-switch +++ b/scripts/bin/git-switch @@ -1,6 +1,69 @@ #!/usr/bin/env python3 -import os import subprocess +from typing import Optional, Tuple +from urllib.parse import urlparse + + +def strip_git_suffix(path: str) -> str: + if path.endswith('.git'): + return path[:-4] + return path + + +def parsed_host(parsed) -> Optional[str]: + if not parsed.hostname: + return None + if parsed.port is not None: + return f'{parsed.hostname}:{parsed.port}' + return parsed.hostname + + +def ssh_url(host: str, repo: str) -> str: + if ':' in host: + return f'ssh://git@{host}/{repo}.git' + return f'git@{host}:{repo}.git' + + +def parse_http_url(url: str) -> Optional[Tuple[str, str]]: + parsed = urlparse(url) + if parsed.scheme not in ('http', 'https'): + return None + + host = parsed_host(parsed) + if host is None: + return None + + repo = strip_git_suffix(parsed.path.lstrip('/')) + if not repo: + return None + return host, repo + + +def parse_ssh_url(url: str) -> Optional[Tuple[str, str]]: + if url.startswith('ssh://'): + parsed = urlparse(url) + host = parsed_host(parsed) + if host is None: + return None + + repo = strip_git_suffix(parsed.path.lstrip('/')) + if not repo: + return None + return host, repo + + if '@' not in url or ':' not in url: + return None + + user_host, repo = url.split(':', 1) + host = user_host.rsplit('@', 1)[-1] + repo = strip_git_suffix(repo) + if repo.startswith('http://') or repo.startswith('https://'): + return parse_http_url(repo) + + if not host or not repo: + return None + return host, repo + print('Checking git repo...') url = subprocess.check_output('git remote get-url origin'.split()).decode('utf-8').strip() @@ -9,18 +72,27 @@ print(f'Current url: {url}') if url.startswith('http'): print('> HTTP git remote detected, switching to SSH') - repo = url.split('github.com/')[-1] - if repo.endswith('.git'): - repo = repo[:-4] + parsed = parse_http_url(url) + if parsed is None: + print('Failed to parse HTTP git remote, exiting') + exit(-1) + + host, repo = parsed print(f'> Repo detected: {repo}') - new_url = f'git@github.com:{repo}.git' - -elif url.startswith('git@'): + new_url = ssh_url(host, repo) + +elif url.startswith('git@') or url.startswith('ssh://'): # git@github.com:hykilpikonna/zshrc.git + # ssh://git@github.com/hykilpikonna/zshrc.git print('> SSH git remote detected, switching to HTTP') - repo = url.split(':')[-1].split('.git')[0] + parsed = parse_ssh_url(url) + if parsed is None: + print('Failed to parse SSH git remote, exiting') + exit(-1) + + host, repo = parsed print(f'> Repo detected: {repo}') - new_url = f'https://github.com/{repo}' + new_url = f'https://{host}/{repo}' else: print('Failed to detect protocol, exiting') @@ -28,5 +100,5 @@ else: print(f'New URL: {new_url}') print('> Setting new url...') -os.system(f'git remote set-url origin {new_url}') -print('> Done!') \ No newline at end of file +subprocess.check_call(['git', 'remote', 'set-url', 'origin', new_url]) +print('> Done!')