blob: 98ed1e2f383c47a537c9deda20d9a8125586ea81 [file] [log] [blame]
Mike Frysingerf6013762019-06-13 02:30:51 -04001# -*- coding:utf-8 -*-
Shawn O. Pearced237b692009-04-17 18:49:50 -07002#
3# Copyright (C) 2009 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import os
Mike Frysinger8a11f6f2019-08-27 00:26:15 -040018from repo_trace import Trace
Renaud Paquaybed8b622018-09-27 10:46:58 -070019import platform_utils
Shawn O. Pearced237b692009-04-17 18:49:50 -070020
Zac Livingston9ead97b2017-06-13 08:29:04 -060021HEAD = 'HEAD'
22R_CHANGES = 'refs/changes/'
23R_HEADS = 'refs/heads/'
24R_TAGS = 'refs/tags/'
25R_PUB = 'refs/published/'
26R_M = 'refs/remotes/m/'
Shawn O. Pearced237b692009-04-17 18:49:50 -070027
28
29class GitRefs(object):
30 def __init__(self, gitdir):
31 self._gitdir = gitdir
32 self._phyref = None
33 self._symref = None
34 self._mtime = {}
35
36 @property
37 def all(self):
Shawn O. Pearce0f3dd232009-04-17 20:32:44 -070038 self._EnsureLoaded()
Shawn O. Pearced237b692009-04-17 18:49:50 -070039 return self._phyref
40
41 def get(self, name):
42 try:
43 return self.all[name]
44 except KeyError:
45 return ''
46
Shawn O. Pearcefbcde472009-04-17 20:58:02 -070047 def deleted(self, name):
48 if self._phyref is not None:
49 if name in self._phyref:
50 del self._phyref[name]
51
52 if name in self._symref:
53 del self._symref[name]
54
55 if name in self._mtime:
56 del self._mtime[name]
57
Shawn O. Pearce0f3dd232009-04-17 20:32:44 -070058 def symref(self, name):
59 try:
60 self._EnsureLoaded()
61 return self._symref[name]
62 except KeyError:
63 return ''
64
65 def _EnsureLoaded(self):
66 if self._phyref is None or self._NeedUpdate():
67 self._LoadAll()
68
Shawn O. Pearced237b692009-04-17 18:49:50 -070069 def _NeedUpdate(self):
Shawn O. Pearcead3193a2009-04-18 09:54:51 -070070 Trace(': scan refs %s', self._gitdir)
71
Chirayu Desai217ea7d2013-03-01 19:14:38 +053072 for name, mtime in self._mtime.items():
Shawn O. Pearced237b692009-04-17 18:49:50 -070073 try:
74 if mtime != os.path.getmtime(os.path.join(self._gitdir, name)):
75 return True
76 except OSError:
77 return True
78 return False
79
80 def _LoadAll(self):
Shawn O. Pearcead3193a2009-04-18 09:54:51 -070081 Trace(': load refs %s', self._gitdir)
82
Shawn O. Pearced237b692009-04-17 18:49:50 -070083 self._phyref = {}
84 self._symref = {}
85 self._mtime = {}
86
87 self._ReadPackedRefs()
88 self._ReadLoose('refs/')
89 self._ReadLoose1(os.path.join(self._gitdir, HEAD), HEAD)
90
91 scan = self._symref
92 attempts = 0
93 while scan and attempts < 5:
94 scan_next = {}
Chirayu Desai217ea7d2013-03-01 19:14:38 +053095 for name, dest in scan.items():
Shawn O. Pearced237b692009-04-17 18:49:50 -070096 if dest in self._phyref:
97 self._phyref[name] = self._phyref[dest]
98 else:
99 scan_next[name] = dest
100 scan = scan_next
101 attempts += 1
102
103 def _ReadPackedRefs(self):
104 path = os.path.join(self._gitdir, 'packed-refs')
105 try:
Chirayu Desai0eb35cb2013-11-19 18:46:29 +0530106 fd = open(path, 'r')
Shawn O. Pearced237b692009-04-17 18:49:50 -0700107 mtime = os.path.getmtime(path)
108 except IOError:
109 return
110 except OSError:
111 return
112 try:
113 for line in fd:
Chirayu Desai217ea7d2013-03-01 19:14:38 +0530114 line = str(line)
Shawn O. Pearced237b692009-04-17 18:49:50 -0700115 if line[0] == '#':
116 continue
117 if line[0] == '^':
118 continue
119
120 line = line[:-1]
121 p = line.split(' ')
David Pursehouse8a68ff92012-09-24 12:15:13 +0900122 ref_id = p[0]
Shawn O. Pearced237b692009-04-17 18:49:50 -0700123 name = p[1]
124
David Pursehouse8a68ff92012-09-24 12:15:13 +0900125 self._phyref[name] = ref_id
Shawn O. Pearced237b692009-04-17 18:49:50 -0700126 finally:
127 fd.close()
128 self._mtime['packed-refs'] = mtime
129
130 def _ReadLoose(self, prefix):
131 base = os.path.join(self._gitdir, prefix)
Renaud Paquaybed8b622018-09-27 10:46:58 -0700132 for name in platform_utils.listdir(base):
Shawn O. Pearced237b692009-04-17 18:49:50 -0700133 p = os.path.join(base, name)
Renaud Paquaybed8b622018-09-27 10:46:58 -0700134 if platform_utils.isdir(p):
Shawn O. Pearced237b692009-04-17 18:49:50 -0700135 self._mtime[prefix] = os.path.getmtime(base)
136 self._ReadLoose(prefix + name + '/')
137 elif name.endswith('.lock'):
138 pass
139 else:
140 self._ReadLoose1(p, prefix + name)
141
142 def _ReadLoose1(self, path, name):
143 try:
Renaud Paquay2a4be942016-11-01 13:48:15 -0700144 fd = open(path)
David Pursehouse1d947b32012-10-25 12:23:11 +0900145 except IOError:
Shawn O. Pearced237b692009-04-17 18:49:50 -0700146 return
Shawn O. Pearcecc14fa92011-11-29 12:32:56 -0800147
Shawn O. Pearced237b692009-04-17 18:49:50 -0700148 try:
Shawn O. Pearcecc14fa92011-11-29 12:32:56 -0800149 try:
150 mtime = os.path.getmtime(path)
David Pursehouse8a68ff92012-09-24 12:15:13 +0900151 ref_id = fd.readline()
David Pursehouse1d947b32012-10-25 12:23:11 +0900152 except (IOError, OSError):
Shawn O. Pearcecc14fa92011-11-29 12:32:56 -0800153 return
Shawn O. Pearced237b692009-04-17 18:49:50 -0700154 finally:
155 fd.close()
156
Chirayu Desai217ea7d2013-03-01 19:14:38 +0530157 try:
158 ref_id = ref_id.decode()
159 except AttributeError:
160 pass
David Pursehouse8a68ff92012-09-24 12:15:13 +0900161 if not ref_id:
Shawn O. Pearced237b692009-04-17 18:49:50 -0700162 return
David Pursehouse8a68ff92012-09-24 12:15:13 +0900163 ref_id = ref_id[:-1]
Shawn O. Pearced237b692009-04-17 18:49:50 -0700164
David Pursehouse8a68ff92012-09-24 12:15:13 +0900165 if ref_id.startswith('ref: '):
166 self._symref[name] = ref_id[5:]
Shawn O. Pearced237b692009-04-17 18:49:50 -0700167 else:
David Pursehouse8a68ff92012-09-24 12:15:13 +0900168 self._phyref[name] = ref_id
Shawn O. Pearced237b692009-04-17 18:49:50 -0700169 self._mtime[name] = mtime