Exemple #1
0
 def savediff():
     opts = {'git': True}
     fp = opener('.saved', 'w')
     for chunk in patch.diff(repo, head, None,
                              opts=patch.diffopts(self.ui, opts)):
         fp.write(chunk)
     fp.close()
Exemple #2
0
 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 []
Exemple #3
0
def cdm_pdiffs(ui, repo, *pats, **opts):
    '''diff workspace against its parent

    Show differences between this workspace and its parent workspace
    in the same manner as 'hg diff'.

    For a description of the changeset used to represent the parent
    workspace, see The Parent in the extension documentation ('hg help
    cdm').
    '''

    act = wslist[repo].active(opts.get('parent'))
    if not act.revs:
        return

    #
    # If no patterns were specified, either explicitly or via -I or -X
    # use the active list files to avoid a workspace walk.
    #
    if pats or opts.get('include') or opts.get('exclude'):
        matchfunc = wslist[repo].matcher(pats=pats, opts=opts)
    else:
        matchfunc = wslist[repo].matcher(files=act.files())

    opts = patch.diffopts(ui, opts)
    diffs = wslist[repo].diff(act.parenttip.node(), act.localtip.node(),
                              match=matchfunc, opts=opts)
    if diffs:
        ui.write(diffs)
Exemple #4
0
def diff(orig, ui, repo, *args, **opts):
    """show a diff of the most recent revision against its parent from svn
    """
    if not opts.get('svn', False) or opts.get('change', None):
        return orig(ui, repo, *args, **opts)
    meta = repo.svnmeta()
    hashes = meta.revmap.hashes()
    if not opts.get('rev', None):
        parent = repo.parents()[0]
        o_r = util.outgoing_revisions(repo, hashes, parent.node())
        if o_r:
            parent = repo[o_r[-1]].parents()[0]
        opts['rev'] = ['%s:.' % node.hex(parent.node()), ]
    node1, node2 = cmdutil.revpair(repo, opts['rev'])
    baserev, _junk = hashes.get(node1, (-1, 'junk'))
    newrev, _junk = hashes.get(node2, (-1, 'junk'))
    it = patch.diff(repo, node1, node2,
                    opts=patch.diffopts(ui, opts={'git': True,
                                                  'show_function': False,
                                                  'ignore_all_space': False,
                                                  'ignore_space_change': False,
                                                  'ignore_blank_lines': False,
                                                  'unified': True,
                                                  'text': False,
                                                  }))
    ui.write(util.filterdiff(''.join(it), baserev, newrev))
    def recordfunc(ui, repo, message, match, opts):
        """This is generic record driver.

        Its job is to interactively filter local changes, and
        accordingly prepare working directory into a state in which the
        job can be delegated to a non-interactive commit command such as
        'commit' or 'qrefresh'.

        After the actual job is done by non-interactive command, the
        working directory is restored to its original state.

        In the end we'll record interesting changes, and everything else
        will be left in place, so the user can continue working.
        """

        cmdutil.checkunfinished(repo, commit=True)
        merge = len(repo[None].parents()) > 1
        if merge:
            raise util.Abort(_("cannot partially commit a merge " '(use "hg commit" instead)'))

        status = repo.status(match=match)
        diffopts = opts.copy()
        diffopts["nodates"] = True
        diffopts["git"] = True
        diffopts = patch.diffopts(ui, opts=diffopts)
        chunks = patch.diff(repo, changes=status, opts=diffopts)
        fp = cStringIO.StringIO()
        fp.write("".join(chunks))
        fp.seek(0)

        # 1. filter patch, so we have intending-to apply subset of it
        try:
            chunks = filterpatch(ui, parsepatch(fp))
        except patch.PatchError, err:
            raise util.Abort(_("error parsing patch: %s") % err)
Exemple #6
0
def pick(ui, repo, ctx, ha, opts):
    oldctx = repo[ha]
    if oldctx.parents()[0] == ctx:
        ui.debug('node %s unchanged\n' % ha)
        return oldctx, [], [], []
    hg.update(repo, ctx.node())
    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
    fp = os.fdopen(fd, 'w')
    diffopts = patch.diffopts(ui, opts)
    diffopts.git = True
    gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
    for chunk in gen:
        fp.write(chunk)
    fp.close()
    try:
        files = {}
        try:
            patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None)
            if not files:
                ui.warn(_('%s: empty changeset')
                             % node.hex(ha))
                return ctx, [], [], []
        finally:
            files = patch.updatedir(ui, repo, files)
            os.unlink(patchfile)
    except Exception, inst:
        raise util.Abort(_('Fix up the change and run '
                           'hg histedit --continue'))
Exemple #7
0
def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
    parent = ctx.parents()[0].node()
    hg.update(repo, parent)
    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
    fp = os.fdopen(fd, 'w')
    diffopts = patch.diffopts(ui, opts)
    diffopts.git = True
    gen = patch.diff(repo, parent, newnode, opts=diffopts)
    for chunk in gen:
        fp.write(chunk)
    fp.close()
    files = {}
    try:
        patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None)
    finally:
        files = patch.updatedir(ui, repo, files)
        os.unlink(patchfile)
    newmessage = '\n***\n'.join(
        [ctx.description(), ] +
        [repo[r].description() for r in internalchanges] +
        [oldctx.description(), ])
    newmessage = ui.edit(newmessage, ui.username())
    n = repo.commit(text=newmessage, user=ui.username(), date=max(ctx.date(), oldctx.date()),
                    extra=oldctx.extra())
    return repo[n], [n, ], [oldctx.node(), ctx.node() ], [newnode, ] # xxx
Exemple #8
0
 def generate_text_diffs(self, row):
     wfile = self.filemodel[row][FM_PATH]
     pfile = util.pconvert(wfile)
     lines = chunks.check_max_diff(self.get_ctx(), pfile)
     if lines:
         return self.diff_highlight_buffer(lines)
     matcher = cmdutil.matchfiles(self.repo, [pfile])
     opts = patch.diffopts(self.ui, self.opts)
     opts.git = True
     difftext = []
     if self.is_merge():
         wctx = self.repo[None]
         pctx1, pctx2 = wctx.parents()
         difftext = [_('===== Diff to first parent %d:%s =====\n') % (
                     pctx1.rev(), str(pctx1))]
         try:
             for s in patch.diff(self.repo, pctx1.node(), None,
                                 match=matcher, opts=opts):
                 difftext.extend(s.splitlines(True))
             difftext.append(_('\n===== Diff to second parent %d:%s =====\n') % (
                             pctx2.rev(), str(pctx2)))
             for s in patch.diff(self.repo, pctx2.node(), None,
                                 match=matcher, opts=opts):
                 difftext.extend(s.splitlines(True))
         except (IOError, error.RepoError, error.LookupError, util.Abort), e:
             self.stbar.set_text(str(e))
Exemple #9
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()
Exemple #10
0
 def savediff():
     opts = {'git': True}
     fp = self.opener('.saved', 'w')
     for chunk in patch.diff(repo, head, None,
                              opts=patch.diffopts(self.ui, opts)):
         fp.write(chunk)
     fp.close()
