Пример #1
0
        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()
Пример #2
0
    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
Пример #3
0
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'))
Пример #4
0
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'))
Пример #5
0
    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()
Пример #6
0
    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)
Пример #7
0
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)
Пример #8
0
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)
Пример #9
0
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)