Ejemplo n.º 1
0
    def runPatcher(self, fp, wfile, updatestate):
        ui = self.repo.ui.copy()
        class warncapt(ui.__class__):
            def warn(self, msg, *args, **opts):
                self.write(msg)
        ui.__class__ = warncapt

        ok = True
        repo = self.repo
        ui.pushbuffer()
        try:
            eolmode = ui.config('patch', 'eol', 'strict')
            if eolmode.lower() not in patch.eolmodes:
                eolmode = 'strict'
            else:
                eolmode = eolmode.lower()
            try:
                # hg-1.9
                ret = patch.internalpatch(ui, repo, fp, 1, files=None,
                                          eolmode=eolmode, similarity=0)
            except TypeError:
                # hg-1.8
                pfiles = {}
                ret = patch.internalpatch(fp, ui, 1, repo.root, pfiles,
                                          eolmode=eolmode)
                if updatestate:
                    cmdutil.updatedir(repo.ui, repo, pfiles)
            if ret < 0:
                ok = False
                self.showMessage.emit(_('Patch failed to apply'))
        except (patch.PatchError, EnvironmentError), err:
            ok = False
            self.showMessage.emit(hglib.tounicode(str(err)))
Ejemplo n.º 2
0
def updatedir(*args, **kwargs):
    # updatedir moved from patch to cmdutil in hg 1.7
    if hasattr(patch, 'updatedir'):
        patch.updatedir(*args, **kwargs)
    elif hasattr(cmdutil, 'updatedir'):
        cmdutil.updatedir(*args, **kwargs)
    else:
        # hg 1.9+ moved updatedir, and more importantly it's not needed with the way patch is called now..
        scmutil.updatedir(*args, **kwargs)
Ejemplo n.º 3
0
def unshelve(ui, repo, *pats, **opts):
    '''restore shelved changes'''

    try:
        fp = cStringIO.StringIO()
        fp.write(repo.opener('shelve').read())
    except:
        ui.warn(_('nothing to unshelve\n'))
    else:
        if opts['inspect']:
            ui.status(fp.getvalue())
        else:
            files = []
            fp.seek(0)
            for chunk in parsepatch(fp):
                if isinstance(chunk, header):
                    files += chunk.files()
            backupdir = repo.join('shelve-backups')
            try:
                backups = makebackup(ui, repo, backupdir, set(files))
            except:
                ui.warn(_('unshelve backup aborted\n'))
                delete_backup(ui, repo, backupdir)
                raise

            ui.debug(_('applying shelved patch\n'))
            patchdone = 0
            try:
                try:
                    fp.seek(0)
                    pfiles = {}
                    internalpatch(fp, ui, 1, repo.root, files=pfiles)
                    cmdutil.updatedir(ui, repo, pfiles)
                    patchdone = 1
                except:
                    if opts['force']:
                        patchdone = 1
                    else:
                        ui.status(_('restoring backup files\n'))
                        for realname, tmpname in backups.iteritems():
                            ui.debug(_('restoring %r to %r\n') %
                                     (tmpname, realname))
                            util.copyfile(tmpname, repo.wjoin(realname))
            finally:
                delete_backup(ui, repo, backupdir)

            if patchdone:
                ui.debug(_('removing shelved patches\n'))
                os.unlink(repo.join('shelve'))
                ui.status(_('unshelve completed\n'))
            else:
                raise patch.PatchError
Ejemplo n.º 4
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
    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 = {}
        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 = updatedir(ui, repo, files)
            os.unlink(patchfile)
    except Exception, inst:
        raise util.Abort(_('Fix up the change and run '
                           'hg histedit --continue'))
Ejemplo n.º 5
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 = {}
    try:
        patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None)
    finally:
        files = 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
