Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/commands.py @ 3527:45620faafa28
Pull getchange out of walkchangerevs
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 26 Oct 2006 17:45:03 -0500 |
parents | 68341c06bc61 |
children | cd2216599c99 |
comparison
equal
deleted
inserted
replaced
3526:68341c06bc61 | 3527:45620faafa28 |
---|---|
48 except IOError, inst: | 48 except IOError, inst: |
49 raise util.Abort(_("can't read commit message '%s': %s") % | 49 raise util.Abort(_("can't read commit message '%s': %s") % |
50 (logfile, inst.strerror)) | 50 (logfile, inst.strerror)) |
51 return message | 51 return message |
52 | 52 |
53 def walkchangerevs(ui, repo, pats, opts): | 53 def walkchangerevs(ui, repo, pats, change, opts): |
54 '''Iterate over files and the revs they changed in. | 54 '''Iterate over files and the revs they changed in. |
55 | 55 |
56 Callers most commonly need to iterate backwards over the history | 56 Callers most commonly need to iterate backwards over the history |
57 it is interested in. Doing so has awful (quadratic-looking) | 57 it is interested in. Doing so has awful (quadratic-looking) |
58 performance, so we use iterators in a "windowed" way. | 58 performance, so we use iterators in a "windowed" way. |
59 | 59 |
60 We walk a window of revisions in the desired order. Within the | 60 We walk a window of revisions in the desired order. Within the |
61 window, we first walk forwards to gather data, then in the desired | 61 window, we first walk forwards to gather data, then in the desired |
62 order (usually backwards) to display it. | 62 order (usually backwards) to display it. |
63 | 63 |
64 This function returns an (iterator, getchange, matchfn) tuple. The | 64 This function returns an (iterator, matchfn) tuple. The iterator |
65 getchange function returns the changelog entry for a numeric | 65 yields 3-tuples. They will be of one of the following forms: |
66 revision. The iterator yields 3-tuples. They will be of one of | |
67 the following forms: | |
68 | 66 |
69 "window", incrementing, lastrev: stepping through a window, | 67 "window", incrementing, lastrev: stepping through a window, |
70 positive if walking forwards through revs, last rev in the | 68 positive if walking forwards through revs, last rev in the |
71 sequence iterated over - use to reset state for the current window | 69 sequence iterated over - use to reset state for the current window |
72 | 70 |
89 yield start, min(windowsize, start-end-1) | 87 yield start, min(windowsize, start-end-1) |
90 start -= windowsize | 88 start -= windowsize |
91 if windowsize < sizelimit: | 89 if windowsize < sizelimit: |
92 windowsize *= 2 | 90 windowsize *= 2 |
93 | 91 |
94 | |
95 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | 92 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) |
96 follow = opts.get('follow') or opts.get('follow_first') | 93 follow = opts.get('follow') or opts.get('follow_first') |
97 | 94 |
98 if repo.changelog.count() == 0: | 95 if repo.changelog.count() == 0: |
99 return [], False, matchfn | 96 return [], matchfn |
100 | 97 |
101 if follow: | 98 if follow: |
102 defrange = '%s:0' % repo.changectx().rev() | 99 defrange = '%s:0' % repo.changectx().rev() |
103 else: | 100 else: |
104 defrange = 'tip:0' | 101 defrange = 'tip:0' |
105 revs = cmdutil.revrange(ui, repo, opts['rev'] or [defrange]) | 102 revs = cmdutil.revrange(ui, repo, opts['rev'] or [defrange]) |
106 wanted = {} | 103 wanted = {} |
107 slowpath = anypats | 104 slowpath = anypats |
108 fncache = {} | 105 fncache = {} |
109 | |
110 chcache = {} | |
111 def getchange(rev): | |
112 ch = chcache.get(rev) | |
113 if ch is None: | |
114 chcache[rev] = ch = repo.changelog.read(repo.lookup(str(rev))) | |
115 return ch | |
116 | 106 |
117 if not slowpath and not files: | 107 if not slowpath and not files: |
118 # No files, no patterns. Display all revs. | 108 # No files, no patterns. Display all revs. |
119 wanted = dict(zip(revs, revs)) | 109 wanted = dict(zip(revs, revs)) |
120 copies = [] | 110 copies = [] |
167 | 157 |
168 # The slow path checks files modified in every changeset. | 158 # The slow path checks files modified in every changeset. |
169 def changerevgen(): | 159 def changerevgen(): |
170 for i, window in increasing_windows(repo.changelog.count()-1, -1): | 160 for i, window in increasing_windows(repo.changelog.count()-1, -1): |
171 for j in xrange(i - window, i + 1): | 161 for j in xrange(i - window, i + 1): |
172 yield j, getchange(j)[3] | 162 yield j, change(j)[3] |
173 | 163 |
174 for rev, changefiles in changerevgen(): | 164 for rev, changefiles in changerevgen(): |
175 matches = filter(matchfn, changefiles) | 165 matches = filter(matchfn, changefiles) |
176 if matches: | 166 if matches: |
177 fncache[rev] = matches | 167 fncache[rev] = matches |
238 yield 'window', revs[0] < revs[-1], revs[-1] | 228 yield 'window', revs[0] < revs[-1], revs[-1] |
239 nrevs = [rev for rev in revs[i:i+window] if want(rev)] | 229 nrevs = [rev for rev in revs[i:i+window] if want(rev)] |
240 srevs = list(nrevs) | 230 srevs = list(nrevs) |
241 srevs.sort() | 231 srevs.sort() |
242 for rev in srevs: | 232 for rev in srevs: |
243 fns = fncache.get(rev) or filter(matchfn, getchange(rev)[3]) | 233 fns = fncache.get(rev) or filter(matchfn, change(rev)[3]) |
244 yield 'add', rev, fns | 234 yield 'add', rev, fns |
245 for rev in nrevs: | 235 for rev in nrevs: |
246 yield 'iter', rev, None | 236 yield 'iter', rev, None |
247 return iterate(), getchange, matchfn | 237 return iterate(), matchfn |
248 | 238 |
249 def write_bundle(cg, filename=None, compress=True): | 239 def write_bundle(cg, filename=None, compress=True): |
250 """Write a bundle file and return its filename. | 240 """Write a bundle file and return its filename. |
251 | 241 |
252 Existing files will not be overwritten. | 242 Existing files will not be overwritten. |
1489 counts[change] += 1 | 1479 counts[change] += 1 |
1490 return counts['+'], counts['-'] | 1480 return counts['+'], counts['-'] |
1491 | 1481 |
1492 fstate = {} | 1482 fstate = {} |
1493 skip = {} | 1483 skip = {} |
1494 changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts) | 1484 getchange = util.cachefunc(lambda r:repo.changectx(r).changeset()) |
1485 changeiter, matchfn = walkchangerevs(ui, repo, pats, getchange, opts) | |
1495 count = 0 | 1486 count = 0 |
1496 incrementing = False | 1487 incrementing = False |
1497 follow = opts.get('follow') | 1488 follow = opts.get('follow') |
1498 for st, rev, fns in changeiter: | 1489 for st, rev, fns in changeiter: |
1499 if st == 'window': | 1490 if st == 'window': |
1822 if self.debugflag: | 1813 if self.debugflag: |
1823 self.write(*args) | 1814 self.write(*args) |
1824 def __getattr__(self, key): | 1815 def __getattr__(self, key): |
1825 return getattr(self.ui, key) | 1816 return getattr(self.ui, key) |
1826 | 1817 |
1827 changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts) | 1818 getchange = util.cachefunc(lambda r:repo.changectx(r).changeset()) |
1819 changeiter, matchfn = walkchangerevs(ui, repo, pats, getchange, opts) | |
1828 | 1820 |
1829 if opts['branches']: | 1821 if opts['branches']: |
1830 ui.warn(_("the --branches option is deprecated, " | 1822 ui.warn(_("the --branches option is deprecated, " |
1831 "please use 'hg branches' instead\n")) | 1823 "please use 'hg branches' instead\n")) |
1832 | 1824 |