Mercurial > public > mercurial-scm > hg
comparison mercurial/cmdutil.py @ 3645:b984dcb1df71
Refactor log ui buffering and patch display
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 13 Nov 2006 13:26:57 -0600 |
parents | b4ad640a3bcf |
children | 2801a3efc7c3 |
comparison
equal
deleted
inserted
replaced
3644:b7547efe78fb | 3645:b984dcb1df71 |
---|---|
7 | 7 |
8 from demandload import demandload | 8 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 |
16 def revpair(ui, repo, revs): | 16 def revpair(ui, repo, revs): |
17 '''return pair of nodes, given list of revisions. second item can | 17 '''return pair of nodes, given list of revisions. second item can |
194 '(%d%% similar)\n') % | 194 '(%d%% similar)\n') % |
195 (oldrel, newrel, score * 100)) | 195 (oldrel, newrel, score * 100)) |
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) |
211 elif not rev: | 259 elif not rev: |
212 rev = log.rev(changenode) | 260 rev = log.rev(changenode) |
278 else: | 326 else: |
279 self.ui.write(_("summary: %s\n") % | 327 self.ui.write(_("summary: %s\n") % |
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''' |
297 self.t.cache['changeset'] = t | 351 self.t.cache['changeset'] = t |
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) |
304 elif not rev: | 360 elif not rev: |
305 rev = log.rev(changenode) | 361 rev = log.rev(changenode) |
438 } | 494 } |
439 props = props.copy() | 495 props = props.copy() |
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: |
447 key = 'header_quiet' | 502 key = 'header_quiet' |
448 elif self.ui.verbose and 'header_verbose' in self.t: | 503 elif self.ui.verbose and 'header_verbose' in self.t: |
450 elif 'header' in self.t: | 505 elif 'header' in self.t: |
451 key = 'header' | 506 key = 'header' |
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: |
459 key = 'changeset_quiet' | 518 key = 'changeset_quiet' |
460 elif self.ui.verbose and 'changeset_verbose' in self.t: | 519 elif self.ui.verbose and 'changeset_verbose' in self.t: |
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])) |
468 except SyntaxError, inst: | 528 except SyntaxError, inst: |
469 raise util.Abort(_('%s: %s') % (self.t.mapfile, inst.args[0])) | 529 raise util.Abort(_('%s: %s') % (self.t.mapfile, inst.args[0])) |
480 write_header = write | 540 write_header = write |
481 | 541 |
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: |
489 1. option 'template' | 549 1. option 'template' |
490 2. option 'style' | 550 2. option 'style' |
492 4. [ui] setting 'style' | 552 4. [ui] setting 'style' |
493 If all of these values are either the unset or the empty string, | 553 If all of these values are either the unset or the empty string, |
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: |
500 tmpl = templater.parsestring(tmpl, quoted=False) | 561 tmpl = templater.parsestring(tmpl, quoted=False) |
501 else: | 562 else: |
513 if not os.path.split(mapfile)[0]: | 574 if not os.path.split(mapfile)[0]: |
514 mapname = (templater.templatepath('map-cmdline.' + mapfile) | 575 mapname = (templater.templatepath('map-cmdline.' + mapfile) |
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 |