Ejemplo n.º 6
0
    def runPatcher(self, fp, wfile, updatestate):
        ui = self.repo.ui.copy()

        class warncapt(ui.__class__):
            def warn(self, msg, *args, **opts):
                self.write(msg)

        ui.__class__ = warncapt

        ok = True
        repo = self.repo
        ui.pushbuffer()
        try:
            eolmode = ui.config('patch', 'eol', 'strict')
            if eolmode.lower() not in patch.eolmodes:
                eolmode = 'strict'
            else:
                eolmode = eolmode.lower()
            try:
                # hg-1.9
                ret = patch.internalpatch(ui,
                                          repo,
                                          fp,
                                          1,
                                          files=None,
                                          eolmode=eolmode,
                                          similarity=0)
            except TypeError:
                # hg-1.8
                pfiles = {}
                ret = patch.internalpatch(fp,
                                          ui,
                                          1,
                                          repo.root,
                                          pfiles,
                                          eolmode=eolmode)
                if updatestate:
                    cmdutil.updatedir(repo.ui, repo, pfiles)
            except ValueError:
                ret = -1
            if ret < 0:
                ok = False
                self.showMessage.emit(_('Patch failed to apply'))
        except (patch.PatchError, EnvironmentError), err:
            ok = False
            self.showMessage.emit(hglib.tounicode(str(err)))
Ejemplo n.º 7
0
    def applyone(self,
                 repo,
                 node,
                 cl,
                 patchfile,
                 merge=False,
                 log=False,
                 filter=None):
        '''apply the patch in patchfile to the repository as a transplant'''
        (manifest, user, (time, timezone), files, message) = cl[:5]
        date = "%d %d" % (time, timezone)
        extra = {'transplant_source': node}
        if filter:
            (user, date, message) = self.filter(filter, cl, patchfile)

        if log:
            # we don't translate messages inserted into commits
            message += '\n(transplanted from %s)' % revlog.hex(node)

        self.ui.status(_('applying %s\n') % revlog.short(node))
        self.ui.note('%s %s\n%s\n' % (user, date, message))

        if not patchfile and not merge:
            raise util.Abort(_('can only omit patchfile if merging'))
        if patchfile:
            try:
                files = {}
                try:
                    patch.patch(patchfile,
                                self.ui,
                                cwd=repo.root,
                                files=files,
                                eolmode=None)
                    if not files:
                        self.ui.warn(
                            _('%s: empty changeset') % revlog.hex(node))
                        return None
                finally:
                    files = cmdutil.updatedir(self.ui, repo, files)
            except Exception, inst:
                seriespath = os.path.join(self.path, 'series')
                if os.path.exists(seriespath):
                    os.unlink(seriespath)
                p1 = repo.dirstate.parents()[0]
                p2 = node
                self.log(user, date, message, p1, p2, merge=merge)
                self.ui.write(str(inst) + '\n')
                raise util.Abort(
                    _('fix up the merge and run '
                      'hg transplant --continue'))
Ejemplo n.º 8
0
    def applyone(self, repo, node, cl, patchfile, merge=False, log=False,
                 filter=None):
        '''apply the patch in patchfile to the repository as a transplant'''
        (manifest, user, (time, timezone), files, message) = cl[:5]
        date = "%d %d" % (time, timezone)
        extra = {'transplant_source': node}
        if filter:
            (user, date, message) = self.filter(filter, cl, patchfile)

        if log:
            # we don't translate messages inserted into commits
            message += '\n(transplanted from %s)' % revlog.hex(node)

        self.ui.status(_('applying %s\n') % revlog.short(node))
        self.ui.note('%s %s\n%s\n' % (user, date, message))

        if not patchfile and not merge:
            raise util.Abort(_('can only omit patchfile if merging'))
        if patchfile:
            try:
                files = {}
                try:
                    patch.patch(patchfile, self.ui, cwd=repo.root,
                                files=files, eolmode=None)
                    if not files:
                        self.ui.warn(_('%s: empty changeset')
                                     % revlog.hex(node))
                        return None
                finally:
                    files = cmdutil.updatedir(self.ui, repo, files)
            except Exception, inst:
                seriespath = os.path.join(self.path, 'series')
                if os.path.exists(seriespath):
                    os.unlink(seriespath)
                p1 = repo.dirstate.parents()[0]
                p2 = node
                self.log(user, date, message, p1, p2, merge=merge)
                self.ui.write(str(inst) + '\n')
                raise util.Abort(_('fix up the merge and run '
                                   'hg transplant --continue'))
