hgext/convert/bzr.py
author Patrick Mezard <pmezard@gmail.com>
Sun, 26 Apr 2009 11:35:53 +0200
changeset 8165 78658990c725
parent 8148 adce97d28389
child 8166 56719b1aa6f4
child 8423 eb7be0e752d9
permissions -rw-r--r--
convert/bzr: make it work with filemaps (issue1631) The bzr converter maintains a child -> parents mapping and drop entries whenever a child is read. It does not work with filemaps, getchangedfiles() may be called more than once when filtered files belong to merge revisions. getchanges() still works that way but it is not clear whether a similar issue can arise when interacting with merges.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7053
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
     1
# bzr support for the convert extension
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
     2
# This module is for handling 'bzr', that was formerly known as Bazaar-NG;
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
     3
# it cannot access 'bar' repositories, but they were never used very much
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
     4
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
     5
import os
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
     6
from mercurial import demandimport
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
     7
# these do not work with demandimport, blacklist
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
     8
demandimport.ignore.extend([
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
     9
        'bzrlib.transactions',
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    10
        'bzrlib.urlutils',
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    11
    ])
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    12
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    13
from mercurial.i18n import _
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    14
from mercurial import util
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    15
from common import NoRepo, commit, converter_source
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    16
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    17
try:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    18
    # bazaar imports
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    19
    from bzrlib import branch, revision, errors
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    20
    from bzrlib.revisionspec import RevisionSpec
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    21
except ImportError:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    22
    pass
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    23
8045
e09a2f2ef85d convert/bzr: fix file rename replaced by a dir case (issue1583)
Patrick Mezard <pmezard@gmail.com>
parents: 8035
diff changeset
    24
supportedkinds = ('file', 'symlink')
e09a2f2ef85d convert/bzr: fix file rename replaced by a dir case (issue1583)
Patrick Mezard <pmezard@gmail.com>
parents: 8035
diff changeset
    25
