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.
# commit.py - TortoiseHg's commit widget and standalone 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.importosfrommercurialimportui,util,errorfromtortoisehg.utilimporthglib,shlib,wconfig,bugtraqfrom tortoisehg.hgqt.i18n import _
from tortoisehg.hgqt.messageentry import MessageEntry
from tortoisehg.hgqt import qtlib, qscilib, status, cmdui, branchop, revpanel
-from tortoisehg.hgqt import hgrcutil, mq
+from tortoisehg.hgqt import hgrcutil, mq, lfpromptfrom PyQt4.QtCore import *
from PyQt4.QtGui import *
fromPyQt4.QsciimportQsciAPIs# Technical Debt for CommitWidget# disable commit button while no message is entered or no files are selected# qtlib decode failure dialog (ask for retry locale, suggest HGENCODING)# spell check / tab completion# in-memory patching / committing chunk selected filesclassCommitWidget(QWidget,qtlib.TaskWidget):'A widget that encompasses a StatusWidget and commit extras'commitButtonEnable=pyqtSignal(bool)mqButtonEnable=pyqtSignal(bool)linkActivated=pyqtSignal(QString)showMessage=pyqtSignal(unicode)commitComplete=pyqtSignal()progress=pyqtSignal(QString,object,QString,QString,object)output=pyqtSignal(QString,QString)makeLogVisible=pyqtSignal(bool)beginSuppressPrompt=pyqtSignal()endSuppressPrompt=pyqtSignal()def__init__(self,repo,pats,opts,embedded=False,parent=None,rev=None):QWidget.__init__(self,parent=parent)repo.configChanged.connect(self.configChanged)repo.repositoryChanged.connect(self.repositoryChanged)repo.workingBranchChanged.connect(self.workingBranchChanged)self.repo=repoself._rev=revself.lastAction=Noneself.lastCommitMsg=''self.currentAction=Noneself.currentProgress=Noneopts['ciexclude']=repo.ui.config('tortoisehg','ciexclude','')opts['pushafter']=repo.ui.config('tortoisehg','cipushafter','')opts['autoinc']=repo.ui.config('tortoisehg','autoinc','')opts['bugtraqplugin']=repo.ui.config('tortoisehg','issue.bugtraqplugin',None)opts['bugtraqparameters']=repo.ui.config('tortoisehg','issue.bugtraqparameters',None)self.opts=opts# user, dateself.stwidget=status.StatusWidget(repo,pats,opts,self)self.stwidget.showMessage.connect(self.showMessage)self.stwidget.progress.connect(self.progress)self.stwidget.linkActivated.connect(self.linkActivated)self.stwidget.fileDisplayed.connect(self.fileDisplayed)self.msghistory=[]self.runner=cmdui.Runner(notembedded,self)self.runner.setTitle(_('Commit','window title'))self.runner.output.connect(self.output)self.runner.progress.connect(self.progress)self.runner.makeLogVisible.connect(self.makeLogVisible)self.runner.commandStarted.connect(self.beginSuppressPrompt)self.runner.commandFinished.connect(self.endSuppressPrompt)self.runner.commandFinished.connect(self.commandFinished)layout=QVBoxLayout()layout.setContentsMargins(2,2,2,2)layout.setSpacing(0)layout.addWidget(self.stwidget)self.setLayout(layout)vbox=QVBoxLayout()vbox.setMargin(0)vbox.setSpacing(0)vbox.setContentsMargins(*(0,)*4)hbox=QHBoxLayout()hbox.setMargin(0)hbox.setContentsMargins(*(0,)*4)tbar=QToolBar(_("Commit Dialog Toolbar"),self)tbar.setStyleSheet(qtlib.tbstylesheet)hbox.addWidget(tbar)self.branchbutton=tbar.addAction(_('Branch: '))font=self.branchbutton.font()font.setBold(True)self.branchbutton.setFont(font)self.branchbutton.triggered.connect(self.branchOp)self.branchop=Noneself.recentMessagesButton=QToolButton(text=_('Copy message'),popupMode=QToolButton.MenuButtonPopup,toolTip=_('Copy one of the recent commit messages'))self.recentMessagesButton.clicked.connect(self.recentMessagesButton.showMenu)tbar.addWidget(self.recentMessagesButton)self.updateRecentMessages()tbar.addAction(_('Options')).triggered.connect(self.details)tbar.setIconSize(QSize(16,16))ifself.opts['bugtraqplugin']!=None:self.bugtraq=self.createBugTracker()try:parameters=self.opts['bugtraqparameters']linktext=self.bugtraq.get_link_text(parameters)exceptException,e:tracker=self.opts['bugtraqplugin'].split(' ',1)[1]qtlib.ErrorMsgBox(_('Issue Tracker'),_('Failed to load issue tracker \'%s\': %s'%(tracker,e)),parent=self)self.bugtraq=Noneelse:# connect UI because we have a valid bug trackerself.commitComplete.connect(self.bugTrackerPostCommit)tbar.addAction(linktext).triggered.connect(self.getBugTrackerCommitMessage)self.stopAction=tbar.addAction(_('Stop'))self.stopAction.triggered.connect(self.stop)self.stopAction.setIcon(qtlib.geticon('process-stop'))self.stopAction.setEnabled(False)hbox.addStretch(1)vbox.addLayout(hbox,0)self.buttonHBox=hboxifembeddedand'mq'inself.repo.extensions():self.hasmqbutton=Truepnhbox=QHBoxLayout()self.pnlabel=QLabel()pnhbox.addWidget(self.pnlabel)self.pnedit=mq.getPatchNameLineEdit()self.pnedit.setMaximumWidth(250)pnhbox.addWidget(self.pnedit)pnhbox.addStretch()vbox.addLayout(pnhbox)else:self.hasmqbutton=Falseself.pcsinfo=revpanel.ParentWidget(repo)vbox.addWidget(self.pcsinfo,0)msgte=MessageEntry(self,self.stwidget.getChecked)msgte.installEventFilter(qscilib.KeyPressInterceptor(self))vbox.addWidget(msgte,1)upperframe=QFrame()SP=QSizePolicysp=SP(SP.Expanding,SP.Expanding)sp.setHorizontalStretch(1)upperframe.setSizePolicy(sp)upperframe.setLayout(vbox)self.split=QSplitter(Qt.Vertical)sp=SP(SP.Expanding,SP.Expanding)sp.setHorizontalStretch(1)sp.setVerticalStretch(0)self.split.setSizePolicy(sp)# Add our widgets to the top of our splitterself.split.addWidget(upperframe)self.split.setCollapsible(0,False)# Add status widget document frame below our splitter# this reparents the docf from the status splitterself.split.addWidget(self.stwidget.docf)# add our splitter where the docf used to beself.stwidget.split.addWidget(self.split)self.msgte=msgteifnotself.hasmqbutton:QShortcut(QKeySequence('Ctrl+Return'),self,self.commit).setContext(Qt.WidgetWithChildrenShortcut)QShortcut(QKeySequence('Ctrl+Enter'),self,self.commit).setContext(Qt.WidgetWithChildrenShortcut)@propertydefrev(self):"""Return current revision"""returnself._revdefselectRev(self,rev):""" Select the revision that must be set when the dialog is shown again """self._rev=rev@pyqtSlot(int)@pyqtSlot(object)defsetRev(self,rev):"""Change revision to show"""self.selectRev(rev)ifself.hasmqbutton:preferredActionName=self._getPreferredActionName()curractionName=self.mqgroup.checkedAction()._nameifcurractionName!=preferredActionName:self.mqSetAction(refresh=True,actionName=preferredActionName)def_getPreferredActionName(self):"""Select the preferred action, depending on the selected revision"""ifnotself.hasmqbutton:return'commit'else:pctx=self.repo.changectx('.')ispatch='qtip'inpctx.tags()ifnotispatch:# Set the button to Commitreturn'commit'elifself.revisNone:# Set the button to QNewreturn'qnew'else:# Set the button to QRefreshreturn'qref'defmqSetupButton(self):ispatch=lambdar:'qtip'inr.changectx('.').tags()notpatch=lambdar:'qtip'notinr.changectx('.').tags()acts=(('commit',_('Commit changes'),_('Commit'),notpatch),('qnew',_('Create a new patch'),_('QNew'),None),('qref',_('Refresh current patch'),_('QRefresh'),ispatch),)classMQToolButton(QToolButton):defstyleOption(self):opt=QStyleOptionToolButton()opt.initFrom(self)returnoptdefmenuButtonWidth(self):style=self.style()opt=self.styleOption()opt.features=QStyleOptionToolButton.MenuButtonPopuprect=style.subControlRect(QStyle.CC_ToolButton,opt,QStyle.SC_ToolButtonMenu,self)returnrect.width()defsetBold(self):f=self.font()f.setWeight(QFont.Bold)self.setFont(f)defsizeHint(self):# Set the desired width to keep the button from resizingreturnQSize(self._width,QToolButton.sizeHint(self).height())self.mqtb=mqtb=MQToolButton(self)mqtb.setBold()mqtb.setPopupMode(QToolButton.MenuButtonPopup)fmk=lambdas:mqtb.fontMetrics().width(hglib.tounicode(s[2]))mqtb._width=max(map(fmk,acts))+4*mqtb.menuButtonWidth()classMQMenu(QMenu):def__init__(self,parent,repo):self.repo=reporeturnQMenu.__init__(self,parent)defgetActionByName(self,act):return[aforainself.actions()ifa._name==act][0]defshowEvent(self,event):forainself.actions():ifa._enablefunc:a.setEnabled(a._enablefunc(self.repo))returnQMenu.showEvent(self,event)self.mqgroup=QActionGroup(self)mqmenu=MQMenu(mqtb,self.repo)menurefresh=lambda:self.mqSetAction(refresh=True)forainacts:action=QAction(a[1],self.mqgroup)action._name=a[0]action._text=a[2]action._enablefunc=a[3]action.triggered.connect(menurefresh)action.setCheckable(True)mqmenu.addAction(action)mqtb.setMenu(mqmenu)mqtb.clicked.connect(self.mqPerformAction)self.mqButtonEnable.connect(mqtb.setEnabled)self.mqSetAction(actionName=self._getPreferredActionName())sc=QShortcut(QKeySequence('Ctrl+Return'),self,self.mqPerformAction)sc.setContext(Qt.WidgetWithChildrenShortcut)sc=QShortcut(QKeySequence('Ctrl+Enter'),self,self.mqPerformAction)sc.setContext(Qt.WidgetWithChildrenShortcut)returnmqtb@pyqtSlot(bool)defmqSetAction(self,refresh=False,actionName=None):ifactionName:selectedAction= \
[actforactinself.mqgroup.actions() \
ifact._name==actionName][0]selectedAction.setChecked(True)curraction=self.mqgroup.checkedAction()oldpctx=self.stwidget.pctxpctx=self.repo.changectx('.')ifcurraction._name=='qnew':self.pnlabel.setVisible(True)self.pnedit.setVisible(True)self.pnedit.setFocus()self.pnedit.setText(mq.defaultNewPatchName(self.repo))self.pnedit.selectAll()self.stwidget.setPatchContext(None)refreshwctx=refreshandoldpctxisnotNoneelse:self.pnlabel.setVisible(False)self.pnedit.setVisible(False)ispatch='qtip'inpctx.tags()defswitchAction(action,name):action.setChecked(False)action=self.mqtb.menu().getActionByName(name)action.setChecked(True)returnactionifcurraction._name=='qref'andnotispatch:curraction=switchAction(curraction,'commit')elifcurraction._name=='commit'andispatch:curraction=switchAction(curraction,'qref')ifcurraction._name=='qref':refreshwctx=refreshself.stwidget.setPatchContext(pctx)elifcurraction._name=='commit':refreshwctx=refreshandoldpctxisnotNoneself.stwidget.setPatchContext(None)ifcurraction._name=='qref':ifself.lastAction!='qref':self.lastCommitMsg=self.msgte.text()self.setMessage(hglib.tounicode(pctx.description()))else:ifself.lastAction=='qref':self.setMessage(self.lastCommitMsg)ifrefreshwctx:self.stwidget.refreshWctx()self.mqtb.setText(curraction._text)self.lastAction=curraction._namedefgetBranchCommandLine(self,branchName,repo):''' Create the command line to change or create the selected branch unless it is the selected branch Verify whether a branch exists on a repo. If it doesn't ask the user to confirm that it wants to create the branch. If it does and it is not the current branch as the user whether it wants to change to that branch. Depending on the user input, create the command line which will perform the selected action '''# This function is used both by commit() and mqPerformAction()commandlines=[]newbranch=Falsebranch=hglib.fromunicode(self.branchop)ifbranchinrepo.branchtags():# response: 0=Yes, 1=No, 2=Cancelifbranchin[p.branch()forpinrepo.parents()]:resp=0else:rev=repo[branch].rev()resp=qtlib.CustomPrompt(_('Confirm Branch Change'),_('Named branch "%s" already exists, ''last used in revision %d\n')%(self.branchop,rev),self,(_('Restart &Branch'),_('&Commit to current branch'),_('Cancel')),2,2).run()else:resp=qtlib.CustomPrompt(_('Confirm New Branch'),_('Create new named branch "%s" with this commit?\n')%self.branchop,self,(_('Create &Branch'),_('&Commit to current branch'),_('Cancel')),2,2).run()ifresp==0:newbranch=Truecommandlines.append(['branch','--repository',repo.root,'--force',branch])elifresp==2:returnNone,Falsereturncommandlines,newbranch@pyqtSlot()defmqPerformAction(self):curraction=self.mqgroup.checkedAction()ifcurraction._name=='commit':returnself.commit()# Check if we need to change branch firstcommandlines=[]ifself.branchop:commandlines,newbranch=self.getBranchCommandLine(self.branchop,self.repo)ifcommandlinesisNone:returnolist=('user','date')cmdlines=commandlines+mq.mqNewRefreshCommand(self.repo,curraction._name=='qnew',self.stwidget,self.pnedit,self.msgte.text(),self.opts,olist)self.repo.incrementBusyCount()self.currentAction=curraction._nameself.currentProgress=_('MQ Action','start progress')self.progress.emit(*cmdui.startProgress(self.currentProgress,''))self.commitButtonEnable.emit(False)self.mqButtonEnable.emit(False)self.runner.run(*cmdlines)@pyqtSlot(QString,QString)deffileDisplayed(self,wfile,contents):'Status widget is displaying a new file'ifnot(wfileandcontents):returnwfile=unicode(wfile)self._apis=QsciAPIs(self.msgte.lexer())tokens=set()foreinself.stwidget.getChecked():e=hglib.tounicode(e)tokens.add(e)tokens.add(os.path.basename(e))tokens.add(wfile)tokens.add(os.path.basename(wfile))try:frompygments.lexersimportguess_lexer_for_filenamefrompygments.tokenimportTokenfrompygments.utilimportClassNotFoundtry:contents=unicode(contents)lexer=guess_lexer_for_filename(wfile,contents)fortokentype,valueinlexer.get_tokens(contents):iftokentypeinToken.Nameandlen(value)>4:tokens.add(value)exceptClassNotFound,TypeError:passexceptImportError:passforninsorted(list(tokens)):self._apis.add(n)self._apis.apiPreparationFinished.connect(self.apiPrepFinished)self._apis.prepare()defapiPrepFinished(self):'QsciAPIs has finished parsing displayed file'self.msgte.lexer().setAPIs(self._apis)defbugTrackerPostCommit(self):# commit already happened, get last message in historymessage=self.lastmessageerror=self.bugtraq.on_commit_finished(message)iferror!=Noneandlen(error)>0:qtlib.ErrorMsgBox(_('Issue Tracker'),error,parent=self)# recreate bug tracker to get new COM object for next commitself.bugtraq=self.createBugTracker()defcreateBugTracker(self):bugtraqid=self.opts['bugtraqplugin'].split(' ',1)[0]result=bugtraq.BugTraq(bugtraqid)returnresultdefgetBugTrackerCommitMessage(self):parameters=self.opts['bugtraqparameters']message=self.getMessage()newMessage=self.bugtraq.get_commit_message(parameters,message)self.setMessage(newMessage)defdetails(self):dlg=DetailsDialog(self.opts,self.userhist,self)dlg.finished.connect(dlg.deleteLater)dlg.setWindowFlags(Qt.Sheet)dlg.setWindowModality(Qt.WindowModal)ifdlg.exec_()==QDialog.Accepted:self.opts.update(dlg.outopts)self.refresh()defworkingBranchChanged(self):'Repository has detected a change in .hg/branch'self.refresh()defrepositoryChanged(self):'Repository has detected a changelog / dirstate change'self.refresh()self.stwidget.refreshWctx()# Trigger reload of working contextdefconfigChanged(self):'Repository is reporting its config files have changed'self.refresh()@pyqtSlot()defreload(self):'User has requested a reload'self.repo.thginvalidate()self.refresh()self.stwidget.refreshWctx()# Trigger reload of working contextdefrefresh(self):ispatch=self.repo.changectx('.').thgmqappliedpatch()self.commitButtonEnable.emit(notispatch)self.msgte.refresh(self.repo)# Update branch operation buttonbranchu=hglib.tounicode(self.repo[None].branch())ifself.branchopisNone:title=_('Branch: ')+branchuelifself.branchop==False:title=_('Close Branch: ')+branchuelse:title=_('New Branch: ')+self.branchopself.branchbutton.setText(title)# Update parent csinfo widgetself.pcsinfo.set_revision(None)self.pcsinfo.update()# This is ugly, but want pnlabel to have the same alignment/style/etc# as pcsinfo, so extract the needed parts of pcsinfo's markup. Would# be nicer if csinfo exposed this information, or if csinfo could hold# widgets like pnlabel.ifself.hasmqbutton:parent=hglib.fromunicode(_('Parent:'))patchname=hglib.fromunicode(_('Patch name:'))text=hglib.fromunicode(self.pcsinfo.revlabel.text())cellend='</td>'firstidx=text.find(cellend)+len(cellend)secondidx=text[firstidx:].rfind('</tr>')iffirstidx>=0andsecondidx>=0:start=text[0:firstidx].replace(parent,patchname)self.pnlabel.setText(start+text[firstidx+secondidx:])else:self.pnlabel.setText(patchname)self.mqSetAction()defbranchOp(self):d=branchop.BranchOpDialog(self.repo,self.branchop,self)d.setWindowFlags(Qt.Sheet)d.setWindowModality(Qt.WindowModal)ifd.exec_()==QDialog.Accepted:self.branchop=d.branchopself.refresh()defcanUndo(self):'Returns undo description or None if not valid'ifos.path.exists(self.repo.sjoin('undo')):try:args=self.repo.opener('undo.desc','r').read().splitlines()ifargs[1]!='commit':returnNonereturn_('Rollback commit to revision %d')%(int(args[0])-1)except(IOError,IndexError,ValueError):passreturnNonedefrollback(self):msg=self.canUndo()ifnotmsg:returnd=QMessageBox.question(self,_('Confirm Undo'),msg,QMessageBox.Ok|QMessageBox.Cancel)ifd!=QMessageBox.Ok:returnself.repo.incrementBusyCount()self.repo.rollback()self.repo.decrementBusyCount()self.reload()QTimer.singleShot(500,lambda:shlib.shell_notify([self.repo.root]))defupdateRecentMessages(self):# Define a menu that lists recent messagesm=QMenu()forsinself.msghistory:title=s.split('\n',1)[0][:70]defoverwriteMsg(newMsg):returnlambda:self.msgSelected(newMsg)m.addAction(title).triggered.connect(overwriteMsg(s))self.recentMessagesButton.setMenu(m)defgetMessage(self):text=self.msgte.text()try:text=hglib.fromunicode(text,'strict')exceptUnicodeEncodeError:pass# TODOreturntextdefmsgSelected(self,message):ifself.msgte.text()andself.msgte.isModified():d=QMessageBox.question(self,_('Confirm Discard Message'),_('Discard current commit message?'),QMessageBox.Ok|QMessageBox.Cancel)ifd!=QMessageBox.Ok:returnself.setMessage(message)self.msgte.setFocus()defsetMessage(self,msg):self.msgte.setText(msg)self.msgte.moveCursorToEnd()self.msgte.setModified(False)defcanExit(self):ifnotself.stwidget.canExit():returnFalsereturnnotself.runner.core.running()defloadSettings(self,s,prefix):'Load history, etc, from QSettings instance'repoid=str(self.repo[0])lpref=prefix+'/commit/'# local settings (splitter, etc)gpref='commit/'# global settings (history, etc)# message history is stored in unicodeself.split.restoreState(s.value(lpref+'split').toByteArray())self.msgte.loadSettings(s,lpref+'msgte')self.stwidget.loadSettings(s,lpref+'status')self.msghistory=list(s.value(gpref+'history-'+repoid).toStringList())self.msghistory=[unicode(m)forminself.msghistoryifm]self.updateRecentMessages()self.userhist=s.value(gpref+'userhist').toStringList()self.userhist=[uforuinself.userhistifu]try:curmsg=self.repo.opener('cur-message.txt').read()self.setMessage(hglib.tounicode(curmsg))exceptEnvironmentError:passtry:curmsg=self.repo.opener('last-message.txt').read()ifcurmsg:self.addMessageToHistory(hglib.tounicode(curmsg))exceptEnvironmentError:passdefsaveSettings(self,s,prefix):'Save history, etc, in QSettings instance'repoid=str(self.repo[0])lpref=prefix+'/commit/'gpref='commit/'s.setValue(lpref+'split',self.split.saveState())self.msgte.saveSettings(s,lpref+'msgte')self.stwidget.saveSettings(s,lpref+'status')s.setValue(gpref+'history-'+repoid,self.msghistory)s.setValue(gpref+'userhist',self.userhist)try:msg=self.getMessage()self.repo.opener('cur-message.txt','w').write(msg)exceptEnvironmentError:passdefaddMessageToHistory(self,umsg):umsg=unicode(umsg)ifumsginself.msghistory:self.msghistory.remove(umsg)self.msghistory.insert(0,umsg)self.msghistory=self.msghistory[:10]self.updateRecentMessages()defaddUsernameToHistory(self,user):user=hglib.tounicode(user)ifuserinself.userhist:self.userhist.remove(user)self.userhist.insert(0,user)self.userhist=self.userhist[:10]defcommit(self):repo=self.repomsg=self.getMessage()ifnotmsg:qtlib.WarningMsgBox(_('Nothing Commited'),_('Please enter commit message'),parent=self)self.msgte.setFocus()returncommandlines=[]brcmd=[]newbranch=Falseifself.branchopisNone:newbranch=repo[None].branch()!=repo['.'].branch()elifself.branchop==False:brcmd=['--close-branch']else:commandlines,newbranch=self.getBranchCommandLine(self.branchop,self.repo)ifcommandlinesisNone:returnself.files=self.stwidget.getChecked('MAR?!S')ifnot(self.filesorbrcmdornewbranch):qtlib.WarningMsgBox(_('No files checked'),_('No modified files checkmarked for commit'),parent=self)self.stwidget.tv.setFocus()returniflen(repo.parents())>1:self.files=[]user=qtlib.getCurrentUsername(self,self.repo,self.opts)ifnotuser:returnself.addUsernameToHistory(user)checkedUnknowns=self.stwidget.getChecked('?I')ifcheckedUnknowns:res=qtlib.CustomPrompt(_('Confirm Add'),_('Add selected untracked files?'),self, (_('&Add'), _('Cancel')), 0, 1,
checkedUnknowns).run()
if res == 0:
+ haslf = 'largefiles' in repo.extensions()+ haskbf = 'kbfiles' in repo.extensions()+ if haslf or haskbf:+ result = lfprompt.promptForLfiles(self, repo.ui, repo,+ checkedUnknowns, haskbf)+ if not result:+ return+ checkedUnknowns, lfiles = result+ if lfiles:+ if haslf:+ cmd = ['add', '--repository', repo.root, '--large'] + \+ [repo.wjoin(f) for f in lfiles]+ else:+ cmd = ['add', '--repository', repo.root, '--bf'] + \+ [repo.wjoin(f) for f in lfiles]+ commandlines.append(cmd) cmd = ['add', '--repository', repo.root] + \
[repo.wjoin(f) for f in checkedUnknowns]
commandlines.append(cmd)
else:returncheckedMissing=self.stwidget.getChecked('!')ifcheckedMissing:res=qtlib.CustomPrompt(_('Confirm Remove'),_('Remove selected deleted files?'),self,(_('&Remove'),_('Cancel')),0,1,checkedMissing).run()ifres==0:cmd=['remove','--repository',repo.root]+ \
[repo.wjoin(f)forfincheckedMissing]commandlines.append(cmd)else:returntry:date=self.opts.get('date')ifdate:util.parsedate(date)dcmd=['--date',date]else:dcmd=[]excepterror.Abort,e:ife.hint:err=_('%s (hint: %s)')%(hglib.tounicode(str(e)),hglib.tounicode(e.hint))else:err=hglib.tounicode(str(e))self.showMessage.emit(err)dcmd=[]cmdline=['commit','--repository',repo.root,'--verbose','--user',user,'--message='+msg]cmdline+=dcmd+brcmd+[repo.wjoin(f)forfinself.files]iflen(repo.parents())==1:forfnameinself.opts.get('autoinc','').split(','):fname=fname.strip()iffname:cmdline.extend(['--include',fname])commandlines.append(cmdline)ifself.opts.get('pushafter'):cmd=['push','--repository',repo.root,self.opts['pushafter']]commandlines.append(cmd)repo.incrementBusyCount()self.currentAction='commit'self.currentProgress=_('Commit','start progress')self.progress.emit(*cmdui.startProgress(self.currentProgress,''))self.commitButtonEnable.emit(False)self.mqButtonEnable.emit(False)self.runner.run(*commandlines)self.stopAction.setEnabled(True)defstop(self):self.runner.cancel()defcommandFinished(self,ret):self.progress.emit(*cmdui.stopProgress(self.currentProgress))self.stopAction.setEnabled(False)self.commitButtonEnable.emit(True)self.mqButtonEnable.emit(True)self.repo.decrementBusyCount()ifret==0:self.branchop=Noneumsg=self.msgte.text()ifself.currentAction!='qref':self.lastCommitMsg=''ifself.currentAction=='commit':# capture last message for BugTraq pluginself.lastmessage=self.getMessage()ifumsg:self.addMessageToHistory(umsg)self.setMessage('')ifself.currentAction=='commit':shlib.shell_notify(self.files)self.commitComplete.emit()classDetailsDialog(QDialog):'Utility dialog for configuring uncommon settings'def__init__(self,opts,userhistory,parent):QDialog.__init__(self,parent)self.setWindowTitle(_('%s - commit options')%parent.repo.displayname)self.repo=parent.repolayout=QVBoxLayout()self.setLayout(layout)hbox=QHBoxLayout()self.usercb=QCheckBox(_('Set username:'))usercombo=QComboBox()usercombo.setEditable(True)usercombo.setEnabled(False)SP=QSizePolicyusercombo.setSizePolicy(SP(SP.Expanding,SP.Minimum))self.usercb.toggled.connect(usercombo.setEnabled)self.usercb.toggled.connect(lambdas:sandusercombo.setFocus())l=[]ifopts.get('user'):val=hglib.tounicode(opts['user'])self.usercb.setChecked(True)l.append(val)try:val=hglib.tounicode(self.repo.ui.username())l.append(val)exceptutil.Abort:passfornameinuserhistory:ifnamenotinl:l.append(name)fornameinl:usercombo.addItem(name)self.usercombo=usercombousersaverepo=QPushButton(_('Save in Repo'))usersaverepo.clicked.connect(self.saveInRepo)usersaverepo.setEnabled(False)self.usercb.toggled.connect(usersaverepo.setEnabled)usersaveglobal=QPushButton(_('Save Global'))usersaveglobal.clicked.connect(self.saveGlobal)usersaveglobal.setEnabled(False)self.usercb.toggled.connect(usersaveglobal.setEnabled)hbox.addWidget(self.usercb)hbox.addWidget(self.usercombo)hbox.addWidget(usersaverepo)hbox.addWidget(usersaveglobal)layout.addLayout(hbox)hbox=QHBoxLayout()self.datecb=QCheckBox(_('Set Date:'))self.datele=QLineEdit()self.datele.setEnabled(False)self.datecb.toggled.connect(self.datele.setEnabled)curdate=QPushButton(_('Update'))curdate.setEnabled(False)self.datecb.toggled.connect(curdate.setEnabled)self.datecb.toggled.connect(lambdas:sandcurdate.setFocus())curdate.clicked.connect(lambda:self.datele.setText(hglib.tounicode(hglib.displaytime(util.makedate()))))ifopts.get('date'):self.datele.setText(opts['date'])self.datecb.setChecked(True)else:self.datecb.setChecked(False)curdate.clicked.emit(True)hbox.addWidget(self.datecb)hbox.addWidget(self.datele)hbox.addWidget(curdate)layout.addLayout(hbox)hbox=QHBoxLayout()self.pushaftercb=QCheckBox(_('Push After Commit:'))self.pushafterle=QLineEdit()self.pushafterle.setEnabled(False)self.pushaftercb.toggled.connect(self.pushafterle.setEnabled)self.pushaftercb.toggled.connect(lambdas:sandself.pushafterle.setFocus())pushaftersave=QPushButton(_('Save in Repo'))pushaftersave.clicked.connect(self.savePushAfter)pushaftersave.setEnabled(False)self.pushaftercb.toggled.connect(pushaftersave.setEnabled)ifopts.get('pushafter'):val=hglib.tounicode(opts['pushafter'])self.pushafterle.setText(val)self.pushaftercb.setChecked(True)hbox.addWidget(self.pushaftercb)hbox.addWidget(self.pushafterle)hbox.addWidget(pushaftersave)layout.addLayout(hbox)hbox=QHBoxLayout()self.autoinccb=QCheckBox(_('Auto Includes:'))self.autoincle=QLineEdit()self.autoincle.setEnabled(False)self.autoinccb.toggled.connect(self.autoincle.setEnabled)self.autoinccb.toggled.connect(lambdas:sandself.autoincle.setFocus())autoincsave=QPushButton(_('Save in Repo'))autoincsave.clicked.connect(self.saveAutoInc)autoincsave.setEnabled(False)self.autoinccb.toggled.connect(autoincsave.setEnabled)ifopts.get('autoinc'):val=hglib.tounicode(opts['autoinc'])self.autoincle.setText(val)self.autoinccb.setChecked(True)hbox.addWidget(self.autoinccb)hbox.addWidget(self.autoincle)hbox.addWidget(autoincsave)layout.addLayout(hbox)BB=QDialogButtonBoxbb=QDialogButtonBox(BB.Ok|BB.Cancel)bb.accepted.connect(self.accept)bb.rejected.connect(self.reject)self.bb=bblayout.addWidget(bb)defsaveInRepo(self):fn=os.path.join(self.repo.root,'.hg','hgrc')self.saveToPath([fn])defsaveGlobal(self):self.saveToPath(hglib.user_rcpath())defsaveToPath(self,path):fn,cfg=hgrcutil.loadIniFile(path,self)ifnothasattr(cfg,'write'):qtlib.WarningMsgBox(_('Unable to save username'),_('Iniparse must be installed.'),parent=self)returniffnisNone:returntry:user=hglib.fromunicode(self.usercombo.currentText())ifuser:cfg.set('ui','username',user)else:try:delcfg['ui']['username']exceptKeyError:passwconfig.writefile(cfg,fn)exceptIOError,e:qtlib.WarningMsgBox(_('Unable to write configuration file'),hglib.tounicode(e),parent=self)defsavePushAfter(self):path=os.path.join(self.repo.root,'.hg','hgrc')fn,cfg=hgrcutil.loadIniFile([path],self)ifnothasattr(cfg,'write'):qtlib.WarningMsgBox(_('Unable to save after commit push'),_('Iniparse must be installed.'),parent=self)returniffnisNone:returntry:remote=hglib.fromunicode(self.pushafterle.text())ifremote:cfg.set('tortoisehg','cipushafter',remote)else:try:delcfg['tortoisehg']['cipushafter']exceptKeyError:passwconfig.writefile(cfg,fn)exceptIOError,e:qtlib.WarningMsgBox(_('Unable to write configuration file'),hglib.tounicode(e),parent=self)defsaveAutoInc(self):path=os.path.join(self.repo.root,'.hg','hgrc')fn,cfg=hgrcutil.loadIniFile([path],self)ifnothasattr(cfg,'write'):qtlib.WarningMsgBox(_('Unable to save auto include list'),_('Iniparse must be installed.'),parent=self)returniffnisNone:returntry:list=hglib.fromunicode(self.autoincle.text())iflist:cfg.set('tortoisehg','autoinc',list)else:try:delcfg['tortoisehg']['autoinc']exceptKeyError:passwconfig.writefile(cfg,fn)exceptIOError,e:qtlib.WarningMsgBox(_('Unable to write configuration file'),hglib.tounicode(e),parent=self)defaccept(self):outopts={}ifself.datecb.isChecked():date=hglib.fromunicode(self.datele.text())try:util.parsedate(date)excepterror.Abort,e:ife.hint:err=_('%s (hint: %s)')%(hglib.tounicode(str(e)),hglib.tounicode(e.hint))else:err=hglib.tounicode(str(e))qtlib.WarningMsgBox(_('Invalid date format'),err,parent=self)returnoutopts['date']=dateelse:outopts['date']=''ifself.usercb.isChecked():user=hglib.fromunicode(self.usercombo.currentText())else:user=''outopts['user']=userifnotuser:try:self.repo.ui.username()exceptutil.Abort,e:ife.hint:err=_('%s (hint: %s)')%(hglib.tounicode(str(e)),hglib.tounicode(e.hint))else:err=hglib.tounicode(str(e))qtlib.WarningMsgBox(_('No username configured'),err,parent=self)returnifself.pushaftercb.isChecked():remote=hglib.fromunicode(self.pushafterle.text())outopts['pushafter']=remoteelse:outopts['pushafter']=''self.outopts=outoptsQDialog.accept(self)classCommitDialog(QDialog):'Standalone commit tool, a wrapper for CommitWidget'def__init__(self,repo,pats,opts,parent=None):QDialog.__init__(self,parent)self.setWindowFlags(Qt.Window)self.setWindowIcon(qtlib.geticon('hg-commit'))self.pats=patsself.opts=optslayout=QVBoxLayout()layout.setMargin(0)self.setLayout(layout)toplayout=QVBoxLayout()toplayout.setContentsMargins(5,5,5,0)layout.addLayout(toplayout)commit=CommitWidget(repo,pats,opts,False,self)toplayout.addWidget(commit,1)self.statusbar=cmdui.ThgStatusBar(self)commit.showMessage.connect(self.statusbar.showMessage)commit.progress.connect(self.statusbar.progress)commit.linkActivated.connect(self.linkActivated)BB=QDialogButtonBoxbb=QDialogButtonBox(BB.Ok|BB.Close|BB.Discard)bb.accepted.connect(self.accept)bb.rejected.connect(self.reject)bb.button(BB.Discard).setText('Undo')bb.button(BB.Discard).clicked.connect(commit.rollback)bb.button(BB.Close).setDefault(False)bb.button(BB.Discard).setDefault(False)bb.button(BB.Ok).setDefault(True)self.commitButton=bb.button(BB.Ok)self.commitButton.setText(_('Commit','action button'))self.bb=bbtoplayout.addWidget(self.bb)layout.addWidget(self.statusbar)s=QSettings()self.restoreGeometry(s.value('commit/geom').toByteArray())commit.loadSettings(s,'committool')repo.repositoryChanged.connect(self.updateUndo)commit.commitComplete.connect(self.postcommit)commit.commitButtonEnable.connect(self.commitButton.setEnabled)self.setWindowTitle(_('%s - commit')%repo.displayname)self.commit=commitself.commit.reload()self.updateUndo()self.commit.msgte.setFocus()QShortcut(QKeySequence.Refresh,self,self.refresh)defdone(self,ret):self.commit.repo.configChanged.disconnect(self.commit.configChanged)self.commit.repo.repositoryChanged.disconnect(self.commit.repositoryChanged)self.commit.repo.workingBranchChanged.disconnect(self.commit.workingBranchChanged)self.commit.repo.repositoryChanged.disconnect(self.updateUndo)super(CommitDialog,self).done(ret)deflinkActivated(self,link):link=hglib.fromunicode(link)iflink.startswith('subrepo:'):fromtortoisehg.hgqt.runimportqtrunqtrun(run,ui.ui(),root=link[8:])iflink.startswith('shelve:'):repo=self.commit.repofromtortoisehg.hgqtimportshelvedlg=shelve.ShelveDialog(repo,self)dlg.finished.connect(dlg.deleteLater)dlg.exec_()self.refresh()defupdateUndo(self):BB=QDialogButtonBoxundomsg=self.commit.canUndo()ifundomsg:self.bb.button(BB.Discard).setEnabled(True)self.bb.button(BB.Discard).setToolTip(undomsg)else:self.bb.button(BB.Discard).setEnabled(False)self.bb.button(BB.Discard).setToolTip('')defrefresh(self):self.updateUndo()self.commit.reload()defpostcommit(self):repo=self.commit.stwidget.repoifrepo.ui.configbool('tortoisehg','closeci'):ifself.commit.canExit():self.reject()else:self.commit.stwidget.refthread.wait()QTimer.singleShot(0,self.reject)defaccept(self):self.commit.commit()defreject(self):ifself.commit.canExit():s=QSettings()s.setValue('commit/geom',self.saveGeometry())self.commit.saveSettings(s,'committool')QDialog.reject(self)defrun(ui,*pats,**opts):fromtortoisehg.utilimportpathsfromtortoisehg.hgqtimportthgreporoot=opts.get('root',paths.find_root())repo=thgrepo.repository(ui,path=root)pats=hglib.canonpaths(pats)os.chdir(repo.root)returnCommitDialog(repo,pats,opts)
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.