Exemple #11
0
def autodiff(ui, repo, *pats, **opts):
    diffopts = patch.diffopts(ui, opts)
    git = opts.get('git', 'no')
    brokenfiles = set()
    losedatafn = None
    if git in ('yes', 'no'):
        diffopts.git = git == 'yes'
        diffopts.upgrade = False
    elif git == 'auto':
        diffopts.git = False
        diffopts.upgrade = True
    elif git == 'warn':
        diffopts.git = False
        diffopts.upgrade = True
        def losedatafn(fn=None, **kwargs):
            brokenfiles.add(fn)
            return True
    elif git == 'abort':
        diffopts.git = False
        diffopts.upgrade = True
        def losedatafn(fn=None, **kwargs):
            raise util.Abort('losing data for %s' % fn)
    else:
        raise util.Abort('--git must be yes, no or auto')

    node1, node2 = scmutil.revpair(repo, [])
    m = scmutil.match(repo[node2], pats, opts)
    it = patch.diff(repo, node1, node2, match=m, opts=diffopts,
                    losedatafn=losedatafn)
    for chunk in it:
        ui.write(chunk)
    for fn in sorted(brokenfiles):
        ui.write(('data lost for: %s\n' % fn))
Exemple #12
0
    def __init__(self, repoagent, parent=None):
        super(AnnotateView, self).__init__(parent)
        self.setReadOnly(True)
        self.setMarginLineNumbers(1, True)
        self.setMarginType(2, qsci.TextMarginRightJustified)
        self.setMouseTracking(False)

        self._repoagent = repoagent
        repo = repoagent.rawRepo()
        # TODO: replace by repoagent if sci.repo = bundlerepo can be removed
        self.repo = repo

        self._annotation_enabled = False
        self._links = []  # by line
        self._anncache = {}  # by rev
        self._revmarkers = {}  # by rev
        self._lastrev = None

        diffopts = patch.diffopts(repo.ui, section='annotate')
        self._thread = AnnotateThread(self, diffopts=diffopts)
        self._thread.finished.connect(self.fillModel)

        self._initAnnotateOptionActions()

        self._repoagent.configChanged.connect(self.configChanged)
        self.configChanged()
        self._loadAnnotateSettings()
Exemple #13
0
def fold(ui, repo, ctx, ha, opts):
    oldctx = repo[ha]
    hg.update(repo, ctx.node())
    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
    fp = os.fdopen(fd, 'w')
    diffopts = patch.diffopts(ui, opts)
    diffopts.git = True
    diffopts.ignorews = False
    diffopts.ignorewsamount = False
    diffopts.ignoreblanklines = False
    gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
    for chunk in gen:
        fp.write(chunk)
    fp.close()
    try:
        files = set()
        try:
            applypatch(ui, repo, patchfile, files=files, eolmode=None)
            if not files:
                ui.warn(_('%s: empty changeset') % node.hex(ha))
                return ctx, [], [], []
        finally:
            os.unlink(patchfile)
    except Exception, inst:
        raise util.Abort(
            _('Fix up the change and run '
              'hg histedit --continue'))
Exemple #14
0
def fold(ui, repo, ctx, ha, opts):
    oldctx = repo[ha]
    hg.update(repo, ctx.node())
    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
    fp = os.fdopen(fd, 'w')
    diffopts = patch.diffopts(ui, opts)
    diffopts.git = True
    diffopts.ignorews = False
    diffopts.ignorewsamount = False
    diffopts.ignoreblanklines = False
    gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
    for chunk in gen:
        fp.write(chunk)
    fp.close()
    try:
        files = set()
        try:
            applypatch(ui, repo, patchfile, files=files, eolmode=None)
            if not files:
                ui.warn(_('%s: empty changeset')
                             % node.hex(ha))
                return ctx, [], [], []
        finally:
            os.unlink(patchfile)
    except Exception, inst:
        raise util.Abort(_('Fix up the change and run '
                           'hg histedit --continue'))
Exemple #15
0
def diff(orig, ui, repo, *args, **opts):
    """show a diff of the most recent revision against its parent from svn
    """
    if not opts.get('svn', False) or opts.get('change', None):
        return orig(ui, repo, *args, **opts)
    meta = repo.svnmeta()
    hashes = meta.revmap.hashes()
    if not opts.get('rev', None):
        parent = repo[None].parents()[0]
        o_r = util.outgoing_revisions(repo, hashes, parent.node())
        if o_r:
            parent = repo[o_r[-1]].parents()[0]
        opts['rev'] = ['%s:.' % node.hex(parent.node()), ]
    node1, node2 = scmutil.revpair(repo, opts['rev'])
    if not isinstance(node1, bytes):
        # hg 4.6 and later return contexts, so convert to bytestr
        node1, node2 = node1.node(), node2.node()
    baserev, _junk = hashes.get(node1, (-1, 'junk'))
    newrev, _junk = hashes.get(node2, (-1, 'junk'))
    it = patch.diff(repo, node1, node2,
                    opts=patch.diffopts(ui, opts={'git': True,
                                                  'show_function': False,
                                                  'ignore_all_space': False,
                                                  'ignore_space_change': False,
                                                  'ignore_blank_lines': False,
                                                  'unified': True,
                                                  'text': False,
                                                  }))
    ui.write(util.filterdiff(''.join(it), baserev, newrev))
Exemple #16
0
def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
    parent = ctx.parents()[0].node()
    hg.update(repo, parent)
    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
    fp = os.fdopen(fd, 'w')
    diffopts = patch.diffopts(ui, opts)
    diffopts.git = True
    diffopts.ignorews = False
    diffopts.ignorewsamount = False
    diffopts.ignoreblanklines = False
    gen = patch.diff(repo, parent, newnode, opts=diffopts)
    for chunk in gen:
        fp.write(chunk)
    fp.close()
    files = set()
    try:
        applypatch(ui, repo, patchfile, files=files, eolmode=None)
    finally:
        os.unlink(patchfile)
    newmessage = '\n***\n'.join(
        [ctx.description(), ] +
        [repo[r].description() for r in internalchanges] +
        [oldctx.description(), ])
    # If the changesets are from the same author, keep it.
    if ctx.user() == oldctx.user():
        username = ctx.user()
    else:
        username = ui.username()
    newmessage = ui.edit(newmessage, username)
    n = repo.commit(text=newmessage, user=username, date=max(ctx.date(), oldctx.date()),
                    extra=oldctx.extra())
    return repo[n], [n, ], [oldctx.node(), ctx.node() ], [newnode, ] # xxx
