Mercurial > public > mercurial-scm > hg
comparison hgext/fastannotate/context.py @ 43077:687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Done with
python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py')
black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**')
# skip-blame mass-reformatting only
Differential Revision: https://phab.mercurial-scm.org/D6972
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:48:39 -0400 |
parents | 2372284d9457 |
children | eef9a2d67051 |
comparison
equal
deleted
inserted
replaced
43076:2372284d9457 | 43077:687b865b95ad |
---|---|
50 pl = [p for p in pl if p.path() == f.path()] | 50 pl = [p for p in pl if p.path() == f.path()] |
51 | 51 |
52 # renamed filectx won't have a filelog yet, so set it | 52 # renamed filectx won't have a filelog yet, so set it |
53 # from the cache to save time | 53 # from the cache to save time |
54 for p in pl: | 54 for p in pl: |
55 if not '_filelog' in p.__dict__: | 55 if not b'_filelog' in p.__dict__: |
56 p._filelog = _getflog(f._repo, p.path()) | 56 p._filelog = _getflog(f._repo, p.path()) |
57 | 57 |
58 return pl | 58 return pl |
59 | 59 |
60 | 60 |
61 # extracted from mercurial.context.basefilectx.annotate. slightly modified | 61 # extracted from mercurial.context.basefilectx.annotate. slightly modified |
62 # so it takes a fctx instead of a pair of text and fctx. | 62 # so it takes a fctx instead of a pair of text and fctx. |
63 def _decorate(fctx): | 63 def _decorate(fctx): |
64 text = fctx.data() | 64 text = fctx.data() |
65 linecount = text.count('\n') | 65 linecount = text.count(b'\n') |
66 if text and not text.endswith('\n'): | 66 if text and not text.endswith(b'\n'): |
67 linecount += 1 | 67 linecount += 1 |
68 return ([(fctx, i) for i in pycompat.xrange(linecount)], text) | 68 return ([(fctx, i) for i in pycompat.xrange(linecount)], text) |
69 | 69 |
70 | 70 |
71 # extracted from mercurial.context.basefilectx.annotate. slightly modified | 71 # extracted from mercurial.context.basefilectx.annotate. slightly modified |
73 # calculating diff here. | 73 # calculating diff here. |
74 def _pair(parent, child, blocks): | 74 def _pair(parent, child, blocks): |
75 for (a1, a2, b1, b2), t in blocks: | 75 for (a1, a2, b1, b2), t in blocks: |
76 # Changed blocks ('!') or blocks made only of blank lines ('~') | 76 # Changed blocks ('!') or blocks made only of blank lines ('~') |
77 # belong to the child. | 77 # belong to the child. |
78 if t == '=': | 78 if t == b'=': |
79 child[0][b1:b2] = parent[0][a1:a2] | 79 child[0][b1:b2] = parent[0][a1:a2] |
80 return child | 80 return child |
81 | 81 |
82 | 82 |
83 # like scmutil.revsingle, but with lru cache, so their states (like manifests) | 83 # like scmutil.revsingle, but with lru cache, so their states (like manifests) |
117 fctx = ctx[path] | 117 fctx = ctx[path] |
118 else: | 118 else: |
119 fctx = repo.filectx(path, changeid=ctx.rev()) | 119 fctx = repo.filectx(path, changeid=ctx.rev()) |
120 else: | 120 else: |
121 fctx = ctx[path] | 121 fctx = ctx[path] |
122 if adjustctx == 'linkrev': | 122 if adjustctx == b'linkrev': |
123 introrev = fctx.linkrev() | 123 introrev = fctx.linkrev() |
124 else: | 124 else: |
125 introrev = fctx.introrev() | 125 introrev = fctx.introrev() |
126 if introrev != ctx.rev(): | 126 if introrev != ctx.rev(): |
127 fctx._changeid = introrev | 127 fctx._changeid = introrev |
130 | 130 |
131 | 131 |
132 # like mercurial.store.encodedir, but use linelog suffixes: .m, .l, .lock | 132 # like mercurial.store.encodedir, but use linelog suffixes: .m, .l, .lock |
133 def encodedir(path): | 133 def encodedir(path): |
134 return ( | 134 return ( |
135 path.replace('.hg/', '.hg.hg/') | 135 path.replace(b'.hg/', b'.hg.hg/') |
136 .replace('.l/', '.l.hg/') | 136 .replace(b'.l/', b'.l.hg/') |
137 .replace('.m/', '.m.hg/') | 137 .replace(b'.m/', b'.m.hg/') |
138 .replace('.lock/', '.lock.hg/') | 138 .replace(b'.lock/', b'.lock.hg/') |
139 ) | 139 ) |
140 | 140 |
141 | 141 |
142 def hashdiffopts(diffopts): | 142 def hashdiffopts(diffopts): |
143 diffoptstr = stringutil.pprint( | 143 diffoptstr = stringutil.pprint( |
155 followrename: follow renames, like "hg annotate -f" | 155 followrename: follow renames, like "hg annotate -f" |
156 followmerge: follow p2 of a merge changeset, otherwise p2 is ignored | 156 followmerge: follow p2 of a merge changeset, otherwise p2 is ignored |
157 """ | 157 """ |
158 | 158 |
159 defaults = { | 159 defaults = { |
160 'diffopts': None, | 160 b'diffopts': None, |
161 'followrename': True, | 161 b'followrename': True, |
162 'followmerge': True, | 162 b'followmerge': True, |
163 } | 163 } |
164 | 164 |
165 def __init__(self, **opts): | 165 def __init__(self, **opts): |
166 opts = pycompat.byteskwargs(opts) | 166 opts = pycompat.byteskwargs(opts) |
167 for k, v in self.defaults.iteritems(): | 167 for k, v in self.defaults.iteritems(): |
168 setattr(self, k, opts.get(k, v)) | 168 setattr(self, k, opts.get(k, v)) |
169 | 169 |
170 @util.propertycache | 170 @util.propertycache |
171 def shortstr(self): | 171 def shortstr(self): |
172 """represent opts in a short string, suitable for a directory name""" | 172 """represent opts in a short string, suitable for a directory name""" |
173 result = '' | 173 result = b'' |
174 if not self.followrename: | 174 if not self.followrename: |
175 result += 'r0' | 175 result += b'r0' |
176 if not self.followmerge: | 176 if not self.followmerge: |
177 result += 'm0' | 177 result += b'm0' |
178 if self.diffopts is not None: | 178 if self.diffopts is not None: |
179 assert isinstance(self.diffopts, mdiff.diffopts) | 179 assert isinstance(self.diffopts, mdiff.diffopts) |
180 diffopthash = hashdiffopts(self.diffopts) | 180 diffopthash = hashdiffopts(self.diffopts) |
181 if diffopthash != _defaultdiffopthash: | 181 if diffopthash != _defaultdiffopthash: |
182 result += 'i' + diffopthash | 182 result += b'i' + diffopthash |
183 return result or 'default' | 183 return result or b'default' |
184 | 184 |
185 | 185 |
186 defaultopts = annotateopts() | 186 defaultopts = annotateopts() |
187 | 187 |
188 | 188 |
204 | 204 |
205 @property | 205 @property |
206 def linelog(self): | 206 def linelog(self): |
207 if self._linelog is None: | 207 if self._linelog is None: |
208 if os.path.exists(self.linelogpath): | 208 if os.path.exists(self.linelogpath): |
209 with open(self.linelogpath, 'rb') as f: | 209 with open(self.linelogpath, b'rb') as f: |
210 try: | 210 try: |
211 self._linelog = linelogmod.linelog.fromdata(f.read()) | 211 self._linelog = linelogmod.linelog.fromdata(f.read()) |
212 except linelogmod.LineLogError: | 212 except linelogmod.LineLogError: |
213 self._linelog = linelogmod.linelog() | 213 self._linelog = linelogmod.linelog() |
214 else: | 214 else: |
224 def close(self): | 224 def close(self): |
225 if self._revmap is not None: | 225 if self._revmap is not None: |
226 self._revmap.flush() | 226 self._revmap.flush() |
227 self._revmap = None | 227 self._revmap = None |
228 if self._linelog is not None: | 228 if self._linelog is not None: |
229 with open(self.linelogpath, 'wb') as f: | 229 with open(self.linelogpath, b'wb') as f: |
230 f.write(self._linelog.encode()) | 230 f.write(self._linelog.encode()) |
231 self._linelog = None | 231 self._linelog = None |
232 | 232 |
233 __del__ = close | 233 __del__ = close |
234 | 234 |
306 # fast path: if rev is in the main branch already | 306 # fast path: if rev is in the main branch already |
307 directly, revfctx = self.canannotatedirectly(rev) | 307 directly, revfctx = self.canannotatedirectly(rev) |
308 if directly: | 308 if directly: |
309 if self.ui.debugflag: | 309 if self.ui.debugflag: |
310 self.ui.debug( | 310 self.ui.debug( |
311 'fastannotate: %s: using fast path ' | 311 b'fastannotate: %s: using fast path ' |
312 '(resolved fctx: %s)\n' | 312 b'(resolved fctx: %s)\n' |
313 % ( | 313 % ( |
314 self.path, | 314 self.path, |
315 stringutil.pprint(util.safehasattr(revfctx, 'node')), | 315 stringutil.pprint(util.safehasattr(revfctx, b'node')), |
316 ) | 316 ) |
317 ) | 317 ) |
318 return self.annotatedirectly(revfctx, showpath, showlines) | 318 return self.annotatedirectly(revfctx, showpath, showlines) |
319 | 319 |
320 # resolve master | 320 # resolve master |
354 # "hist", reducing its memory usage otherwise could be huge. | 354 # "hist", reducing its memory usage otherwise could be huge. |
355 initvisit = [revfctx] | 355 initvisit = [revfctx] |
356 if masterfctx: | 356 if masterfctx: |
357 if masterfctx.rev() is None: | 357 if masterfctx.rev() is None: |
358 raise error.Abort( | 358 raise error.Abort( |
359 _('cannot update linelog to wdir()'), | 359 _(b'cannot update linelog to wdir()'), |
360 hint=_('set fastannotate.mainbranch'), | 360 hint=_(b'set fastannotate.mainbranch'), |
361 ) | 361 ) |
362 initvisit.append(masterfctx) | 362 initvisit.append(masterfctx) |
363 visit = initvisit[:] | 363 visit = initvisit[:] |
364 pcache = {} | 364 pcache = {} |
365 needed = {revfctx: 1} | 365 needed = {revfctx: 1} |
401 self._checklastmasterhead(f) | 401 self._checklastmasterhead(f) |
402 | 402 |
403 if self.ui.debugflag: | 403 if self.ui.debugflag: |
404 if newmainbranch: | 404 if newmainbranch: |
405 self.ui.debug( | 405 self.ui.debug( |
406 'fastannotate: %s: %d new changesets in the main' | 406 b'fastannotate: %s: %d new changesets in the main' |
407 ' branch\n' % (self.path, len(newmainbranch)) | 407 b' branch\n' % (self.path, len(newmainbranch)) |
408 ) | 408 ) |
409 elif not hist: # no joints, no updates | 409 elif not hist: # no joints, no updates |
410 self.ui.debug( | 410 self.ui.debug( |
411 'fastannotate: %s: linelog cannot help in ' | 411 b'fastannotate: %s: linelog cannot help in ' |
412 'annotating this revision\n' % self.path | 412 b'annotating this revision\n' % self.path |
413 ) | 413 ) |
414 | 414 |
415 # prepare annotateresult so we can update linelog incrementally | 415 # prepare annotateresult so we can update linelog incrementally |
416 self.linelog.annotate(self.linelog.maxrev) | 416 self.linelog.annotate(self.linelog.maxrev) |
417 | 417 |
418 # 3rd DFS does the actual annotate | 418 # 3rd DFS does the actual annotate |
419 visit = initvisit[:] | 419 visit = initvisit[:] |
420 progress = self.ui.makeprogress( | 420 progress = self.ui.makeprogress( |
421 'building cache', total=len(newmainbranch) | 421 b'building cache', total=len(newmainbranch) |
422 ) | 422 ) |
423 while visit: | 423 while visit: |
424 f = visit[-1] | 424 f = visit[-1] |
425 if f in hist: | 425 if f in hist: |
426 visit.pop() | 426 visit.pop() |
461 progress.increment() | 461 progress.increment() |
462 bannotated = None | 462 bannotated = None |
463 if len(pl) == 2 and self.opts.followmerge: # merge | 463 if len(pl) == 2 and self.opts.followmerge: # merge |
464 bannotated = curr[0] | 464 bannotated = curr[0] |
465 if blocks is None: # no parents, add an empty one | 465 if blocks is None: # no parents, add an empty one |
466 blocks = list(self._diffblocks('', curr[1])) | 466 blocks = list(self._diffblocks(b'', curr[1])) |
467 self._appendrev(f, blocks, bannotated) | 467 self._appendrev(f, blocks, bannotated) |
468 elif showpath: # not append linelog, but we need to record path | 468 elif showpath: # not append linelog, but we need to record path |
469 self._node2path[f.node()] = f.path() | 469 self._node2path[f.node()] = f.path() |
470 | 470 |
471 progress.complete() | 471 progress.complete() |
488 if not isinstance(rev, int) and rev is not None: | 488 if not isinstance(rev, int) and rev is not None: |
489 hsh = {20: bytes, 40: node.bin}.get(len(rev), lambda x: None)(rev) | 489 hsh = {20: bytes, 40: node.bin}.get(len(rev), lambda x: None)(rev) |
490 if hsh is not None and (hsh, self.path) in self.revmap: | 490 if hsh is not None and (hsh, self.path) in self.revmap: |
491 f = hsh | 491 f = hsh |
492 if f is None: | 492 if f is None: |
493 adjustctx = 'linkrev' if self._perfhack else True | 493 adjustctx = b'linkrev' if self._perfhack else True |
494 f = self._resolvefctx(rev, adjustctx=adjustctx, resolverev=True) | 494 f = self._resolvefctx(rev, adjustctx=adjustctx, resolverev=True) |
495 result = f in self.revmap | 495 result = f in self.revmap |
496 if not result and self._perfhack: | 496 if not result and self._perfhack: |
497 # redo the resolution without perfhack - as we are going to | 497 # redo the resolution without perfhack - as we are going to |
498 # do write operations, we need a correct fctx. | 498 # do write operations, we need a correct fctx. |
509 revfctx = self._resolvefctx(rev, resolverev=True, adjustctx=True) | 509 revfctx = self._resolvefctx(rev, resolverev=True, adjustctx=True) |
510 | 510 |
511 # find a chain from rev to anything in the mainbranch | 511 # find a chain from rev to anything in the mainbranch |
512 if revfctx not in self.revmap: | 512 if revfctx not in self.revmap: |
513 chain = [revfctx] | 513 chain = [revfctx] |
514 a = '' | 514 a = b'' |
515 while True: | 515 while True: |
516 f = chain[-1] | 516 f = chain[-1] |
517 pl = self._parentfunc(f) | 517 pl = self._parentfunc(f) |
518 if not pl: | 518 if not pl: |
519 break | 519 break |
587 for (rev, linenum), idxs in key2idxs.iteritems(): | 587 for (rev, linenum), idxs in key2idxs.iteritems(): |
588 if rev not in revlines: | 588 if rev not in revlines: |
589 hsh = annotateresult[idxs[0]][0] | 589 hsh = annotateresult[idxs[0]][0] |
590 if self.ui.debugflag: | 590 if self.ui.debugflag: |
591 self.ui.debug( | 591 self.ui.debug( |
592 'fastannotate: reading %s line #%d ' | 592 b'fastannotate: reading %s line #%d ' |
593 'to resolve lines %r\n' | 593 b'to resolve lines %r\n' |
594 % (node.short(hsh), linenum, idxs) | 594 % (node.short(hsh), linenum, idxs) |
595 ) | 595 ) |
596 fctx = self._resolvefctx(hsh, revmap.rev2path(rev)) | 596 fctx = self._resolvefctx(hsh, revmap.rev2path(rev)) |
597 lines = mdiff.splitnewlines(fctx.data()) | 597 lines = mdiff.splitnewlines(fctx.data()) |
598 revlines[rev] = lines | 598 revlines[rev] = lines |
601 assert all(x is not None for x in result) | 601 assert all(x is not None for x in result) |
602 return result | 602 return result |
603 | 603 |
604 # run the annotate and the lines should match to the file content | 604 # run the annotate and the lines should match to the file content |
605 self.ui.debug( | 605 self.ui.debug( |
606 'fastannotate: annotate %s to resolve lines\n' % node.short(hsh) | 606 b'fastannotate: annotate %s to resolve lines\n' |
607 % node.short(hsh) | |
607 ) | 608 ) |
608 linelog.annotate(rev) | 609 linelog.annotate(rev) |
609 fctx = self._resolvefctx(hsh, revmap.rev2path(rev)) | 610 fctx = self._resolvefctx(hsh, revmap.rev2path(rev)) |
610 annotated = linelog.annotateresult | 611 annotated = linelog.annotateresult |
611 lines = mdiff.splitnewlines(fctx.data()) | 612 lines = mdiff.splitnewlines(fctx.data()) |
612 if len(lines) != len(annotated): | 613 if len(lines) != len(annotated): |
613 raise faerror.CorruptedFileError('unexpected annotated lines') | 614 raise faerror.CorruptedFileError(b'unexpected annotated lines') |
614 # resolve lines from the annotate result | 615 # resolve lines from the annotate result |
615 for i, line in enumerate(lines): | 616 for i, line in enumerate(lines): |
616 k = annotated[i] | 617 k = annotated[i] |
617 if k in key2idxs: | 618 if k in key2idxs: |
618 for idx in key2idxs[k]: | 619 for idx in key2idxs[k]: |
631 else: | 632 else: |
632 hsh = f.node() | 633 hsh = f.node() |
633 llrev = self.revmap.hsh2rev(hsh) | 634 llrev = self.revmap.hsh2rev(hsh) |
634 if not llrev: | 635 if not llrev: |
635 raise faerror.CorruptedFileError( | 636 raise faerror.CorruptedFileError( |
636 '%s is not in revmap' % node.hex(hsh) | 637 b'%s is not in revmap' % node.hex(hsh) |
637 ) | 638 ) |
638 if (self.revmap.rev2flag(llrev) & revmapmod.sidebranchflag) != 0: | 639 if (self.revmap.rev2flag(llrev) & revmapmod.sidebranchflag) != 0: |
639 raise faerror.CorruptedFileError( | 640 raise faerror.CorruptedFileError( |
640 '%s is not in revmap mainbranch' % node.hex(hsh) | 641 b'%s is not in revmap mainbranch' % node.hex(hsh) |
641 ) | 642 ) |
642 self.linelog.annotate(llrev) | 643 self.linelog.annotate(llrev) |
643 result = [ | 644 result = [ |
644 (self.revmap.rev2hsh(r), l) for r, l in self.linelog.annotateresult | 645 (self.revmap.rev2hsh(r), l) for r, l in self.linelog.annotateresult |
645 ] | 646 ] |
675 | 676 |
676 def getllrev(f): | 677 def getllrev(f): |
677 """(fctx) -> int""" | 678 """(fctx) -> int""" |
678 # f should not be a linelog revision | 679 # f should not be a linelog revision |
679 if isinstance(f, int): | 680 if isinstance(f, int): |
680 raise error.ProgrammingError('f should not be an int') | 681 raise error.ProgrammingError(b'f should not be an int') |
681 # f is a fctx, allocate linelog rev on demand | 682 # f is a fctx, allocate linelog rev on demand |
682 hsh = f.node() | 683 hsh = f.node() |
683 rev = revmap.hsh2rev(hsh) | 684 rev = revmap.hsh2rev(hsh) |
684 if rev is None: | 685 if rev is None: |
685 rev = revmap.append(hsh, sidebranch=True, path=f.path()) | 686 rev = revmap.append(hsh, sidebranch=True, path=f.path()) |
688 # append sidebranch revisions to revmap | 689 # append sidebranch revisions to revmap |
689 siderevs = [] | 690 siderevs = [] |
690 siderevmap = {} # node: int | 691 siderevmap = {} # node: int |
691 if bannotated is not None: | 692 if bannotated is not None: |
692 for (a1, a2, b1, b2), op in blocks: | 693 for (a1, a2, b1, b2), op in blocks: |
693 if op != '=': | 694 if op != b'=': |
694 # f could be either linelong rev, or fctx. | 695 # f could be either linelong rev, or fctx. |
695 siderevs += [ | 696 siderevs += [ |
696 f | 697 f |
697 for f, l in bannotated[b1:b2] | 698 for f, l in bannotated[b1:b2] |
698 if not isinstance(f, int) | 699 if not isinstance(f, int) |
706 # the changeset in the main branch, could be a merge | 707 # the changeset in the main branch, could be a merge |
707 llrev = revmap.append(fctx.node(), path=fctx.path()) | 708 llrev = revmap.append(fctx.node(), path=fctx.path()) |
708 siderevmap[fctx] = llrev | 709 siderevmap[fctx] = llrev |
709 | 710 |
710 for (a1, a2, b1, b2), op in reversed(blocks): | 711 for (a1, a2, b1, b2), op in reversed(blocks): |
711 if op == '=': | 712 if op == b'=': |
712 continue | 713 continue |
713 if bannotated is None: | 714 if bannotated is None: |
714 linelog.replacelines(llrev, a1, a2, b1, b2) | 715 linelog.replacelines(llrev, a1, a2, b1, b2) |
715 else: | 716 else: |
716 blines = [ | 717 blines = [ |
758 | 759 |
759 return parents | 760 return parents |
760 | 761 |
761 @util.propertycache | 762 @util.propertycache |
762 def _perfhack(self): | 763 def _perfhack(self): |
763 return self.ui.configbool('fastannotate', 'perfhack') | 764 return self.ui.configbool(b'fastannotate', b'perfhack') |
764 | 765 |
765 def _resolvefctx(self, rev, path=None, **kwds): | 766 def _resolvefctx(self, rev, path=None, **kwds): |
766 return resolvefctx(self.repo, rev, (path or self.path), **kwds) | 767 return resolvefctx(self.repo, rev, (path or self.path), **kwds) |
767 | 768 |
768 | 769 |
779 """helper for getting paths for lockfile, linelog and revmap""" | 780 """helper for getting paths for lockfile, linelog and revmap""" |
780 | 781 |
781 def __init__(self, repo, path, opts=defaultopts): | 782 def __init__(self, repo, path, opts=defaultopts): |
782 # different options use different directories | 783 # different options use different directories |
783 self._vfspath = os.path.join( | 784 self._vfspath = os.path.join( |
784 'fastannotate', opts.shortstr, encodedir(path) | 785 b'fastannotate', opts.shortstr, encodedir(path) |
785 ) | 786 ) |
786 self._repo = repo | 787 self._repo = repo |
787 | 788 |
788 @property | 789 @property |
789 def dirname(self): | 790 def dirname(self): |
790 return os.path.dirname(self._repo.vfs.join(self._vfspath)) | 791 return os.path.dirname(self._repo.vfs.join(self._vfspath)) |
791 | 792 |
792 @property | 793 @property |
793 def linelogpath(self): | 794 def linelogpath(self): |
794 return self._repo.vfs.join(self._vfspath + '.l') | 795 return self._repo.vfs.join(self._vfspath + b'.l') |
795 | 796 |
796 def lock(self): | 797 def lock(self): |
797 return lockmod.lock(self._repo.vfs, self._vfspath + '.lock') | 798 return lockmod.lock(self._repo.vfs, self._vfspath + b'.lock') |
798 | 799 |
799 @property | 800 @property |
800 def revmappath(self): | 801 def revmappath(self): |
801 return self._repo.vfs.join(self._vfspath + '.m') | 802 return self._repo.vfs.join(self._vfspath + b'.m') |
802 | 803 |
803 | 804 |
804 @contextlib.contextmanager | 805 @contextlib.contextmanager |
805 def annotatecontext(repo, path, opts=defaultopts, rebuild=False): | 806 def annotatecontext(repo, path, opts=defaultopts, rebuild=False): |
806 """context needed to perform (fast) annotate on a file | 807 """context needed to perform (fast) annotate on a file |
829 actx.rebuild() | 830 actx.rebuild() |
830 yield actx | 831 yield actx |
831 except Exception: | 832 except Exception: |
832 if actx is not None: | 833 if actx is not None: |
833 actx.rebuild() | 834 actx.rebuild() |
834 repo.ui.debug('fastannotate: %s: cache broken and deleted\n' % path) | 835 repo.ui.debug(b'fastannotate: %s: cache broken and deleted\n' % path) |
835 raise | 836 raise |
836 finally: | 837 finally: |
837 if actx is not None: | 838 if actx is not None: |
838 actx.close() | 839 actx.close() |
839 | 840 |
842 """like annotatecontext but get the context from a fctx. convenient when | 843 """like annotatecontext but get the context from a fctx. convenient when |
843 used in fctx.annotate | 844 used in fctx.annotate |
844 """ | 845 """ |
845 repo = fctx._repo | 846 repo = fctx._repo |
846 path = fctx._path | 847 path = fctx._path |
847 if repo.ui.configbool('fastannotate', 'forcefollow', True): | 848 if repo.ui.configbool(b'fastannotate', b'forcefollow', True): |
848 follow = True | 849 follow = True |
849 aopts = annotateopts(diffopts=diffopts, followrename=follow) | 850 aopts = annotateopts(diffopts=diffopts, followrename=follow) |
850 return annotatecontext(repo, path, aopts, rebuild) | 851 return annotatecontext(repo, path, aopts, rebuild) |