7053
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    26
class bzr_source(converter_source):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    27
    """Reads Bazaar repositories by using the Bazaar Python libraries"""
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    28
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    29
    def __init__(self, ui, path, rev=None):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    30
        super(bzr_source, self).__init__(ui, path, rev=rev)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    31
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    32
        try:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    33
            # access bzrlib stuff
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    34
            branch
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    35
        except NameError:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    36
            raise NoRepo('Bazaar modules could not be loaded')
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    37
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    38
        if not os.path.exists(os.path.join(path, '.bzr')):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    39
            raise NoRepo('%s does not look like a Bazaar repo' % path)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    40
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    41
        path = os.path.abspath(path)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    42
        self.branch = branch.Branch.open(path)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    43
        self.sourcerepo = self.branch.repository
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    44
        self._parentids = {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    45
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    46
    def before(self):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    47
        """Before the conversion begins, acquire a read lock
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    48
        for all the operations that might need it. Fortunately
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    49
        read locks don't block other reads or writes to the
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    50
        repository, so this shouldn't have any impact on the usage of
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    51
        the source repository.
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    52
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    53
        The alternative would be locking on every operation that
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    54
        needs locks (there are currently two: getting the file and
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    55
        getting the parent map) and releasing immediately after,
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    56
        but this approach can take even 40% longer."""
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    57
        self.sourcerepo.lock_read()
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    58
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    59
    def after(self):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    60
        self.sourcerepo.unlock()
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    61
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    62
    def getheads(self):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    63
        if not self.rev:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    64
            return [self.branch.last_revision()]
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    65
        try:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    66
            r = RevisionSpec.from_string(self.rev)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    67
            info = r.in_history(self.branch)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    68
        except errors.BzrError:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    69
            raise util.Abort(_('%s is not a valid revision in current branch')
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    70
                             % self.rev)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    71
        return [info.rev_id]
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    72
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    73
    def getfile(self, name, rev):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    74
        revtree = self.sourcerepo.revision_tree(rev)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    75
        fileid = revtree.path2id(name)
8045
e09a2f2ef85d convert/bzr: fix file rename replaced by a dir case (issue1583)
Patrick Mezard <pmezard@gmail.com>
parents: 8035
diff changeset
    76
        if fileid is None or revtree.kind(fileid) not in supportedkinds:
7053
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    77
            # the file is not available anymore - was deleted
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    78
            raise IOError(_('%s is not available in %s anymore') %
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    79
                    (name, rev))
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    80
        sio = revtree.get_file(fileid)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    81
        return sio.read()
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    82
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    83
    def getmode(self, name, rev):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    84
        return self._modecache[(name, rev)]
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    85
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    86
    def getchanges(self, version):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    87
        # set up caches: modecache and revtree
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    88
        self._modecache = {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    89
        self._revtree = self.sourcerepo.revision_tree(version)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    90
        # get the parentids from the cache
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    91
        parentids = self._parentids.pop(version)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    92
        # only diff against first parent id
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    93
        prevtree = self.sourcerepo.revision_tree(parentids[0])
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    94
        return self._gettreechanges(self._revtree, prevtree)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    95
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    96
    def getcommit(self, version):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    97
        rev = self.sourcerepo.get_revision(version)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    98
        # populate parent id cache
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
    99
        if not rev.parent_ids:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   100
            parents = []
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   101
            self._parentids[version] = (revision.NULL_REVISION,)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   102
        else:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   103
            parents = self._filterghosts(rev.parent_ids)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   104
            self._parentids[version] = parents
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   105
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   106
        return commit(parents=parents,
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   107
                # bzr uses 1 second timezone precision
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   108
                date='%d %d' % (rev.timestamp, rev.timezone / 3600),
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   109
                author=self.recode(rev.committer),
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   110
                # bzr returns bytestrings or unicode, depending on the content
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   111
                desc=self.recode(rev.message),
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   112
                rev=version)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   113
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   114
    def gettags(self):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   115
        if not self.branch.supports_tags():
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   116
            return {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   117
        tagdict = self.branch.tags.get_tag_dict()
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   118
        bytetags = {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   119
        for name, rev in tagdict.iteritems():
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   120
            bytetags[self.recode(name)] = rev
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   121
        return bytetags
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   122
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   123
    def getchangedfiles(self, rev, i):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   124
        self._modecache = {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   125
        curtree = self.sourcerepo.revision_tree(rev)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   126
        if i is not None:
8165
78658990c725 convert/bzr: make it work with filemaps (issue1631)
Patrick Mezard <pmezard@gmail.com>
parents: 8148
diff changeset
   127
            parentid = self._parentids[rev][i]
7053
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   128
        else:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   129
            # no parent id, get the empty revision
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   130
            parentid = revision.NULL_REVISION
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   131
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   132
        prevtree = self.sourcerepo.revision_tree(parentid)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   133
        changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   134
        return changes
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   135
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   136
    def _gettreechanges(self, current, origin):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   137
        revid = current._revision_id;
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   138
        changes = []
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   139
        renames = {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   140
        for (fileid, paths, changed_content, versioned, parent, name,
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   141
            kind, executable) in current.iter_changes(origin):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   142
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   143
            if paths[0] == u'' or paths[1] == u'':
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   144
                # ignore changes to tree root
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   145
                continue
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   146
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   147
            # bazaar tracks directories, mercurial does not, so
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   148
            # we have to rename the directory contents
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   149
            if kind[1] == 'directory':
8126
13b36eb14324 convert/bzr: handle files replaced by directories (issue1623)
Patrick Mezard <pmezard@gmail.com>
parents: 8045
diff changeset
   150
                if kind[0] not in (None, 'directory'):
13b36eb14324 convert/bzr: handle files replaced by directories (issue1623)
Patrick Mezard <pmezard@gmail.com>
parents: 8045
diff changeset
   151
                    # Replacing 'something' with a directory, record it
13b36eb14324 convert/bzr: handle files replaced by directories (issue1623)
Patrick Mezard <pmezard@gmail.com>
parents: 8045
diff changeset
   152
                    # so it can be removed.
13b36eb14324 convert/bzr: handle files replaced by directories (issue1623)
Patrick Mezard <pmezard@gmail.com>
parents: 8045
diff changeset
   153
                    changes.append((self.recode(paths[0]), revid))
13b36eb14324 convert/bzr: handle files replaced by directories (issue1623)
Patrick Mezard <pmezard@gmail.com>
parents: 8045
diff changeset
   154
7053
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   155
                if None not in paths and paths[0] != paths[1]:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   156
                    # neither an add nor an delete - a move
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   157
                    # rename all directory contents manually
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   158
                    subdir = origin.inventory.path2id(paths[0])
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   159
                    # get all child-entries of the directory
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   160
                    for name, entry in origin.inventory.iter_entries(subdir):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   161
                        # hg does not track directory renames
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   162
                        if entry.kind == 'directory':
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   163
                            continue
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   164
                        frompath = self.recode(paths[0] + '/' + name)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   165
                        topath = self.recode(paths[1] + '/' + name)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   166
                        # register the files as changed
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   167
                        changes.append((frompath, revid))
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   168
                        changes.append((topath, revid))
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   169
                        # add to mode cache
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   170
                        mode = ((entry.executable and 'x') or (entry.kind == 'symlink' and 's')
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   171
                                or '')
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   172
                        self._modecache[(topath, revid)] = mode
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   173
                        # register the change as move
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   174
                        renames[topath] = frompath
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   175
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   176
                # no futher changes, go to the next change
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   177
                continue
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   178
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   179
            # we got unicode paths, need to convert them
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   180
            path, topath = [self.recode(part) for part in paths]
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   181
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   182
            if topath is None:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   183
                # file deleted
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   184
                changes.append((path, revid))
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   185
                continue
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   186
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   187
            # renamed
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   188
            if path and path != topath:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   189
                renames[topath] = path
8035
cb77c0fbec39 convert: remove renamed source files (issue1505)
Xavier ALT <dex@phoenix-ind.net>
parents: 7060
diff changeset
   190
                changes.append((path, revid))
7053
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   191
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   192
            # populate the mode cache
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   193
            kind, executable = [e[1] for e in (kind, executable)]
8148
adce97d28389 convert/bzr: fix symlink handling (issue1626)
Patrick Mezard <pmezard@gmail.com>
parents: 8126
diff changeset
   194
            mode = ((executable and 'x') or (kind == 'symlink' and 'l')
7053
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   195
                    or '')
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   196
            self._modecache[(topath, revid)] = mode
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   197
            changes.append((topath, revid))
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   198
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   199
        return changes, renames
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   200
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   201
    def _filterghosts(self, ids):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   202
        """Filters out ghost revisions which hg does not support, see
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   203
        <http://bazaar-vcs.org/GhostRevision>
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   204
        """
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   205
        parentmap = self.sourcerepo.get_parent_map(ids)
7060
972cce34f345 convert: fixed python2.3 incompatibility in bzr source (generator expression)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7053
diff changeset
   206
        parents = tuple([parent for parent in ids if parent in parentmap])
7053
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   207
        return parents
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   208
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   209
    def recode(self, s, encoding=None):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   210
        """This version of recode tries to encode unicode to bytecode,
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   211
        and preferably using the UTF-8 codec.
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   212
        Other types than Unicode are silently returned, this is by
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   213
        intention, e.g. the None-type is not going to be encoded but instead
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   214
        just passed through
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   215
        """
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   216
        if not encoding:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   217
            encoding = self.encoding or 'utf-8'
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   218
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   219
        if isinstance(s, unicode):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   220
            return s.encode(encoding)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   221
        else:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   222
            # leave it alone
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
   223
            return s