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.
# resolve.py - TortoiseHg merge conflict resolve## 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.fromPyQt4.QtCoreimport*fromPyQt4.QtGuiimport*importosfrommercurialimportmergeasmergemodfromtortoisehg.utilimporthglibfromtortoisehg.hgqt.i18nimport_fromtortoisehg.hgqtimportqtlib,cmdui,wctxactions,visdiff,thgrepoMARGINS=(8,0,0,0)classResolveDialog(QDialog):def__init__(self,repo,parent=None):super(ResolveDialog,self).__init__(parent)self.setWindowFlags(Qt.Window)self.setWindowTitle(_('Resolve conflicts - %s')%repo.displayname)self.setWindowIcon(qtlib.geticon('hg-merge'))self.repo=repoself.setLayout(QVBoxLayout())self.layout().setSpacing(5)hbox=QHBoxLayout()self.layout().addLayout(hbox)self.refreshButton=tb=QToolButton(self)tb.setIcon(qtlib.geticon('view-refresh'))tb.setShortcut(QKeySequence.Refresh)tb.clicked.connect(self.refresh)self.stlabel=QLabel()hbox.addWidget(tb)hbox.addWidget(self.stlabel)unres=qtlib.LabeledSeparator(_('Unresolved conflicts'))self.layout().addWidget(unres)hbox=QHBoxLayout()hbox.setSpacing(0)hbox.setContentsMargins(*MARGINS)self.layout().addLayout(hbox)self.utree=PathsTree(self.repo,self)hbox.addWidget(self.utree)vbox=QVBoxLayout()vbox.setContentsMargins(*MARGINS)hbox.addLayout(vbox)auto=QPushButton(_('Auto Resolve'))auto.setToolTip(_('Attempt automatic merge'))auto.clicked.connect(lambda:self.merge('internal:merge'))manual=QPushButton(_('Manual Resolve'))manual.setToolTip(_('Merge with selected merge tool'))manual.clicked.connect(self.merge)local=QPushButton(_('Take Local'))local.setToolTip(_('Accept the local file version (yours)'))local.clicked.connect(lambda:self.merge('internal:local'))other=QPushButton(_('Take Other'))other.setToolTip(_('Accept the other file version (theirs)'))other.clicked.connect(lambda:self.merge('internal:other'))res=QPushButton(_('Mark as Resolved'))res.setToolTip(_('Mark this file as resolved'))res.clicked.connect(self.markresolved)vbox.addWidget(auto)vbox.addWidget(manual)vbox.addWidget(local)vbox.addWidget(other)vbox.addWidget(res)vbox.addStretch(1)self.ubuttons=(auto,manual,local,other,res)res=qtlib.LabeledSeparator(_('Resolved conflicts'))self.layout().addWidget(res)hbox=QHBoxLayout()hbox.setContentsMargins(*MARGINS)hbox.setSpacing(0)self.layout().addLayout(hbox)self.rtree=PathsTree(self.repo,self)hbox.addWidget(self.rtree)vbox=QVBoxLayout()vbox.setContentsMargins(*MARGINS)hbox.addLayout(vbox)edit=QPushButton(_('Edit File'))edit.setToolTip(_('Edit resolved file'))edit.clicked.connect(self.edit)v3way=QPushButton(_('3-Way Diff'))v3way.setToolTip(_('Visual three-way diff'))v3way.clicked.connect(self.v3way)vp0=QPushButton(_('Diff to Local'))vp0.setToolTip(_('Visual diff between resolved file and first parent'))vp0.clicked.connect(self.vp0)vp1=QPushButton(_('Diff to Other'))vp1.setToolTip(_('Visual diff between resolved file and second parent'))vp1.clicked.connect(self.vp1)ures=QPushButton(_('Mark as Unresolved'))ures.setToolTip(_('Mark this file as unresolved'))ures.clicked.connect(self.markunresolved)vbox.addWidget(edit)vbox.addWidget(v3way)vbox.addWidget(vp0)vbox.addWidget(vp1)vbox.addWidget(ures)vbox.addStretch(1)self.rbuttons=(edit,vp0,ures)self.rmbuttons=(vp1,v3way)hbox=QHBoxLayout()hbox.setContentsMargins(*MARGINS)hbox.setSpacing(4)self.layout().addLayout(hbox)self.tcombo=ToolsCombo(self.repo,self)hbox.addWidget(QLabel(_('Detected merge/diff tools:')))hbox.addWidget(self.tcombo)hbox.addStretch(1)out=qtlib.LabeledSeparator(_('Command output'))self.layout().addWidget(out)self.cmd=cmdui.Widget(True,False,self)self.cmd.commandFinished.connect(self.refresh)self.cmd.setShowOutput(True)self.layout().addWidget(self.cmd)BB=QDialogButtonBoxbbox=QDialogButtonBox(BB.Close)bbox.rejected.connect(self.reject)self.layout().addWidget(bbox)self.bbox=bboxs=QSettings()self.restoreGeometry(s.value('resolve/geom').toByteArray())self.refresh()self.utree.selectAll()self.utree.setFocus()repo.configChanged.connect(self.configChanged)repo.repositoryChanged.connect(self.repositoryChanged)defrepositoryChanged(self):self.refresh()defgetSelectedPaths(self,tree):paths=[]repo=self.repoifnottree.selectionModel():returnpathsforidxintree.selectionModel().selectedRows():root,wfile=tree.model().getPathForIndex(idx)paths.append((root,wfile))returnpathsdefrunCommand(self,tree,cmdline):cmdlines=[]selected=self.getSelectedPaths(tree)whileselected:curroot=selected[0][0]cmd=cmdline+['--repository',curroot,'--']forroot,wfileinselected:ifroot==curroot:cmd.append(os.path.join(root,wfile))cmdlines.append(cmd)selected=[(r,w)forr,winselectedifr!=curroot]ifcmdlines:self.cmd.run(*cmdlines)defmerge(self,tool=False):ifnottool:tool=self.tcombo.readValue()cmd=['resolve']iftool:cmd+=['--tool='+tool]self.runCommand(self.utree,cmd)defmarkresolved(self):self.runCommand(self.utree,['resolve','--mark'])defmarkunresolved(self):self.runCommand(self.rtree,['resolve','--unmark'])defedit(self):paths=self.getSelectedPaths(self.rtree)ifpaths:abspaths=[os.path.join(r,w)forr,winpaths]wctxactions.edit(self,self.repo.ui,self.repo,abspaths)defgetVdiffFiles(self,tree):paths=self.getSelectedPaths(self.rtree)ifnotpaths:return[]files,sub=[],Falseforroot,wfileinpaths:ifroot==self.repo.root:files.append(wfile)else:sub=Trueifsub:qtlib.InfoMsgBox(_('Unable to show subrepository files'),_('Visual diffs are not supported for files in ''subrepositories. They will not be shown.'))returnfilesdefv3way(self):paths=self.getVdiffFiles(self.rtree)ifpaths:opts={}opts['rev']=[]opts['tool']=self.tcombo.readValue()dlg=visdiff.visualdiff(self.repo.ui,self.repo,paths,opts)ifdlg:dlg.exec_()defvp0(self):paths=self.getVdiffFiles(self.rtree)ifpaths:opts={}opts['rev']=['p1()']opts['tool']=self.tcombo.readValue()dlg=visdiff.visualdiff(self.repo.ui,self.repo,paths,opts)ifdlg:dlg.exec_()defvp1(self):paths=self.getVdiffFiles(self.rtree)ifpaths:opts={}opts['rev']=['p2()']opts['tool']=self.tcombo.readValue()dlg=visdiff.visualdiff(self.repo.ui,self.repo,paths,opts)ifdlg:dlg.exec_()defconfigChanged(self):'repository has detected a change to config files'self.tcombo.reset()defrefresh(self):repo=self.repou,r=[],[]forroot,path,statusinthgrepo.recursiveMergeStatus(self.repo):ifstatus=='u':u.append((root,path))else:r.append((root,path))paths=self.getSelectedPaths(self.utree)self.utree.setModel(PathsModel(u,self))self.utree.resizeColumnToContents(0)self.utree.resizeColumnToContents(1)model=self.utree.model()smodel=self.utree.selectionModel()sflags=QItemSelectionModel.Select|QItemSelectionModel.Columnsfori,pathinenumerate(u):ifpathinpaths:smodel.select(model.index(i,0),sflags)smodel.select(model.index(i,1),sflags)smodel.select(model.index(i,2),sflags)@pyqtSlot(QItemSelection,QItemSelection)defuchanged(selected,deselected):enable=self.utree.selectionModel().hasSelection()forbinself.ubuttons:b.setEnabled(enable)smodel.selectionChanged.connect(uchanged)uchanged(None,None)paths=self.getSelectedPaths(self.rtree)self.rtree.setModel(PathsModel(r,self))self.rtree.resizeColumnToContents(0)self.rtree.resizeColumnToContents(1)model=self.rtree.model()smodel=self.rtree.selectionModel()fori,pathinenumerate(r):ifpathinpaths:smodel.select(model.index(i,0),sflags)smodel.select(model.index(i,1),sflags)smodel.select(model.index(i,2),sflags)@pyqtSlot(QItemSelection,QItemSelection)defrchanged(selected,deselected):enable=self.rtree.selectionModel().hasSelection()forbinself.rbuttons:b.setEnabled(enable)merge=len(self.repo.parents())>1forbinself.rmbuttons:b.setEnabled(enableandmerge)smodel.selectionChanged.connect(rchanged)rchanged(None,None)ifu:txt=_('There are merge <b>conflicts</b> to be resolved')elifr:txt=_('All conflicts are resolved.')else:txt=_('There are no conflicting file merges.')self.stlabel.setText(u'<h2>'+txt+u'</h2>')defreject(self): s = QSettings()
s.setValue('resolve/geom', self.saveGeometry())
if len(self.utree.model()):
- main = _('Quit without finishing resolve?')
+ main = _('Exit without finishing resolve?')
text = _('Unresolved conflicts remain. Are you sure?')
- labels = ((QMessageBox.Yes, _('&Quit')),
+ labels = ((QMessageBox.Yes, _('E&xit')),
(QMessageBox.No, _('Cancel')))
if not qtlib.QuestionMsgBox(_('Confirm Exit'), main, text,
labels=labels, parent=self):
returnsuper(ResolveDialog,self).reject()classPathsTree(QTreeView):def__init__(self,repo,parent):QTreeView.__init__(self,parent)self.repo=repoself.setSelectionMode(QTreeView.ExtendedSelection)self.setSortingEnabled(True)defdragObject(self):urls=[]forindexinself.selectionModel().selectedRows():root,path=self.model().getPathForIndex(index)urls.append(QUrl.fromLocalFile(os.path.join(root,path)))ifurls:d=QDrag(self)m=QMimeData()m.setUrls(urls)d.setMimeData(m)d.start(Qt.CopyAction)defmousePressEvent(self,event):self.pressPos=event.pos()self.pressTime=QTime.currentTime()returnQTreeView.mousePressEvent(self,event)defmouseMoveEvent(self,event):d=event.pos()-self.pressPosifd.manhattanLength()<QApplication.startDragDistance():returnQTreeView.mouseMoveEvent(self,event)elapsed=self.pressTime.msecsTo(QTime.currentTime())ifelapsed<QApplication.startDragTime():returnQTreeView.mouseMoveEvent(self,event)self.dragObject()returnQTreeView.mouseMoveEvent(self,event)classPathsModel(QAbstractTableModel):def__init__(self,pathlist,parent):QAbstractTableModel.__init__(self,parent)self.headers=(_('Path'),_('Ext'),_('Repository'))self.rows=[]forroot,pathinpathlist:name,ext=os.path.splitext(path)self.rows.append([path,ext,root])def__len__(self):returnlen(self.rows)defrowCount(self,parent):ifparent.isValid():return0# no childreturnlen(self.rows)defcolumnCount(self,parent):ifparent.isValid():return0# no childreturnlen(self.headers)defdata(self,index,role):ifnotindex.isValid():returnQVariant()ifrole==Qt.DisplayRole:data=self.rows[index.row()][index.column()]returnQVariant(hglib.tounicode(data))returnQVariant()defheaderData(self,col,orientation,role):ifrole!=Qt.DisplayRoleororientation!=Qt.Horizontal:returnQVariant()else:returnQVariant(self.headers[col])defgetPathForIndex(self,index):'return root, wfile for the given row'row=index.row()returnself.rows[row][2],self.rows[row][0]classToolsCombo(QComboBox):def__init__(self,repo,parent):QComboBox.__init__(self,parent)self.setEditable(False)self.loaded=Falseself.default=_('<default>')self.addItem(self.default)self.repo=repodefreset(self):self.loaded=Falseself.clear()self.addItem(self.default)defshowPopup(self):ifnotself.loaded:self.loaded=Trueself.clear()self.addItem(self.default)fortinself.repo.mergetools:self.addItem(hglib.tounicode(t))QComboBox.showPopup(self)defreadValue(self):ifself.loaded:text=self.currentText()iftext!=self.default:returnhglib.fromunicode(text)else:returnNonedefrun(ui,*pats,**opts):fromtortoisehg.utilimportpathsrepo=thgrepo.repository(ui,path=paths.find_root())returnResolveDialog(repo,None)
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.