/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
1
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
0.200.228 by Jelmer Vernooij
Split out map.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Map from Git sha's to Bazaar objects."""
18
0.200.249 by Jelmer Vernooij
Implement Tree.
19
import stat
20
0.200.228 by Jelmer Vernooij
Split out map.
21
import bzrlib
0.200.231 by Jelmer Vernooij
Partially fix pull.
22
from bzrlib import ui
0.200.228 by Jelmer Vernooij
Split out map.
23
from bzrlib.errors import NoSuchRevision
24
0.200.229 by Jelmer Vernooij
More work on converter.
25
from bzrlib.plugins.git.mapping import (
26
    inventory_to_tree_and_blobs,
27
    revision_to_commit,
28
    )
29
from bzrlib.plugins.git.shamap import GitShaMap
30
0.200.231 by Jelmer Vernooij
Partially fix pull.
31
from dulwich.objects import (
32
    Blob,
0.200.249 by Jelmer Vernooij
Implement Tree.
33
    Tree,
0.200.231 by Jelmer Vernooij
Partially fix pull.
34
    )
35
0.200.228 by Jelmer Vernooij
Split out map.
36
37
class GitObjectConverter(object):
38
39
    def __init__(self, repository, mapping=None):
40
        self.repository = repository
41
        if mapping is None:
42
            self.mapping = self.repository.get_mapping()
43
        else:
44
            self.mapping = mapping
45
        self._idmap = GitShaMap(self.repository._transport)
46
47
    def _update_sha_map(self):
0.200.231 by Jelmer Vernooij
Partially fix pull.
48
        all_revids = self.repository.all_revision_ids()
49
        graph = self.repository.get_graph()
0.200.230 by Jelmer Vernooij
Implement sha cache.
50
        present_revids = set(self._idmap.revids())
0.200.231 by Jelmer Vernooij
Partially fix pull.
51
        pb = ui.ui_factory.nested_progress_bar()
52
        try:
53
            for i, revid in enumerate(graph.iter_topo_order(all_revids)):
54
                if revid in present_revids:
55
                    continue
56
                pb.update("updating git map", i, len(all_revids))
57
                self._update_sha_map_revision(revid)
58
        finally:
0.200.232 by Jelmer Vernooij
Fix pull from remote branches.
59
            self._idmap.commit()
0.200.231 by Jelmer Vernooij
Partially fix pull.
60
            pb.finished()
0.200.229 by Jelmer Vernooij
More work on converter.
61
62
    def _update_sha_map_revision(self, revid):
63
        inv = self.repository.get_inventory(revid)
0.200.230 by Jelmer Vernooij
Implement sha cache.
64
        objects = inventory_to_tree_and_blobs(self.repository, self.mapping, revid)
0.200.229 by Jelmer Vernooij
More work on converter.
65
        for sha, o, path in objects:
66
            if path == "":
67
                tree_sha = sha
68
            ie = inv[inv.path2id(path)]
69
            if ie.kind in ("file", "symlink"):
70
                self._idmap.add_entry(sha, "blob", (ie.file_id, ie.revision))
0.200.232 by Jelmer Vernooij
Fix pull from remote branches.
71
            elif ie.kind == "directory":
72
                self._idmap.add_entry(sha, "tree", (path, ie.revision))
0.200.229 by Jelmer Vernooij
More work on converter.
73
            else:
0.200.232 by Jelmer Vernooij
Fix pull from remote branches.
74
                raise AssertionError()
0.200.229 by Jelmer Vernooij
More work on converter.
75
        rev = self.repository.get_revision(revid)
0.200.231 by Jelmer Vernooij
Partially fix pull.
76
        commit_obj = revision_to_commit(rev, tree_sha, self._idmap._parent_lookup)
77
        self._idmap.add_entry(commit_obj.sha().hexdigest(), "commit", (revid, tree_sha))
0.200.229 by Jelmer Vernooij
More work on converter.
78
79
    def _get_blob(self, fileid, revision):
0.200.236 by Jelmer Vernooij
require bzr 1.13.
80
        """Return a Git Blob object from a fileid and revision stored in bzr.
81
        
82
        :param fileid: File id of the text
83
        :param revision: Revision of the text
84
        """
0.200.229 by Jelmer Vernooij
More work on converter.
85
        text = self.repository.texts.get_record_stream([(fileid, revision)], "unordered", True).next().get_bytes_as("fulltext")
86
        blob = Blob()
87
        blob._text = text
88
        return blob
89
0.200.249 by Jelmer Vernooij
Implement Tree.
90
    def _get_tree(self, path, revid, inv=None):
91
        """Return a Git Tree object from a path and a revision stored in bzr.
92
93
        :param path: path in the tree.
94
        :param revision: Revision of the tree.
95
        """
96
        if inv is None:
97
            inv = self.repository.get_inventory(revid)
98
        tree = Tree()
99
        fileid = inv.path2id(path)
100
        for name, ie in inv[fileid].children.iteritems():
101
            if ie.kind == "directory":
102
                subtree = self._get_tree(inv.id2path(ie.file_id), revid, inv)
103
                tree.add(stat.S_IFDIR, name.encode('UTF-8'), subtree.sha().hexdigest())
104
            elif ie.kind == "file":
105
                blob = self._get_blob(inv.path2id(ie.file_id), revid)
106
                mode = stat.S_IFREG | 0644
107
                if ie.executable:
108
                    mode |= 0111
109
                tree.add(mode, name.encode('UTF-8'), blob.sha().hexdigest())
110
            elif ie.kind == "symlink":
111
                raise AssertionError("Symlinks not yet supported")
112
        tree.serialize()
113
        return tree
0.200.229 by Jelmer Vernooij
More work on converter.
114
115
    def _get_commit(self, revid, tree_sha):
116
        rev = self.repository.get_revision(revid)
0.200.231 by Jelmer Vernooij
Partially fix pull.
117
        return revision_to_commit(rev, tree_sha, self._idmap._parent_lookup)
0.200.228 by Jelmer Vernooij
Split out map.
118
119
    def __getitem__(self, sha):
120
        # See if sha is in map
121
        try:
122
            (type, type_data) = self._idmap.lookup_git_sha(sha)
123
        except KeyError:
124
            # if not, see if there are any unconverted revisions and add them 
125
            # to the map, search for sha in map again
126
            self._update_sha_map()
127
            (type, type_data) = self._idmap.lookup_git_sha(sha)
128
        # convert object to git object
0.200.229 by Jelmer Vernooij
More work on converter.
129
        if type == "commit":
0.200.228 by Jelmer Vernooij
Split out map.
130
            return self._get_commit(*type_data)
0.200.229 by Jelmer Vernooij
More work on converter.
131
        elif type == "blob":
132
            return self._get_blob(*type_data)
133
        elif type == "tree":
134
            return self._get_tree(*type_data)
0.200.228 by Jelmer Vernooij
Split out map.
135
        else:
136
            raise AssertionError("Unknown object type '%s'" % type)