Exemple #17
0
def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
    parent = ctx.parents()[0].node()
    hg.update(repo, parent)
    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
    fp = os.fdopen(fd, 'w')
    diffopts = patch.diffopts(ui, opts)
    diffopts.git = True
    diffopts.ignorews = False
    diffopts.ignorewsamount = False
    diffopts.ignoreblanklines = False
    gen = patch.diff(repo, parent, newnode, opts=diffopts)
    for chunk in gen:
        fp.write(chunk)
    fp.close()
    files = set()
    try:
        applypatch(ui, repo, patchfile, files=files, eolmode=None)
    finally:
        os.unlink(patchfile)
    newmessage = '\n***\n'.join(
        [ctx.description(), ] +
        [repo[r].description() for r in internalchanges] +
        [oldctx.description(), ])
    # If the changesets are from the same author, keep it.
    if ctx.user() == oldctx.user():
        username = ctx.user()
    else:
        username = ui.username()
    newmessage = ui.edit(newmessage, username)
    n = repo.commit(text=newmessage, user=username, date=max(ctx.date(), oldctx.date()),
                    extra=oldctx.extra())
    return repo[n], [n, ], [oldctx.node(), ctx.node() ], [newnode, ] # xxx
Exemple #18
0
def diffs(repo, tmpl, ctx, basectx, files, parity, style):
    def countgen():
        start = 1
        while True:
            yield start
            start += 1

    blockcount = countgen()

    def prettyprintlines(diff, blockno):
        for lineno, l in enumerate(diff.splitlines(True)):
            difflineno = "%d.%d" % (blockno, lineno + 1)
            if l.startswith('+'):
                ltype = "difflineplus"
            elif l.startswith('-'):
                ltype = "difflineminus"
            elif l.startswith('@'):
                ltype = "difflineat"
            else:
                ltype = "diffline"
            yield tmpl(ltype,
                       line=l,
                       lineno=lineno + 1,
                       lineid="l%s" % difflineno,
                       linenumber="% 8s" % difflineno)

    if files:
        m = match.exact(repo.root, repo.getcwd(), files)
    else:
        m = match.always(repo.root, repo.getcwd())

    diffopts = patch.diffopts(repo.ui, untrusted=True)
    if basectx is None:
        parents = ctx.parents()
        if parents:
            node1 = parents[0].node()
        else:
            node1 = nullid
    else:
        node1 = basectx.node()
    node2 = ctx.node()

    block = []
    for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
        if chunk.startswith('diff') and block:
            blockno = blockcount.next()
            yield tmpl('diffblock',
                       parity=parity.next(),
                       blockno=blockno,
                       lines=prettyprintlines(''.join(block), blockno))
            block = []
        if chunk.startswith('diff') and style != 'raw':
            chunk = ''.join(chunk.splitlines(True)[1:])
        block.append(chunk)
    blockno = blockcount.next()
    yield tmpl('diffblock',
               parity=parity.next(),
               blockno=blockno,
               lines=prettyprintlines(''.join(block), blockno))
Exemple #19
0
    def _show(self, ctx, copies, matchfn, props):
        if not matchfn:
            matchfn = self.patch

        node = ctx.node()
        diffopts = patch.diffopts(self.ui, self.diffopts)
        prev = self.repo.changelog.parents(node)[0]
        self.diff(diffopts, prev, node, match=matchfn)
        self.ui.write("\n")
 def getpatches(revs):
     prev = repo['.'].rev()
     for r in scmutil.revrange(repo, revs):
         if r == prev and (repo[None].files() or repo[None].deleted()):
             ui.warn(_('warning: working directory has '
                       'uncommitted changes\n'))
         output = cStringIO.StringIO()
         cmdutil.export(repo, [r], fp=output,
                      opts=patch.diffopts(ui, opts))
         yield output.getvalue().split('\n')
Exemple #21
0
 def getpatches(revs):
     prev = repo['.'].rev()
     for r in scmutil.revrange(repo, revs):
         if r == prev and (repo[None].files() or repo[None].deleted()):
             ui.warn(
                 _('warning: working directory has '
                   'uncommitted changes\n'))
         output = cStringIO.StringIO()
         cmdutil.export(repo, [r], fp=output, opts=patch.diffopts(ui, opts))
         yield output.getvalue().split('\n')
Exemple #22
0
def difftree(ui, repo, node1=None, node2=None, *files, **opts):
    """diff trees from two commits"""
    def __difftree(repo, node1, node2, files=[]):
        assert node2 is not None
        mmap = repo[node1].manifest()
        mmap2 = repo[node2].manifest()
        m = cmdutil.match(repo, files)
        modified, added, removed = repo.status(node1, node2, m)[:3]
        empty = short(nullid)

        for f in modified:
            # TODO get file permissions
            ui.write(":100664 100664 %s %s M\t%s\t%s\n" %
                     (short(mmap[f]), short(mmap2[f]), f, f))
        for f in added:
            ui.write(":000000 100664 %s %s N\t%s\t%s\n" %
                     (empty, short(mmap2[f]), f, f))
        for f in removed:
            ui.write(":100664 000000 %s %s D\t%s\t%s\n" %
                     (short(mmap[f]), empty, f, f))

    ##

    while True:
        if opts['stdin']:
            try:
                line = raw_input().split(' ')
                node1 = line[0]
                if len(line) > 1:
                    node2 = line[1]
                else:
                    node2 = None
            except EOFError:
                break
        node1 = repo.lookup(node1)
        if node2:
            node2 = repo.lookup(node2)
        else:
            node2 = node1
            node1 = repo.changelog.parents(node1)[0]
        if opts['patch']:
            if opts['pretty']:
                catcommit(ui, repo, node2, "")
            m = cmdutil.match(repo, files)
            chunks = patch.diff(repo,
                                node1,
                                node2,
                                match=m,
                                opts=patch.diffopts(ui, {'git': True}))
            for chunk in chunks:
                ui.write(chunk)
        else:
            __difftree(repo, node1, node2, files=files)
        if not opts['stdin']:
            break
Exemple #23
0
    def get_diffs(self):
        from mercurial import mdiff, util, patch
        from repo_browser.integration import Diff

        ctx = self.ctx

        parent = ctx.parents()[0]
        parent_date = util.datestr(parent.date())
        this_date = util.datestr(ctx.date())
        diffopts = patch.diffopts(self.repo.repo.ui, untrusted=True)

        # Returns a tuple of modified, added, removed, deleted, unknown
        # TODO: look up in the api what FIXME* are
        modified, added, removed, deleted, unknown, FIXME, FIXME2 = \
            self.repo.repo.status(
            parent.node(),
            ctx.node(),)

        for modified_file in modified:
            filectx = ctx.filectx(modified_file)
            parent_filectx = parent.filectx(modified_file)
            this_data = filectx.data()
            parent_data = parent_filectx.data()
            yield Diff(
                mdiff.unidiff(parent_data,
                              parent_date,
                              this_data,
                              this_date,
                              modified_file,
                              modified_file,
                              opts=diffopts))

        for added_file in added:
            filectx = ctx.filectx(added_file)
            this_data = filectx.data()
            yield Diff(
                mdiff.unidiff(None,
                              parent_date,
                              this_data,
                              this_date,
                              added_file,
                              added_file,
                              opts=diffopts))

        for removed_file in removed:
            parent_filectx = parent.filectx(removed_file)
            parent_data = parent_filectx.data()
            yield Diff(
                mdiff.unidiff(parent_data,
                              parent_date,
                              None,
                              ctx.date(),
                              removed_file,
                              removed_file,
                              opts=diffopts))
