Ejemplo n.º 1
0
 def add(self, filepaths, dry_run=False, subrepo=None):
     "add the specified files on the next commit"
     m = match(self.repo, filepaths)
     prefix = ""
     uio = self.repo.ui
     rejected = cmdutil.add(uio, self.repo, m, dry_run, subrepo, prefix)
     return rejected
Ejemplo n.º 2
0
 def add(self, filepaths, dry_run=False, subrepo=None):
     "add the specified files on the next commit"
     m = match(self.repo, filepaths)
     prefix = ""
     uio = self.repo.ui
     rejected = cmdutil.add(uio, self.repo, m, dry_run, subrepo, prefix)
     return rejected
Ejemplo n.º 3
0
def shelve(ui, repo, *pats, **opts):
    '''interactively select changes to set aside

    If a list of files is omitted, all changes reported by :hg:` status`
    will be candidates for shelving.

    You will be prompted for whether to shelve changes to each
    modified file, and for files with multiple changes, for each
    change to use.

    The shelve command works with the Color extension to display
    diffs in color.

    On each prompt, the following responses are possible::

      y - shelve this change
      n - skip this change

      s - skip remaining changes to this file
      f - shelve remaining changes to this file

      d - done, skip remaining changes and files
      a - shelve all changes to all remaining files
      q - quit, shelving no changes

      ? - display help
    '''

    if not ui.interactive():
        raise util.Abort(_('shelve can only be run interactively'))

    # List all the active shelves by name and return '
    if opts['list']:
        listshelves(ui, repo)
        return

    forced = opts['force'] or opts['append']

    # Shelf name and path
    shelfname = opts.get('name')
    shelfpath = getshelfpath(repo, shelfname)

    if os.path.exists(repo.join(shelfpath)) and not forced:
        raise util.Abort(_('shelve data already exists'))

    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)

        del fp

        # 1. filter patch, so we have intending-to apply subset of it
        chunks = filterpatch(ui, ac, not opts['all'])
        rc = refilterpatch(ac, chunks)

        # set of files to be processed
        contenders = set()
        for h in chunks:
            try:
                contenders.update(set(h.files()))
            except AttributeError:
                pass

        # exclude sources of copies that are otherwise untouched
        changed = modified + added + removed
        newfiles = set(f for f in changed if f in contenders)
        if not newfiles:
            ui.status(_('no changes to shelve\n'))
            return 0

        # 2. backup changed files, so we can restore them in case of error
        backupdir = repo.join('shelve-backups')
        try:
            backups = makebackup(ui, repo, backupdir, newfiles)

            # patch to shelve
            sp = cStringIO.StringIO()
            for c in chunks:
                c.write(sp)

            # patch to apply to shelved files
            fp = cStringIO.StringIO()
            for c in rc:
                # skip files not selected for shelving
                if c.filename() in newfiles:
                    c.write(fp)
            dopatch = fp.tell()
            fp.seek(0)

            try:
                # 3a. apply filtered patch to clean repo  (clean)
                opts['no_backup'] = True
                cmdutil.revert(ui, repo, repo['.'], parents,
                               *[os.path.join(repo.root, f) for f in newfiles],
                               **opts)
                for f in added:
                    if f in newfiles:
                        util.unlinkpath(repo.wjoin(f))

                # 3b. (apply)
                if dopatch:
                    try:
                        ui.debug('applying patch\n')
                        ui.debug(fp.getvalue())
                        patch.internalpatch(ui, repo, fp, 1, eolmode=None)
                    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 save the shelved changes!
                ui.debug("saving patch to shelve\n")
                if opts['append']:
                    sp.write(repo.opener(shelfpath).read())
                sp.seek(0)
                f = repo.opener(shelfpath, "w")
                f.write(sp.getvalue())
                del f, sp
            except:
                ui.warn("shelving failed: %s\n" % sys.exc_info()[1])
                try:
                    # re-schedule remove
                    matchremoved = scmutil.matchfiles(repo, removed)
                    cmdutil.forget(ui, repo, matchremoved, "", True)
                    for f in removed:
                        if f in newfiles and os.path.isfile(f):
                            os.unlink(f)
                    # copy back backups
                    for realname, tmpname in backups.iteritems():
                        ui.debug('restoring %r to %r\n' % (tmpname, realname))
                        util.copyfile(tmpname, repo.wjoin(realname))
                        # Our calls to copystat() here and above are a
                        # hack to trick any editors that have f open that
                        # we haven't modified them.
                        #
                        # Also note that this racy as an editor could
                        # notice the file's mtime before we've finished
                        # writing it.
                        shutil.copystat(tmpname, repo.wjoin(realname))
                    # re-schedule add
                    matchadded = scmutil.matchfiles(repo, added)
                    cmdutil.add(ui, repo, matchadded, False, False, "", True)

                    ui.debug('removing shelve file\n')
                    if os.path.isfile(repo.wjoin(shelfpath)):
                        os.unlink(repo.join(shelfpath))
                except OSError, err:
                    ui.warn("restoring backup failed: %s\n" % err)
