Example #1
0
def cdm_restore(ui, repo, backup, **opts):
    '''restore workspace from backup

    Restores a workspace from the specified backup directory and generation
    (which defaults to the latest).'''

    if not os.getcwd().startswith(repo.root):
        raise util.Abort('restore is not safe to run with -R')

    abort_if_dirty(wslist[repo])

    if opts['generation']:
        gen = int(opts['generation'])
    else:
        gen = None

    if os.path.exists(backup):
        backup = os.path.abspath(backup)

    wlock = repo.wlock()
    lock = repo.lock()

    try:
        bk = CdmBackup(ui, wslist[repo], backup)
        bk.restore(gen)
    finally:
        lock.release()
        wlock.release()
Example #2
0
def cdm_restore(ui, repo, backup, **opts):
    '''restore workspace from backup

    Restores a workspace from the specified backup directory and generation
    (which defaults to the latest).'''

    if not os.getcwd().startswith(repo.root):
        raise util.Abort('restore is not safe to run with -R')
    if wslist[repo].modified():
        raise util.Abort('Workspace has uncommitted changes')
    if wslist[repo].merged():
        raise util.Abort('Workspace has an uncommitted merge')
    if wslist[repo].branched():
        raise util.Abort('Workspace has an uncommitted branch')

    if opts['generation']:
        gen = int(opts['generation'])
    else:
        gen = None

    if os.path.exists(backup):
        backup = os.path.abspath(backup)

    bk = CdmBackup(ui, wslist[repo], backup)
    bk.restore(gen)
Example #3
0
def cdm_backup(ui, repo, if_newer=False):
    '''make backup copies of all workspace changes

    Backups will be stored in ~/cdm.backup/<basename of workspace>.'''

    name = backup_name(repo.root)
    bk = CdmBackup(ui, wslist[repo], name)

    if if_newer and not bk.need_backup():
        ui.status('backup is up-to-date\n')
    else:
        bk.backup()
Example #4
0
def cdm_backup(ui, repo, if_newer=False):
    '''backup workspace changes and metadata

    Create a backup copy of changes made in this workspace as compared
    to its parent workspace, as well as important metadata of this
    workspace.

    NOTE: Only changes as compared to the parent workspace are backed
    up.  If you lose this workspace and its parent, you will not be
    able to restore a backup into a clone of the grandparent
    workspace.

    By default, backups are stored in the cdm.backup/ directory in
    your home directory.  This is configurable using the cdm.backupdir
    configuration variable, for example:

      hg backup --config cdm.backupdir=/net/foo/backups

    or place the following in an appropriate hgrc file::

      [cdm]
      backupdir = /net/foo/backups

    Backups have the same name as the workspace in which they were
    taken, with '-closed' appended in the case of O/N's usr/closed.
    '''

    name = backup_name(repo.root)
    bk = CdmBackup(ui, wslist[repo], name)

    wlock = repo.wlock()
    lock = repo.lock()

    try:
        if if_newer and not bk.need_backup():
            ui.status('backup is up-to-date\n')
        else:
            bk.backup()
    finally:
        lock.release()
        wlock.release()
Example #5
0
def cdm_restore(ui, repo, backup, **opts):
    '''restore workspace from backup

    Restore this workspace from a backup (taken by 'hg backup').

    If the specified backup directory does not exist, it is assumed to
    be relative to the cadmium backup directory (~/cdm.backup/ by
    default).

    For example::

      % hg restore on-rfe - Restore the latest backup of ~/cdm.backup/on-rfe
      % hg restore -g3 on-rfe - Restore the 3rd backup of ~/cdm.backup/on-rfe
      % hg restore /net/foo/backup/on-rfe - Restore from an explicit path
    '''

    if not os.getcwd().startswith(repo.root):
        raise util.Abort('restore is not safe to run with -R')

    abort_if_dirty(wslist[repo])

    if opts['generation']:
        gen = int(opts['generation'])
    else:
        gen = None

    if os.path.exists(backup):
        backup = os.path.abspath(backup)

    wlock = repo.wlock()
    lock = repo.lock()

    try:
        bk = CdmBackup(ui, wslist[repo], backup)
        bk.restore(gen)
    finally:
        lock.release()
        wlock.release()
