git_remote_helpers / git / repo.pyon commit pack-object: tolerate broken packs that have duplicated objects (f63c79d)
   1import os
   2import subprocess
   3
   4def sanitize(rev, sep='\t'):
   5    """Converts a for-each-ref line to a name/value pair.
   6    """
   7
   8    splitrev = rev.split(sep)
   9    branchval = splitrev[0]
  10    branchname = splitrev[1].strip()
  11    if branchname.startswith("refs/heads/"):
  12        branchname = branchname[11:]
  13
  14    return branchname, branchval
  15
  16def is_remote(url):
  17    """Checks whether the specified value is a remote url.
  18    """
  19
  20    prefixes = ["http", "file", "git"]
  21
  22    for prefix in prefixes:
  23        if url.startswith(prefix):
  24            return True
  25    return False
  26
  27class GitRepo(object):
  28    """Repo object representing a repo.
  29    """
  30
  31    def __init__(self, path):
  32        """Initializes a new repo at the given path.
  33        """
  34
  35        self.path = path
  36        self.head = None
  37        self.revmap = {}
  38        self.local = not is_remote(self.path)
  39
  40        if(self.path.endswith('.git')):
  41            self.gitpath = self.path
  42        else:
  43            self.gitpath = os.path.join(self.path, '.git')
  44
  45        if self.local and not os.path.exists(self.gitpath):
  46            os.makedirs(self.gitpath)
  47
  48    def get_revs(self):
  49        """Fetches all revs from the remote.
  50        """
  51
  52        args = ["git", "ls-remote", self.gitpath]
  53        path = ".cached_revs"
  54        ofile = open(path, "w")
  55
  56        child = subprocess.Popen(args, stdout=ofile)
  57        if child.wait() != 0:
  58            raise CalledProcessError
  59        output = open(path).readlines()
  60        self.revmap = dict(sanitize(i) for i in output)
  61        if "HEAD" in self.revmap:
  62            del self.revmap["HEAD"]
  63        self.revs = self.revmap.keys()
  64        ofile.close()
  65
  66    def get_head(self):
  67        """Determines the head of a local repo.
  68        """
  69
  70        if not self.local:
  71            return
  72
  73        path = os.path.join(self.gitpath, "HEAD")
  74        head = open(path).readline()
  75        self.head, _ = sanitize(head, ' ')