/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
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
130
    def __init__(self, source, target):
131
        super(InterToGitRepository, self).__init__(source, target)
132
        self.mapping = self.target.get_mapping()
133
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
134
    @staticmethod
135
    def _get_repo_format_to_test():
136
        return None
137
138
    def copy_content(self, revision_id=None, pb=None):
139
        """See InterRepository.copy_content."""
140
        self.fetch(revision_id, pb, find_ghosts=False)
141
142
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
143
            fetch_spec=None):
144
        raise NoPushSupport()
145
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
146
147
class InterToLocalGitRepository(InterToGitRepository):
148
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
149
    def missing_revisions(self, stop_revision):
150
        if stop_revision is None:
151
            raise NotImplementedError
0.200.357 by Jelmer Vernooij
Move push code to push.py.
152
        missing = []
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
153
        pb = ui.ui_factory.nested_progress_bar()
154
        try:
155
            graph = self.source.get_graph()
156
            for revid, _ in graph.iter_ancestry([stop_revision]):
157
                pb.update("determining revisions to fetch", len(missing))
158
                if not self.target.has_revision(revid):
159
                    missing.append(revid)
160
            return graph.iter_topo_order(missing)
161
        finally:
162
            pb.finished()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
163
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
164
    def dfetch_refs(self, refs):
165
        revidmap = {}
166
        gitidmap = {}
167
        for name, revid in refs.iteritems():
168
            newrevidmap, newgitidmap = self.dfetch(revid)
169
            revidmap.update(newrevidmap)
170
            gitidmap.update(newgitidmap)
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
171
            if revid in gitidmap:
172
                gitid = gitidmap[revid]
173
            else:
174
                gitid, _ = self.mapping.revision_id_bzr_to_foreign(revid)
175
            self.target._git.set_ref(name, gitid)
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
176
        return revidmap, gitidmap
177
0.200.360 by Jelmer Vernooij
Remove dpush ghost support - it makes no sense, git doesn't do ghosts.
178
    def dfetch(self, stop_revision=None):
0.200.357 by Jelmer Vernooij
Move push code to push.py.
179
        """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.
180
        gitidmap = {}
0.200.357 by Jelmer Vernooij
Move push code to push.py.
181
        revidmap = {}
0.200.367 by Jelmer Vernooij
In dfetch, skip fetching pushed revisions back, as cmd_dpush will already take care of that.
182
        self.source.lock_read()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
183
        try:
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
184
            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.
185
            pb = ui.ui_factory.nested_progress_bar()
186
            try:
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
187
                object_generator = MissingObjectsIterator(self.source, self.mapping, pb)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
188
                for old_bzr_revid, git_commit in object_generator.import_revisions(
189
                    todo):
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
190
                    new_bzr_revid = self.mapping.revision_id_foreign_to_bzr(git_commit)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
191
                    revidmap[old_bzr_revid] = new_bzr_revid
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
192
                    gitidmap[old_bzr_revid] = git_commit
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
193
                self.target._git.object_store.add_objects(object_generator) 
194
            finally:
195
                pb.finished()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
196
        finally:
197
            self.source.unlock()
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
198
        return revidmap, gitidmap
0.200.357 by Jelmer Vernooij
Move push code to push.py.
199
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
200
    @staticmethod
201
    def is_compatible(source, target):
202
        """Be compatible with GitRepository."""
203
        return (not isinstance(source, GitRepository) and 
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
204
                isinstance(target, LocalGitRepository))
205
206
207
class InterToRemoteGitRepository(InterToGitRepository):
208
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
209
    def dfetch_refs(self, new_refs):
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
210
        """Import the gist of the ancestry of a particular revision."""
211
        revidmap = {}
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
212
        def get_changed_refs(refs):
213
            ret = {}
214
            for name, revid in new_refs.iteritems():
0.200.436 by Jelmer Vernooij
Follow new API for send-pack.
215
                ret[name] = object_generator._object_store._lookup_revision_sha1(revid)
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
216
            return ret
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
217
        self.source.lock_read()
218
        try:
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
219
            object_generator = MissingObjectsIterator(self.source, self.mapping)
0.200.436 by Jelmer Vernooij
Follow new API for send-pack.
220
            def generate_blob_contents(have, want):
221
                import pdb; pdb.set_trace()
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
222
            self.target.send_pack(get_changed_refs, generate_blob_contents)
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
223
        finally:
224
            self.source.unlock()
225
        return revidmap
226
227
    @staticmethod
228
    def is_compatible(source, target):
229
        """Be compatible with GitRepository."""
230
        return (not isinstance(source, GitRepository) and 
231
                isinstance(target, RemoteGitRepository))