git-url 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #!/usr/bin/env python3
  2. import re
  3. import subprocess
  4. import sys
  5. import urllib.parse
  6. def oneliner(*args):
  7. return subprocess.check_output(args, universal_newlines=True).strip()
  8. commit = oneliner('git', 'rev-parse', 'HEAD')
  9. local_branch = oneliner('git', 'name-rev', '--name-only', 'HEAD')
  10. tag = None
  11. if local_branch.startswith('tags/'):
  12. tag = local_branch[5:]
  13. if tag.endswith('^0'):
  14. tag = tag[:-2]
  15. remote_url = oneliner('git', 'config', 'remote.origin.url')
  16. else:
  17. tracking_branch = oneliner('git', 'config', 'branch.%s.merge' % local_branch)
  18. if tracking_branch.startswith('refs/heads/'):
  19. tracking_branch = tracking_branch[len('refs/heads/'):]
  20. else:
  21. raise Exception("can't handle " + tracking_branch)
  22. tracking_remote = oneliner('git', 'config', 'branch.%s.remote' % local_branch)
  23. remote_url = oneliner('git', 'config', 'remote.%s.url' % tracking_remote)
  24. relpath = oneliner('git', 'rev-parse', '--show-prefix')[:-1]
  25. remote_url = re.sub(r'^(.+@.+):(.+)$', r'ssh://\1/\2', remote_url)
  26. if remote_url.endswith('.git'):
  27. remote_url = remote_url[:-len('.git')]
  28. parsed = urllib.parse.urlparse(remote_url)
  29. hostname = parsed.hostname
  30. obj_type = 'tree'
  31. if len(sys.argv) == 2:
  32. obj_type = 'blob'
  33. repo_url = urllib.parse.urlunparse(('https', hostname, parsed.path, '', '', ''))
  34. def url_for(treeish):
  35. dir_url = '%s/%s/%s' % (repo_url, obj_type, treeish)
  36. if relpath:
  37. dir_url = '%s/%s' % (dir_url, relpath)
  38. if len(sys.argv) == 2:
  39. return '%s/%s' % (dir_url, sys.argv[1])
  40. else:
  41. return dir_url
  42. if tag is not None:
  43. print(url_for(tag))
  44. else:
  45. print(url_for(tracking_branch))
  46. print(url_for(commit))