def getChunksForFile(self, wfile): repo = self.repo ctx = self.ctx if isinstance(ctx, patchctx): if wfile in ctx._files: return ctx._files[wfile] else: return [] else: buf = cStringIO.StringIO() diffopts = patch.diffopts(repo.ui, {'git': True}) m = matchmod.exact(repo.root, repo.root, [wfile]) for p in patch.diff(repo, ctx.p1().node(), None, match=m, opts=diffopts): buf.write(p) buf.seek(0) chunks = record.parsepatch(buf) if chunks: header = chunks[0] return [header] + header.hunks else: return []
def displayFile(self, filename, status): self.clearDisplay() if filename == self._lastfile: reenable = [(c.fromline, len(c.before)) for c in self.curchunks[1:]\ if c.selected] else: reenable = [] self._lastfile = filename self.clearChunks() fd = filedata.FileData(self._ctx, None, filename, status) if fd.elabel: self.extralabel.setText(fd.elabel) self.extralabel.show() else: self.extralabel.hide() self.filenamelabel.setText(fd.flabel) if not fd.isValid() or not fd.diff: self.sci.setText(fd.error or '') return elif type(self._ctx.rev()) is str: chunks = self._ctx._files[filename] else: header = record.parsepatch(cStringIO.StringIO(fd.diff))[0] chunks = [header] + header.hunks utext = [] for chunk in chunks[1:]: buf = cStringIO.StringIO() chunk.selected = False chunk.write(buf) chunk.lines = buf.getvalue().splitlines() utext += [hglib.tounicode(l) for l in chunk.lines] utext.append('') self.sci.setText(u'\n'.join(utext)) start = 0 self.sci.markerDeleteAll(-1) for chunk in chunks[1:]: chunk.lrange = (start, start+len(chunk.lines)) chunk.mline = start + len(chunk.lines)/2 if start: self.sci.markerAdd(start-1, self.divider) for i in xrange(1,len(chunk.lines)-1): if start + i == chunk.mline: self.sci.markerAdd(chunk.mline, self.unselected) else: self.sci.markerAdd(start+i, self.vertical) start += len(chunk.lines) + 1 self.origcontents = fd.olddata self.countselected = 0 self.curchunks = chunks for c in chunks[1:]: if (c.fromline, len(c.before)) in reenable: self.toggleChunk(c) self.updateSummary()
def displayFile(self, filename, status): self.clearDisplay() if filename == self._lastfile: reenable = [(c.fromline, len(c.before)) for c in self.curchunks[1:]\ if c.selected] else: reenable = [] self._lastfile = filename self.clearChunks() fd = filedata.FileData(self._ctx, None, filename, status) if fd.elabel: self.extralabel.setText(fd.elabel) self.extralabel.show() else: self.extralabel.hide() self.filenamelabel.setText(fd.flabel) if not fd.isValid() or not fd.diff: self.sci.setText(fd.error or '') return elif type(self._ctx.rev()) is str: chunks = self._ctx._files[filename] else: header = record.parsepatch(cStringIO.StringIO(fd.diff))[0] chunks = [header] + header.hunks utext = [] for chunk in chunks[1:]: buf = cStringIO.StringIO() chunk.selected = False chunk.write(buf) chunk.lines = buf.getvalue().splitlines() utext += [hglib.tounicode(l) for l in chunk.lines] utext.append('') self.sci.setText(u'\n'.join(utext)) start = 0 self.sci.markerDeleteAll(-1) for chunk in chunks[1:]: chunk.lrange = (start, start + len(chunk.lines)) chunk.mline = start + len(chunk.lines) / 2 if start: self.sci.markerAdd(start - 1, self.divider) for i in xrange(1, len(chunk.lines) - 1): if start + i == chunk.mline: self.sci.markerAdd(chunk.mline, self.unselected) else: self.sci.markerAdd(start + i, self.vertical) start += len(chunk.lines) + 1 self.origcontents = fd.olddata self.countselected = 0 self.curchunks = chunks for c in chunks[1:]: if (c.fromline, len(c.before)) in reenable: self.toggleChunk(c) self.updateSummary()
def _files(self): if not hasattr(self, '_ph') or not self._ph.haspatch: return {} M, A, R = 0, 1, 2 def get_path(a, b): type = (a == '/dev/null') and A or M type = (b == '/dev/null') and R or type rawpath = (b != '/dev/null') and b or a if not (rawpath.startswith('a/') or rawpath.startswith('b/')): return type, rawpath return type, rawpath.split('/', 1)[-1] files = {} pf = open(self._path, 'rb') try: try: # consume comments and headers for i in range(self._ph.diffstartline): pf.readline() for chunk in record.parsepatch(pf): if not isinstance(chunk, record.header): continue top = patch.parsefilename(chunk.header[-2]) bot = patch.parsefilename(chunk.header[-1]) type, path = get_path(top, bot) if path not in chunk.files(): type, path = 0, chunk.files()[-1] if path not in files: self._status[type].append(path) files[path] = [chunk] self._fileorder.append(path) files[path].extend(chunk.hunks) except (patch.PatchError, AttributeError), e: self._status[2].append(self._parseErrorFileName) files[self._parseErrorFileName] = [] self._parseerror = e if 'THGDEBUG' in os.environ: print e finally: pf.close() return files
def getChunksForFile(self, wfile): repo = self.repo ctx = self.ctx if isinstance(ctx, patchctx): if wfile in ctx._files: return ctx._files[wfile] else: return [] else: buf = cStringIO.StringIO() diffopts = patch.diffopts(repo.ui, {'git':True}) m = matchmod.exact(repo.root, repo.root, [wfile]) for p in patch.diff(repo, ctx.p1().node(), None, match=m, opts=diffopts): buf.write(p) buf.seek(0) chunks = record.parsepatch(buf) if chunks: header = chunks[0] return [header] + header.hunks else: return []
class RejectsDialog(QDialog): def __init__(self, path, parent): super(RejectsDialog, self).__init__(parent) self.setWindowTitle(_('Merge rejected patch chunks into %s') % hglib.tounicode(path)) self.setWindowFlags(Qt.Window) self.path = path self.setLayout(QVBoxLayout()) editor = qscilib.Scintilla() editor.setBraceMatching(qsci.SloppyBraceMatch) editor.setFolding(qsci.BoxedTreeFoldStyle) editor.installEventFilter(qscilib.KeyPressInterceptor(self)) editor.setContextMenuPolicy(Qt.CustomContextMenu) editor.customContextMenuRequested.connect(self.menuRequested) self.baseLineColor = editor.markerDefine(qsci.Background, -1) editor.setMarkerBackgroundColor(QColor('lightblue'), self.baseLineColor) self.layout().addWidget(editor, 3) searchbar = qscilib.SearchToolBar(self, hidable=True) searchbar.searchRequested.connect(editor.find) searchbar.conditionChanged.connect(editor.highlightText) searchbar.hide() def showsearchbar(): searchbar.show() searchbar.setFocus(Qt.OtherFocusReason) qtlib.newshortcutsforstdkey(QKeySequence.Find, self, showsearchbar) self.layout().addWidget(searchbar) hbox = QHBoxLayout() hbox.setContentsMargins(2, 2, 2, 2) self.layout().addLayout(hbox, 1) self.chunklist = QListWidget(self) self.updating = True self.chunklist.currentRowChanged.connect(self.showChunk) hbox.addWidget(self.chunklist, 1) bvbox = QVBoxLayout() bvbox.setContentsMargins(2, 2, 2, 2) self.resolved = tb = QToolButton() tb.setIcon(qtlib.geticon('thg-success')) tb.setToolTip(_('Mark this chunk as resolved, goto next unresolved')) tb.pressed.connect(self.resolveCurrentChunk) self.unresolved = tb = QToolButton() tb.setIcon(qtlib.geticon('thg-warning')) tb.setToolTip(_('Mark this chunk as unresolved')) tb.pressed.connect(self.unresolveCurrentChunk) bvbox.addStretch(1) bvbox.addWidget(self.resolved, 0) bvbox.addWidget(self.unresolved, 0) bvbox.addStretch(1) hbox.addLayout(bvbox, 0) self.editor = editor self.rejectbrowser = RejectBrowser(self) hbox.addWidget(self.rejectbrowser, 5) BB = QDialogButtonBox bb = QDialogButtonBox(BB.Save|BB.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.layout().addWidget(bb) self.saveButton = bb.button(BB.Save) s = QSettings() self.restoreGeometry(s.value('rejects/geometry').toByteArray()) self.editor.loadSettings(s, 'rejects/editor') self.rejectbrowser.loadSettings(s, 'rejects/rejbrowse') f = QFile(hglib.tounicode(path)) if not f.open(QIODevice.ReadOnly): qtlib.ErrorMsgBox(_('Unable to merge rejects'), _("Can't read this file (maybe deleted)")) self.hide() QTimer.singleShot(0, self.reject) return earlybytes = f.read(4096) if '\0' in earlybytes: qtlib.ErrorMsgBox(_('Unable to merge rejects'), _('This appears to be a binary file')) self.hide() QTimer.singleShot(0, self.reject) return f.seek(0) editor.read(f) editor.setModified(False) lexer = lexers.getlexer(ui.ui(), path, earlybytes, self) editor.setLexer(lexer) editor.setMarginLineNumbers(1, True) editor.setMarginWidth(1, str(editor.lines())+'X') buf = cStringIO.StringIO() try: buf.write('diff -r aaaaaaaaaaaa -r bbbbbbbbbbb %s\n' % path) buf.write(open(path + '.rej', 'rb').read()) buf.seek(0) except IOError, e: pass try: header = record.parsepatch(buf)[0] self.chunks = header.hunks except (patch.PatchError, IndexError), e: self.chunks = []
else: return self.olddata = olddata if changeselect: diffopts = patch.diffopts(repo.ui, {}) diffopts.git = True m = match.exact(repo.root, repo.root, [wfile]) fp = cStringIO.StringIO() for c in patch.diff(repo, ctx.node(), None, match=m, opts=diffopts): fp.write(c) fp.seek(0) # feed diffs through record.parsepatch() for more fine grained # chunk selection filediffs = record.parsepatch(fp) if filediffs: self.changes = filediffs[0] else: self.diff = '' return self.changes.excludecount = 0 values = [] lines = 0 for chunk in self.changes.hunks: buf = cStringIO.StringIO() chunk.write(buf) chunk.excluded = False val = buf.getvalue() values.append(val) chunk.lineno = lines