Ejemplo n.º 9
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 = {}
        try:
            patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None)
        finally:
            files = updatedir(ui, repo, files)
            os.unlink(patchfile)
    except Exception, inst:
        pass
Ejemplo n.º 10
0
def updatedir(*args, **kwargs):
    # updatedir moved from patch to cmdutil in hg 1.7
    if hasattr(patch, 'updatedir'):
        patch.updatedir(*args, **kwargs)
    else:
        cmdutil.updatedir(*args, **kwargs)
Ejemplo n.º 11
0
def dorecord(ui, repo, commitfunc, *pats, **opts):
    try:
        if not ui.interactive():
            raise util.Abort(_('running non-interactively, use commit instead'))
    except TypeError: # backwards compatibility with hg 1.1
        if not ui.interactive:
            raise util.Abort(_('running non-interactively, use commit instead'))

    def recordfunc(ui, repo, message, match, opts):
        """This is generic record driver.

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

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

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

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

        # status gives back
        #   modified, added, removed, deleted, unknown, ignored, clean
        # we take only the first 3 of these
        changes = repo.status(match=match)[:3]
        modified, added, removed = changes
        diffopts = opts.copy()
        diffopts['nodates'] = True
        diffopts['git'] = True
        diffopts = patch.diffopts(ui, opts=diffopts)
        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
        chunks = crpatch.filterpatch(opts,
                                     crpatch.parsepatch(changes, fp),
                                     chunk_selector.chunkselector, ui)
        del fp

        contenders = set()
        for h in chunks:
            try:
                contenders.update(set(h.files()))
            except AttributeError:
                pass

        changed = changes[0] + changes[1] + changes[2]
        newfiles = [f for f in changed if f in contenders]

        if not newfiles:
            ui.status(_('no changes to record\n'))
            return 0


        # 2. backup changed files, so we can restore them in the end
        backups = {}
        newly_added_backups = {}
        backupdir = repo.join('record-backups')
        try:
            os.mkdir(backupdir)
        except OSError, err:
            if err.errno != errno.EEXIST:
                raise
        try:
            # backup continues
            for f in newfiles:
                if f not in (modified + added):
                    continue
                fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
                                               dir=backupdir)
                os.close(fd)
                ui.debug('backup %r as %r\n' % (f, tmpname))
                util.copyfile(repo.wjoin(f), tmpname)
                if f in modified:
                    backups[f] = tmpname
                elif f in added:
                    newly_added_backups[f] = tmpname

            fp = cStringIO.StringIO()
            all_backups = {}
            all_backups.update(backups)
            all_backups.update(newly_added_backups)
            for c in chunks:
                if c.filename() in all_backups:
                    c.write(fp)
            dopatch = fp.tell()
            fp.seek(0)

            # 2.5 optionally review / modify patch in text editor
            if opts['crecord_reviewpatch']:
                patchtext = fp.read()
                reviewedpatch = ui.edit(patchtext, "")
                fp.truncate(0)
                fp.write(reviewedpatch)
                fp.seek(0)

            # 3a. apply filtered patch to clean repo  (clean)
            if backups:
                hg.revert(repo, repo.dirstate.parents()[0],
                          lambda key: key in backups)
            # remove newly added files from 'clean' repo (so patch can apply)
            for f in newly_added_backups:
                os.unlink(f)

            # 3b. (apply)
            if dopatch:
                try:
                    ui.debug('applying patch\n')
                    ui.debug(fp.getvalue())
                    if hasattr(patch, 'workingbackend'): # detect 1.9
                        patch.internalpatch(ui, repo, fp, strip=1, eolmode=None)
                    else:
                        pfiles = {}
                        try:
                            patch.internalpatch(ui, repo, fp, 1, eolmode=None)
                        except (TypeError, AttributeError): # pre 17cea10c343e
                            try:
                                patch.internalpatch(ui, repo, fp, 1, repo.root,
                                                    eolmode=None)
                            except (TypeError, AttributeError): # pre 00a881581400
                                try:
                                    patch.internalpatch(fp, ui, 1, repo.root,
                                                        files=pfiles, eolmode=None)
                                except TypeError: # backwards compatible with hg 1.1
                                    patch.internalpatch(fp, ui, 1,
                                                        repo.root, files=pfiles)
                        try:
                            cmdutil.updatedir(ui, repo, pfiles)
                        except AttributeError:
                            try:
                                patch.updatedir(ui, repo, pfiles)
                            except AttributeError:
                                # from 00a881581400 onwards
                                pass
                except patch.PatchError, err:
                    s = str(err)
                    if s:
                        raise util.Abort(s)
                    else:
                        raise util.Abort(_('patch failed to apply'))
            del fp

            # 4. We prepared working directory according to filtered patch.
            #    Now is the time to delegate the job to commit/qrefresh or the like!

            # it is important to first chdir to repo root -- we'll call a
            # highlevel command with list of pathnames relative to repo root
            newfiles = [repo.wjoin(n) for n in newfiles]
            commitfunc(ui, repo, *newfiles, **opts)

            return 0
Ejemplo n.º 12
0
def dorecord(ui, repo, commitfunc, *pats, **opts):
    if not ui.interactive():
        raise util.Abort(_('running non-interactively, use commit instead'))

    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.
        """

        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 = mdiff.diffopts(git=True, nodates=True)
        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
        chunks = filterpatch(ui, parsepatch(fp))
        del fp

        contenders = set()
        for h in chunks:
            try:
                contenders.update(set(h.files()))
            except AttributeError:
                pass

        changed = changes[0] + changes[1] + changes[2]
        newfiles = [f for f in changed if f in contenders]
        if not newfiles:
            ui.status(_('no changes to record\n'))
            return 0

        modified = set(changes[0])

        # 2. backup changed files, so we can restore them in the end
        backups = {}
        backupdir = repo.join('record-backups')
        try:
            os.mkdir(backupdir)
        except OSError, err:
            if err.errno != errno.EEXIST:
                raise
        try:
            # backup continues
            for f in newfiles:
                if f not in modified:
                    continue
                fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_') +
                                               '.',
                                               dir=backupdir)
                os.close(fd)
                ui.debug('backup %r as %r\n' % (f, tmpname))
                util.copyfile(repo.wjoin(f), tmpname)
                shutil.copystat(repo.wjoin(f), tmpname)
                backups[f] = tmpname

            fp = cStringIO.StringIO()
            for c in chunks:
                if c.filename() in backups:
                    c.write(fp)
            dopatch = fp.tell()
            fp.seek(0)

            # 3a. apply filtered patch to clean repo  (clean)
            if backups:
                hg.revert(repo,
                          repo.dirstate.parents()[0],
                          lambda key: key in backups)

            # 3b. (apply)
            if dopatch:
                try:
                    ui.debug('applying patch\n')
                    ui.debug(fp.getvalue())
                    pfiles = {}
                    patch.internalpatch(fp,
                                        ui,
                                        1,
                                        repo.root,
                                        files=pfiles,
                                        eolmode=None)
                    cmdutil.updatedir(ui, repo, pfiles)
                except patch.PatchError, err:
                    raise util.Abort(str(err))
            del fp

            # 4. We prepared working directory according to filtered
            #    patch. Now is the time to delegate the job to
            #    commit/qrefresh or the like!

            # it is important to first chdir to repo root -- we'll call
            # a highlevel command with list of pathnames relative to
            # repo root
            cwd = os.getcwd()
            os.chdir(repo.root)
            try:
                commitfunc(ui, repo, *newfiles, **opts)
            finally:
                os.chdir(cwd)

            return 0
