view utility_commands.py @ 313:942f198b8ff5

hg_delta_editor: detect new branches issued from non-branch directories This fix solves the following case: let's /dumb/layout/project be an existing project. To normalize the trunk/branches/tags layout, people may do: $ mkdir /project $ mv /dumb/layout/project /project/project # Oups, should have been trunk! $ mv /project/project /project/trunk trunk creation was ignore because: - update_branch_map() sees it come from a non-branch copy source and ignores it (case #3). - since it is not in self.branches, add_directory() ignores the non-existing path. Then trunk is left uninitialized. To solve this, we allow update_branch_map() to detect branches copied from non-canonical locations.
author Patrick Mezard <pmezard@gmail.com>
date Sun, 03 May 2009 21:42:42 -0500
parents 9f0738587f94
children 1d48d9a34c19
line wrap: on
line source

import os

from mercurial import util as hgutil

import svnwrap
import cmdutil
import util
import hg_delta_editor

def url(ui, repo, hg_repo_path, **opts):
    """show the location (URL) of the Subversion repository
    """
    hge = hg_delta_editor.HgChangeReceiver(hg_repo_path,
                                           ui_=ui)
    ui.status(hge.url, '\n')


def genignore(ui, repo, hg_repo_path, force=False, **opts):
    """generate .hgignore from svn:ignore properties.
    """
    ignpath = os.path.join(hg_repo_path, '.hgignore')
    if not force and os.path.exists(ignpath):
        raise hgutil.Abort('not overwriting existing .hgignore, try --force?')
    ignorefile = open(ignpath, 'w')
    ignorefile.write('.hgignore\nsyntax:glob\n')
    hge = hg_delta_editor.HgChangeReceiver(hg_repo_path,
                                           ui_=ui)
    svn_commit_hashes = dict(zip(hge.revmap.itervalues(),
                                 hge.revmap.iterkeys()))
    parent = cmdutil.parentrev(ui, repo, hge, svn_commit_hashes)
    r, br = svn_commit_hashes[parent.node()]
    if br == None:
        branchpath = 'trunk'
    else:
        branchpath = 'branches/%s' % br
    url = hge.url
    if url[-1] == '/':
        url = url[:-1]
    user, passwd = util.getuserpass(opts)
    svn = svnwrap.SubversionRepo(url, user, passwd)
    dirs = [''] + [d[0] for d in svn.list_files(branchpath, r) if d[1] == 'd']
    for dir in dirs:
        props = svn.list_props('%s/%s/' % (branchpath,dir), r)
        if 'svn:ignore' in props:
            lines = props['svn:ignore'].strip().split('\n')
            for prop in lines:
                if dir:
                    ignorefile.write('%s/%s\n' % (dir, prop))
                else:
                    ignorefile.write('%s\n' % prop)


def info(ui, repo, hg_repo_path, **opts):
    """show Subversion details similar to `svn info'
    """
    hge = hg_delta_editor.HgChangeReceiver(hg_repo_path,
                                           ui_=ui)
    svn_commit_hashes = dict(zip(hge.revmap.itervalues(),
                                 hge.revmap.iterkeys()))
    parent = cmdutil.parentrev(ui, repo, hge, svn_commit_hashes)
    pn = parent.node()
    if pn not in svn_commit_hashes:
        ui.status('Not a child of an svn revision.\n')
        return 0
    r, br = svn_commit_hashes[pn]
    subdir = parent.extra()['convert_revision'][40:].split('@')[0]
    if br == None:
        branchpath = '/trunk'
    elif br.startswith('../'):
        branchpath = '/%s' % br[3:]
        subdir = subdir.replace('branches/../', '')
    else:
        branchpath = '/branches/%s' % br
    url = hge.url
    if url[-1] == '/':
        url = url[:-1]
    url = '%s%s' % (url, branchpath)
    author = hge.svnauthorforauthor(parent.user())
    # cleverly figure out repo root w/o actually contacting the server
    reporoot = url[:len(url)-len(subdir)]
    ui.status('''URL: %(url)s
Repository Root: %(reporoot)s
Repository UUID: %(uuid)s
Revision: %(revision)s
Node Kind: directory
Last Changed Author: %(author)s
Last Changed Rev: %(revision)s
Last Changed Date: %(date)s\n''' %
              {'reporoot': reporoot,
               'uuid': open(hge.uuid_file).read(),
               'url': url,
               'author': author,
               'revision': r,
               # TODO I'd like to format this to the user's local TZ if possible
               'date': hgutil.datestr(parent.date(),
                                      '%Y-%m-%d %H:%M:%S %1%2 (%a, %d %b %Y)')
              })


def listauthors(ui, args, authors=None, **opts):
    """list all authors in a Subversion repository
    """
    if not len(args):
        ui.status('No repository specified.\n')
        return
    svn = svnwrap.SubversionRepo(util.normalize_url(args[0]))
    author_set = set()
    for rev in svn.revisions():
        author_set.add(str(rev.author)) # So None becomes 'None'
    if authors:
        authorfile = open(authors, 'w')
        authorfile.write('%s=\n' % '=\n'.join(sorted(author_set)))
        authorfile.close()
    else:
        ui.status('%s\n' % '\n'.join(sorted(author_set)))


def version(ui, **opts):
    """Show current version of hg and hgsubversion.
    """
    ui.status('hg: %s\n' % hgutil.version())
    ui.status('svn bindings: %s\n' % svnwrap.version())
    ui.status('hgsubversion: %s\n' % util.version(ui))


nourl = ['version', 'listauthors']
table = {
    'url': url,
    'genignore': genignore,
    'info': info,
    'listauthors': listauthors,
    'version': version,
}