Merge branch 'jn/fsck-ident'
[git] / git_remote_helpers / git / repo.py
1 import os
2 import subprocess
3
4 def 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
16 def is_remote(url):
17     """Checks whether the specified value is a remote url.
18     """
19
20     prefixes = ["http", "file", "git"]
21
22     return any(url.startswith(i) for i in prefixes)
23
24 class GitRepo(object):
25     """Repo object representing a repo.
26     """
27
28     def __init__(self, path):
29         """Initializes a new repo at the given path.
30         """
31
32         self.path = path
33         self.head = None
34         self.revmap = {}
35         self.local = not is_remote(self.path)
36
37         if(self.path.endswith('.git')):
38             self.gitpath = self.path
39         else:
40             self.gitpath = os.path.join(self.path, '.git')
41
42         if self.local and not os.path.exists(self.gitpath):
43             os.makedirs(self.gitpath)
44
45     def get_revs(self):
46         """Fetches all revs from the remote.
47         """
48
49         args = ["git", "ls-remote", self.gitpath]
50         path = ".cached_revs"
51         ofile = open(path, "w")
52
53         subprocess.check_call(args, stdout=ofile)
54         output = open(path).readlines()
55         self.revmap = dict(sanitize(i) for i in output)
56         if "HEAD" in self.revmap:
57             del self.revmap["HEAD"]
58         self.revs = self.revmap.keys()
59         ofile.close()
60
61     def get_head(self):
62         """Determines the head of a local repo.
63         """
64
65         if not self.local:
66             return
67
68         path = os.path.join(self.gitpath, "HEAD")
69         head = open(path).readline()
70         self.head, _ = sanitize(head, ' ')