Ejemplo n.º 4
0
    def shelvefunc(ui, repo, message, match, opts):
        parents = repo.dirstate.parents()
        changes = repo.status(match=match)[:5]
        modified, added, removed = changes[:3]
        files = modified + added + removed
        diffopts = mdiff.diffopts(git=True, nodates=True)
        patch_diff = "".join(patch.diff(repo, parents[0], match=match, changes=changes, opts=diffopts))

        fp = cStringIO.StringIO(patch_diff)
        ac = parsepatch(fp)
        fp.close()

        chunks = filterpatch(ui, ac, not opts["all"])
        rc = refilterpatch(ac, chunks)

        # set of files to be processed
        contenders = {}
        for h in chunks:
            try:
                contenders.update(dict.fromkeys(h.files()))
            except AttributeError:
                pass

        # exclude sources of copies that are otherwise untouched
        newfiles = set(f for f in files if f in contenders)

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

        backupdir = repo.join("shelve-backups")

        try:
            backups = makebackup(ui, repo, backupdir, newfiles)

            # patch to shelve
            sp = cStringIO.StringIO()
            for c in chunks:
                c.write(sp)

            # patch to apply to shelved files
            fp = cStringIO.StringIO()
            for c in rc:
                # skip files not selected for shelving
                if c.filename() in newfiles:
                    c.write(fp)
            dopatch = fp.tell()
            fp.seek(0)

            try:
                # 3a. apply filtered patch to clean repo (clean)
                opts["no_backup"] = True
                cmdutil.revert(ui, repo, repo["."], parents, *[os.path.join(repo.root, f) for f in newfiles], **opts)
                for f in added:
                    if f in newfiles:
                        util.unlinkpath(repo.wjoin(f))

                # 3b. apply filtered patch to clean repo (apply)
                if dopatch:
                    ui.debug("applying patch\n")
                    ui.debug(fp.getvalue())
                    patch.internalpatch(ui, repo, fp, 1)
                del fp

                # 3c. apply filtered patch to clean repo (shelve)
                ui.debug("saving patch to shelve\n")
                if opts["append"]:
                    sp.write(repo.opener(shelfpath).read())
                sp.seek(0)
                f = repo.opener(shelfpath, "w")
                f.write(sp.getvalue())
                del f, sp
            except:
                ui.warn("shelving failed: %s\n" % sys.exc_info()[1])
                try:
                    # re-schedule remove
                    matchremoved = scmutil.matchfiles(repo, removed)
                    cmdutil.forget(ui, repo, matchremoved, "", True)
                    for f in removed:
                        if f in newfiles and os.path.isfile(f):
                            os.unlink(f)
                    # copy back backups
                    for realname, tmpname in backups.iteritems():
                        ui.debug("restoring %r to %r\n" % (tmpname, realname))
                        util.copyfile(tmpname, repo.wjoin(realname))
                    # re-schedule add
                    matchadded = scmutil.matchfiles(repo, added)
                    cmdutil.add(ui, repo, matchadded, False, False, "", True)

                    ui.debug("removing shelve file\n")
                    if os.path.isfile(repo.wjoin(shelfpath)):
                        os.unlink(repo.join(shelfpath))
                except OSError, err:
                    ui.warn("restoring backup failed: %s\n" % err)

            return 0
