/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
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
"""Push implementation that simply prints message saying push is not supported."""
18
0.200.357 by Jelmer Vernooij
Move push code to push.py.
19
from bzrlib import (
20
    ui,
21
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
22
from bzrlib.repository import (
23
    InterRepository,
24
    )
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
25
from bzrlib.revision import (
26
    NULL_REVISION,
27
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
28
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
29
from bzrlib.plugins.git.converter import (
30
    BazaarObjectStore,
31
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
32
from bzrlib.plugins.git.errors import (
33
    NoPushSupport,
34
    )
0.200.357 by Jelmer Vernooij
Move push code to push.py.
35
from bzrlib.plugins.git.mapping import (
36
    inventory_to_tree_and_blobs,
37
    revision_to_commit,
38
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
39
from bzrlib.plugins.git.repository import (
40
    GitRepository,
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
41
    LocalGitRepository,
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
42
    GitRepositoryFormat,
43
    )
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
44
from bzrlib.plugins.git.remote import (
45
    RemoteGitRepository,
46
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
47
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
48
49
class MissingObjectsIterator(object):
50
    """Iterate over git objects that are missing from a target repository.
51
52
    """
53
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
54
    def __init__(self, source, mapping, pb=None):
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
55
        """Create a new missing objects iterator.
56
57
        """
58
        self.source = source
59
        self._object_store = BazaarObjectStore(self.source, mapping)
60
        self._revids = set()
61
        self._sent_shas = set()
62
        self._pending = []
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
63
        self.pb = pb
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
64
65
    def import_revisions(self, revids):
66
        self._revids.update(revids)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
67
        for i, revid in enumerate(revids):
68
            if self.pb:
69
                self.pb.update("pushing revisions", i, len(revids))
70
            git_commit = self.import_revision(revid)
71
            yield (revid, git_commit)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
72
73
    def need_sha(self, sha):
74
        if sha in self._sent_shas:
75
            return False
76
        (type, (fileid, revid)) = self._object_store._idmap.lookup_git_sha(sha)
77
        assert type in ("blob", "tree")
78
        if revid in self._revids:
79
            # Not sent yet, and part of the set of revisions to send
80
            return True
81
        # Not changed in the revisions to send, so either not necessary
82
        # or already present remotely (as git doesn't do ghosts)
83
        return False
84
85
    def queue(self, sha, obj, path, ie=None, inv=None):
86
        if obj is None:
87
            obj = (ie, inv)
88
        self._pending.append((obj, path))
89
        self._sent_shas.add(sha)
90
91
    def import_revision(self, revid):
92
        """Import the gist of a revision into this Git repository.
93
94
        """
95
        inv = self.source.get_inventory(revid)
96
        todo = [inv.root]
97
        tree_sha = None
98
        while todo:
99
            ie = todo.pop()
100
            (sha, object) = self._object_store._get_ie_object_or_sha1(ie, inv)
101
            if ie.parent_id is None:
102
                tree_sha = sha
103
            if not self.need_sha(sha):
104
                continue
105
            self.queue(sha, object, inv.id2path(ie.file_id), ie, inv)
106
            if ie.kind == "directory":
107
                todo.extend(ie.children.values())
108
        assert tree_sha is not None
109
        commit = self._object_store._get_commit(revid, tree_sha)
110
        self.queue(commit.id, commit, None)
111
        return commit.id
112
113
    def __len__(self):
114
        return len(self._pending)
115
116
    def __iter__(self):
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
117
        for i, (object, path) in enumerate(self._pending):
118
            if self.pb:
119
                self.pb.update("writing pack objects", i, len(self))
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
120
            if isinstance(object, tuple):
121
                object = self._object_store._get_ie_object(*object)
122
            yield (object, path)   
123
124
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
125
class InterToGitRepository(InterRepository):
126
    """InterRepository that copies into a Git repository."""
127
128
    _matching_repo_format = GitRepositoryFormat()
129
130
    @staticmethod
131
    def _get_repo_format_to_test():
132
        return None
133
134
    def copy_content(self, revision_id=None, pb=None):
135
        """See InterRepository.copy_content."""
136
        self.fetch(revision_id, pb, find_ghosts=False)
137
138
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
139
            fetch_spec=None):
140
        raise NoPushSupport()
141
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
142
143
class InterToLocalGitRepository(InterToGitRepository):
144
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
145
    def missing_revisions(self, stop_revision):
146
        if stop_revision is None:
147
            raise NotImplementedError
0.200.357 by Jelmer Vernooij
Move push code to push.py.
148
        missing = []
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
149
        pb = ui.ui_factory.nested_progress_bar()
150
        try:
151
            graph = self.source.get_graph()
152
            for revid, _ in graph.iter_ancestry([stop_revision]):
153
                pb.update("determining revisions to fetch", len(missing))
154
                if not self.target.has_revision(revid):
155
                    missing.append(revid)
156
            return graph.iter_topo_order(missing)
157
        finally:
158
            pb.finished()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
159
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
160
    def dfetch_refs(self, refs):
161
        revidmap = {}
162
        gitidmap = {}
163
        for name, revid in refs.iteritems():
164
            newrevidmap, newgitidmap = self.dfetch(revid)
165
            revidmap.update(newrevidmap)
166
            gitidmap.update(newgitidmap)
167
            self.target._git.set_ref(name, gitidmap[revid])
168
        return revidmap, gitidmap
169
0.200.360 by Jelmer Vernooij
Remove dpush ghost support - it makes no sense, git doesn't do ghosts.
170
    def dfetch(self, stop_revision=None):
0.200.357 by Jelmer Vernooij
Move push code to push.py.
171
        """Import the gist of the ancestry of a particular revision."""
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
172
        gitidmap = {}
0.200.357 by Jelmer Vernooij
Move push code to push.py.
173
        revidmap = {}
174
        mapping = self.target.get_mapping()
0.200.367 by Jelmer Vernooij
In dfetch, skip fetching pushed revisions back, as cmd_dpush will already take care of that.
175
        self.source.lock_read()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
176
        try:
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
177
            todo = [revid for revid in self.missing_revisions(stop_revision) if revid != NULL_REVISION]
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
178
            pb = ui.ui_factory.nested_progress_bar()
179
            try:
180
                object_generator = MissingObjectsIterator(self.source, mapping, pb)
181
                for old_bzr_revid, git_commit in object_generator.import_revisions(
182
                    todo):
183
                    new_bzr_revid = mapping.revision_id_foreign_to_bzr(git_commit)
184
                    revidmap[old_bzr_revid] = new_bzr_revid
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
185
                    gitidmap[old_bzr_revid] = git_commit
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
186
                self.target._git.object_store.add_objects(object_generator) 
187
            finally:
188
                pb.finished()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
189
        finally:
190
            self.source.unlock()
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
191
        return revidmap, gitidmap
0.200.357 by Jelmer Vernooij
Move push code to push.py.
192
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
193
    @staticmethod
194
    def is_compatible(source, target):
195
        """Be compatible with GitRepository."""
196
        return (not isinstance(source, GitRepository) and 
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
197
                isinstance(target, LocalGitRepository))
198
199
200
class InterToRemoteGitRepository(InterToGitRepository):
201
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
202
    def dfetch_refs(self, new_refs):
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
203
        """Import the gist of the ancestry of a particular revision."""
204
        revidmap = {}
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
205
        def get_changed_refs(refs):
206
            ret = {}
207
            for name, revid in new_refs.iteritems():
208
                ret[name] = (refs.get(name), object_generator._object_store._lookup_revision_sha1(revid))
209
            return ret
210
        def generate_blob_contents(have, want):
211
            import pdb; pdb.set_trace()
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
212
        mapping = self.target.get_mapping()
213
        self.source.lock_read()
214
        try:
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
215
            object_generator = MissingObjectsIterator(self.source, mapping)
216
            self.target.send_pack(get_changed_refs, generate_blob_contents)
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
217
        finally:
218
            self.source.unlock()
219
        return revidmap
220
221
    @staticmethod
222
    def is_compatible(source, target):
223
        """Be compatible with GitRepository."""
224
        return (not isinstance(source, GitRepository) and 
225
                isinstance(target, RemoteGitRepository))