write_index: optionally allow broken null sha1s
[git.git] / git_remote_helpers / git / repo.py
blobacbf8d7785e2253777456f8910e2352992dda474
1 import os
2 import subprocess
4 from git_remote_helpers.util import check_call
7 def sanitize(rev, sep='\t'):
8 """Converts a for-each-ref line to a name/value pair.
9 """
11 splitrev = rev.split(sep)
12 branchval = splitrev[0]
13 branchname = splitrev[1].strip()
14 if branchname.startswith("refs/heads/"):
15 branchname = branchname[11:]
17 return branchname, branchval
19 def is_remote(url):
20 """Checks whether the specified value is a remote url.
21 """
23 prefixes = ["http", "file", "git"]
25 for prefix in prefixes:
26 if url.startswith(prefix):
27 return True
28 return False
30 class GitRepo(object):
31 """Repo object representing a repo.
32 """
34 def __init__(self, path):
35 """Initializes a new repo at the given path.
36 """
38 self.path = path
39 self.head = None
40 self.revmap = {}
41 self.local = not is_remote(self.path)
43 if(self.path.endswith('.git')):
44 self.gitpath = self.path
45 else:
46 self.gitpath = os.path.join(self.path, '.git')
48 if self.local and not os.path.exists(self.gitpath):
49 os.makedirs(self.gitpath)
51 def get_revs(self):
52 """Fetches all revs from the remote.
53 """
55 args = ["git", "ls-remote", self.gitpath]
56 path = ".cached_revs"
57 ofile = open(path, "w")
59 check_call(args, stdout=ofile)
60 output = open(path).readlines()
61 self.revmap = dict(sanitize(i) for i in output)
62 if "HEAD" in self.revmap:
63 del self.revmap["HEAD"]
64 self.revs = self.revmap.keys()
65 ofile.close()
67 def get_head(self):
68 """Determines the head of a local repo.
69 """
71 if not self.local:
72 return
74 path = os.path.join(self.gitpath, "HEAD")
75 head = open(path).readline()
76 self.head, _ = sanitize(head, ' ')