Ejemplo n.º 5
0
    def shelvefunc(ui, repo, message, match, opts):
        parents = repo.dirstate.parents()
        changes = repo.status(match=match)[:5]
        modified, added, removed = changes[:3]
        files = modified + added + removed
        diffopts = mdiff.diffopts(git=True, nodates=True)
        patch_diff = ''.join(
            patch.diff(repo,
                       parents[0],
                       match=match,
                       changes=changes,
                       opts=diffopts))

        fp = cStringIO.StringIO(patch_diff)
        ac = parsepatch(fp)
        fp.close()

        chunks = filterpatch(ui, ac, not opts['all'])
        rc = refilterpatch(ac, chunks)

        # set of files to be processed
        contenders = {}
        for h in chunks:
            try:
                contenders.update(dict.fromkeys(h.files()))
            except AttributeError:
                pass

        # exclude sources of copies that are otherwise untouched
        newfiles = set(f for f in files if f in contenders)

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

        backupdir = repo.join('shelve-backups')

        try:
            backups = makebackup(ui, repo, backupdir, newfiles)

            # patch to shelve
            sp = cStringIO.StringIO()
            for c in chunks:
                c.write(sp)

            # patch to apply to shelved files
            fp = cStringIO.StringIO()
            for c in rc:
                # skip files not selected for shelving
                if c.filename() in newfiles:
                    c.write(fp)
            dopatch = fp.tell()
            fp.seek(0)

            try:
                # 3a. apply filtered patch to clean repo (clean)
                opts['no_backup'] = True
                cmdutil.revert(ui, repo, repo['.'], parents,
                               *[os.path.join(repo.root, f) for f in newfiles],
                               **opts)
                for f in added:
                    if f in newfiles:
                        util.unlinkpath(repo.wjoin(f))

                # 3b. apply filtered patch to clean repo (apply)
                if dopatch:
                    ui.debug('applying patch\n')
                    ui.debug(fp.getvalue())
                    patch.internalpatch(ui, repo, fp, 1)
                del fp

                # 3c. apply filtered patch to clean repo (shelve)
                ui.debug("saving patch to shelve\n")
                if opts['append']:
                    sp.write(repo.opener(shelfpath).read())
                sp.seek(0)
                f = repo.opener(shelfpath, "w")
                f.write(sp.getvalue())
                del f, sp
            except:
                ui.warn("shelving failed: %s\n" % sys.exc_info()[1])
                try:
                    # re-schedule remove
                    matchremoved = scmutil.matchfiles(repo, removed)
                    cmdutil.forget(ui, repo, matchremoved, "", True)
                    for f in removed:
                        if f in newfiles and os.path.isfile(f):
                            os.unlink(f)
                    # copy back backups
                    for realname, tmpname in backups.iteritems():
                        ui.debug('restoring %r to %r\n' % (tmpname, realname))
                        util.copyfile(tmpname, repo.wjoin(realname))
                    # re-schedule add
                    matchadded = scmutil.matchfiles(repo, added)
                    cmdutil.add(ui, repo, matchadded, False, False, "", True)

                    ui.debug('removing shelve file\n')
                    if os.path.isfile(repo.wjoin(shelfpath)):
                        os.unlink(repo.join(shelfpath))
                except OSError, err:
                    ui.warn("restoring backup failed: %s\n" % err)

            return 0
