Mercurial and Git clients can push and pull from this alias URL to interact with this repository. You can change to which repository an alias points by going to the Aliases link on the project page.
# revset.py - revision set query dialog## Copyright 2010 Steve Borho <steve@borho.org>## This software may be used and distributed according to the terms of the# GNU General Public License version 2, incorporated herein by reference.importosfrommercurialimportrevset,hg,errorfromtortoisehg.hgqtimportqtlib,cmduifromtortoisehg.utilimporthglibfromtortoisehg.hgqt.i18nimport_fromPyQt4.QsciimportQsciScintilla,QsciAPIs,QsciLexerPythonfromPyQt4.QtCoreimport*fromPyQt4.QtGuiimport*# TODO:# Connect to repoview revisionClicked events# Shift-Click rev range -> revision range X:Y# Ctrl-Click two revs -> DAG range X::Y# QFontMetrics.elidedText for help label_common=(('user(string)',_('Changesets where username contains string.')),('keyword(string)',_('Search commit message, user name, and names of changed ''files for string.')),('grep(regex)',_('Like "keyword(string)" but accepts a regex.')),('outgoing([path])',_('Changesets not found in the specified destination repository, ''or the default push location.')),('bookmark([name])',_('The named bookmark or all bookmarks.')),('tag([name])',_('The named tag or all tags.')),('tagged()',_('Changeset is tagged.')),('head()',_('Changeset is a named branch head.')),('merge()',_('Changeset is a merge changeset.')),('closed()',_('Changeset is closed.')),('date(interval)',_('Changesets within the interval, see <a href="http://www.selenic.com/''mercurial/hg.1.html#dates">help dates</a>')),('ancestor(single, single)',_('Greatest common ancestor of the two changesets.')),)_filepatterns=(('file(pattern)',_('Changesets affecting files matched by pattern. ''See <a href="http://www.selenic.com/mercurial/hg.1.html#patterns">''help patterns</a>')),('modifies(pattern)',_('Changesets which modify files matched by pattern.')),('adds(pattern)',_('Changesets which add files matched by pattern.')),('removes(pattern)',_('Changesets which remove files matched by pattern.')),('contains(pattern)',_('Changesets containing files matched by pattern.')),)_ancestry=(('branch(set)',_('All changesets belonging to the branches of changesets in set.')),('heads(set)',_('Members of a set with no children in set.')),('descendants(set)',_('Changesets which are descendants of changesets in set.')),('ancestors(set)',_('Changesets that are ancestors of a changeset in set.')),('children(set)',_('Child changesets of changesets in set.')),('parents(set)',_('The set of all parents for all changesets in set.')),('p1(set)',_('First parent for all changesets in set, or the working directory.')),('p2(set)',_('Second parent for all changesets in set, or the working directory.')),('roots(set)',_('Changesets whith no parent changeset in set.')),('present(set)',_('An empty set, if any revision in set isn\'t found; otherwise, ''all revisions in set.')),)_logical=(('min(set)',_('Changeset with lowest revision number in set.')),('max(set)',_('Changeset with highest revision number in set.')),('limit(set, n)',_('First n members of a set.')),('sort(set[, [-]key...])',_('Sort set by keys. The default sort order is ascending, specify a ''key as "-key" to sort in descending order.')),('follow()',_('An alias for "::." (ancestors of the working copy\'s first parent).')),('all()',_('All changesets, the same as 0:tip.')),)classRevisionSetQuery(QDialog):# Emit query string and resulting revision setqueryIssued=pyqtSignal(QString,object)showMessage=pyqtSignal(QString)progress=pyqtSignal(QString,object,QString,QString,object)def__init__(self,repo,parent=None):QDialog.__init__(self,parent)self.repo=repo# Since the revset dialot belongs to a repository, we display# the repository name in the dialog titleself.setWindowTitle(_('Revision Set Query')+' - '+repo.displayname)self.setWindowFlags(Qt.Window)layout=QVBoxLayout()layout.setMargin(0)layout.setContentsMargins(*(4,)*4)self.setLayout(layout)if'hgsubversion'inrepo.extensions():global_logical,_ancestry_logical=list(_logical)+[('fromsvn()',_('all revisions converted from subversion')),]_ancestry=list(_ancestry)+[('svnrev(rev)',_('changeset which represents converted svn revision')),]self.stbar=cmdui.ThgStatusBar(self)self.stbar.setSizeGripEnabled(False)self.stbar.lbl.setOpenExternalLinks(True)self.showMessage.connect(self.stbar.showMessage)self.progress.connect(self.stbar.progress)hbox=QHBoxLayout()hbox.setContentsMargins(*(0,)*4)cgb=QGroupBox(_('Common sets'))cgb.setLayout(QVBoxLayout())cgb.layout().setContentsMargins(*(2,)*4)defsetCommonHelp(item):self.stbar.showMessage(self.clw._help[self.clw.row(item)])self.clw=QListWidget(self)self.clw.addItems([xforx,yin_common])self.clw._help=[yforx,yin_common]self.clw.itemClicked.connect(setCommonHelp)cgb.layout().addWidget(self.clw)hbox.addWidget(cgb)fgb=QGroupBox(_('File pattern sets'))fgb.setLayout(QVBoxLayout())fgb.layout().setContentsMargins(*(2,)*4)defsetFileHelp(item):self.stbar.showMessage(self.flw._help[self.flw.row(item)])self.flw=QListWidget(self)self.flw.addItems([xforx,yin_filepatterns])self.flw._help=[yforx,yin_filepatterns]self.flw.itemClicked.connect(setFileHelp)fgb.layout().addWidget(self.flw)hbox.addWidget(fgb)agb=QGroupBox(_('Set Ancestry'))agb.setLayout(QVBoxLayout())agb.layout().setContentsMargins(*(2,)*4)defsetAncHelp(item):self.stbar.showMessage(self.alw._help[self.alw.row(item)])self.alw=QListWidget(self)self.alw.addItems([xforx,yin_ancestry])self.alw._help=[yforx,yin_ancestry]self.alw.itemClicked.connect(setAncHelp)agb.layout().addWidget(self.alw)hbox.addWidget(agb)lgb=QGroupBox(_('Set Logic'))lgb.setLayout(QVBoxLayout())lgb.layout().setContentsMargins(*(2,)*4)defsetManipHelp(item):self.stbar.showMessage(self.llw._help[self.llw.row(item)])self.llw=QListWidget(self)self.llw.addItems([xforx,yin_logical])self.llw._help=[yforx,yin_logical]self.llw.itemClicked.connect(setManipHelp)lgb.layout().addWidget(self.llw)hbox.addWidget(lgb)# Clicking on one listwidget should clear selection of the otherslistwidgets=(self.clw,self.flw,self.alw,self.llw)forwinlistwidgets:w.itemClicked.connect(self.itemClicked)#w.itemActivated.connect(self.returnPressed)forw2inlistwidgets:ifwisnotw2:w.itemClicked.connect(w2.clearSelection)layout.addLayout(hbox,1)self.entry=RevsetEntry(self)self.entry.addCompletions(_logical,_ancestry,_filepatterns,_common)layout.addWidget(self.entry,0)txt=_('<a href="http://www.selenic.com/mercurial/hg.1.html#revsets">''help revsets</a>')helpLabel=QLabel(txt)helpLabel.setOpenExternalLinks(True)self.stbar.addPermanentWidget(helpLabel)layout.addWidget(self.stbar,0)QShortcut(QKeySequence('Return'),self,self.returnPressed)QShortcut(QKeySequence('Escape'),self,self.reject)defrunQuery(self):self.entry.setEnabled(False)self.showMessage.emit(_('Searching...'))self.progress.emit(*cmdui.startProgress(_('Running'),_('query')))self.refreshing=RevsetThread(self.repo,self.entry.text(),self)self.refreshing.showMessage.connect(self.showMessage)self.refreshing.queryIssued.connect(self.queryIssued)self.refreshing.finished.connect(self.queryFinished)self.refreshing.setCursorPosition.connect(self.entry.setCursorPosition)self.refreshing.start()defqueryFinished(self):self.refreshing.wait()self.entry.setEnabled(True)self.progress.emit(*cmdui.stopProgress(_('Running')))defreturnPressed(self):text=self.entry.text()ifself.entry.hasSelectedText():lineFrom,indexFrom,lineTo,indexTo=self.entry.getSelection()start=self.entry.positionFromLineIndex(lineFrom,indexFrom)end=self.entry.positionFromLineIndex(lineTo,indexTo)sel=self.entry.selectedText()ifsel.count('(')andsel.contains(')'):bopen=sel.indexOf('(')bclose=sel.lastIndexOf(')')ifbopen<bclose:self.entry.setSelection(lineFrom,start+bopen+1,lineFrom,start+bclose)self.entry.setFocus()returnself.entry.setSelection(lineTo,indexTo,lineTo,indexTo)else:self.runQuery()self.entry.setFocus()defitemClicked(self,item):self.entry.beginUndoAction()text=self.entry.text()itext,ilen=item.text(),len(item.text())ifself.entry.hasSelectedText():# replace selectionlineFrom,indexFrom,lineTo,indexTo=self.entry.getSelection()start=self.entry.positionFromLineIndex(lineFrom,indexFrom)end=self.entry.positionFromLineIndex(lineTo,indexTo)newtext=text[:start]+itext+text[end:]self.entry.setText(newtext)self.entry.setSelection(lineFrom,indexFrom,lineFrom,indexFrom+ilen)else:line,index=self.entry.getCursorPosition()pos=self.entry.positionFromLineIndex(line,index)iflen(text)<=pos:# cursor at end of text, appendiftextandtext[-1]!=u' ':text=text+u' 'newtext=text+itextself.entry.setText(newtext)self.entry.setSelection(line,len(text),line,len(newtext))eliftext[pos]==u' ':# cursor is at a space, insert itemnewtext=text[:pos]+itext+text[pos:]self.entry.setText(newtext)self.entry.setSelection(line,pos,line,pos+ilen)else:# cursor is on text, wrap current wordstart,end=pos,poswhilestartandtext[start-1]!=u' ':start=start-1whileend<len(text)andtext[end]!=u' ':end=end+1bopen=itext.indexOf('(')newtext=text[:start]+itext[:bopen+1]+text[start:end]+ \
')'+text[end:]self.entry.setText(newtext)self.entry.setSelection(line,start,line,end+bopen+2)self.entry.endUndoAction()defaccept(self):self.hide()defreject(self):self.accept()classRevsetEntry(QsciScintilla):def__init__(self,parent=None):super(RevsetEntry,self).__init__(parent)self.setMarginWidth(1,0)self.setReadOnly(False)self.setUtf8(True)self.setCaretWidth(10)self.setCaretLineBackgroundColor(QColor("#e6fff0"))self.setCaretLineVisible(True)self.setAutoIndent(True)self.setMatchedBraceBackgroundColor(Qt.yellow)self.setIndentationsUseTabs(False)self.setBraceMatching(QsciScintilla.SloppyBraceMatch)self.setWrapMode(QsciScintilla.WrapWord)self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)sp=QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Minimum)sp.setHorizontalStretch(1)sp.setVerticalStretch(0)self.setSizePolicy(sp)self.setAutoCompletionThreshold(2)self.setAutoCompletionSource(QsciScintilla.AcsAPIs)self.setAutoCompletionFillupsEnabled(True)self.setLexer(QsciLexerPython(self))self.lexer().setFont(qtlib.getfont('fontcomment').font())self.apis=QsciAPIs(self.lexer())defaddCompletions(self,*lists):forlistinlists:forx,yinlist:self.apis.add(x)self.apis.prepare()defkeyPressEvent(self,event):ifevent.key()==Qt.Key_Escape:event.ignore()returnifevent.key()in(Qt.Key_Enter,Qt.Key_Return):ifnotself.isListActive():event.ignore()returnsuper(RevsetEntry,self).keyPressEvent(event)defsizeHint(self):returnQSize(10,self.fontMetrics().height())classRevsetThread(QThread):queryIssued=pyqtSignal(QString,object)showMessage=pyqtSignal(QString)setCursorPosition=pyqtSignal(int,int)def__init__(self,repo,query,parent):super(RevsetThread,self).__init__(parent)self.repo=hg.repository(repo.ui,repo.root)self.text=hglib.fromunicode(query)self.query=querydefrun(self):if'('notinself.text:try:ctx=self.repo[self.text]self.showMessage.emit(_('found revision'))self.queryIssued.emit(self.query,[ctx.rev()])returnexcept(error.RepoError,error.LookupError,error.Abort):self.text='keyword("%s")'%self.text cwd = os.getcwd()
try:
os.chdir(self.repo.root)
- func = revset.match(self.text)
+ func = revset.match(self.repo.ui, self.text)
l = []
for c in func(self.repo, range(len(self.repo))):
l.append(c)
self.showMessage.emit(_('%d matches found')%len(l))self.queryIssued.emit(self.query,l)excepterror.ParseError,e:iflen(e.args)==2:msg,pos=e.argsself.setCursorPosition.emit(0,pos)else:msg=e.args[0]self.showMessage.emit(_('Parse Error: ')+hglib.tounicode(msg))exceptTypeError:raiseexceptException,e:self.showMessage.emit(_('Invalid query: ')+hglib.tounicode(str(e)))os.chdir(cwd)defrun(ui,*pats,**opts):fromtortoisehg.utilimportpathsfromtortoisehg.hgqtimportthgreporepo=thgrepo.repository(ui,path=paths.find_root())returnRevisionSetQuery(repo)
Attach a Trello Card
Add a tag
Your session has expired
You are no longer logged in. Please log in and try your request again.
Filter RSS Feed
This RSS feed URL allows you to see the contents of your current filter using any feed reader.
This link includes a special authentication token. If you share the URL with anyone else, they can see this RSS feed's activity. You can disable these tokens when needed.
Your current filter is unsaved; changing it won't affect this RSS feed.