Exemple #24
0
def diffs(repo, tmpl, ctx, basectx, files, parity, style):

    def countgen():
        start = 1
        while True:
            yield start
            start += 1

    blockcount = countgen()
    def prettyprintlines(diff, blockno):
        for lineno, l in enumerate(diff.splitlines(True)):
            difflineno = "%d.%d" % (blockno, lineno + 1)
            if l.startswith('+'):
                ltype = "difflineplus"
            elif l.startswith('-'):
                ltype = "difflineminus"
            elif l.startswith('@'):
                ltype = "difflineat"
            else:
                ltype = "diffline"
            yield tmpl(ltype,
                       line=l,
                       lineno=lineno + 1,
                       lineid="l%s" % difflineno,
                       linenumber="% 8s" % difflineno)

    if files:
        m = match.exact(repo.root, repo.getcwd(), files)
    else:
        m = match.always(repo.root, repo.getcwd())

    diffopts = patch.diffopts(repo.ui, untrusted=True)
    if basectx is None:
        parents = ctx.parents()
        if parents:
            node1 = parents[0].node()
        else:
            node1 = nullid
    else:
        node1 = basectx.node()
    node2 = ctx.node()

    block = []
    for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
        if chunk.startswith('diff') and block:
            blockno = blockcount.next()
            yield tmpl('diffblock', parity=parity.next(), blockno=blockno,
                       lines=prettyprintlines(''.join(block), blockno))
            block = []
        if chunk.startswith('diff') and style != 'raw':
            chunk = ''.join(chunk.splitlines(True)[1:])
        block.append(chunk)
    blockno = blockcount.next()
    yield tmpl('diffblock', parity=parity.next(), blockno=blockno,
               lines=prettyprintlines(''.join(block), blockno))
Exemple #25
0
 def getdiff(ui, repo, r, parent, opts):
     '''return diff for the specified revision'''
     output = ""
     if opts.get('git') or ui.configbool('diff', 'git'):
         # Git diffs don't include the revision numbers with each file, so
         # we have to put them in the header instead.
         output += "# Node ID " + node.hex(r.node()) + "\n"
         output += "# Parent  " + node.hex(parent.node()) + "\n"
     diffopts = patch.diffopts(ui, opts)
     for chunk in patch.diff(repo, parent.node(), r.node(), opts=diffopts):
         output += chunk
     return output
Exemple #26
0
 def getdiff(ui, repo, r, parent, opts):
     '''return diff for the specified revision'''
     output = ""
     if opts.get('git') or ui.configbool('diff', 'git'):
         # Git diffs don't include the revision numbers with each file, so
         # we have to put them in the header instead.
         output += "# Node ID " + node.hex(r.node()) + "\n"
         output += "# Parent  " + node.hex(parent.node()) + "\n"
     diffopts = patch.diffopts(ui, opts)
     for chunk in patch.diff(repo, parent.node(), r.node(), opts=diffopts):
         output += chunk
     return output
Exemple #27
0
    def shelvefunc(ui, repo, message, match, opts):
        parents = repo.dirstate.parents()
        changes = repo.status(match=match)[:3]
        modified, added, removed = changes
        diffopts = patch.diffopts(ui, opts={'git': True, 'nodates': True})
        chunks = patch.diff(repo, changes=changes, opts=diffopts)
        fp = cStringIO.StringIO(''.join(chunks))

        try:
            ac = parsepatch(fp)
        except patch.PatchError, err:
            raise util.Abort(_('error parsing patch: %s') % err)
Exemple #28
0
    def shelvefunc(ui, repo, message, match, opts):
        parents = repo.dirstate.parents()
        changes = repo.status(match=match)[:3]
        modified, added, removed = changes
        diffopts = patch.diffopts(ui, opts={'git': True, 'nodates': True})
        chunks = patch.diff(repo, changes=changes, opts=diffopts)
        fp = cStringIO.StringIO(''.join(chunks))

        try:
            ac = parsepatch(fp)
        except patch.PatchError, err:
            raise util.Abort(_('error parsing patch: %s') % err)
Exemple #29
0
def annotate(web, req, tmpl):
    fctx = webutil.filectx(web.repo, req)
    f = fctx.path()
    parity = paritygen(web.stripecount)
    diffopts = patch.diffopts(web.repo.ui, untrusted=True, section='annotate')

    def annotate(**map):
        last = None
        if binary(fctx.data()):
            mt = (mimetypes.guess_type(fctx.path())[0]
                  or 'application/octet-stream')
            lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
                                '(binary:%s)' % mt)])
        else:
            lines = enumerate(
                fctx.annotate(follow=True, linenumber=True, diffopts=diffopts))
        for lineno, ((f, targetline), l) in lines:
            fnode = f.filenode()

            if last != fnode:
                last = fnode

            yield {
                "parity": parity.next(),
                "node": f.hex(),
                "rev": f.rev(),
                "author": f.user(),
                "desc": f.description(),
                "extra": f.extra(),
                "file": f.path(),
                "targetline": targetline,
                "line": l,
                "lineid": "l%d" % (lineno + 1),
                "linenumber": "% 6d" % (lineno + 1),
                "revdate": f.date()
            }

    return tmpl("fileannotate",
                file=f,
                annotate=annotate,
                path=webutil.up(f),
                rev=fctx.rev(),
                node=fctx.hex(),
                author=fctx.user(),
                date=fctx.date(),
                desc=fctx.description(),
                extra=fctx.extra(),
                rename=webutil.renamelink(fctx),
                branch=webutil.nodebranchnodefault(fctx),
                parent=webutil.parents(fctx),
                child=webutil.children(fctx),
                permissions=fctx.manifest().flags(f))
Exemple #30
0
def difftree(ui, repo, node1=None, node2=None, *files, **opts):
    """diff trees from two commits"""
    def __difftree(repo, node1, node2, files=[]):
        assert node2 is not None
        mmap = repo[node1].manifest()
        mmap2 = repo[node2].manifest()
        m = cmdutil.match(repo, files)
        modified, added, removed  = repo.status(node1, node2, m)[:3]
        empty = short(nullid)

        for f in modified:
            # TODO get file permissions
            ui.write(":100664 100664 %s %s M\t%s\t%s\n" %
                     (short(mmap[f]), short(mmap2[f]), f, f))
        for f in added:
            ui.write(":000000 100664 %s %s N\t%s\t%s\n" %
                     (empty, short(mmap2[f]), f, f))
        for f in removed:
            ui.write(":100664 000000 %s %s D\t%s\t%s\n" %
                     (short(mmap[f]), empty, f, f))
    ##

    while True:
        if opts['stdin']:
            try:
                line = raw_input().split(' ')
                node1 = line[0]
                if len(line) > 1:
                    node2 = line[1]
                else:
                    node2 = None
            except EOFError:
                break
        node1 = repo.lookup(node1)
        if node2:
            node2 = repo.lookup(node2)
        else:
            node2 = node1
            node1 = repo.changelog.parents(node1)[0]
        if opts['patch']:
            if opts['pretty']:
                catcommit(ui, repo, node2, "")
            m = cmdutil.match(repo, files)
            chunks = patch.diff(repo, node1, node2, match=m,
                                opts=patch.diffopts(ui, {'git': True}))
            for chunk in chunks:
                ui.write(chunk)
        else:
            __difftree(repo, node1, node2, files=files)
        if not opts['stdin']:
            break