Ejemplo n.º 6
0
def shelve(ui, repo, *pats, **opts):
    '''interactively select changes to set aside

    If a list of files is omitted, all changes reported by :hg:` status`
    will be candidates for shelving.

    You will be prompted for whether to shelve changes to each
    modified file, and for files with multiple changes, for each
    change to use.

    The shelve command works with the Color extension to display
    diffs in color.

    On each prompt, the following responses are possible::

      y - shelve this change
      n - skip this change

      s - skip remaining changes to this file
      f - shelve remaining changes to this file

      d - done, skip remaining changes and files
      a - shelve all changes to all remaining files
      q - quit, shelving no changes

      ? - display help
    '''

    if not ui.interactive() and not (opts['all'] or opts['list']):
        raise util.Abort(_('shelve can only be run interactively'))

    # List all the active shelves by name and return '
    if opts['list']:
        listshelves(ui, repo)
        return

    forced = opts['force'] or opts['append']

    # Shelf name and path
    shelfname = opts.get('name')
    shelfpath = getshelfpath(repo, shelfname)

    if os.path.exists(repo.join(shelfpath)) and not forced:
        raise util.Abort(_('shelve data already exists'))

    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)

        del fp

        # 1. filter patch, so we have intending-to apply subset of it
        chunks = filterpatch(ui, ac, not opts['all'])
        rc = refilterpatch(ac, chunks)

        # set of files to be processed
        contenders = set()
        for h in chunks:
            try:
                contenders.update(set(h.files()))
            except AttributeError:
                pass

        # exclude sources of copies that are otherwise untouched
        changed = modified + added + removed
        newfiles = set(f for f in changed if f in contenders)
        if not newfiles:
            ui.status(_('no changes to shelve\n'))
            return 0

        # 2. backup changed files, so we can restore them in case of error
        backupdir = repo.join('shelve-backups')
        try:
            backups = makebackup(ui, repo, backupdir, newfiles)

            # patch to shelve
            sp = cStringIO.StringIO()
            for c in chunks:
                c.write(sp)

            # patch to apply to shelved files
            fp = cStringIO.StringIO()
            for c in rc:
                # skip files not selected for shelving
                if c.filename() in newfiles:
                    c.write(fp)
            dopatch = fp.tell()
            fp.seek(0)

            try:
                # 3a. apply filtered patch to clean repo  (clean)
                opts['no_backup'] = True
                cmdutil.revert(ui, repo, repo['.'], parents,
                               *[repo.wjoin(f) for f in newfiles], **opts)
                for f in added:
                    if f in newfiles:
                        util.unlinkpath(repo.wjoin(f))

                # 3b. (apply)
                if dopatch:
                    try:
                        ui.debug('applying patch\n')
                        ui.debug(fp.getvalue())
                        patch.internalpatch(ui, repo, fp, 1, eolmode=None)
                    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 save the shelved changes!
                ui.debug("saving patch to shelve\n")
                if opts['append']:
                    sp.write(repo.opener(shelfpath).read())
                sp.seek(0)
                f = repo.opener(shelfpath, "w")
                f.write(sp.getvalue())
                del f, sp
            except:
                ui.warn("shelving failed: %s\n" % sys.exc_info()[1])
                try:
                    # re-schedule remove
                    matchremoved = scmutil.matchfiles(repo, removed)
                    cmdutil.forget(ui, repo, matchremoved, "", True)
                    for f in removed:
                        if f in newfiles and os.path.isfile(repo.wjoin(f)):
                            os.unlink(repo.wjoin(f))
                    # copy back backups
                    for realname, tmpname in backups.iteritems():
                        ui.debug('restoring %r to %r\n' % (tmpname, realname))
                        util.copyfile(tmpname, repo.wjoin(realname))
                        # Our calls to copystat() here and above are a
                        # hack to trick any editors that have f open that
                        # we haven't modified them.
                        #
                        # Also note that this racy as an editor could
                        # notice the file's mtime before we've finished
                        # writing it.
                        shutil.copystat(tmpname, repo.wjoin(realname))
                    # re-schedule add
                    matchadded = scmutil.matchfiles(repo, added)
                    cmdutil.add(ui, repo, matchadded, False, False, "", True)

                    ui.debug('removing shelve file\n')
                    if os.path.isfile(repo.join(shelfpath)):
                        os.unlink(repo.join(shelfpath))
                except OSError, err:
                    ui.warn("restoring backup failed: %s\n" % err)
