/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to converter.py

  • Committer: Robert Collins
  • Date: 2007-03-25 08:59:56 UTC
  • mto: (2376.3.1 integration)
  • mto: This revision was merged to the branch mainline in revision 2401.
  • Revision ID: robertc@robertcollins.net-20070325085956-my8jv7cifqzyltyz
New SmartServer hooks facility. There are two initial hooks documented
in bzrlib.transport.smart.SmartServerHooks. The two initial hooks allow
plugins to execute code upon server startup and shutdown.
(Robert Collins).

SmartServer in standalone mode will now close its listening socket
when it stops, rather than waiting for garbage collection. This primarily
fixes test suite hangs when a test tries to connect to a shutdown server.
It may also help improve behaviour when dealing with a server running
on a specific port (rather than dynamically assigned ports).
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
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
 
 
19
 
from dulwich.objects import (
20
 
    Blob,
21
 
    Tree,
22
 
    )
23
 
import stat
24
 
 
25
 
from bzrlib import (
26
 
    errors,
27
 
    ui,
28
 
    )
29
 
 
30
 
from bzrlib.plugins.git.mapping import (
31
 
    inventory_to_tree_and_blobs,
32
 
    mapping_registry,
33
 
    revision_to_commit,
34
 
    )
35
 
from bzrlib.plugins.git.shamap import (
36
 
    SqliteGitShaMap,
37
 
    )
38
 
 
39
 
 
40
 
class BazaarObjectStore(object):
41
 
    """A Git-style object store backed onto a Bazaar repository."""
42
 
 
43
 
    def __init__(self, repository, mapping=None):
44
 
        self.repository = repository
45
 
        if mapping is None:
46
 
            self.mapping = self.repository.get_mapping()
47
 
        else:
48
 
            self.mapping = mapping
49
 
        self._idmap = SqliteGitShaMap(self.repository._transport)
50
 
 
51
 
    def _update_sha_map(self):
52
 
        all_revids = self.repository.all_revision_ids()
53
 
        graph = self.repository.get_graph()
54
 
        present_revids = set(self._idmap.revids())
55
 
        pb = ui.ui_factory.nested_progress_bar()
56
 
        try:
57
 
            for i, revid in enumerate(graph.iter_topo_order(all_revids)):
58
 
                if revid in present_revids:
59
 
                    continue
60
 
                pb.update("updating git map", i, len(all_revids))
61
 
                self._update_sha_map_revision(revid)
62
 
        finally:
63
 
            self._idmap.commit()
64
 
            pb.finished()
65
 
 
66
 
    def _update_sha_map_revision(self, revid):
67
 
        inv = self.repository.get_inventory(revid)
68
 
        objects = inventory_to_tree_and_blobs(self.repository, self.mapping,
69
 
            revid)
70
 
        for sha, o, path in objects:
71
 
            if path == "":
72
 
                tree_sha = sha
73
 
            ie = inv[inv.path2id(path)]
74
 
            if ie.kind in ("file", "symlink"):
75
 
                self._idmap.add_entry(sha, "blob", (ie.file_id, ie.revision))
76
 
            elif ie.kind == "directory":
77
 
                self._idmap.add_entry(sha, "tree", (path, ie.revision))
78
 
            else:
79
 
                raise AssertionError()
80
 
        rev = self.repository.get_revision(revid)
81
 
        commit_obj = revision_to_commit(rev, tree_sha,
82
 
            self._idmap._parent_lookup)
83
 
        try:
84
 
            foreign_revid, mapping = mapping_registry.parse_revision_id(revid)
85
 
        except errors.InvalidRevisionId:
86
 
            pass
87
 
        else:
88
 
            if foreign_revid != commit_obj.id:
89
 
                raise AssertionError("recreated git commit had different sha1: expected %s, got %s" % (foreign_revid, commit_obj.id))
90
 
        self._idmap.add_entry(commit_obj.id, "commit", (revid, tree_sha))
91
 
 
92
 
    def _get_blob(self, fileid, revision):
93
 
        """Return a Git Blob object from a fileid and revision stored in bzr.
94
 
        
95
 
        :param fileid: File id of the text
96
 
        :param revision: Revision of the text
97
 
        """
98
 
        text = self.repository.texts.get_record_stream([(fileid, revision)],
99
 
            "unordered", True).next().get_bytes_as("fulltext")
100
 
        blob = Blob()
101
 
        blob._text = text
102
 
        return blob
103
 
 
104
 
    def _get_tree(self, path, revid, inv=None):
105
 
        """Return a Git Tree object from a path and a revision stored in bzr.
106
 
 
107
 
        :param path: path in the tree.
108
 
        :param revision: Revision of the tree.
109
 
        """
110
 
        if inv is None:
111
 
            inv = self.repository.get_inventory(revid)
112
 
        tree = Tree()
113
 
        fileid = inv.path2id(path)
114
 
        for name, ie in inv[fileid].children.iteritems():
115
 
            if ie.kind == "directory":
116
 
                subtree = self._get_tree(inv.id2path(ie.file_id), revid, inv)
117
 
                tree.add(stat.S_IFDIR, name.encode('UTF-8'), subtree.id)
118
 
            elif ie.kind == "file":
119
 
                blob = self._get_blob(ie.file_id, ie.revision)
120
 
                mode = stat.S_IFREG | 0644
121
 
                if ie.executable:
122
 
                    mode |= 0111
123
 
                tree.add(mode, name.encode('UTF-8'), blob.id)
124
 
            elif ie.kind == "symlink":
125
 
                raise AssertionError("Symlinks not yet supported")
126
 
        tree.serialize()
127
 
        return tree
128
 
 
129
 
    def _get_commit(self, revid, tree_sha):
130
 
        rev = self.repository.get_revision(revid)
131
 
        return revision_to_commit(rev, tree_sha, self._idmap._parent_lookup)
132
 
 
133
 
    def get_raw(self, sha):
134
 
        obj = self[sha]
135
 
        assert obj.id == sha
136
 
        return obj._text
137
 
 
138
 
    def __getitem__(self, sha):
139
 
        # See if sha is in map
140
 
        try:
141
 
            (type, type_data) = self._idmap.lookup_git_sha(sha)
142
 
        except KeyError:
143
 
            # if not, see if there are any unconverted revisions and add them 
144
 
            # to the map, search for sha in map again
145
 
            self._update_sha_map()
146
 
            (type, type_data) = self._idmap.lookup_git_sha(sha)
147
 
        # convert object to git object
148
 
        if type == "commit":
149
 
            return self._get_commit(*type_data)
150
 
        elif type == "blob":
151
 
            return self._get_blob(*type_data)
152
 
        elif type == "tree":
153
 
            return self._get_tree(*type_data)
154
 
        else:
155
 
            raise AssertionError("Unknown object type '%s'" % type)