Exemple #31
0
def annotate(web, req, tmpl):
    fctx = webutil.filectx(web.repo, req)
    f = fctx.path()
    parity = paritygen(web.stripecount)
    diffopts = patch.diffopts(web.repo.ui, untrusted=True, section="annotate")

    def annotate(**map):
        last = None
        if binary(fctx.data()):
            mt = mimetypes.guess_type(fctx.path())[0] or "application/octet-stream"
            lines = enumerate([((fctx.filectx(fctx.filerev()), 1), "(binary:%s)" % mt)])
        else:
            lines = enumerate(fctx.annotate(follow=True, linenumber=True, diffopts=diffopts))
        for lineno, ((f, targetline), l) in lines:
            fnode = f.filenode()

            if last != fnode:
                last = fnode

            yield {
                "parity": parity.next(),
                "node": f.hex(),
                "rev": f.rev(),
                "author": f.user(),
                "desc": f.description(),
                "extra": f.extra(),
                "file": f.path(),
                "targetline": targetline,
                "line": l,
                "lineid": "l%d" % (lineno + 1),
                "linenumber": "% 6d" % (lineno + 1),
                "revdate": f.date(),
            }

    return tmpl(
        "fileannotate",
        file=f,
        annotate=annotate,
        path=webutil.up(f),
        rev=fctx.rev(),
        node=fctx.hex(),
        author=fctx.user(),
        date=fctx.date(),
        desc=fctx.description(),
        extra=fctx.extra(),
        rename=webutil.renamelink(fctx),
        branch=webutil.nodebranchnodefault(fctx),
        parent=webutil.parents(fctx),
        child=webutil.children(fctx),
        permissions=fctx.manifest().flags(f),
    )
Exemple #32
0
 def diffopts(self, opts={}, patchfn=None):
     diffopts = patchmod.diffopts(self.ui, opts)
     if self.gitmode == 'auto':
         diffopts.upgrade = True
     elif self.gitmode == 'keep':
         pass
     elif self.gitmode in ('yes', 'no'):
         diffopts.git = self.gitmode == 'yes'
     else:
         raise util.Abort(_('mq.git option can be auto/keep/yes/no'
                            ' got %s') % self.gitmode)
     if patchfn:
         diffopts = self.patchopts(diffopts, patchfn)
     return diffopts
Exemple #33
0
    def need_backup(self):
        '''Compare backup of uncommitted changes to workspace'''
        if self._dirstate() != node.hex(self.ws.repo.changectx().node()):
            return True

        curdiff = StringIO()
        diff = self.bu.backupfile('diff')
        fd = None

        patch.diff(self.ws.repo,
                   fp=curdiff,
                   opts=patch.diffopts(self.ws.ui, opts={'git': True}))

        if os.path.exists(diff):
            try:
                try:
                    fd = open(diff)
                    backdiff = fd.read()
                except EnvironmentError, e:
                    raise util.Abort("couldn't open backup diff %s\n"
                                     "   %s" % (diff, e))
            finally:
                if fd and not fd.closed:
                    fd.close()
        else:
            backdiff = ''

        if backdiff != curdiff.getvalue():
            return True

        currrenamed = self._clobbering_renames()
        bakrenamed = None

        if os.path.exists(self.bu.backupfile('renames')):
            try:
                try:
                    fd = open(self.bu.backupfile('renames'))
                    bakrenamed = [line.strip().split(' ') for line in fd]
                except EnvironmentError, e:
                    raise util.Abort("couldn't open renames file %s: %s\n" %
                                     (self.bu.backupfile('renames'), e))
            finally:
                if fd and not fd.closed:
                    fd.close()

            if currrenamed != bakrenamed:
                return True

        return False
Exemple #34
0
    def _get_diffs(self, repository=None, filepath=None):
        diffs = []
        for repo, root in self.repositories:
            if repository and root != repository:
                continue
            #commands.pull(thisui, user_repo)

            # The hg diff command returns the entire set of diffs as one big
            # chunk.  The following code is lifted from the source (version
            # 1.2) as the method for getting the individual diffs.  As such,
            # this is prone to break in the case of internal changes.  We
            # should try and get an external method to do the same thing.
            node1, node2 = cmdutil.revpair(repo, None)

            match = cmdutil.match(repo, (), {})
            repodiffs = []
            for diff in patch.diff(repo, node1, node2, match=match, opts=patch.diffopts(self.ui)):
                diffheader = diff.split('\n')[0]
                filename = DIFF_FILE.match(diffheader).groups()[0]
                if filepath and filepath == filename:
                    return {'repository':root,
                            'filename':filename,
                            'diff': highlight(diff, DiffLexer(), HtmlFormatter())}
                # Should I instantiate a single lexer and formatter and share them?
                repodiffs.append({'repository':root,
                               'filename':filename,
                               'diff': highlight(diff, DiffLexer(), HtmlFormatter())})
            # At the repo level, we want to go through all found files and look
            # for related issues
            try:
                issues = yamltrak.issues([repo.root])[root]
            except KeyError:
                # There is no issue database, or maybe just no open issues...
                issues = {}
            for diff in repodiffs:
                relatedissues = yamltrak.relatedissues(repo.root, filename=diff['filename'], ids=issues.keys())
                related = {}
                for issue in relatedissues:
                    related[issue] = {'repo':root,
                                      'title':issues[issue]['title']}
                diff['relatedissues'] = related
            diffs += repodiffs
        # Done collecting the diffs
        if filepath:
            # User wanted a specific diff, and we didn't find it.  This
            # probably isn't the best exception, but it will have to do...
            raise LookupError

        return diffs
Exemple #35
0
def diff_branch(ui, repo, branch, **opts):
    """Shows the changes from a branch"""
    if branch not in repo.branchtags():
        ui.warn("Branch %s does not exist! (use 'hg branches' to get a list of branches)\n" % branch)
        return
    curr = repo[None].branch()
    if branch == curr:
        ui.status("Already on branch %s\n" % branch)
        return
    rev = repo.branchtip(branch)
    dest = "default"
    drev = repo.branchtip(dest)
    ancestor = repo.changelog.ancestor(rev, drev)
    diffopts = patch.diffopts(ui, opts)
    cmdutil.diffordiffstat(ui, repo, diffopts, ancestor, rev, None)