Ejemplo n.º 13
0
        time.sleep(1)

        files = {}
        try:
            diff = self.bu.backupfile('diff')
            try:
                fuzz = patch.patch(diff, self.ws.ui, strip=1,
                                   cwd=self.ws.repo.root, files=files)
                if fuzz:
                    raise util.Abort('working copy diff applied with fuzz')
            except Exception, e:
                raise util.Abort("couldn't apply working copy diff: %s\n"
                                 "   %s" % (diff, e))
        finally:
            if Version.at_least("1.7"):
                cmdutil.updatedir(self.ws.ui, self.ws.repo, files)
            else:
                patch.updatedir(self.ws.ui, self.ws.repo, files)

        if not self.bu.exists('renames'):
            return

        #
        # We need to re-apply name changes where the new name
        # (rename/copy destination) is an already versioned file, as
        # Hg would otherwise ignore them.
        #
        try:
            fp = self.bu.open('renames')
            for line in fp:
                source, dest = line.strip().split()
Ejemplo n.º 14
0
def updatedir(*args, **kwargs):
    # updatedir moved from patch to cmdutil in hg 1.7
    if hasattr(patch, 'updatedir'):
        patch.updatedir(*args, **kwargs)
    else:
        cmdutil.updatedir(*args, **kwargs)
