/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.910 by Jelmer Vernooij
update copyright years
1
# Copyright (C) 2009-2010 Jelmer Vernooij <jelmer@samba.org>
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
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 (
0.200.598 by Jelmer Vernooij
Cope with ghosts.
20
    errors,
0.200.357 by Jelmer Vernooij
Move push code to push.py.
21
    ui,
22
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
23
from bzrlib.repository import (
24
    InterRepository,
25
    )
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
26
from bzrlib.revision import (
27
    NULL_REVISION,
28
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
29
30
from bzrlib.plugins.git.errors import (
31
    NoPushSupport,
32
    )
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
33
from bzrlib.plugins.git.object_store import (
34
    BazaarObjectStore,
35
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
36
from bzrlib.plugins.git.repository import (
37
    GitRepository,
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
38
    LocalGitRepository,
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
39
    GitRepositoryFormat,
40
    )
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
41
from bzrlib.plugins.git.remote import (
42
    RemoteGitRepository,
43
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
44
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
45
46
class MissingObjectsIterator(object):
47
    """Iterate over git objects that are missing from a target repository.
48
49
    """
50
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
51
    def __init__(self, store, source, 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.
52
        """Create a new missing objects iterator.
53
54
        """
55
        self.source = source
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
56
        self._object_store = store
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
57
        self._pending = []
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
58
        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.
59
0.252.4 by Jelmer Vernooij
More work on roundtripping.
60
    def import_revisions(self, revids, roundtrip):
0.200.947 by Jelmer Vernooij
Add convenience method for getting missing objects iterator.
61
        """Import a set of revisions into this git repository.
62
63
        :param revids: Revision ids of revisions to import
64
        :param roundtrip: Whether to roundtrip bzr metadata
65
        """
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
66
        for i, revid in enumerate(revids):
67
            if self.pb:
68
                self.pb.update("pushing revisions", i, len(revids))
0.252.4 by Jelmer Vernooij
More work on roundtripping.
69
            git_commit = self.import_revision(revid, roundtrip)
0.252.6 by Jelmer Vernooij
Roundtripping support for revision ids works.
70
            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.
71
0.252.4 by Jelmer Vernooij
More work on roundtripping.
72
    def import_revision(self, revid, roundtrip):
0.200.947 by Jelmer Vernooij
Add convenience method for getting missing objects iterator.
73
        """Import a revision into this Git repository.
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
74
0.200.947 by Jelmer Vernooij
Add convenience method for getting missing objects iterator.
75
        :param revid: Revision id of the revision
76
        :param roundtrip: Whether to roundtrip bzr metadata
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
77
        """
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
78
        tree = self._object_store.tree_cache.revision_tree(revid)
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
79
        rev = self.source.get_revision(revid)
0.200.784 by Jelmer Vernooij
Use common object generation code in push.
80
        commit = None
0.252.4 by Jelmer Vernooij
More work on roundtripping.
81
        for path, obj, ie in self._object_store._revision_to_objects(rev, tree,
82
            roundtrip):
0.200.829 by Jelmer Vernooij
Cope with the fact that _type is gone in upstream dulwich.
83
            if obj.type_name == "commit":
0.200.784 by Jelmer Vernooij
Use common object generation code in push.
84
                commit = obj
0.200.786 by Jelmer Vernooij
Simplify push code.
85
            self._pending.append((obj, path))
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
86
        return commit.id
87
88
    def __len__(self):
89
        return len(self._pending)
90
91
    def __iter__(self):
0.200.786 by Jelmer Vernooij
Simplify push code.
92
        return iter(self._pending)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
93
94
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
95
class InterToGitRepository(InterRepository):
96
    """InterRepository that copies into a Git repository."""
97
98
    _matching_repo_format = GitRepositoryFormat()
99
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
100
    def __init__(self, source, target):
101
        super(InterToGitRepository, self).__init__(source, target)
102
        self.mapping = self.target.get_mapping()
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
103
        self.source_store = BazaarObjectStore(self.source, self.mapping)
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
104
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
105
    @staticmethod
106
    def _get_repo_format_to_test():
107
        return None
108
109
    def copy_content(self, revision_id=None, pb=None):
110
        """See InterRepository.copy_content."""
111
        self.fetch(revision_id, pb, find_ghosts=False)
112
0.200.943 by Jelmer Vernooij
Add stubs.
113
    def dfetch_refs(self, update_refs):
114
        """Fetch non-roundtripped revisions into the target repository.
115
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
116
        :param update_refs: Generate refs to fetch. Receives dictionary
0.200.943 by Jelmer Vernooij
Add stubs.
117
            with old names to old git shas. Should return a dictionary
118
            of new names to Bazaar revision ids.
119
        :return: revision id map, old refs dictionary and new refs dictionary
120
        """
121
        raise NotImplementedError(self.dfetch_refs)
122
123
    def fetch_refs(self, update_refs):
124
        """Fetch possibly roundtripped revisions into the target repository.
125
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
126
        :param update_refs: Generate refs to fetch. Receives dictionary
127
            with old refs (git shas), returns dictionary of new names to
0.200.943 by Jelmer Vernooij
Add stubs.
128
            git shas.
129
        :return: old refs, new refs
130
        """
131
        raise NotImplementedError(self.fetch_refs)
132
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
133
134
class InterToLocalGitRepository(InterToGitRepository):
0.200.966 by Jelmer Vernooij
Some more docstrings.
135
    """InterBranch implementation between a Bazaar and a Git repository."""
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
136
0.252.3 by Jelmer Vernooij
Refactor revision finding code.
137
    def __init__(self, source, target):
138
        super(InterToLocalGitRepository, self).__init__(source, target)
139
        self.target_store = self.target._git.object_store
0.252.6 by Jelmer Vernooij
Roundtripping support for revision ids works.
140
        self.target_refs = self.target._git.refs
0.252.3 by Jelmer Vernooij
Refactor revision finding code.
141
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
142
    def _revision_needs_fetching(self, sha_id, revid):
0.200.968 by Jelmer Vernooij
Add more tests, simplify push code.
143
        if revid == NULL_REVISION:
144
            return False
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
145
        if sha_id is None:
146
            try:
147
                sha_id = self.source_store._lookup_revision_sha1(revid)
148
            except KeyError:
149
                return False
0.200.968 by Jelmer Vernooij
Add more tests, simplify push code.
150
        try:
151
            return (sha_id not in self.target_store)
152
        except errors.NoSuchRevision:
153
            # Ghost, can't push
154
            return False
155
156
    def missing_revisions(self, stop_revisions):
0.200.966 by Jelmer Vernooij
Some more docstrings.
157
        """Find the revisions that are missing from the target repository.
158
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
159
        :param stop_revisions: Revisions to check for (tuples with
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
160
            Git SHA1, bzr revid)
0.200.966 by Jelmer Vernooij
Some more docstrings.
161
        :return: sequence of missing revisions, in topological order
0.200.968 by Jelmer Vernooij
Add more tests, simplify push code.
162
        :raise: NoSuchRevision if the stop_revisions are not present in
163
            the source
0.200.966 by Jelmer Vernooij
Some more docstrings.
164
        """
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
165
        revid_sha_map = {}
166
        stop_revids = []
167
        stop_sha1s = []
168
        for (sha1, revid) in stop_revisions:
169
            if sha1 is not None and revid is not None:
170
                revid_sha_map[revid] = sha1
171
            elif sha1 is not None:
172
                stop_sha1s.append(sha1)
173
            else:
174
                assert revid is not None
175
                stop_revids.append(revid)
0.200.357 by Jelmer Vernooij
Move push code to push.py.
176
        missing = []
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
177
        graph = self.source.get_graph()
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
178
        pb = ui.ui_factory.nested_progress_bar()
179
        try:
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
180
            for revid, _ in graph.iter_ancestry(stop_revids):
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
181
                assert type(revid) is str
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
182
                pb.update("determining revisions to fetch", len(missing))
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
183
                sha1 = revid_sha_map.get(revid)
184
                if self._revision_needs_fetching(sha1, revid):
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
185
                    missing.append(revid)
186
        finally:
187
            pb.finished()
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
188
        for sha1 in stop_sha1s:
189
            try:
190
                (kind, (revid, tree_sha, verifiers)) = self.source_store.lookup_git_sha(sha1)
191
            except KeyError:
192
                continue
193
            else:
194
                missing.append(revid)
195
                revid_sha_map[revid] = sha1
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
196
        return graph.iter_topo_order(missing)
0.200.357 by Jelmer Vernooij
Move push code to push.py.
197
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
198
    def _get_target_bzr_refs(self):
199
        """Return a dictionary with references.
200
201
        :return: Dictionary with reference names as keys and tuples
202
            with Git SHA, Bazaar revid as values.
203
        """
204
        bzr_refs = {}
205
        refs = self.target._git.get_refs()
206
        for k, v in refs.iteritems():
207
            try:
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
208
                (kind, type_data) = self.source_store.lookup_git_sha(v)
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
209
            except KeyError:
210
                revid = None
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
211
            else:
212
                if kind == "commit":
213
                    revid = type_data[0]
214
                else:
215
                    revid = None
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
216
            bzr_refs[k] = (v, revid)
217
        return bzr_refs
218
0.200.941 by Jelmer Vernooij
Pass update_refs argument to fetch_refs.
219
    def fetch_refs(self, update_refs):
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
220
        self.source.lock_read()
221
        try:
222
            old_refs = self._get_target_bzr_refs()
223
            new_refs = update_refs(old_refs)
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
224
            self.fetch(mapped_refs=new_refs.values())
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
225
        finally:
226
            self.source.unlock()
0.200.941 by Jelmer Vernooij
Pass update_refs argument to fetch_refs.
227
        return old_refs, new_refs
0.252.5 by Jelmer Vernooij
enable 'bzr push'.
228
0.200.942 by Jelmer Vernooij
pass update_refs to dfetch_refs.
229
    def dfetch_refs(self, update_refs):
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
230
        self.source.lock_read()
231
        try:
232
            old_refs = self._get_target_bzr_refs()
233
            new_refs = update_refs(old_refs)
234
            revidmap, gitidmap = self.dfetch(new_refs.values())
235
            for name, (gitid, revid) in new_refs.iteritems():
236
                if gitid is None:
237
                    try:
238
                        gitid = gitidmap[revid]
239
                    except KeyError:
240
                        gitid = self.source_store._lookup_revision_sha1(revid)
241
                self.target._git.refs[name] = gitid
242
                new_refs[name] = (gitid, self.source_store.lookup_git_sha(gitid)[1][0])
243
        finally:
244
            self.source.unlock()
0.200.822 by Jelmer Vernooij
Fix indication of number of revisions pushed in dpush.
245
        return revidmap, old_refs, new_refs
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
246
0.200.947 by Jelmer Vernooij
Add convenience method for getting missing objects iterator.
247
    def _get_missing_objects_iterator(self, pb):
248
        return MissingObjectsIterator(self.source_store, self.source, pb)
249
0.200.524 by Jelmer Vernooij
Simplify dpushing multiple heads.
250
    def dfetch(self, stop_revisions):
0.200.357 by Jelmer Vernooij
Move push code to push.py.
251
        """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.
252
        gitidmap = {}
0.200.357 by Jelmer Vernooij
Move push code to push.py.
253
        revidmap = {}
0.200.367 by Jelmer Vernooij
In dfetch, skip fetching pushed revisions back, as cmd_dpush will already take care of that.
254
        self.source.lock_read()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
255
        try:
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
256
            todo = list(self.missing_revisions(stop_revisions))
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
257
            pb = ui.ui_factory.nested_progress_bar()
258
            try:
0.200.968 by Jelmer Vernooij
Add more tests, simplify push code.
259
                object_generator = self._get_missing_objects_iterator(pb)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
260
                for old_bzr_revid, git_commit in object_generator.import_revisions(
0.252.4 by Jelmer Vernooij
More work on roundtripping.
261
                    todo, roundtrip=False):
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
262
                    new_bzr_revid = self.mapping.revision_id_foreign_to_bzr(git_commit)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
263
                    revidmap[old_bzr_revid] = new_bzr_revid
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
264
                    gitidmap[old_bzr_revid] = git_commit
0.252.3 by Jelmer Vernooij
Refactor revision finding code.
265
                self.target_store.add_objects(object_generator)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
266
            finally:
267
                pb.finished()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
268
        finally:
269
            self.source.unlock()
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
270
        return revidmap, gitidmap
0.200.357 by Jelmer Vernooij
Move push code to push.py.
271
0.252.4 by Jelmer Vernooij
More work on roundtripping.
272
    def fetch(self, revision_id=None, pb=None, find_ghosts=False,
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
273
            fetch_spec=None, mapped_refs=None):
274
        if mapped_refs is not None:
275
            stop_revisions = mapped_refs
276
        elif revision_id is not None:
277
            stop_revisions = [(None, revision_id)]
0.252.4 by Jelmer Vernooij
More work on roundtripping.
278
        elif fetch_spec is not None:
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
279
            stop_revisions = [(None, revid) for revid in fetch_spec.heads]
0.252.4 by Jelmer Vernooij
More work on roundtripping.
280
        else:
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
281
            stop_revisions = [(None, revid) for revid in self.source.all_revision_ids()]
0.252.4 by Jelmer Vernooij
More work on roundtripping.
282
        self.source.lock_read()
283
        try:
0.200.968 by Jelmer Vernooij
Add more tests, simplify push code.
284
            todo = list(self.missing_revisions(stop_revisions))
0.252.4 by Jelmer Vernooij
More work on roundtripping.
285
            pb = ui.ui_factory.nested_progress_bar()
286
            try:
0.200.947 by Jelmer Vernooij
Add convenience method for getting missing objects iterator.
287
                object_generator = self._get_missing_objects_iterator(pb)
0.252.6 by Jelmer Vernooij
Roundtripping support for revision ids works.
288
                for (revid, git_sha) in object_generator.import_revisions(
289
                    todo, roundtrip=True):
0.252.11 by Jelmer Vernooij
only set refs/bzr for roundtripped revisions that otherwise couldn't be found.
290
                    try:
291
                        self.mapping.revision_id_bzr_to_foreign(revid)
292
                    except errors.InvalidRevisionId:
0.252.31 by Jelmer Vernooij
Properly escape revids when using them in ref names.
293
                        self.target_refs[self.mapping.revid_as_refname(revid)] = git_sha
0.252.4 by Jelmer Vernooij
More work on roundtripping.
294
                self.target_store.add_objects(object_generator)
295
            finally:
296
                pb.finished()
297
        finally:
298
            self.source.unlock()
299
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
300
    @staticmethod
301
    def is_compatible(source, target):
302
        """Be compatible with GitRepository."""
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
303
        return (not isinstance(source, GitRepository) and
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
304
                isinstance(target, LocalGitRepository))
305
306
307
class InterToRemoteGitRepository(InterToGitRepository):
308
0.200.942 by Jelmer Vernooij
pass update_refs to dfetch_refs.
309
    def dfetch_refs(self, update_refs):
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
310
        """Import the gist of the ancestry of a particular revision."""
311
        revidmap = {}
0.200.942 by Jelmer Vernooij
pass update_refs to dfetch_refs.
312
        def determine_wants(old_refs):
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
313
            ret = {}
0.200.942 by Jelmer Vernooij
pass update_refs to dfetch_refs.
314
            self.old_refs = old_refs
315
            self.new_refs = update_refs(self.old_refs)
0.200.970 by Jelmer Vernooij
Fix dpush to remote locations.
316
            for name, (gitid, revid) in self.new_refs.iteritems():
317
                if gitid is None:
318
                    ret[name] = self.source_store._lookup_revision_sha1(revid)
319
                else:
320
                    ret[name] = gitid
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
321
            return ret
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
322
        self.source.lock_read()
323
        try:
0.200.460 by Jelmer Vernooij
Somewhat fix commit in git working trees.
324
            new_refs = self.target.send_pack(determine_wants,
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
325
                    self.source_store.generate_lossy_pack_contents)
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
326
        finally:
327
            self.source.unlock()
0.200.942 by Jelmer Vernooij
pass update_refs to dfetch_refs.
328
        return revidmap, self.old_refs, self.new_refs
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
329
0.200.944 by Jelmer Vernooij
Properly error about not supporting push.
330
    def fetch_refs(self, update_refs):
0.252.4 by Jelmer Vernooij
More work on roundtripping.
331
        raise NoPushSupport()
332
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
333
    @staticmethod
334
    def is_compatible(source, target):
335
        """Be compatible with GitRepository."""
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
336
        return (not isinstance(source, GitRepository) and
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
337
                isinstance(target, RemoteGitRepository))