Exemple #36
0
    def diff(self, node1=None, node2=None, match=None, opts=None):
        '''Return the diff of changes between two changesets as a string'''

        #
        # Retain compatibility by only calling diffopts() if it
        # obviously has not already been done.
        #
        if isinstance(opts, dict):
            opts = patch.diffopts(self.ui, opts)

        ret = cStringIO.StringIO()
        for chunk in patch.diff(self.repo, node1, node2, match=match,
                                opts=opts):
            ret.write(chunk)

        return ret.getvalue()
Exemple #37
0
 def update_commit_preview(self):
     if self.is_merge():
         opts = patch.diffopts(self.ui, self.opts)
         opts.git = True
         wctx = self.repo[None]
         pctx1, pctx2 = wctx.parents()
         difftext = [_('===== Diff to first parent %d:%s =====\n') % (
                     pctx1.rev(), str(pctx1))]
         try:
             for s in patch.diff(self.repo, pctx1.node(), None, opts=opts):
                 difftext.extend(s.splitlines(True))
             difftext.append(_('\n===== Diff to second parent %d:%s =====\n') % (
                             pctx2.rev(), str(pctx2)))
             for s in patch.diff(self.repo, pctx2.node(), None, opts=opts):
                 difftext.extend(s.splitlines(True))
         except (IOError, error.RepoError, error.LookupError, util.Abort), e:
             self.stbar.set_text(str(e))
Exemple #38
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

        matchfunc = cmdutil.match(self.repo, pats, opts)
        opts = patch.diffopts(self.ui, opts)

        return self.diff(act.parenttip.node(), act.localtip.node(),
                         match=matchfunc, opts=opts)
Exemple #39
0
    def diff(self, node1=None, node2=None, match=None, opts=None):
        '''Return the diff of changes between two changesets as a string'''

        #
        # Retain compatibility by only calling diffopts() if it
        # obviously has not already been done.
        #
        if isinstance(opts, dict):
            opts = patch.diffopts(self.ui, opts)

        ret = cStringIO.StringIO()
        for chunk in patch.diff(self.repo,
                                node1,
                                node2,
                                match=match,
                                opts=opts):
            ret.write(chunk)

        return ret.getvalue()
Exemple #40
0
def diffs(repo, tmpl, ctx, files, parity, style):
    def countgen():
        start = 1
        while True:
            yield start
            start += 1

    blockcount = countgen()

    def prettyprintlines(diff):
        blockno = blockcount.next()
        for lineno, l in enumerate(diff.splitlines(True)):
            lineno = "%d.%d" % (blockno, lineno + 1)
            if l.startswith("+"):
                ltype = "difflineplus"
            elif l.startswith("-"):
                ltype = "difflineminus"
            elif l.startswith("@"):
                ltype = "difflineat"
            else:
                ltype = "diffline"
            yield tmpl(ltype, line=l, lineid="l%s" % lineno, linenumber="% 8s" % lineno)

    if files:
        m = match.exact(repo.root, repo.getcwd(), files)
    else:
        m = match.always(repo.root, repo.getcwd())

    diffopts = patch.diffopts(repo.ui, untrusted=True)
    parents = ctx.parents()
    node1 = parents and parents[0].node() or nullid
    node2 = ctx.node()

    block = []
    for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
        if chunk.startswith("diff") and block:
            yield tmpl("diffblock", parity=parity.next(), lines=prettyprintlines("".join(block)))
            block = []
        if chunk.startswith("diff") and style != "raw":
            chunk = "".join(chunk.splitlines(True)[1:])
        block.append(chunk)
    yield tmpl("diffblock", parity=parity.next(), lines=prettyprintlines("".join(block)))
Exemple #41
0
    def backup(self):
        '''Backup uncommitted changes'''

        if self.ws.merged():
            raise util.Abort("Unable to backup an uncommitted merge.\n"
                             "Please complete your merge and commit")

        dirstate = node.hex(self.ws.repo.changectx().node())

        fp = None
        try:
            try:
                fp = open(self.bu.backupfile('dirstate'), 'w')
                fp.write(dirstate + '\n')
            except EnvironmentError, e:
                raise util.Abort("couldn't save working copy parent: %s" % e)
        finally:
            if fp and not fp.closed:
                fp.close()

        try:
            try:
                fp = open(self.bu.backupfile('renames'), 'w')
                for cons in self._clobbering_renames():
                    fp.write("%s %s\n" % cons)
            except EnvironmentError, e:
                raise util.Abort("couldn't save clobbering copies: %s" % e)
        finally:
            if fp and not fp.closed:
                fp.close()

        try:
            try:
                fp = open(self.bu.backupfile('diff'), 'w')
                patch.diff(self.ws.repo,
                           fp=fp,
                           opts=patch.diffopts(self.ws.ui, opts={'git': True}))
            except EnvironmentError, e:
                raise util.Abort("couldn't save working copy diff: %s" % e)
        finally:
            if fp and not fp.closed:
                fp.close()
Exemple #42
0
 def diff(self, node, ref):
     maxdiff = int(self.ui.config('notify', 'maxdiff', 300))
     prev = self.repo.changelog.parents(node)[0]
     self.ui.pushbuffer()
     patch.diff(self.repo, prev, ref, opts=patch.diffopts(self.ui))
     difflines = self.ui.popbuffer().splitlines(1)
     if self.ui.configbool('notify', 'diffstat', True):
         s = patch.diffstat(difflines)
         # s may be nil, don't include the header if it is
         if s:
             self.ui.write('\ndiffstat:\n\n%s' % s)
     if maxdiff == 0:
         return
     if maxdiff > 0 and len(difflines) > maxdiff:
         self.ui.write(_('\ndiffs (truncated from %d to %d lines):\n\n') %
                       (len(difflines), maxdiff))
         difflines = difflines[:maxdiff]
     elif difflines:
         self.ui.write(_('\ndiffs (%d lines):\n\n') % len(difflines))
     self.ui.write(*difflines)
Exemple #43
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()
Exemple #44
0
def edit(ui, repo, ctx, ha, opts):
    oldctx = repo[ha]
    hg.update(repo, ctx.node())
    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
    fp = os.fdopen(fd, 'w')
    diffopts = patch.diffopts(ui, opts)
    diffopts.git = True
    gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
    for chunk in gen:
        fp.write(chunk)
    fp.close()
    try:
        files = {}
        try:
            patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None)
        finally:
            files = patch.updatedir(ui, repo, files)
            os.unlink(patchfile)
    except Exception, inst:
        pass
