import time import datetime from mercurial import repo localrepo util

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import time
import datetime
from mercurial import repo, localrepo, util, cmdutil, hg
from mercurial import ui
hgui = ui.ui(interactive=False, quiet=True, report_untrusted=False)
def hgdate(date):
t, tz = date
return datetime.datetime(*time.gmtime(float(t) - tz)[:6])
class ChangeLog(object):
_revrange = None
def __init__(self, repo):
self.repo = repo
self._result_cache = None
self._iter = None
def __repr__(self):
return repr(list(self))
def __len__(self):
return self.repo.changelog.count()
def __iter__(self):
if self._result_cache is None:
self._iter = self.iterator()
self._result_cache = []
if self._iter:
return self._result_iter()
return iter(self._result_cache)
def _result_iter(self):
pos = 0
while 1:
upper = len(self._result_cache)
while pos < upper:
yield self._result_cache[pos]
pos += 1
if not self._iter:
raise StopIteration
if len(self._result_cache) <= pos:
self._fill_cache()
def __nonzero__(self):
if self._result_cache is not None:
return bool(self._result_cache)
try:
iter(self).next()
except StopIteration:
return False
return True
def __getitem__(self, k):
"Retrieve an item or slice from the set of results."
if not isinstance(k, (slice, int, long)):
raise TypeError
if self._result_cache is not None:
if self._iter is not None:
# The result cache has only been partially populated, so we may
# need to fill it out a bit more.
if isinstance(k, slice):
if k.stop is not None:
# Some people insist on passing in strings here.
bound = int(k.stop)
else:
bound = None
else:
bound = k + 1
if len(self._result_cache) < bound:
self._fill_cache(bound - len(self._result_cache))
return self._result_cache[k]
def revfix(repo, val, defval):
if not val and val != 0 and defval is not None:
return defval
return self.repo.changelog.rev(self.repo.lookup(val))
if isinstance(k, slice):
cl = self._clone()
start = revfix(self.repo, k.start, 0)
stop = revfix(self.repo, k.stop, self.repo.changelog.count() - 1)
cl._revrange = ['%s:%s' % (start or '', stop or '')]
return cl
cl = self._clone()
cl._revrange = ['%s' % k]
return list(cl)[0]
#############
# REAL WORK #
#############
def iterator(self):
"""
An iterator over the changes from repo.
"""
get = util.cachefunc(lambda r: self.repo.changectx(r).changeset())
log = self.repo.changelog
if self._revrange:
endrev = max(cmdutil.revrange(self.repo, self._revrange)) + 1
else:
endrev = self.repo.changelog.count()
opts = { 'rev': self._revrange, }
changeiter, matchfn = cmdutil.walkchangerevs(hgui, self.repo, [], get, opts)
cache = []
for st, rev, fns in changeiter:
if st == 'add':
node = log.node(rev)
changes = get(node)
cur_rev = {
'rev': rev,
'node': short(node),
'author': changes[1],
'date': hgdate(changes[2]),
'summary': changes[4].splitlines()[0],
}
cache.append(cur_rev)
elif st == 'iter':
# Don't worry, len(iter) == len(add),
# so cache will not raise IndexError
yield cache.pop()
###################
# PRIVATE METHODS #
###################
def _clone(self, **kwargs):
klass = self.__class__
c = klass(repo=self.repo)
c.__dict__.update(kwargs)
return c
def _fill_cache(self, num=100):
if self._iter:
try:
for i in xrange(num):
self._result_cache.append(self._iter.next())
except StopIteration:
self._iter = None