Source

hg-importfs / importfs.py

# importfs.py
#
# Copyright 2010 Lantiq Beteiligungs- GmbH & Co. KG
#
# This software may be used and distributed according to the terms of
# the GNU General Public License version 2 or any later version.
"""import a set of files from a file-system into a repository"""
import os

from mercurial import commands, hg, util
from mercurial.error import Abort, RepoError
from mercurial.i18n import _

def _get_repo(ui, path):
    """Initialize or create a repository."""
    try:
        repo = hg.repository(ui, path)
    except RepoError:
        repo = hg.repository(ui, path, True)
        ui.status(_('created repository %s\n' % repo.root))
    return repo

def _update_repo(ui, repo, rev, branch):
    """Update the repository.

    Creates a new branch if necessary.
    """
    if branch:
        if branch not in repo.branchmap():
            commands.update(ui, repo, rev=rev)
            commands.branch(ui, repo, label=branch)
        else:
            commands.update(ui, repo, rev=branch)
    else:
        if repo.dirstate.branch() != 'default':
            commands.update(ui, repo, rev='default')
        else:
            commands.update(ui, repo, rev=rev or 'tip')

def importfs(ui, source, dest, **opts):
    """Import a set of files from a file-system into a repository.

    Imports a set of files from a given file-system into a Mercurial
    repository as a changeset. If anything fails, the program exits, leaving
    the repository as it is.

    The specified repository is created if it doesn't exist. It is updated to
    the specified parent revision or null.

    If the repository is updated to a revision other than "tip" a new branch
    is created. In this case it is mandatory to use the "branch" option to
    name it.

    If a branch is specified it is created or reused.

    The files in the directory specified in SOURCE are compared with the files
    (if any) in the working directory of the specified repository (DEST) to
    detect missing files (i.e. files deleted since the last revision). These
    files are deleted in the repository working directory.

    The files are copied into the working directory. "hg addremove" with the
    specified similarity is executed. "hg commit" with the specified message
    is executed. If a tag is specified, "hg tag" with the name is executed. If
    no tag is specified a default tag with the format import_YYYYMMDD-HHMMSSTZ
    is created.
    """
    sourcepath = util.expandpath(source)
    if not os.path.exists(sourcepath):
        raise Abort(_('directory %s does not exist') % sourcepath)
    if opts.get('rev') and not opts.get('branch'):
        raise Abort(_('you specified a revision without giving a branch name'))
    repo = _get_repo(ui, dest)
    _update_repo(ui, repo, opts.get('rev'), opts.get('branch'))
    util.system('rm -rf *', cwd=repo.root)
    for node in os.listdir(sourcepath):
        src = os.path.join(sourcepath, node)
        dst = os.path.join(repo.root, node)
        util.copyfiles(src, dst, False)
    commands.addremove(ui, repo, similarity=opts.get('similarity'))
    message = opts.get('message') or 'importfs commit.'
    commands.commit(ui, repo, message=message)
    tag = opts.get('tag')
    if tag:
        commands.tag(ui, repo, tag)

cmdtable = {'importfs':
    (importfs,
    [('r', 'rev', '', _('The revision to use as the immediate predecessor of '
        'the new revision. If omitted the revision null is used.'), _('REV')),
    ('b', 'branch', '', _("The name of a branch for the new revision. If it "
        "doesn't exist it is created. If omitted the default branch is used. "
        "This option is required if a revision other than tip is specified."),
        _('NAME')),
    ('s', 'similarity', 100, _('A number to pass as the value of the '
        'similarity option to "hg addremove" for guessing file renames. (See '
        'hg help for an explanation.) If omitted the value "100" is used.'),
        _('SIMILARITY')),
    ('m', 'message', '', _('The commit message to be used. If omitted the '
        'tag string is used.'), _('TEXT')),
    ('t', 'tag', '', _('The tag for the resulting revision. If omitted the '
        'revision is not tagged.'), _('NAME'))],
    '[OPTION]... SOURCE DEST')
}
commands.norepo += ' importfs'