Exemple #45
0
    def get_diffs(self):
        from mercurial import mdiff, util, patch
        from repo_browser.integration import Diff

        ctx = self.ctx

        parent = ctx.parents()[0]
        parent_date = util.datestr(parent.date())
        this_date = util.datestr(ctx.date())
        diffopts = patch.diffopts(self.repo.repo.ui, untrusted=True)

        # Returns a tuple of modified, added, removed, deleted, unknown
        # TODO: look up in the api what FIXME* are
        modified, added, removed, deleted, unknown, FIXME, FIXME2 = \
            self.repo.repo.status(
            parent.node(),
            ctx.node(),)

        for modified_file in modified:
            filectx = ctx.filectx(modified_file)
            parent_filectx = parent.filectx(modified_file)
            this_data = filectx.data()
            parent_data = parent_filectx.data()
            yield Diff(mdiff.unidiff(parent_data, parent_date,
                                this_data,this_date,
                                modified_file, modified_file,
                                opts=diffopts))

        for added_file in added:
            filectx = ctx.filectx(added_file)
            this_data = filectx.data()
            yield Diff(mdiff.unidiff(
                None, parent_date, this_data, this_date,
                added_file, added_file, opts=diffopts))

        for removed_file in removed:
            parent_filectx = parent.filectx(removed_file)
            parent_data = parent_filectx.data()
            yield Diff(mdiff.unidiff(
                parent_data, parent_date, None, ctx.date(),
                removed_file, removed_file, opts=diffopts))
Exemple #46
0
 def diff(self, node, ref):
     maxdiff = int(self.ui.config('notify', 'maxdiff', 300))
     prev = self.repo.changelog.parents(node)[0]
     self.ui.pushbuffer()
     patch.diff(self.repo, prev, ref, opts=patch.diffopts(self.ui))
     difflines = self.ui.popbuffer().splitlines(1)
     if self.ui.configbool('notify', 'diffstat', True):
         s = patch.diffstat(difflines)
         # s may be nil, don't include the header if it is
         if s:
             self.ui.write('\ndiffstat:\n\n%s' % s)
     if maxdiff == 0:
         return
     if maxdiff > 0 and len(difflines) > maxdiff:
         self.ui.write(
             _('\ndiffs (truncated from %d to %d lines):\n\n') %
             (len(difflines), maxdiff))
         difflines = difflines[:maxdiff]
     elif difflines:
         self.ui.write(_('\ndiffs (%d lines):\n\n') % len(difflines))
     self.ui.write(*difflines)
Exemple #47
0
    def recordfunc(ui, repo, message, match, opts):
        """This is generic record driver.

        Its job is to interactively filter local changes, and
        accordingly prepare working directory into a state in which the
        job can be delegated to a non-interactive commit command such as
        'commit' or 'qrefresh'.

        After the actual job is done by non-interactive command, the
        working directory is restored to its original state.

        In the end we'll record interesting changes, and everything else
        will be left in place, so the user can continue working.
        """

        cmdutil.checkunfinished(repo, commit=True)
        merge = len(repo[None].parents()) > 1
        if merge:
            raise util.Abort(
                _('cannot partially commit a merge '
                  '(use "hg commit" instead)'))

        changes = repo.status(match=match)[:3]
        diffopts = patch.diffopts(
            ui,
            opts=dict(git=True,
                      nodates=True,
                      ignorews=opts.get('ignore_all_space'),
                      ignorewsamount=opts.get('ignore_space_change'),
                      ignoreblanklines=opts.get('ignore_blank_lines')))
        chunks = patch.diff(repo, changes=changes, opts=diffopts)
        fp = cStringIO.StringIO()
        fp.write(''.join(chunks))
        fp.seek(0)

        # 1. filter patch, so we have intending-to apply subset of it
        try:
            chunks = filterpatch(ui, parsepatch(fp))
        except patch.PatchError, err:
            raise util.Abort(_('error parsing patch: %s') % err)
Exemple #48
0
 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 []
Exemple #49
0
def edit(ui, repo, ctx, ha, opts):
    oldctx = repo[ha]
    hg.update(repo, ctx.node())
    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
    fp = os.fdopen(fd, 'w')
    diffopts = patch.diffopts(ui, opts)
    diffopts.git = True
    diffopts.ignorews = False
    diffopts.ignorewsamount = False
    diffopts.ignoreblanklines = False
    gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
    for chunk in gen:
        fp.write(chunk)
    fp.close()
    try:
        files = set()
        try:
            applypatch(ui, repo, patchfile, files=files, eolmode=None)
        finally:
            os.unlink(patchfile)
    except Exception, inst:
        pass
Exemple #50
0
def edit(ui, repo, ctx, ha, opts):
    oldctx = repo[ha]
    hg.update(repo, ctx.node())
    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
    fp = os.fdopen(fd, 'w')
    diffopts = patch.diffopts(ui, opts)
    diffopts.git = True
    diffopts.ignorews = False
    diffopts.ignorewsamount = False
    diffopts.ignoreblanklines = False
    gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
    for chunk in gen:
        fp.write(chunk)
    fp.close()
    try:
        files = set()
        try:
            applypatch(ui, repo, patchfile, files=files, eolmode=None)
        finally:
            os.unlink(patchfile)
    except Exception, inst:
        pass
Exemple #51
0
    def diff(self, ctx, ref=None):

        maxdiff = int(self.ui.config('notify', 'maxdiff', 300))
        prev = ctx.p1().node()
        ref = ref and ref.node() or ctx.node()
        chunks = patch.diff(self.repo, prev, ref, opts=patch.diffopts(self.ui))
        difflines = ''.join(chunks).splitlines()

        if self.ui.configbool('notify', 'diffstat', True):
            s = patch.diffstat(difflines)
            # s may be nil, don't include the header if it is
            if s:
                self.ui.write('\ndiffstat:\n\n%s' % s)

        if maxdiff == 0:
            return
        elif maxdiff > 0 and len(difflines) > maxdiff:
            msg = _('\ndiffs (truncated from %d to %d lines):\n\n')
            self.ui.write(msg % (len(difflines), maxdiff))
            difflines = difflines[:maxdiff]
        elif difflines:
            self.ui.write(_('\ndiffs (%d lines):\n\n') % len(difflines))

        self.ui.write("\n".join(difflines))
Exemple #52
0
 def getpatches(revs):
     for r in scmutil.revrange(repo, revs):
         output = cStringIO.StringIO()
         cmdutil.export(repo, [r], fp=output, opts=patch.diffopts(ui, opts))
         yield output.getvalue().split('\n')
