/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 (
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.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
33
from bzrlib.plugins.git.mapping import (
34
    extract_unusual_modes,
35
    )
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
36
from bzrlib.plugins.git.object_store import (
37
    BazaarObjectStore,
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.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
54
    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.
55
        """Create a new missing objects iterator.
56
57
        """
58
        self.source = source
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
59
        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.
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):
0.200.593 by Jelmer Vernooij
Avoid writing empty trees.
74
        if sha is None or sha in self._sent_shas:
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
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
0.200.581 by Jelmer Vernooij
Fix number of arguments.
85
    def queue(self, sha, obj, path, ie=None, inv=None, unusual_modes=None):
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
86
        if obj is None:
0.200.593 by Jelmer Vernooij
Avoid writing empty trees.
87
            # Can't lazy-evaluate directories, since they might be eliminated
88
            if ie.kind == "directory":
89
                obj = self._object_store._get_ie_object(ie, inv, unusual_modes)
90
                if obj is None:
91
                    return
92
            else:
93
                obj = (ie, inv, unusual_modes)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
94
        self._pending.append((obj, path))
95
        self._sent_shas.add(sha)
96
97
    def import_revision(self, revid):
98
        """Import the gist of a revision into this Git repository.
99
100
        """
101
        inv = self.source.get_inventory(revid)
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
102
        rev = self.source.get_revision(revid)
0.200.761 by Jelmer Vernooij
Defer invshamap calls.
103
        invshamap = self._object_store._idmap.get_inventory_sha_map(revid)
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
104
        unusual_modes = extract_unusual_modes(rev)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
105
        todo = [inv.root]
106
        tree_sha = None
107
        while todo:
108
            ie = todo.pop()
0.200.761 by Jelmer Vernooij
Defer invshamap calls.
109
            (sha, object) = self._object_store._get_ie_object_or_sha1(ie, inv, invshamap, unusual_modes)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
110
            if ie.parent_id is None:
111
                tree_sha = sha
112
            if not self.need_sha(sha):
113
                continue
0.200.581 by Jelmer Vernooij
Fix number of arguments.
114
            self.queue(sha, object, inv.id2path(ie.file_id), ie, inv, unusual_modes)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
115
            if ie.kind == "directory":
116
                todo.extend(ie.children.values())
117
        assert tree_sha is not None
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
118
        commit = self._object_store._get_commit(rev, tree_sha)
0.200.581 by Jelmer Vernooij
Fix number of arguments.
119
        self.queue(commit.id, commit, None, None)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
120
        return commit.id
121
122
    def __len__(self):
123
        return len(self._pending)
124
125
    def __iter__(self):
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
126
        for i, (object, path) in enumerate(self._pending):
127
            if self.pb:
128
                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.
129
            if isinstance(object, tuple):
130
                object = self._object_store._get_ie_object(*object)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
131
            yield (object, path)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
132
133
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
134
class InterToGitRepository(InterRepository):
135
    """InterRepository that copies into a Git repository."""
136
137
    _matching_repo_format = GitRepositoryFormat()
138
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
139
    def __init__(self, source, target):
140
        super(InterToGitRepository, self).__init__(source, target)
141
        self.mapping = self.target.get_mapping()
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
142
        self.source_store = BazaarObjectStore(self.source, self.mapping)
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
143
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
144
    @staticmethod
145
    def _get_repo_format_to_test():
146
        return None
147
148
    def copy_content(self, revision_id=None, pb=None):
149
        """See InterRepository.copy_content."""
150
        self.fetch(revision_id, pb, find_ghosts=False)
151
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
152
    def fetch(self, revision_id=None, pb=None, find_ghosts=False,
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
153
            fetch_spec=None):
154
        raise NoPushSupport()
155
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
156
157
class InterToLocalGitRepository(InterToGitRepository):
158
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
159
    def missing_revisions(self, stop_revisions, check_revid):
0.200.357 by Jelmer Vernooij
Move push code to push.py.
160
        missing = []
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
161
        pb = ui.ui_factory.nested_progress_bar()
162
        try:
163
            graph = self.source.get_graph()
0.200.524 by Jelmer Vernooij
Simplify dpushing multiple heads.
164
            for revid, _ in graph.iter_ancestry(stop_revisions):
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
165
                pb.update("determining revisions to fetch", len(missing))
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
166
                if not check_revid(revid):
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
167
                    missing.append(revid)
168
            return graph.iter_topo_order(missing)
169
        finally:
170
            pb.finished()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
171
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
172
    def dfetch_refs(self, refs):
0.200.438 by Jelmer Vernooij
Somewhat fix dpushing to remote repos.
173
        new_refs = {}
0.200.524 by Jelmer Vernooij
Simplify dpushing multiple heads.
174
        revidmap, gitidmap = self.dfetch(refs.values())
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
175
        for name, revid in refs.iteritems():
0.200.524 by Jelmer Vernooij
Simplify dpushing multiple heads.
176
            if revid in gitidmap:
177
                gitid = gitidmap[revid]
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
178
            else:
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
179
                gitid = self.source_store._lookup_revision_sha1(revid)
0.200.480 by Jelmer Vernooij
Cope with API changes in Dulwich.
180
            self.target._git.refs[name] = gitid
0.200.438 by Jelmer Vernooij
Somewhat fix dpushing to remote repos.
181
            new_refs[name] = gitid
182
        return revidmap, new_refs
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
183
0.200.524 by Jelmer Vernooij
Simplify dpushing multiple heads.
184
    def dfetch(self, stop_revisions):
0.200.357 by Jelmer Vernooij
Move push code to push.py.
185
        """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.
186
        gitidmap = {}
0.200.357 by Jelmer Vernooij
Move push code to push.py.
187
        revidmap = {}
0.200.367 by Jelmer Vernooij
In dfetch, skip fetching pushed revisions back, as cmd_dpush will already take care of that.
188
        self.source.lock_read()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
189
        try:
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
190
            target_store = self.target._git.object_store
191
            def check_revid(revid):
192
                if revid == NULL_REVISION:
193
                    return True
0.200.598 by Jelmer Vernooij
Cope with ghosts.
194
                try:
195
                    return (self.source_store._lookup_revision_sha1(revid) in target_store)
196
                except errors.NoSuchRevision:
197
                    # Ghost, can't dpush
198
                    return True
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
199
            todo = list(self.missing_revisions(stop_revisions, check_revid))
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
200
            pb = ui.ui_factory.nested_progress_bar()
201
            try:
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
202
                object_generator = MissingObjectsIterator(self.source_store, self.source, pb)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
203
                for old_bzr_revid, git_commit in object_generator.import_revisions(
204
                    todo):
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
205
                    new_bzr_revid = self.mapping.revision_id_foreign_to_bzr(git_commit)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
206
                    revidmap[old_bzr_revid] = new_bzr_revid
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
207
                    gitidmap[old_bzr_revid] = git_commit
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
208
                target_store.add_objects(object_generator)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
209
            finally:
210
                pb.finished()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
211
        finally:
212
            self.source.unlock()
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
213
        return revidmap, gitidmap
0.200.357 by Jelmer Vernooij
Move push code to push.py.
214
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
215
    @staticmethod
216
    def is_compatible(source, target):
217
        """Be compatible with GitRepository."""
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
218
        return (not isinstance(source, GitRepository) and
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
219
                isinstance(target, LocalGitRepository))
220
221
222
class InterToRemoteGitRepository(InterToGitRepository):
223
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
224
    def dfetch_refs(self, new_refs):
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
225
        """Import the gist of the ancestry of a particular revision."""
226
        revidmap = {}
0.200.452 by Jelmer Vernooij
Rename converter -> object_store, provide utility function for getting ObjectStore's.
227
        def determine_wants(refs):
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
228
            ret = {}
229
            for name, revid in new_refs.iteritems():
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
230
                ret[name] = self.source_store._lookup_revision_sha1(revid)
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
231
            return ret
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
232
        self.source.lock_read()
233
        try:
0.200.460 by Jelmer Vernooij
Somewhat fix commit in git working trees.
234
            new_refs = self.target.send_pack(determine_wants,
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
235
                    self.source_store.generate_pack_contents)
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
236
        finally:
237
            self.source.unlock()
0.200.438 by Jelmer Vernooij
Somewhat fix dpushing to remote repos.
238
        return revidmap, new_refs
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
239
240
    @staticmethod
241
    def is_compatible(source, target):
242
        """Be compatible with GitRepository."""
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
243
        return (not isinstance(source, GitRepository) and
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
244
                isinstance(target, RemoteGitRepository))