Ejemplo n.º 15
0
def dorecord(ui, repo, commitfunc, *pats, **opts):
    if not ui.interactive():
        raise util.Abort(_('running non-interactively, use commit instead'))

    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.
        """

        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 = mdiff.diffopts(git=True, nodates=True)
        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
        chunks = filterpatch(ui, parsepatch(fp))
        del fp

        contenders = set()
        for h in chunks:
            try:
                contenders.update(set(h.files()))
            except AttributeError:
                pass

        changed = changes[0] + changes[1] + changes[2]
        newfiles = [f for f in changed if f in contenders]
        if not newfiles:
            ui.status(_('no changes to record\n'))
            return 0

        modified = set(changes[0])

        # 2. backup changed files, so we can restore them in the end
        backups = {}
        backupdir = repo.join('record-backups')
        try:
            os.mkdir(backupdir)
        except OSError, err:
            if err.errno != errno.EEXIST:
                raise
        try:
            # backup continues
            for f in newfiles:
                if f not in modified:
                    continue
                fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
                                               dir=backupdir)
                os.close(fd)
                ui.debug('backup %r as %r\n' % (f, tmpname))
                util.copyfile(repo.wjoin(f), tmpname)
                shutil.copystat(repo.wjoin(f), tmpname)
                backups[f] = tmpname

            fp = cStringIO.StringIO()
            for c in chunks:
                if c.filename() in backups:
                    c.write(fp)
            dopatch = fp.tell()
            fp.seek(0)

            # 3a. apply filtered patch to clean repo  (clean)
            if backups:
                hg.revert(repo, repo.dirstate.parents()[0],
                          lambda key: key in backups)

            # 3b. (apply)
            if dopatch:
                try:
                    ui.debug('applying patch\n')
                    ui.debug(fp.getvalue())
                    pfiles = {}
                    patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
                                        eolmode=None)
                    cmdutil.updatedir(ui, repo, pfiles)
                except patch.PatchError, err:
                    raise util.Abort(str(err))
            del fp

            # 4. We prepared working directory according to filtered
            #    patch. Now is the time to delegate the job to
            #    commit/qrefresh or the like!

            # it is important to first chdir to repo root -- we'll call
            # a highlevel command with list of pathnames relative to
            # repo root
            cwd = os.getcwd()
            os.chdir(repo.root)
            try:
                commitfunc(ui, repo, *newfiles, **opts)
            finally:
                os.chdir(cwd)

            return 0