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.
# repowidget.py - TortoiseHg repository widget## Copyright (C) 2007-2010 Logilab. All rights reserved.# Copyright (C) 2010 Adrian Buehlmann <adrian@cadifra.com>## This software may be used and distributed according to the terms# of the GNU General Public License, incorporated herein by reference.importbinasciiimportosfrommercurialimportutil,revsetfromtortoisehg.utilimportshlib,hglibfromtortoisehg.hgqt.i18nimport_fromtortoisehg.hgqt.qtlibimportgeticon,getfont,QuestionMsgBox,InfoMsgBoxfromtortoisehg.hgqt.qtlibimportCustomPrompt,SharedWidget,DemandWidgetfromtortoisehg.hgqt.repomodelimportHgRepoListModelfromtortoisehg.hgqtimportcmdui,update,tag,backout,merge,visdifffromtortoisehg.hgqtimportarchive,thgimport,thgstrip,run,purgefromtortoisehg.hgqtimportbisect,rebase,resolve,thgrepofromtortoisehg.hgqt.repofilterimportRepoFilterBarfromtortoisehg.hgqt.repoviewimportHgRepoViewfromtortoisehg.hgqt.revdetailsimportRevDetailsWidgetfromtortoisehg.hgqt.commitimportCommitWidgetfromtortoisehg.hgqt.manifestdialogimportManifestTaskWidgetfromtortoisehg.hgqt.syncimportSyncWidgetfromtortoisehg.hgqt.grepimportSearchWidgetfromtortoisehg.hgqt.quickbarimportGotoQuickBarfromPyQt4.QtCoreimport*fromPyQt4.QtGuiimport*classRepoWidget(QWidget):showMessageSignal=pyqtSignal(QString)closeSelfSignal=pyqtSignal(QWidget)output=pyqtSignal(QString,QString)progress=pyqtSignal(QString,object,QString,QString,object)makeLogVisible=pyqtSignal(bool)titleChanged=pyqtSignal(unicode)"""Emitted when changed the expected title for the RepoWidget tab"""singlecmenu=Nonepaircmenu=Nonemulticmenu=Nonedef__init__(self,repo,workbench):QWidget.__init__(self,acceptDrops=True)self.repo=reporepo.repositoryChanged.connect(self.repositoryChanged)repo.repositoryDestroyed.connect(self.repositoryDestroyed)repo.configChanged.connect(self.configChanged)self.workbench=workbenchself.revsetfilter=Falseself.branch=''self.bundle=Noneself.revset=set()self._reload_rev='.'# select working parent at startupself.currentMessage=''self.runner=Noneself.dirty=Falseself.setupUi()self.createActions()self.restoreSettings()self.setupModels()defsetupUi(self):SP=QSizePolicyself.repotabs_splitter=QSplitter(orientation=Qt.Vertical)self.setLayout(QVBoxLayout())self.layout().setContentsMargins(0,0,0,0)self.layout().setSpacing(0)hbox=QHBoxLayout()hbox.setContentsMargins(0,0,0,0)hbox.setSpacing(0)self.layout().addLayout(hbox)self.gototb=tb=GotoQuickBar(self)tb.setObjectName('gototb')tb.gotoSignal.connect(self.goto)hbox.addWidget(tb)self.bundleAccept=b=QPushButton(_('Accept'))b.setShown(False)b.setToolTip(_('Pull incoming changesets into your repository'))b.clicked.connect(self.acceptBundle)hbox.addWidget(b)self.bundleReject=b=QPushButton(_('Reject'))b.setToolTip(_('Reject incoming changesets'))b.clicked.connect(self.rejectBundle)b.setShown(False)hbox.addWidget(b)self.filterbar=RepoFilterBar(self.repo)self.filterbar.branchChanged.connect(self.setBranch)self.filterbar.progress.connect(self.progress)self.filterbar.showMessage.connect(self.showMessage)self.filterbar.revisionSet.connect(self.setRevisionSet)self.filterbar.clearSet.connect(self.clearSet)self.filterbar.filterToggled.connect(self.filterToggled)hbox.addWidget(self.filterbar)self.revsetfilter=self.filterbar.filtercb.isChecked()self.layout().addWidget(self.repotabs_splitter)QShortcut(QKeySequence('CTRL+P'),self,self.gotoParent)self.repoview=view=HgRepoView(self.workbench,self.repo)view.revisionSelected.connect(self.revision_selected)view.revisionClicked.connect(self.revision_clicked)view.revisionActivated.connect(self.revision_activated)view.showMessage.connect(self.showMessage)view.menuRequested.connect(self.viewMenuRequest)sp=SP(SP.Expanding,SP.Expanding)sp.setHorizontalStretch(0)sp.setVerticalStretch(1)sp.setHeightForWidth(self.repoview.sizePolicy().hasHeightForWidth())view.setSizePolicy(sp)view.setFrameShape(QFrame.StyledPanel)self.repotabs_splitter.addWidget(self.repoview)self.repotabs_splitter.setCollapsible(0,False)self.repotabs_splitter.setStretchFactor(0,1)self.taskTabsWidget=tt=QTabWidget()tt.setDocumentMode(True)tt.setTabPosition(QTabWidget.East)self.repotabs_splitter.addWidget(self.taskTabsWidget)self.repotabs_splitter.setStretchFactor(1,1)self.revDetailsWidget=w=RevDetailsWidget(self.repo)w.revisionLinkClicked.connect(self.goto)w.fileview.showDescSignal.connect(self.showMessage)self.logTabIndex=idx=tt.addTab(w,geticon('log'),'')tt.setTabToolTip(idx,_("Revision details"))self.commitDemand=w=DemandWidget(self.createCommitWidget)self.commitTabIndex=idx=tt.addTab(w,geticon('commit'),'')tt.setTabToolTip(idx,_("Commit"))self.manifestDemand=w=DemandWidget(self.createManifestWidget)self.manifestTabIndex=idx=tt.addTab(w,geticon('annotate'),'')tt.setTabToolTip(idx,_('Manifest'))self.grepDemand=w=DemandWidget(self.createGrepWidget)self.grepTabIndex=idx=tt.addTab(w,geticon('repobrowse'),'')tt.setTabToolTip(idx,_("Search"))self.syncDemand=w=DemandWidget(self.createSyncWidget)self.syncTabIndex=idx=tt.addTab(w,geticon('sync'),'')tt.setTabToolTip(idx,_("Synchronize"))deftitle(self):"""Returns the expected title for this widget [unicode]"""ifself.bundle:return_('%s <incoming>')%self.repo.shortnameelifself.branch:return'%s [%s]'%(self.repo.shortname,self.branch)else:returnself.repo.shortname@pyqtSlot()defshowSearchBar(self):"""Show tasktab-specific search bar if available"""curtt=self.taskTabsWidget.currentWidget()show=getattr(curtt,'showSearchBar',None)ifshow:show()defgetCommitWidget(self):returngetattr(self.repo,'_commitwidget',None)# TODO: uglydefcreateCommitWidget(self):cw=self.getCommitWidget()ifcw:cw.commitComplete.connect(self.reload)returnSharedWidget(cw)pats={}opts={}b=QPushButton('Commit')cw=CommitWidget(pats,opts,self.repo.root,True,self)# Shared widgets must be connected directly to workbenchcw.output.connect(self.workbench.log.output)cw.progress.connect(lambdatp,p,i,u,tl:self.workbench.statusbar.progress(tp,p,i,u,tl,self.repo.root))cw.makeLogVisible.connect(self.workbench.log.setShown)defopenlink(link):ifunicode(link).startswith('subrepo:'):self.workbench.showRepo(link[8:])cw.linkActivated.connect(openlink)cw.showMessage.connect(self.showMessage)cw.buttonHBox.addWidget(b)cw.commitButtonName.connect(lambdan:b.setText(n))cw.loadConfigs(QSettings())cw.reload()b.clicked.connect(cw.commit)self.repo._commitwidget=cwreturnSharedWidget(cw)defcreateManifestWidget(self):deffilterrev(rev):ifisinstance(rev,basestring):# unapplied patchreturnNone# TODOelse:returnrevw=ManifestTaskWidget(self.repo.ui,self.repo,rev=filterrev(self.rev),parent=self)self.repoview.revisionClicked.connect(lambdarev:w.setRev(filterrev(rev)))w.revChanged.connect(self.repoview.goto)w.revisionHint.connect(self.showMessage)w.grepRequested.connect(self.grep)returnwdefcreateSyncWidget(self):sw=getattr(self.repo,'_syncwidget',None)# TODO: uglyifnotsw:sw=SyncWidget(self.repo.root,True,self)# Shared widgets must be connected directly to workbenchsw.output.connect(self.workbench.log.output)sw.progress.connect(lambdatp,p,i,u,tl:self.workbench.statusbar.progress(tp,p,i,u,tl,self.repo.root))sw.makeLogVisible.connect(self.workbench.log.setShown)self.repo._syncwidget=swsw.outgoingNodes.connect(self.setOutgoingNodes)sw.showMessage.connect(self.showMessage)sw.incomingBundle.connect(self.setBundle)returnSharedWidget(sw)@pyqtSlot(QString)defsetBundle(self,bfile):self.bundle=unicode(bfile)oldlen=len(self.repo)self.repo=thgrepo.repository(self.repo.ui,self.repo.root,bundle=self.bundle)self.repoview.setRepo(self.repo)self.revDetailsWidget.setRepo(self.repo)self.bundleAccept.setHidden(False)self.bundleReject.setHidden(False)self.filterbar.revsetle.setText('incoming()')self.filterbar.setEnabled(False)self.titleChanged.emit(self.title())newlen=len(self.repo)self.revset=[self.repo[n].node()forninrange(oldlen,newlen)]self.repomodel.revset=self.revsetself.reload()defclearBundle(self):self.bundleAccept.setHidden(True)self.bundleReject.setHidden(True)self.filterbar.setEnabled(True)self.filterbar.revsetle.setText('')self.revset=[]self.repomodel.revset=self.revsetself.bundle=Noneself.titleChanged.emit(self.title())self.repo=thgrepo.repository(self.repo.ui,self.repo.root)self.repoview.setRepo(self.repo)self.revDetailsWidget.setRepo(self.repo)defacceptBundle(self):self.taskTabsWidget.setCurrentIndex(self.syncTabIndex)self.syncDemand.pullBundle(self.bundle,None)self.clearBundle()defpullToRev(self):self.taskTabsWidget.setCurrentIndex(self.syncTabIndex)self.syncDemand.pullBundle(self.bundle,self.rev)removed=[self.repo[self.rev]]whileremoved:ctx=removed.pop()ifctx.node()inself.revset:self.revset.remove(ctx.node())removed.extend(ctx.parents())self.repomodel.revset=self.revsetifnotself.revset:self.clearBundle()self.refresh()defrejectBundle(self):self.clearBundle()self.reload()defclearSet(self):self.revset=[]ifself.revsetfilter:self.reload()else:self.repomodel.revset=[]self.refresh()defsetRevisionSet(self,nodes):self.revset=[self.repo[n].node()forninnodes]ifself.revsetfilter:self.reload()else:self.repomodel.revset=self.revsetself.refresh()@pyqtSlot(bool)deffilterToggled(self,checked):self.revsetfilter=checkedifself.revset:self.repomodel.filterbyrevset=checkedself.reload()defsetOutgoingNodes(self,nodes):self.filterbar.revsetle.setText('outgoing()')self.setRevisionSet(nodes)defcreateGrepWidget(self):upats={}gw=SearchWidget(upats,self.repo,self)gw.setRevision(self.repoview.current_rev)gw.showMessage.connect(self.showMessage)returngwdefreponame(self):returnself.repo.shortname@propertydefrev(self):"""Returns the current active revision"""returnself.repoview.current_revdefshowMessage(self,msg):self.currentMessage=msgifself.isVisible():self.showMessageSignal.emit(msg)defshowEvent(self,event):QWidget.showEvent(self,event)self.showMessageSignal.emit(self.currentMessage)ifself.dirty:print'page was dirty, reloading...'self.reload()self.dirty=FalsedefcreateActions(self):self.actionActivateRev=QAction('Activate rev.',self)self.actionActivateRev.setShortcuts([Qt.SHIFT+Qt.Key_Return,Qt.SHIFT+Qt.Key_Enter])self.actionActivateRev.triggered.connect(self.revision_activated)self.addAction(self.actionActivateRev)allactions=[('manifest',_('Browse at rev...'),None,_('Show the manifest at selected revision'),None,self.manifestRevision),('update',_('Update...'),'update',None,None,self.updateToRevision),('merge',_('Merge with...'),'merge',None,None,self.mergeWithRevision),('tag',_('Tag...'),'tag',None,None,self.tagToRevision),('backout',_('Backout...'),None,None,None,self.backoutToRevision),('pushto',_('Push to here'),None,None,None,self.pushToRevision),('export',_('Export patch'),None,None,None,self.exportRevisions),('email',_('Email patch...'),None,None,None,self.emailRevision),('archive',_('Archive...'),None,None,None,self.archiveRevision),('copyhash',_('Copy hash'),None,None,None,self.copyHash),('rebase',_('Rebase...'),None,None,None,self.rebaseRevision),('qimport',_('Import to MQ'),None,None,None,self.qimportRevision),('qfinish',_('Finish patch'),None,None,None,self.qfinishRevision),('qdelete',_('Delete patch'),None,None,None,self.qdeleteRevision),('strip',_('Strip...'),None,None,None,self.stripRevision),('qpop-all',_('Pop all patches'),None,None,None,self.qpopAllRevision),('qgoto',_('Goto patch'),None,None,None,self.qgotoRevision),('postreview',_('Post to Review Board...'),'reviewboard',None,None,self.sendToReviewBoard)]self._actions={}forname,desc,icon,tip,key,cbinallactions:self._actions[name]=act=QAction(desc,self)ificon:act.setIcon(geticon(icon))iftip:act.setStatusTip(tip)ifkey:act.setShortcut(key)ifcb:act.triggered.connect(cb)self.addAction(act)defdragEnterEvent(self,event):paths=[unicode(u.toLocalFile())foruinevent.mimeData().urls()]ifutil.any(os.path.isfile(p)forpinpaths):event.setDropAction(Qt.CopyAction)event.accept()defdropEvent(self,event):paths=[unicode(u.toLocalFile())foruinevent.mimeData().urls()]filepaths=[pforpinpathsifos.path.isfile(p)]iffilepaths:self.thgimport(filepaths)event.setDropAction(Qt.CopyAction)event.accept()defback(self):self.repoview.back()defforward(self):self.repoview.forward()defbisect(self,paths=None):dlg=bisect.BisectDialog(self.repo,{},self)dlg.finished.connect(dlg.deleteLater)dlg.exec_()defresolve(self,paths=None):dlg=resolve.ResolveDialog(self.repo,self)dlg.finished.connect(dlg.deleteLater)dlg.exec_()defthgimport(self,paths=None):dlg=thgimport.ImportDialog(repo=self.repo,parent=self)dlg.finished.connect(dlg.deleteLater)ifpaths:dlg.setfilepaths(paths)dlg.exec_()defverify(self):cmdline=['--repository',self.repo.root,'verify']dlg=cmdui.Dialog(cmdline,self)dlg.exec_()defrecover(self):cmdline=['--repository',self.repo.root,'recover']dlg=cmdui.Dialog(cmdline,self)dlg.exec_()defrollback(self):defread_undo():ifos.path.exists(self.repo.sjoin('undo')):try:args=self.repo.opener('undo.desc','r').read().splitlines()ifargs[1]!='commit':returnNonereturnargs[1],int(args[0])except(IOError,IndexError,ValueError):passreturnNonedata=read_undo()ifdataisNone:InfoMsgBox(_('No transaction available'),_('There is no rollback transaction available'))returnelifdata[0]=='commit':ifnotQuestionMsgBox(_('Undo last commit?'),_('Undo most recent commit (%d), preserving file changes?')%data[1]):returnelse:ifnotQuestionMsgBox(_('Undo last transaction?'),_('Rollback to revision %d (undo %s)?')%(data[1]-1,data[0])):returntry:rev=self.repo['.'].rev()exceptException,e:InfoMsgBox(_('Repository Error'),_('Unable to determine working copy revision\n')+hglib.tounicode(e))returnifrev>=data[1]andnotQuestionMsgBox(_('Remove current working revision?'),_('Your current working revision (%d) will be removed ''by this rollback, leaving uncommitted changes.\n ''Continue?'%rev)):returnself.repo.incrementBusyCount()try:saved=self.repo.ui.quietself.repo.ui.quiet=Trueself.repo.rollback()self.repo.ui.quiet=savedfinally:self.repo.decrementBusyCount()QTimer.singleShot(500,lambda:shlib.shell_notify([self.repo.root]))defpurge(self):try:wctx=self.repo[None]wctx.status(ignored=True,unknown=True)exceptException,e:InfoMsgBox(_('Repository Error'),_('Unable to query unrevisioned files\n')+hglib.tounicode(str(e)))returnU,I=wctx.unknown(),wctx.ignored()ifnotUandnotI:InfoMsgBox(_('No unrevisioned files'),_('There are no purgable unrevisioned files'))returndlg=purge.PurgeDialog(self.repo,U,I,self)dlg.setWindowFlags(Qt.Sheet)dlg.setWindowModality(Qt.WindowModal)dlg.exec_()@pyqtSlot(unicode,dict)defgrep(self,pattern='',opts={}):"""Open grep task tab"""opts=dict((str(k),str(v))fork,vinopts.iteritems())self.taskTabsWidget.setCurrentIndex(self.grepTabIndex)self.grepDemand.setSearch(pattern,**opts)defsetupModels(self):# Filter revision set in case revisions were removedself.revset=[rforrinself.revsetifrinself.repo]self.repomodel=HgRepoListModel(self.repo,self.branch,self.revset,self.revsetfilter,self)self.repomodel.filled.connect(self.modelFilled)self.repomodel.loaded.connect(self.modelLoaded)self.repomodel.showMessage.connect(self.showMessage)self.repoview.setModel(self.repomodel)self.gototb.setCompletionKeys(self.repo.tags().keys())defmodelFilled(self):'initial batch of revisions loaded'self.repoview.resizeColumns()self.repoview.goto(self._reload_rev)# emits revision_selectedself.revDetailsWidget.finishReload()defmodelLoaded(self):'all revisions loaded (graph generator completed)'# Perhaps we can update a GUI element later, to indicate full loadpassdefrevision_clicked(self,rev):'User clicked on a repoview row'tw=self.taskTabsWidgetiftype(rev)==str:# unapplied patchtw.setCurrentIndex(self.logTabIndex)elifrevisNone:tw.setCurrentIndex(self.commitTabIndex)eliftw.currentWidget()in(self.commitDemand,self.syncDemand):tw.setCurrentIndex(self.logTabIndex)defrevision_selected(self,rev):'View selection changed, could be a reload'ifself.repomodel.graphisNone:returniftype(rev)==str:# unapplied patch# FIXME remove unapplied patch branch when# patches fully handled downstreamself.revDetailsWidget.revision_selected(rev)# grep and manifest are unlikely to ever be able to use a# patch ctxelse:self.revDetailsWidget.revision_selected(rev)self.manifestDemand.forward('setRev',rev)self.grepDemand.forward('setRevision',rev)defgotoParent(self):self.repoview.clearSelection()self.goto('.')defgoto(self,rev):ifrevisnotNone:rev=str(rev)self._reload_rev=reviflen(self.repoview.model().graph):self.repoview.goto(rev)defrevision_activated(self,rev=None):rev=revorself.revifisinstance(rev,basestring):# unapplied patchreturnvisdiff.visualdiff(self.repo.ui,self.repo,[],{'change':rev})defreload(self):'Initiate a refresh of the repo model, rebuild graph'self.repo.thginvalidate()self.rebuildGraph()self.commitDemand.forward('reload')self.filterbar.refresh()defrebuildGraph(self):self.showMessage('')ifself.revisnotNoneandlen(self.repo)>=self.rev:self._reload_rev=self.revelse:self._reload_rev='.'self.setupModels()self.revDetailsWidget.record()defreloadTaskTab(self):tti=self.taskTabsWidget.currentIndex()iftti==self.logTabIndex:ttw=self.revDetailsWidgeteliftti==self.commitTabIndex:ttw=self.commitDemand.get()eliftti==self.manifestTabIndex:ttw=self.manifestDemand.get()eliftti==self.syncTabIndex:ttw=self.syncDemand.get()eliftti==self.grepTabIndex:ttw=self.grepDemand.get()ifttw:ttw.reload()defrefresh(self):'Refresh the repo model view, clear cached data'self.repo.thginvalidate()self.repomodel.invalidate()self.revDetailsWidget.reload()self.filterbar.refresh()defrepositoryDestroyed(self):'Repository has detected itself to be deleted'self.closeSelfSignal.emit(self)defrepositoryChanged(self):'Repository has detected a changelog / dirstate change'ifself.isVisible():self.rebuildGraph()else:self.dirty=TruedefconfigChanged(self):'Repository is reporting its config files have changed'self.repomodel.invalidate()self.revDetailsWidget.reload()self.titleChanged.emit(self.title())# TODO: emit only if actually changed@pyqtSlot(unicode,bool)defsetBranch(self,branch,allparents=True):'Change the branch filter'self.branch=branchself.repomodel.setBranch(branch=branch,allparents=allparents)self.titleChanged.emit(self.title())#### Workbench methods##defswitchedTo(self):'Update back / forward actions'self.repoview.updateActions()defstoreSettings(self):self.revDetailsWidget.storeSettings()s=QSettings()repoid=str(self.repo[0])s.setValue('repowidget/splitter-'+repoid,self.repotabs_splitter.saveState())defrestoreSettings(self):self.revDetailsWidget.restoreSettings()s=QSettings()repoid=str(self.repo[0])self.repotabs_splitter.restoreState(s.value('repowidget/splitter-'+repoid).toByteArray())defokToContinue(self):returnself.commitDemand.forward('canExit',default=True)and \
self.syncDemand.forward('canExit',default=True)defcloseRepoWidget(self):'''returns False if close should be aborted'''ifnotself.okToContinue():returnFalseifself.isVisible():# assuming here that there is at most one RepoWidget visibleself.storeSettings()self.revDetailsWidget.storeSettings()s=QSettings()self.commitDemand.forward('storeConfigs',s)self.filterbar.storeConfigs(s)returnTruedefincoming(self):self.syncDemand.get().incoming()defpull(self):self.syncDemand.get().pull()defoutgoing(self):self.syncDemand.get().outgoing()defpush(self):self.syncDemand.get().push()defqpush(self):"""QPush a patch from MQ"""cmdline=['qpush','--repository',self.repo.root]self.runCommand(_('QPush - TortoiseHg'),cmdline)defqpop(self):"""QPop a patch from MQ"""cmdline=['qpop','--repository',self.repo.root]self.runCommand(_('QPop - TortoiseHg'),cmdline)#### Repoview context menu##defviewMenuRequest(self,point,selection):'User requested a context menu in repo view widget'# selection is a list of the currently selected revisions.# Integers for changelog revisions, None for the working copy,# or strings for unapplied patches.iflen(selection)==0:returnelifself.bundle:# Special menu for applied bundlemenu=QMenu(self)# TODO: save in repowidgetact=QAction(_('Pull to here'),self)act.triggered.connect(self.pullToRev)menu.addAction(act)menu.exec_(point)returneliflen(selection)==1:self.singleSelectionMenu(point,selection)eliflen(selection)==2:self.doubleSelectionMenu(point,selection)else:self.multipleSelectionMenu(point,selection)defsingleSelectionMenu(self,point,selection):ifnotself.singlecmenu:menu=QMenu(self)allactions=[[None,['update','manifest','merge','tag','backout','pushto','export','email','archive','copyhash']],['rebase',['rebase']],['mq',['qgoto','qpop-all','qimport','qfinish','qdelete','strip']],['reviewboard',['postreview']]]exs=self.repo.extensions()forext,actionsinallactions:ifextisNoneorextinexs:foractinactions:menu.addAction(self._actions[act])menu.addSeparator()self.singlecmenu=menuctx=self.repo.changectx(self.rev)workingdir=self.revisNoneappliedpatch=ctx.thgmqappliedpatch()unappliedpatch=ctx.thgmqunappliedpatch()qparent='qparent'inctx.tags()patch=appliedpatchorunappliedpatchrealrev=notunappliedpatchandnotworkingdirnormalrev=notpatchandnotworkingdirenabled={'update':notunappliedpatch,'manifest':notunappliedpatch,'merge':normalrev,'tag':normalrev,'backout':normalrev,'export':notworkingdir,'email':notworkingdir,'pushto':realrev,'archive':realrev,'copyhash':realrev,'rebase':notunappliedpatch,'qgoto':patch,'qpop-all':qparent,'qimport':normalrev,'qfinish':appliedpatch,'qdelete':unappliedpatch,'strip':normalrev,'postreview':normalrev}foraction,enabledinenabled.iteritems():self._actions[action].setEnabled(enabled)self.singlecmenu.exec_(point)defexportRevisions(self,revisions):ifnotrevisions:revisions=[self.rev]epath=os.path.join(self.repo.root,self.repo.shortname+'_%r.patch')cmdline=['export','--repository',self.repo.root,'--verbose','--output',epath]forrevinrevisions:cmdline.extend(['--rev',str(rev)])self.runCommand(_('Export - TortoiseHg'),cmdline)defdoubleSelectionMenu(self,point,selection):forrinselection:# No pair menu if working directory or unapplied patchiftype(r)isnotint:returndefdagrange():ifrevA>revB:B,A=selectionelse:A,B=selectionfunc=revset.match('%s::%s'%(A,B))func(self.repo,range(0,1))return[cforcinfunc(self.repo,range(len(self.repo)))]defexportPair():self.exportRevisions(selection)defexportDagRange():l=dagrange()ifl:self.exportRevisions(l)defdiffPair():revA,revB=selectionvisdiff.visualdiff(self.repo.ui,self.repo,[],{'rev':'%s:%s'%(revA,revB)})defemailPair():run.email(self.repo.ui,rev=selection,repo=self.repo)defemailDagRange():l=dagrange()ifl:run.email(self.repo.ui,rev=l,repo=self.repo)defbisectNormal():revA,revB=selectionopts={'good':str(revA),'bad':str(revB)}dlg=bisect.BisectDialog(self.repo,opts,self)dlg.finished.connect(dlg.deleteLater)dlg.exec_()defbisectReverse():revA,revB=selectionopts={'good':str(revB),'bad':str(revA)}dlg=bisect.BisectDialog(self.repo,opts,self)dlg.finished.connect(dlg.deleteLater)dlg.exec_()ifnotself.paircmenu:menu=QMenu(self)forname,cbin((_('Visual Diff'),diffPair),(_('Export Pair'),exportPair),(_('Email Pair'),emailPair),(_('Export DAG Range'),exportDagRange),(_('Email DAG Range'),emailDagRange),(_('Bisect - Good, Bad'),bisectNormal),(_('Bisect - Bad, Good'),bisectReverse),(_('Post Pair to Review Board'),self.sendToReviewBoard),):a=QAction(name,self)a.triggered.connect(cb)menu.addAction(a)self.paircmenu=menuself.paircmenu.exec_(point)defmultipleSelectionMenu(self,point,selection):forrinselection:# No multi menu if working directory or unapplied patchiftype(r)isnotint:returndefexportSel():self.exportRevisions(selection)defemailSel():run.email(self.repo.ui,rev=selection,repo=self.repo)ifnotself.multicmenu:menu=QMenu(self)forname,cbin((_('Export Selected'),exportSel),(_('Email Selected'),emailSel),(_('Post Selected to Review Board'),self.sendToReviewBoard),):a=QAction(name,self)a.triggered.connect(cb)menu.addAction(a)self.multicmenu=menuself.multicmenu.exec_(point)defupdateToRevision(self):dlg=update.UpdateDialog(self.repo,self.rev,self)dlg.output.connect(self.output)dlg.makeLogVisible.connect(self.makeLogVisible)dlg.progress.connect(self.progress)dlg.finished.connect(dlg.deleteLater)dlg.exec_()defmanifestRevision(self):run.manifest(self.repo.ui,repo=self.repo,rev=self.rev)defmergeWithRevision(self):dlg=merge.MergeDialog(self.rev,self.repo,self)dlg.exec_()deftagToRevision(self):dlg=tag.TagDialog(self.repo,rev=str(self.rev),parent=self)dlg.localTagChanged.connect(self.refresh)dlg.showMessage.connect(self.showMessage)dlg.exec_()defpushToRevision(self):self.taskTabsWidget.setCurrentIndex(self.syncTabIndex)self.syncDemand.pushToRevision(self.rev)defbackoutToRevision(self):dlg=backout.BackoutDialog(self.repo,str(self.rev),self)dlg.exec_() def stripRevision(self):
'Strip the selected revision and all descendants'
dlg = thgstrip.StripDialog(self.repo, rev=str(self.rev), parent=self)
+ dlg.finished.connect(dlg.deleteLater) dlg.exec_()
def sendToReviewBoard(self):
run.postreview(self.repo.ui,rev=self.repoview.selectedRevisions(),repo=self.repo)defemailRevision(self):run.email(self.repo.ui,rev=self.repoview.selectedRevisions(),repo=self.repo)defarchiveRevision(self):dlg=archive.ArchiveDialog(self.repo.ui,self.repo,self.rev,self)dlg.makeLogVisible.connect(self.makeLogVisible)dlg.output.connect(self.output)dlg.progress.connect(self.progress)dlg.exec_()defcopyHash(self):clip=QApplication.clipboard()clip.setText(binascii.hexlify(self.repo[self.rev].node()))defrebaseRevision(self):"""Rebase selected revision on top of working directory parent"""opts={'source':self.rev,'dest':self.repo['.'].rev()}dlg=rebase.RebaseDialog(self.repo,self,**opts)dlg.finished.connect(dlg.deleteLater)dlg.exec_()defqimportRevision(self):"""QImport revision and all descendents to MQ"""if'qparent'inself.repo.tags():endrev='qparent'else:endrev=''cmdline=['qimport','--rev','%s::%s'%(self.rev,endrev),'--repository',self.repo.root]self.runCommand(_('QImport - TortoiseHg'),cmdline)defqfinishRevision(self):"""Finish applied patches up to and including selected revision"""cmdline=['qfinish','qbase::%s'%self.rev,'--repository',self.repo.root]self.runCommand(_('QFinish - TortoiseHg'),cmdline)defqdeleteRevision(self):"""Delete unapplied patch"""patchname=self.repo.changectx(self.rev).thgmqpatchname()cmdline=['qdelete',str(patchname),'--repository',self.repo.root]self.runCommand(_('QDelete - TortoiseHg'),cmdline)defqpopAllRevision(self):"""Unapply all patches"""cmdline=['qpop','--all','--repository',self.repo.root]self.runCommand(_('QPop All - TortoiseHg'),cmdline)defqgotoRevision(self):"""Make REV the top applied patch"""patchname=self.repo.changectx(self.rev).thgmqpatchname()cmdline=['qgoto',str(patchname),# FIXME force option'--repository',self.repo.root]self.runCommand(_('QGoto - TortoiseHg'),cmdline)defrunCommand(self,title,cmdline):ifself.runner:InfoMsgBox(_('Unable to start'),_('Previous command is still running'))returndeffinished(ret):self.repo.decrementBusyCount()self.runner=Noneself.runner=cmdui.Runner(title,False,self)self.runner.output.connect(self.output)self.runner.progress.connect(self.progress)self.runner.makeLogVisible.connect(self.makeLogVisible)self.runner.commandFinished.connect(finished)self.repo.incrementBusyCount()self.runner.run(cmdline)
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.