def dohgdiff(): difftext = StringIO.StringIO() try: if len(files) != 0: wfiles = [self.repo.wjoin(x) for x in files] fns, matchfn, anypats = cmdutil.matchpats(self.repo, wfiles, self.opts) patch.diff(self.repo, self._node1, self._node2, fns, match=matchfn, fp=difftext, opts=patch.diffopts(self.ui, self.opts)) buffer = gtk.TextBuffer() buffer.create_tag('removed', foreground='#900000') buffer.create_tag('added', foreground='#006400') buffer.create_tag('position', foreground='#FF8000') buffer.create_tag('header', foreground='#000090') difftext.seek(0) iter = buffer.get_start_iter() for line in difftext: line = toutf(line) if line.startswith('---') or line.startswith('+++'): buffer.insert_with_tags_by_name(iter, line, 'header') elif line.startswith('-'): buffer.insert_with_tags_by_name(iter, line, 'removed') elif line.startswith('+'): buffer.insert_with_tags_by_name(iter, line, 'added') elif line.startswith('@@'): buffer.insert_with_tags_by_name(iter, line, 'position') else: buffer.insert(iter, line) self.diff_text.set_buffer(buffer) finally: difftext.close()
def _do_reload_status(self): """Clear out the existing ListStore model and reload it from the repository status. Also recheck and reselect files that remain in the list. """ self.repo.dirstate.invalidate() self.repo.invalidate() # The following code was copied from the status function in mercurial\commands.py # and modified slightly to work here # node2 is None (the working dir) when 0 or 1 rev is specificed self._node1, self._node2 = cmdutil.revpair(self.repo, self.opts.get('rev')) files, matchfn, anypats = cmdutil.matchpats(self.repo, self.pats, self.opts) cwd = (self.pats and self.repo.getcwd()) or '' modified, added, removed, deleted, unknown, ignored, clean = [ n for n in self.repo.status(node1=self._node1, node2=self._node2, files=files, match=matchfn, list_ignored=self.test_opt('ignored'), list_clean=self.test_opt('clean'))] changetypes = (('modified', 'M', modified), ('added', 'A', added), ('removed', 'R', removed), ('deleted', '!', deleted), ('unknown', '?', unknown), ('ignored', 'I', ignored)) explicit_changetypes = changetypes + (('clean', 'C', clean),) # List of the currently checked and selected files to pass on to the new data recheck = [entry[2] for entry in self.model if entry[0]] reselect = [self.model[iter][2] for iter in self.tree.get_selection().get_selected_rows()[1]] # Load the new data into the tree's model self.tree.hide() self.model.clear() for opt, char, changes in ([ct for ct in explicit_changetypes if self.test_opt(ct[0])] or changetypes) : for file in changes: file = util.localpath(file) self.model.append([file in recheck, char, toutf(file), file]) self._update_check_count() selection = self.tree.get_selection() selected = False for row in self.model: if row[2] in reselect: selection.select_iter(row.iter) selected = True if not selected: selection.select_path((0,)) self.tree.show() self.tree.grab_focus() return True
def _status(ui, repo, kwt, *pats, **opts): '''Bails out if [keyword] configuration is not active. Returns status of working directory.''' if kwt: files, match, anypats = cmdutil.matchpats(repo, pats, opts) return repo.status(files=files, match=match, list_clean=True) if ui.configitems('keyword'): raise util.Abort(_('[keyword] patterns cannot match')) raise util.Abort(_('no [keyword] patterns configured'))
def pdiff(self, pats, opts, parent=None): 'Return diffs relative to PARENT, as best as we can make out' parent = self.parent(parent) act = self.active(parent) # # act.localtip maybe nil, in the case of uncommitted local # changes. # if not act.revs: return names, match = cmdutil.matchpats(self.repo, pats, opts)[:2] opts = patch.diffopts(self.ui, opts) ret = cStringIO.StringIO() patch.diff(self.repo, act.parenttip.node(), act.localtip.node(), names, fp=ret, opts=opts, match=match) return ret.getvalue()
def set_diff(self, root='', files=[], description=''): """Set the differences showed by this window. Compares the two trees and populates the window with the differences. """ self.root = root self.files = files # open Hg repo self.ui = ui.ui() try: self.repo = hg.repository(self.ui, path=self.root) except hg.RepoError: return None self.files, matchfn, anypats = cmdutil.matchpats(self.repo, self.files) modified, added, removed = self.repo.status(files=self.files)[0:3] self.model.clear() self.model.append(None, [ "Complete Diff", "" ]) if len(added): titer = self.model.append(None, [ "Added", None ]) for path in added: self.model.append(titer, [ path, path ]) if len(removed): titer = self.model.append(None, [ "Removed", None ]) for path in removed: self.model.append(titer, [ path, path ]) if len(modified): titer = self.model.append(None, [ "Modified", None ]) for path in modified: self.model.append(titer, [ path, path ]) self.treeview.expand_all() self.set_title("TortoseHg diff - " + description)
def rdiff(ui, repo, url, lrev=None, rrev=None, *pats, **opts): def rui(): try: return hg.remoteui(repo, opts) except AttributeError: # pre 1.6 return cmdutil.remoteui(repo, opts) try: other = getpeer(rui(), {}, url) except AttributeError: # pre-1.3 other = hg.repository(ui, url) cmdutil.setremoteconfig(ui, opts) ui.status(_('comparing with %s\n') % url) if rrev: if capable(other, 'lookup'): rrev = other.lookup(rrev) else: error = _( "Other repository doesn't support revision lookup, so a rev cannot be specified." ) raise util.Abort(error) incoming = findincomingfn(repo)(other, heads=rrev and [rrev] or []) if not incoming: # remote is a subset of local if not rrev: if capable(other, 'lookup'): rrev = other.lookup('tip') else: raise util.Abort(_('cannot determine remote tip')) other = repo bundle = None try: if incoming: # create a bundle (uncompressed if other repo is not local) if not rrev: cg = other.changegroup(incoming, "incoming") else: if not capable(other, 'changegroupsubset'): raise util.Abort( _("Partial incoming cannot be done because other repository doesn't support changegroupsubset." )) cg = other.changegroupsubset(incoming, rrev and [rrev] or [], 'incoming') bundle = changegroup.writebundle(cg, '', 'HG10UN') other = hg.repository(ui, bundle) if lrev: lrev = repo.changectx(lrev).node() rrev = other.changectx(rrev or 'tip').node() if opts['reverse']: lrev, rrev = rrev, lrev if not lrev: # bundle dirstate removed prior to hg 1.1 lrev = repo.dirstate.parents()[0] try: try: # scmutil.match expects a context not a repo m = scmutil.match(repo[None], pats, opts) except (ImportError, AttributeError): m = cmdutil.match(repo, pats, opts) chunks = patch.diff(other, lrev, rrev, match=m, opts=patch.diffopts(ui, opts)) for chunk in chunks: ui.write(chunk) except AttributeError: # 1.0 compatibility fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) patch.diff(other, lrev, rrev, fns, match=matchfn, opts=patch.diffopts(ui, opts)) finally: if hasattr(other, 'close'): other.close() if bundle: os.unlink(bundle)
def rdiff(ui, repo, url, lrev=None, rrev=None, *pats, **opts): def rui(): try: return hg.remoteui(repo, opts) except AttributeError: # pre 1.6 return cmdutil.remoteui(repo, opts) try: other = hg.repository(rui(), url) except AttributeError: # pre-1.3 other = hg.repository(ui, url) cmdutil.setremoteconfig(ui, opts) ui.status(_('comparing with %s\n') % url) if rrev: if 'lookup' in other.capabilities: rrev = other.lookup(rrev) else: error = _("Other repository doesn't support revision lookup, so a rev cannot be specified.") raise util.Abort(error) incoming = findincomingfn(repo)(other, heads=rrev and [rrev] or []) if not incoming: # remote is a subset of local if not rrev: if 'lookup' in other.capabilities: rrev = other.lookup('tip') else: raise util.Abort(_('cannot determine remote tip')) other = repo bundle = None try: if incoming: # create a bundle (uncompressed if other repo is not local) if not rrev: cg = other.changegroup(incoming, "incoming") else: if 'changegroupsubset' not in other.capabilities: raise util.Abort(_("Partial incoming cannot be done because other repository doesn't support changegroupsubset.")) cg = other.changegroupsubset(incoming, rrev and [rrev] or [], 'incoming') bundle = changegroup.writebundle(cg, '', 'HG10UN') other = hg.repository(ui, bundle) if lrev: lrev = repo.changectx(lrev).node() rrev = other.changectx(rrev or 'tip').node() if opts['reverse']: lrev, rrev = rrev, lrev if not lrev: # bundle dirstate removed prior to hg 1.1 lrev = repo.dirstate.parents()[0] try: m = cmdutil.match(repo, pats, opts) chunks = patch.diff(other, lrev, rrev, match=m, opts=patch.diffopts(ui, opts)) for chunk in chunks: ui.write(chunk) except AttributeError: # 1.0 compatibility fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) patch.diff(other, lrev, rrev, fns, match=matchfn, opts=patch.diffopts(ui, opts)) finally: if hasattr(other, 'close'): other.close() if bundle: os.unlink(bundle)
def dodiff(ui, repo, diffcmd, diffopts, pats, opts): '''Do the actuall diff: - copy to a temp structure if diffing 2 internal revisions - copy to a temp structure if diffing working revision with another one and more than 1 file is changed - just invoke the diff for a single file in the working dir ''' node1, node2 = cmdutil.revpair(repo, opts['rev']) files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) modified, added, removed, deleted, unknown = repo.status( node1, node2, files, match=matchfn)[:5] if not (modified or added or removed): return 0 tmproot = tempfile.mkdtemp(prefix='extdiff.') dir2root = '' try: # Always make a copy of node1 dir1 = snapshot_node(ui, repo, modified + removed, node1, tmproot) changes = len(modified) + len(removed) + len(added) fns_and_mtime = [] # If node2 in not the wc or there is >1 change, copy it if node2: dir2 = snapshot_node(ui, repo, modified + added, node2, tmproot) elif changes > 1: #we only actually need to get the files to copy back to the working #dir in this case (because the other cases are: diffing 2 revisions #or single file -- in which case the file is already directly passed #to the diff tool). dir2, fns_and_mtime = snapshot_wdir(ui, repo, modified + added, tmproot) else: # This lets the diff tool open the changed file directly dir2 = '' dir2root = repo.root # If only one change, diff the files instead of the directories if changes == 1 : if len(modified): dir1 = os.path.join(dir1, util.localpath(modified[0])) dir2 = os.path.join(dir2root, dir2, util.localpath(modified[0])) elif len(removed) : dir1 = os.path.join(dir1, util.localpath(removed[0])) dir2 = os.devnull else: dir1 = os.devnull dir2 = os.path.join(dir2root, dir2, util.localpath(added[0])) cmdline = ('%s %s %s %s' % (util.shellquote(diffcmd), ' '.join(diffopts), util.shellquote(dir1), util.shellquote(dir2))) ui.debug('running %r in %s\n' % (cmdline, tmproot)) util.system(cmdline, cwd=tmproot) for copy_fn, working_fn, mtime in fns_and_mtime: if os.path.getmtime(copy_fn) != mtime: ui.debug('File changed while diffing. ' 'Overwriting: %s (src: %s)\n' % (working_fn, copy_fn)) util.copyfile(copy_fn, working_fn) return 1 finally: ui.note(_('cleaning up temp directory\n')) shutil.rmtree(tmproot)