Ejemplo n.º 7
0
def cmd_format_source(ui, repo, tool, *pats, **opts):
    """register a tool to format source files during merges and rebases

    Record a mapping from the given file pattern FILES to a source formatting
    tool TOOL. Mappings are stored in the version-controlled file
    (automatically committed when format-source is used) .hg-format-source in
    the root of the checkout. The mapping causes TOOL to be run on FILES during
    future merge and rebase operations.

    The actual command run for TOOL needs to be registered in the config. See
    :hg:`help -e format-source` for details.

    """
    if repo.getcwd():
        msg = _("format-source must be run from repository root")
        hint = _("cd %s") % repo.root
        raise error.Abort(msg, hint=hint)

    if not pats:
        raise error.Abort(_('no files specified'))

    # XXX We support glob pattern only for now, the recursive behavior of various others is a bit wonky.
    for pattern in pats:
        if not pattern.startswith('glob:'):
            msg = _("format-source only supports explicit 'glob' patterns "
                    "for now ('%s')")
            msg %= pattern
            hint = _('maybe try with "glob:%s"') % pattern
            raise error.Abort(msg, hint=hint)

    # lock the repo to make sure no content is changed
    with repo.wlock():
        # formatting tool
        if ' ' in tool:
            raise error.Abort(_("tool name cannot contain space: '%s'") % tool)

        # if tool was not specified in the cfg maybe we can use our mozilla firefox in tree clang-format tool
        if should_use_default(repo, tool):
            shell_tool, tool_config_files, file_ext = return_default_clang_format(
                repo)
        else:
            shell_tool = repo.ui.config('format-source', tool)
            tool_config_files = repo.ui.configlist('format-source',
                                                   '%s:configpaths' % tool)
            file_ext = tuple(
                repo.ui.configlist('format-source', '%s:fileext' % tool))

        if not shell_tool:
            msg = _("unknown format tool: %s (no 'format-source.%s' config)")
            raise error.Abort(msg.format(tool, tool))
        if not file_ext:
            msg = _("no {}:fileext present".format(tool))
            raise error.Abort(msg.format(tool, tool))
        cmdutil.bailifchanged(repo)
        cmdutil.checkunfinished(repo, commit=True)
        wctx = repo[None]
        # files to be formatted
        matcher = scmutil.match(wctx, pats, opts)
        files = list(wctx.matches(matcher))

        if util.versiontuple(n=2) >= (4, 7):
            # In 4.7 we have ui.makeprogress
            with ui.makeprogress(_('formatting'),
                                 unit=_('files'),
                                 total=len(files)) as progress:
                proc = worker.worker(ui, 0.1, batchformat,
                                     (repo, wctx, tool, shell_tool, file_ext),
                                     files)
                for filepath in proc:
                    progress.increment(item=filepath)
        else:
            proc = worker.worker(ui, 0.1, batchformat,
                                 (repo, wctx, tool, shell_tool, file_ext),
                                 files)
            # Wait for everything to finish
            for filepath in proc:
                pass

        # update the storage to mark formatted file as formatted
        with repo.wvfs(file_storage_path, mode='ab') as storage:
            for pattern in pats:
                # XXX if pattern was relative, we need to reroot it from the
                # repository root. For now we constrained the command to run
                # at the root of the repository.
                data = {
                    'tool': encoding.unifromlocal(tool),
                    'pattern': encoding.unifromlocal(pattern)
                }
                if tool_config_files:
                    data['configpaths'] = [
                        encoding.unifromlocal(path)
                        for path in tool_config_files
                    ]
                entry = json.dumps(data, sort_keys=True)
                assert '\n' not in entry
                storage.write('%s\n' % entry)

        if file_storage_path not in wctx:
            storage_matcher = scmutil.match(wctx,
                                            ['path:' + file_storage_path])
            cmdutil.add(ui, repo, storage_matcher, '', True)

        # commit the whole
        with repo.lock():
            commit_patterns = ['path:' + file_storage_path]
            commit_patterns.extend(pats)
            return commands._docommit(ui, repo, *commit_patterns, **opts)
Ejemplo n.º 8
0
def cmdutiladd(ui, repo, storage_matcher):
    if util.versiontuple(n=2) >= (5, 0):
        uipathfn = scmutil.getuipathfn(repo, forcerelativevalue=True)
        cmdutil.add(ui, repo, storage_matcher, "", uipathfn, True)
    else:
        cmdutil.add(ui, repo, storage_matcher, "", True)