Exemple #53
0
    def apply(self, repo, source, revmap, merges, opts={}):
        '''apply the revisions in revmap one by one in revision order'''
        revs = revmap.keys()
        revs.sort()

        p1, p2 = repo.dirstate.parents()
        pulls = []
        diffopts = patch.diffopts(self.ui, opts)
        diffopts.git = True

        lock = wlock = None
        try:
            wlock = repo.wlock()
            lock = repo.lock()
            for rev in revs:
                node = revmap[rev]
                revstr = '%s:%s' % (rev, revlog.short(node))

                if self.applied(repo, node, p1):
                    self.ui.warn(
                        _('skipping already applied revision %s\n') % revstr)
                    continue

                parents = source.changelog.parents(node)
                if not opts.get('filter'):
                    # If the changeset parent is the same as the wdir's parent,
                    # just pull it.
                    if parents[0] == p1:
                        pulls.append(node)
                        p1 = node
                        continue
                    if pulls:
                        if source != repo:
                            repo.pull(source, heads=pulls)
                        merge.update(repo, pulls[-1], False, False, None)
                        p1, p2 = repo.dirstate.parents()
                        pulls = []

                domerge = False
                if node in merges:
                    # pulling all the merge revs at once would mean we couldn't
                    # transplant after the latest even if transplants before them
                    # fail.
                    domerge = True
                    if not hasnode(repo, node):
                        repo.pull(source, heads=[node])

                if parents[1] != revlog.nullid:
                    self.ui.note(
                        _('skipping merge changeset %s:%s\n') %
                        (rev, revlog.short(node)))
                    patchfile = None
                else:
                    fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
                    fp = os.fdopen(fd, 'w')
                    patch.diff(source, parents[0], node, fp=fp, opts=diffopts)
                    fp.close()

                del revmap[rev]
                if patchfile or domerge:
                    try:
                        n = self.applyone(repo,
                                          node,
                                          source.changelog.read(node),
                                          patchfile,
                                          merge=domerge,
                                          log=opts.get('log'),
                                          filter=opts.get('filter'))
                        if n and domerge:
                            self.ui.status(
                                _('%s merged at %s\n') %
                                (revstr, revlog.short(n)))
                        elif n:
                            self.ui.status(
                                _('%s transplanted to %s\n') %
                                (revlog.short(node), revlog.short(n)))
                    finally:
                        if patchfile:
                            os.unlink(patchfile)
            if pulls:
                repo.pull(source, heads=pulls)
                merge.update(repo, pulls[-1], False, False, None)
        finally:
            self.saveseries(revmap, merges)
            self.transplants.write()
            del lock, wlock
Exemple #54
0
 def diffopts(self, opts={}):
     """proxies a call to patch.diffopts, providing the ui argument"""
     # could this be curried like opener is?
     return patch.diffopts(self.ui, opts)
Exemple #55
0
    def _readStatus(self, ctx, ctx2, wfile, status, changeselect, force):
        def getstatus(repo, n1, n2, wfile):
            m = match.exact(repo.root, repo.getcwd(), [wfile])
            modified, added, removed = repo.status(n1, n2, match=m)[:3]
            if wfile in modified:
                return 'M'
            if wfile in added:
                return 'A'
            if wfile in removed:
                return 'R'
            if wfile in ctx:
                return 'C'
            return None

        isbfile = False
        repo = ctx._repo
        maxdiff = repo.maxdiff
        self.flabel = u'<b>%s</b>' % self.filePath()

        if ctx2:
            # If a revision to compare to was provided, we must put it in
            # the context of the subrepo as well
            if ctx2._repo.root != ctx._repo.root:
                wsub2, wfileinsub2, sctx2 = \
                    hglib.getDeepestSubrepoContainingFile(wfile, ctx2)
                if wsub2:
                    ctx2 = sctx2

        absfile = repo.wjoin(wfile)
        if (wfile in ctx and 'l' in ctx.flags(wfile)) or \
           os.path.islink(absfile):
            if wfile in ctx:
                data = ctx[wfile].data()
            else:
                data = os.readlink(absfile)
            self.contents = data
            self.flabel += _(' <i>(is a symlink)</i>')
            return

        if ctx2 is None:
            ctx2 = ctx.p1()
        if status is None:
            status = getstatus(repo, ctx2.node(), ctx.node(), wfile)

        mde = _('File or diffs not displayed: '
                'File is larger than the specified max size.\n'
                'maxdiff = %s KB') % (maxdiff // 1024)

        if status in ('R', '!'):
            if wfile in ctx.p1():
                fctx = ctx.p1()[wfile]
                if fctx._filelog.rawsize(fctx.filerev()) > maxdiff:
                    self.error = mde
                else:
                    olddata = fctx.data()
                    if '\0' in olddata:
                        self.error = 'binary file'
                    else:
                        self.contents = olddata
                self.flabel += _(' <i>(was deleted)</i>')
            elif hasattr(ctx.p1(), 'hasStandin') and ctx.p1().hasStandin(wfile):
                self.error = 'binary file'
                self.flabel += _(' <i>(was deleted)</i>')
            else:
                self.flabel += _(' <i>(was added, now missing)</i>')
            return

        if status in ('I', '?'):
            assert ctx.rev() is None
            self.flabel += _(' <i>(is unversioned)</i>')
            if os.path.getsize(absfile) > maxdiff:
                self.error = mde
                return
            data = util.posixfile(absfile, 'r').read()
            if not force and '\0' in data:
                self.error = 'binary file'
            else:
                self.contents = data
            return

        if status in ('M', 'A', 'C'):
            if ctx.hasStandin(wfile):
                wfile = ctx.findStandin(wfile)
                isbfile = True
            try:
                fctx, newdata = self._checkMaxDiff(ctx, wfile, maxdiff, force)
            except _BadContent:
                if status == 'A':
                    self._checkRenamed(repo, ctx, ctx2, wfile)
                raise
            self.contents = newdata
            if status == 'C':
                # no further comparison is necessary
                return
            for pctx in ctx.parents():
                if 'x' in fctx.flags() and 'x' not in pctx.flags(wfile):
                    self.elabel = _("exec mode has been "
                                    "<font color='red'>set</font>")
                elif 'x' not in fctx.flags() and 'x' in pctx.flags(wfile):
                    self.elabel = _("exec mode has been "
                                    "<font color='red'>unset</font>")

        if status == 'A':
            oldname = self._checkRenamed(repo, ctx, ctx2, wfile)
            if not oldname:
                return
            olddata = ctx2[oldname].data()
        elif status == 'M':
            if wfile not in ctx2:
                # merge situation where file was added in other branch
                self.flabel += _(' <i>(was added)</i>')
                return
            oldname = wfile
            olddata = ctx2[wfile].data()
        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()

            copy = {}
            if oldname != wfile:
                copy[wfile] = oldname
            patches = patch.diff(repo, ctx.node(), None, match=m,
                                 opts=diffopts, copy=copy)

            for c in patches:
                fp.write(c)
            fp.seek(0)

            # feed diffs through parsepatch() for more fine grained
            # chunk selection
            filediffs = patch.parsepatch(fp)
            if filediffs and filediffs[0].hunks:
                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
                chunk.linecount = len(val.splitlines())
                lines += chunk.linecount
            self.diff = ''.join(values)
        else:
            diffopts = patch.diffopts(repo.ui, {})
            diffopts.git = False
            newdate = util.datestr(ctx.date())
            olddate = util.datestr(ctx2.date())
            if isbfile:
                olddata += '\0'
                newdata += '\0'
            difftext = hglib.unidifftext(olddata, olddate, newdata, newdate,
                                         oldname, wfile, opts=diffopts)
            if difftext:
                self.diff = ('diff -r %s -r %s %s\n' % (ctx, ctx2, oldname)
                             + difftext)
            else:
                self.diff = ''
Exemple #56
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)