Example #6
0
def cdm_recommit(ui, repo, **opts):
    '''replace outgoing changesets with a single equivalent changeset

    Replace all outgoing changesets with a single changeset containing
    equivalent changes.  This removes uninteresting changesets created
    during development that would only serve as noise in the gate.

    Any changed file that is now identical in content to that in the
    parent workspace (whether identical in history or otherwise) will
    not be included in the new changeset.  Any merges information will
    also be removed.

    If no files are changed in comparison to the parent workspace, the
    outgoing changesets will be removed, but no new changeset created.

    recommit will refuse to run if the workspace contains more than
    one outgoing head, even if those heads are on the same branch.  To
    recommit with only one branch containing outgoing changesets, your
    workspace must be on that branch and at that branch head.

    recommit will prompt you to take a backup if your workspace has
    been changed since the last backup was taken.  In almost all
    cases, you should allow it to take one (the default).

    recommit cannot be run if the workspace contains any uncommitted
    changes, applied Mq patches, or has multiple outgoing heads (or
    branches).
    '''

    ws = wslist[repo]

    if not os.getcwd().startswith(repo.root):
        raise util.Abort('recommit is not safe to run with -R')

    abort_if_dirty(ws)

    wlock = repo.wlock()
    lock = repo.lock()

    try:
        parent = ws.parent(opts['parent'])
        between = repo.changelog.nodesbetween(ws.findoutgoing(parent))[2]
        heads = set(between) & set(repo.heads())

        if len(heads) > 1:
            ui.warn('Workspace has multiple outgoing heads (or branches):\n')
            for head in sorted(map(repo.changelog.rev, heads), reverse=True):
                ui.warn('\t%d\n' % head)
            raise util.Abort('you must merge before recommitting')

        #
        # We can safely use the worklist here, as we know (from the
        # abort_if_dirty() check above) that the working copy has not been
        # modified.
        #
        active = ws.active(parent)

        if filter(lambda b: len(b.parents()) > 1, active.bases()):
            raise util.Abort('Cannot recommit a merge of two non-outgoing '
                             'changesets')

        if len(active.revs) <= 0:
            raise util.Abort("no changes to recommit")

        if len(active.files()) <= 0:
            ui.warn("Recommitting %d active changesets, but no active files\n" %
                    len(active.revs))

        #
        # During the course of a recommit, any file bearing a name
        # matching the source name of any renamed file will be
        # clobbered by the operation.
        #
        # As such, we ask the user before proceeding.
        #
        bogosity = [f.parentname for f in active if f.is_renamed() and
                    os.path.exists(repo.wjoin(f.parentname))]
        if bogosity:
            ui.warn("The following file names are the original name of a "
                    "rename and also present\n"
                    "in the working directory:\n")

            for fname in bogosity:
                ui.warn("  %s\n" % fname)

            if not yes_no(ui, "These files will be removed by recommit."
                          "  Continue?",
                          False):
                raise util.Abort("recommit would clobber files")

        user = opts['user'] or ui.username()
        comments = '\n'.join(active.comments())

        message = cmdutil.logmessage(opts) or ui.edit(comments, user)
        if not message:
            raise util.Abort('empty commit message')

        bk = CdmBackup(ui, ws, backup_name(repo.root))
        if bk.need_backup():
            if yes_no(ui, 'Do you want to backup files first?', True):
                bk.backup()

        oldtags = repo.tags()
        clearedtags = [(name, nd, repo.changelog.rev(nd), local)
                for name, nd, local in active.tags()]

        ws.squishdeltas(active, message, user=user)
    finally:
        lock.release()
        wlock.release()

    if clearedtags:
        ui.write("Removed tags:\n")
        for name, nd, rev, local in sorted(clearedtags,
                                           key=lambda x: x[0].lower()):
            ui.write("  %5s:%s:\t%s%s\n" % (rev, node.short(nd),
                                            name, (local and ' (local)' or '')))

        for ntag, nnode in sorted(repo.tags().items(),
                                  key=lambda x: x[0].lower()):
            if ntag in oldtags and ntag != "tip":
                if oldtags[ntag] != nnode:
                    ui.write("tag '%s' now refers to revision %d:%s\n" %
                             (ntag, repo.changelog.rev(nnode),
                              node.short(nnode)))
Example #7
0
def cdm_recommit(ui, repo, **opts):
    '''compact outgoing deltas into a single, conglomerate, delta'''

    if not os.getcwd().startswith(repo.root):
        raise util.Abort('recommit is not safe to run with -R')

    abort_if_dirty(wslist[repo])

    heads = repo.heads()
    if len(heads) > 1:
        ui.warn('Workspace has multiple heads (or branches):\n')
        for head in heads:
            ui.warn('\t%d\n' % repo.changelog.rev(head))
        raise util.Abort('you must merge before recommitting')

    wlock = repo.wlock()
    lock = repo.lock()

    try:
        active = wslist[repo].active(opts['parent'])

        if len(active.revs) <= 0:
            raise util.Abort("no changes to recommit")

        if len(active.files()) <= 0:
            ui.warn(
                "Recommitting %d active changesets, but no active files\n" %
                len(active.revs))

        #
        # During the course of a recommit, any file bearing a name
        # matching the source name of any renamed file will be
        # clobbered by the operation.
        #
        # As such, we ask the user before proceeding.
        #
        bogosity = [
            f.parentname for f in active
            if f.is_renamed() and os.path.exists(repo.wjoin(f.parentname))
        ]
        if bogosity:
            ui.warn("The following file names are the original name of a "
                    "rename and also present\n"
                    "in the working directory:\n")

            for fname in bogosity:
                ui.warn("  %s\n" % fname)

            if not yes_no(
                    ui, "These files will be removed by recommit."
                    "  Continue?", False):
                raise util.Abort("recommit would clobber files")

        user = opts['user'] or ui.username()
        comments = '\n'.join(active.comments())

        message = cmdutil.logmessage(opts) or ui.edit(comments, user)
        if not message:
            raise util.Abort('empty commit message')

        bk = CdmBackup(ui, wslist[repo], backup_name(repo.root))
        if bk.need_backup():
            if yes_no(ui, 'Do you want to backup files first?', True):
                bk.backup()

        oldtags = repo.tags()
        clearedtags = [(name, nd, repo.changelog.rev(nd), local)
                       for name, nd, local in active.tags()]

        wslist[repo].squishdeltas(active, message, user=user)
    finally:
        lock.release()
        wlock.release()

    if clearedtags:
        ui.write("Removed tags:\n")
        for name, nd, rev, local in sorted(clearedtags,
                                           key=lambda x: x[0].lower()):
            ui.write("  %5s:%s:\t%s%s\n" % (rev, node.short(nd), name,
                                            (local and ' (local)' or '')))

        for ntag, nnode in sorted(repo.tags().items(),
                                  key=lambda x: x[0].lower()):
            if ntag in oldtags and ntag != "tip":
                if oldtags[ntag] != nnode:
                    ui.write(
                        "tag '%s' now refers to revision %d:%s\n" %
                        (ntag, repo.changelog.rev(nnode), node.short(nnode)))