##// END OF EJS Templates
Refactor log ui buffering and patch display
Matt Mackall -
r3645:b984dcb1 default
parent child Browse files
Show More
@@ -9,7 +9,7 b' from demandload import demandload'
9 from node import *
9 from node import *
10 from i18n import gettext as _
10 from i18n import gettext as _
11 demandload(globals(), 'os sys')
11 demandload(globals(), 'os sys')
12 demandload(globals(), 'mdiff util templater cStringIO')
12 demandload(globals(), 'mdiff util templater cStringIO patch')
13
13
14 revrangesep = ':'
14 revrangesep = ':'
15
15
@@ -196,15 +196,63 b' def addremove(repo, pats=[], opts={}, wl'
196 if not dry_run:
196 if not dry_run:
197 repo.copy(old, new, wlock=wlock)
197 repo.copy(old, new, wlock=wlock)
198
198
199 class uibuffer(object):
200 # Implement and delegate some ui protocol. Save hunks of
201 # output for later display in the desired order.
202 def __init__(self, ui):
203 self.ui = ui
204 self.hunk = {}
205 self.header = {}
206 self.quiet = ui.quiet
207 self.verbose = ui.verbose
208 self.debugflag = ui.debugflag
209 self.lastheader = None
210 def note(self, *args):
211 if self.verbose:
212 self.write(*args)
213 def status(self, *args):
214 if not self.quiet:
215 self.write(*args)
216 def debug(self, *args):
217 if self.debugflag:
218 self.write(*args)
219 def write(self, *args):
220 self.hunk.setdefault(self.rev, []).extend(args)
221 def write_header(self, *args):
222 self.header.setdefault(self.rev, []).extend(args)
223 def mark(self, rev):
224 self.rev = rev
225 def flush(self, rev):
226 if rev in self.header:
227 h = "".join(self.header[rev])
228 if h != self.lastheader:
229 self.lastheader = h
230 self.ui.write(h)
231 del self.header[rev]
232 if rev in self.hunk:
233 self.ui.write("".join(self.hunk[rev]))
234 del self.hunk[rev]
235 return 1
236 return 0
237
199 class changeset_printer(object):
238 class changeset_printer(object):
200 '''show changeset information when templating not requested.'''
239 '''show changeset information when templating not requested.'''
201
240
202 def __init__(self, ui, repo):
241 def __init__(self, ui, repo, patch, buffered):
203 self.ui = ui
242 self.ui = ui
204 self.repo = repo
243 self.repo = repo
244 self.buffered = buffered
245 self.patch = patch
246 if buffered:
247 self.ui = uibuffer(ui)
248
249 def flush(self, rev):
250 return self.ui.flush(rev)
205
251
206 def show(self, rev=0, changenode=None, brinfo=None, copies=None):
252 def show(self, rev=0, changenode=None, brinfo=None, copies=None):
207 '''show a single changeset or file revision'''
253 '''show a single changeset or file revision'''
254 if self.buffered:
255 self.ui.mark(rev)
208 log = self.repo.changelog
256 log = self.repo.changelog
209 if changenode is None:
257 if changenode is None:
210 changenode = log.node(rev)
258 changenode = log.node(rev)
@@ -280,17 +328,23 b' class changeset_printer(object):'
280 description.splitlines()[0])
328 description.splitlines()[0])
281 self.ui.write("\n")
329 self.ui.write("\n")
282
330
283 class changeset_templater(object):
331 self.showpatch(changenode)
332
333 def showpatch(self, node):
334 if self.patch:
335 prev = self.repo.changelog.parents(node)[0]
336 patch.diff(self.repo, prev, node, fp=self.ui)
337 self.ui.write("\n")
338
339 class changeset_templater(changeset_printer):
284 '''format changeset information.'''
340 '''format changeset information.'''
285
341
286 def __init__(self, ui, repo, mapfile, dest=None):
342 def __init__(self, ui, repo, patch, mapfile, buffered):
343 changeset_printer.__init__(self, ui, repo, patch, buffered)
287 self.t = templater.templater(mapfile, templater.common_filters,
344 self.t = templater.templater(mapfile, templater.common_filters,
288 cache={'parent': '{rev}:{node|short} ',
345 cache={'parent': '{rev}:{node|short} ',
289 'manifest': '{rev}:{node|short}',
346 'manifest': '{rev}:{node|short}',
290 'filecopy': '{name} ({source})'})
347 'filecopy': '{name} ({source})'})
291 self.ui = ui
292 self.dest = dest
293 self.repo = repo
294
348
295 def use_template(self, t):
349 def use_template(self, t):
296 '''set template string to use'''
350 '''set template string to use'''
@@ -298,6 +352,8 b' class changeset_templater(object):'
298
352
299 def show(self, rev=0, changenode=None, brinfo=None, copies=[], **props):
353 def show(self, rev=0, changenode=None, brinfo=None, copies=[], **props):
300 '''show a single changeset or file revision'''
354 '''show a single changeset or file revision'''
355 if self.buffered:
356 self.ui.mark(rev)
301 log = self.repo.changelog
357 log = self.repo.changelog
302 if changenode is None:
358 if changenode is None:
303 changenode = log.node(rev)
359 changenode = log.node(rev)
@@ -440,7 +496,6 b' class changeset_templater(object):'
440 props.update(defprops)
496 props.update(defprops)
441
497
442 try:
498 try:
443 dest = self.dest or self.ui
444 if self.ui.debugflag and 'header_debug' in self.t:
499 if self.ui.debugflag and 'header_debug' in self.t:
445 key = 'header_debug'
500 key = 'header_debug'
446 elif self.ui.quiet and 'header_quiet' in self.t:
501 elif self.ui.quiet and 'header_quiet' in self.t:
@@ -452,7 +507,11 b' class changeset_templater(object):'
452 else:
507 else:
453 key = ''
508 key = ''
454 if key:
509 if key:
455 dest.write_header(templater.stringify(self.t(key, **props)))
510 h = templater.stringify(self.t(key, **props))
511 if self.buffered:
512 self.ui.write_header(h)
513 else:
514 self.ui.write(h)
456 if self.ui.debugflag and 'changeset_debug' in self.t:
515 if self.ui.debugflag and 'changeset_debug' in self.t:
457 key = 'changeset_debug'
516 key = 'changeset_debug'
458 elif self.ui.quiet and 'changeset_quiet' in self.t:
517 elif self.ui.quiet and 'changeset_quiet' in self.t:
@@ -461,7 +520,8 b' class changeset_templater(object):'
461 key = 'changeset_verbose'
520 key = 'changeset_verbose'
462 else:
521 else:
463 key = 'changeset'
522 key = 'changeset'
464 dest.write(templater.stringify(self.t(key, **props)))
523 self.ui.write(templater.stringify(self.t(key, **props)))
524 self.showpatch(changenode)
465 except KeyError, inst:
525 except KeyError, inst:
466 raise util.Abort(_("%s: no key named '%s'") % (self.t.mapfile,
526 raise util.Abort(_("%s: no key named '%s'") % (self.t.mapfile,
467 inst.args[0]))
527 inst.args[0]))
@@ -482,7 +542,7 b' class stringio(object):'
482 def __getattr__(self, key):
542 def __getattr__(self, key):
483 return getattr(self.fp, key)
543 return getattr(self.fp, key)
484
544
485 def show_changeset(ui, repo, opts):
545 def show_changeset(ui, repo, opts, buffered=False):
486 """show one changeset using template or regular display.
546 """show one changeset using template or regular display.
487
547
488 Display format will be the first non-empty hit of:
548 Display format will be the first non-empty hit of:
@@ -494,6 +554,7 b' def show_changeset(ui, repo, opts):'
494 regular display via changeset_printer() is done.
554 regular display via changeset_printer() is done.
495 """
555 """
496 # options
556 # options
557 patch = opts.get('patch')
497 tmpl = opts.get('template')
558 tmpl = opts.get('template')
498 mapfile = None
559 mapfile = None
499 if tmpl:
560 if tmpl:
@@ -515,10 +576,10 b' def show_changeset(ui, repo, opts):'
515 or templater.templatepath(mapfile))
576 or templater.templatepath(mapfile))
516 if mapname: mapfile = mapname
577 if mapname: mapfile = mapname
517 try:
578 try:
518 t = changeset_templater(ui, repo, mapfile)
579 t = changeset_templater(ui, repo, patch, mapfile, buffered)
519 except SyntaxError, inst:
580 except SyntaxError, inst:
520 raise util.Abort(inst.args[0])
581 raise util.Abort(inst.args[0])
521 if tmpl: t.use_template(tmpl)
582 if tmpl: t.use_template(tmpl)
522 return t
583 return t
523 return changeset_printer(ui, repo)
584 return changeset_printer(ui, repo, patch, buffered)
524
585
@@ -1592,10 +1592,6 b' def incoming(ui, repo, source="default",'
1592 if opts['no_merges'] and len(parents) == 2:
1592 if opts['no_merges'] and len(parents) == 2:
1593 continue
1593 continue
1594 displayer.show(changenode=n)
1594 displayer.show(changenode=n)
1595 if opts['patch']:
1596 prev = (parents and parents[0]) or nullid
1597 patch.diff(other, prev, n, fp=repo.ui)
1598 ui.write("\n")
1599 finally:
1595 finally:
1600 if hasattr(other, 'close'):
1596 if hasattr(other, 'close'):
1601 other.close()
1597 other.close()
@@ -1672,35 +1668,6 b' def log(ui, repo, *pats, **opts):'
1672 commit. When the -v/--verbose switch is used, the list of changed
1668 commit. When the -v/--verbose switch is used, the list of changed
1673 files and full commit message is shown.
1669 files and full commit message is shown.
1674 """
1670 """
1675 class dui(object):
1676 # Implement and delegate some ui protocol. Save hunks of
1677 # output for later display in the desired order.
1678 def __init__(self, ui):
1679 self.ui = ui
1680 self.hunk = {}
1681 self.header = {}
1682 self.quiet = ui.quiet
1683 self.verbose = ui.verbose
1684 self.debugflag = ui.debugflag
1685 def bump(self, rev):
1686 self.rev = rev
1687 self.hunk[rev] = []
1688 self.header[rev] = []
1689 def note(self, *args):
1690 if self.verbose:
1691 self.write(*args)
1692 def status(self, *args):
1693 if not self.quiet:
1694 self.write(*args)
1695 def write(self, *args):
1696 self.hunk[self.rev].extend(args)
1697 def write_header(self, *args):
1698 self.header[self.rev].extend(args)
1699 def debug(self, *args):
1700 if self.debugflag:
1701 self.write(*args)
1702 def __getattr__(self, key):
1703 return getattr(self.ui, key)
1704
1671
1705 getchange = util.cachefunc(lambda r:repo.changectx(r).changeset())
1672 getchange = util.cachefunc(lambda r:repo.changectx(r).changeset())
1706 changeiter, matchfn = walkchangerevs(ui, repo, pats, getchange, opts)
1673 changeiter, matchfn = walkchangerevs(ui, repo, pats, getchange, opts)
@@ -1755,13 +1722,9 b' def log(ui, repo, *pats, **opts):'
1755 return ncache[fn].get(dcache[1][fn])
1722 return ncache[fn].get(dcache[1][fn])
1756 return None
1723 return None
1757
1724
1758 displayer = cmdutil.show_changeset(ui, repo, opts)
1725 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
1759 for st, rev, fns in changeiter:
1726 for st, rev, fns in changeiter:
1760 if st == 'window':
1727 if st == 'add':
1761 du = dui(ui)
1762 displayer.ui = du
1763 elif st == 'add':
1764 du.bump(rev)
1765 changenode = repo.changelog.node(rev)
1728 changenode = repo.changelog.node(rev)
1766 parents = [p for p in repo.changelog.parentrevs(rev)
1729 parents = [p for p in repo.changelog.parentrevs(rev)
1767 if p != nullrev]
1730 if p != nullrev]
@@ -1794,21 +1757,10 b' def log(ui, repo, *pats, **opts):'
1794 if rename:
1757 if rename:
1795 copies.append((fn, rename[0]))
1758 copies.append((fn, rename[0]))
1796 displayer.show(rev, changenode, brinfo=br, copies=copies)
1759 displayer.show(rev, changenode, brinfo=br, copies=copies)
1797 if opts['patch']:
1798 if parents:
1799 prev = parents[0]
1800 else:
1801 prev = nullrev
1802 prev = repo.changelog.node(prev)
1803 patch.diff(repo, prev, changenode, match=matchfn, fp=du)
1804 du.write("\n\n")
1805 elif st == 'iter':
1760 elif st == 'iter':
1806 if count == limit: break
1761 if count == limit: break
1807 if du.header[rev]:
1762 if displayer.flush(rev):
1808 ui.write_header(*du.header[rev])
1809 if du.hunk[rev]:
1810 count += 1
1763 count += 1
1811 ui.write(*du.hunk[rev])
1812
1764
1813 def manifest(ui, repo, rev=None):
1765 def manifest(ui, repo, rev=None):
1814 """output the latest or given revision of the project manifest
1766 """output the latest or given revision of the project manifest
@@ -1897,10 +1849,6 b' def outgoing(ui, repo, dest=None, **opts'
1897 if opts['no_merges'] and len(parents) == 2:
1849 if opts['no_merges'] and len(parents) == 2:
1898 continue
1850 continue
1899 displayer.show(changenode=n)
1851 displayer.show(changenode=n)
1900 if opts['patch']:
1901 prev = (parents and parents[0]) or nullid
1902 patch.diff(repo, prev, n)
1903 ui.write("\n")
1904
1852
1905 def parents(ui, repo, file_=None, rev=None, branches=None, **opts):
1853 def parents(ui, repo, file_=None, rev=None, branches=None, **opts):
1906 """show the parents of the working dir or revision
1854 """show the parents of the working dir or revision
@@ -2560,8 +2508,6 b' def tip(ui, repo, **opts):'
2560 "please use 'hg branches' instead\n"))
2508 "please use 'hg branches' instead\n"))
2561 br = repo.branchlookup([n])
2509 br = repo.branchlookup([n])
2562 cmdutil.show_changeset(ui, repo, opts).show(changenode=n, brinfo=br)
2510 cmdutil.show_changeset(ui, repo, opts).show(changenode=n, brinfo=br)
2563 if opts['patch']:
2564 patch.diff(repo, repo.changelog.parents(n)[0], n)
2565
2511
2566 def unbundle(ui, repo, fname, **opts):
2512 def unbundle(ui, repo, fname, **opts):
2567 """apply a changegroup file
2513 """apply a changegroup file
@@ -37,7 +37,6 b' diff -r 000000000000 -r 8ba83d44753d foo'
37 @@ -0,0 +1,1 @@
37 @@ -0,0 +1,1 @@
38 +a
38 +a
39
39
40
41 changeset: 1:a1fce69c50d9
40 changeset: 1:a1fce69c50d9
42 tag: tip
41 tag: tip
43 user: test
42 user: test
@@ -50,7 +49,6 b' diff -r 8ba83d44753d -r a1fce69c50d9 foo'
50 @@ -1,1 +0,0 @@
49 @@ -1,1 +0,0 @@
51 -a
50 -a
52
51
53
54 not removing a: file has been marked for add (use -f to force removal)
52 not removing a: file has been marked for add (use -f to force removal)
55 adding a
53 adding a
56 adding b
54 adding b
General Comments 0
You need to be logged in to leave comments. Login now