Merge branch 'jk/receive-pack-deadlocks-with-early-failure'
[git] / git_remote_helpers / git / repo.py
1 import os
2 import subprocess
3
4 from git_remote_helpers.util import check_call
5
6
7 def sanitize(rev, sep='\t'):
8     """Converts a for-each-ref line to a name/value pair.
9     """
10
11     splitrev = rev.split(sep)
12     branchval = splitrev[0]
13     branchname = splitrev[1].strip()
14     if branchname.startswith("refs/heads/"):
15         branchname = branchname[11:]
16
17     return branchname, branchval
18
19 def is_remote(url):
20     """Checks whether the specified value is a remote url.
21     """
22
23     prefixes = ["http", "file", "git"]
24
25     for prefix in prefixes:
26         if url.startswith(prefix):
27             return True
28     return False
29
30 class GitRepo(object):
31     """Repo object representing a repo.
32     """
33
34     def __init__(self, path):
35         """Initializes a new repo at the given path.
36         """
37
38         self.path = path
39         self.head = None
40         self.revmap = {}
41         self.local = not is_remote(self.path)
42
43         if(self.path.endswith('.git')):
44             self.gitpath = self.path
45         else:
46             self.gitpath = os.path.join(self.path, '.git')
47
48         if self.local and not os.path.exists(self.gitpath):
49             os.makedirs(self.gitpath)
50
51     def get_revs(self):
52         """Fetches all revs from the remote.
53         """
54
55         args = ["git", "ls-remote", self.gitpath]
56         path = ".cached_revs"
57         ofile = open(path, "w")
58
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()
66
67     def get_head(self):
68         """Determines the head of a local repo.
69         """
70
71         if not self.local:
72             return
73
74         path = os.path.join(self.gitpath, "HEAD")
75         head = open(path).readline()
76         self.head, _ = sanitize(head, ' ')