Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 2.0.3, 2.0.4, and 2.0.5

stable grep: include hg subrepositories in working folder scans

If the subrepo root path matches the filter, scan the entire repository. This
does not allow file patterns to filter inside the subrepos themselves, it is an
all or nothing match. Some of this code should be generalized and moved to
thgrepo so all tools that deal with workingctx can deal with subrepositories (on
the default branch).

Bonus fixes:

* Properly catch and report exceptions from the context scanning thread
* Do not hide exception messages by writing 'No matches found'

Changeset ef48dc901ed8

Parent 92a2935b3b70

by Steve Borho

Changes to one file · Browse files at ef48dc901ed8 Showing diff from parent 92a2935b3b70 Diff from another changeset...

 
8
9
10
11
 
12
13
14
 
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
 
 
 
 
 
 
 
 
 
 
 
 
337
338
339
 
353
354
355
 
356
357
358
 
405
406
407
 
408
409
410
 
421
422
423
 
424
425
426
427
428
429
430
431
432
433
434
435
436
 
 
 
 
 
 
 
 
 
437
 
438
439
440
 
441
442
 
443
444
445
446
447
448
449
 
450
451
452
453
454
455
456
 
 
457
458
459
460
 
 
 
461
462
463
464
465
466
 
 
 
 
 
 
 
 
 
467
468
469
 
589
590
591
 
 
 
 
 
 
 
 
 
592
593
594
595
 
596
597
598
 
8
9
10
 
11
12
13
14
 
322
323
324
 
 
 
 
 
 
 
 
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
 
357
358
359
360
361
362
363
 
410
411
412
413
414
415
416
 
427
428
429
430
431
432
433
434
435
 
 
 
 
436
437
438
 
439
440
441
442
443
444
445
446
447
448
449
450
451
 
452
453
 
454
455
456
457
458
459
460
 
461
462
463
464
465
466
 
 
467
468
469
470
 
 
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
 
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
 
626
627
628
629
@@ -8,7 +8,7 @@
 import os  import re   -from mercurial import ui, hg, error, commands, match, util +from mercurial import ui, hg, error, commands, match, util, subrepo    from tortoisehg.hgqt import htmlui, visdiff, qtlib, htmldelegate, thgrepo, cmdui  from tortoisehg.util import paths, hglib, thread2 @@ -322,18 +322,22 @@
  pass     def searchfinished(self): - count = self.tv.model().rowCount(None) - if not count: - self.showMessage.emit(_('No matches found')) - else: - self.showMessage.emit(_('%d matches found') % count) - for col in xrange(COL_TEXT): - self.tv.resizeColumnToContents(col) - self.tv.setSortingEnabled(True)   self.cancelbutton.setEnabled(False)   self.searchbutton.setEnabled(True)   self.regexple.setEnabled(True)   self.regexple.setFocus() + count = self.tv.model().rowCount(None) + if count: + for col in xrange(COL_TEXT): + self.tv.resizeColumnToContents(col) + self.tv.setSortingEnabled(True) + if self.thread.completed == False: + # do not overwrite error message on failure + pass + elif count: + self.showMessage.emit(_('%d matches found') % count) + else: + self.showMessage.emit(_('No matches found'))    class DataWrapper(object):   def __init__(self, data): @@ -353,6 +357,7 @@
  self.inc = inc   self.exc = exc   self.follow = follow + self.completed = False     def cancel(self):   if self.isRunning() and hasattr(self, 'thread_id'): @@ -405,6 +410,7 @@
  self.showMessage.emit(_('Interrupted'))   self.progress.emit(*cmdui.stopProgress(_('Searching')))   os.chdir(cwd) + self.completed = True    class CtxSearchThread(QThread):   '''Background thread for searching a changectx''' @@ -421,49 +427,65 @@
  self.exc = exc   self.once = once   self.canceled = False + self.completed = False     def cancel(self):   self.canceled = True     def run(self): - hu = htmlui.htmlui() - rev = self.ctx.rev() - # generate match function relative to repo root - matchfn = match.match(self.repo.root, '', [], self.inc, self.exc)   def badfn(f, msg):   e = hglib.tounicode("%s: %s" % (matchfn.rel(f), msg))   self.showMessage.emit(e) - matchfn.bad = badfn + self.hu = htmlui.htmlui() + try: + # generate match function relative to repo root + matchfn = match.match(self.repo.root, '', [], self.inc, self.exc) + matchfn.bad = badfn + self.searchRepo(self.ctx, '', matchfn) + self.completed = True + except Exception, e: + self.showMessage.emit(hglib.tounicode(str(e)))   + def searchRepo(self, ctx, prefix, matchfn):   topic = _('Searching')   unit = _('files') - total = len(self.ctx.manifest()) + total = len(ctx.manifest())   count = 0 - for wfile in self.ctx: # walk manifest + for wfile in ctx: # walk manifest   if self.canceled:   break   self.progress.emit(topic, count, wfile, unit, total)   count += 1   if not matchfn(wfile):   continue - data = self.ctx[wfile].data() # load file data + data = ctx[wfile].data() # load file data   if util.binary(data):   continue   for i, line in enumerate(data.splitlines()):   pos = 0   for m in self.regexp.finditer(line): # perform regexp - hu.write(line[pos:m.start()], label='ui.status') - hu.write(line[m.start():m.end()], label='grep.match') + self.hu.write(line[pos:m.start()], label='ui.status') + self.hu.write(line[m.start():m.end()], label='grep.match')   pos = m.end()   if pos: - hu.write(line[pos:], label='ui.status') - row = [wfile, i + 1, rev, None, hu.getdata()[0]] + self.hu.write(line[pos:], label='ui.status') + path = os.path.join(prefix, wfile) + row = [path, i + 1, ctx.rev(), None, self.hu.getdata()[0]]   w = DataWrapper(row)   self.matchedRow.emit(w)   if self.once:   break   self.progress.emit(topic, None, '', '', None)   + if ctx.rev() is None: + for s in ctx.substate: + if not matchfn(s): + continue + sub = ctx.sub(s) + if isinstance(sub, subrepo.hgsubrepo): + newprefix = os.path.join(prefix, s) + self.searchRepo(sub._repo[None], newprefix, lambda x: True) +    COL_PATH = 0  COL_LINE = 1 @@ -589,10 +611,19 @@
  continue   else:   seen.add(path) + if rev is None and path not in repo[None]: + abs = repo.wjoin(path) + root = paths.find_root(abs) + if root and abs.startswith(root): + path = abs[len(root)+1:] + else: + continue + else: + root = repo.root   dlg = annotate.AnnotateDialog(path, rev=rev, line=line,   pattern=pattern, parent=self,   searchwidget=self.parent(), - root=repo.root) + root=root)   dlg.show()     def onViewChangeset(self):