/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
29
from bzrlib.plugins.git.errors import (
30
    NoPushSupport,
31
    )
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
32
from bzrlib.plugins.git.mapping import (
33
    extract_unusual_modes,
34
    )
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
35
from bzrlib.plugins.git.object_store import (
36
    BazaarObjectStore,
37
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
38
from bzrlib.plugins.git.repository import (
39
    GitRepository,
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
40
    LocalGitRepository,
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
41
    GitRepositoryFormat,
42
    )
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
43
from bzrlib.plugins.git.remote import (
44
    RemoteGitRepository,
45
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
46
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
47
48
class MissingObjectsIterator(object):
49
    """Iterate over git objects that are missing from a target repository.
50
51
    """
52
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
53
    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.
54
        """Create a new missing objects iterator.
55
56
        """
57
        self.source = source
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
58
        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.
59
        self._revids = set()
60
        self._sent_shas = set()
61
        self._pending = []
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
62
        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.
63
64
    def import_revisions(self, revids):
65
        self._revids.update(revids)
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))
69
            git_commit = self.import_revision(revid)
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
72
    def need_sha(self, sha):
73
        if sha in self._sent_shas:
74
            return False
75
        (type, (fileid, revid)) = self._object_store._idmap.lookup_git_sha(sha)
76
        assert type in ("blob", "tree")
77
        if revid in self._revids:
78
            # Not sent yet, and part of the set of revisions to send
79
            return True
80
        # Not changed in the revisions to send, so either not necessary
81
        # or already present remotely (as git doesn't do ghosts)
82
        return False
83
84
    def queue(self, sha, obj, path, ie=None, inv=None):
85
        if obj is None:
86
            obj = (ie, inv)
87
        self._pending.append((obj, path))
88
        self._sent_shas.add(sha)
89
90
    def import_revision(self, revid):
91
        """Import the gist of a revision into this Git repository.
92
93
        """
94
        inv = self.source.get_inventory(revid)
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
95
        rev = self.source.get_revision(revid)
96
        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.
97
        todo = [inv.root]
98
        tree_sha = None
99
        while todo:
100
            ie = todo.pop()
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
101
            (sha, object) = self._object_store._get_ie_object_or_sha1(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.
102
            if ie.parent_id is None:
103
                tree_sha = sha
104
            if not self.need_sha(sha):
105
                continue
106
            self.queue(sha, object, inv.id2path(ie.file_id), ie, inv)
107
            if ie.kind == "directory":
108
                todo.extend(ie.children.values())
109
        assert tree_sha is not None
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
110
        commit = self._object_store._get_commit(rev, tree_sha)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
111
        self.queue(commit.id, commit, None)
112
        return commit.id
113
114
    def __len__(self):
115
        return len(self._pending)
116
117
    def __iter__(self):
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
118
        for i, (object, path) in enumerate(self._pending):
119
            if self.pb:
120
                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.
121
            if isinstance(object, tuple):
122
                object = self._object_store._get_ie_object(*object)
123
            yield (object, path)   
124
125
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
126
class InterToGitRepository(InterRepository):
127
    """InterRepository that copies into a Git repository."""
128
129
    _matching_repo_format = GitRepositoryFormat()
130
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
131
    def __init__(self, source, target):
132
        super(InterToGitRepository, self).__init__(source, target)
133
        self.mapping = self.target.get_mapping()
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
134
        self.source_store = BazaarObjectStore(self.source, self.mapping)
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
135
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
136
    @staticmethod
137
    def _get_repo_format_to_test():
138
        return None
139
140
    def copy_content(self, revision_id=None, pb=None):
141
        """See InterRepository.copy_content."""
142
        self.fetch(revision_id, pb, find_ghosts=False)
143
144
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
145
            fetch_spec=None):
146
        raise NoPushSupport()
147
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
148
149
class InterToLocalGitRepository(InterToGitRepository):
150
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
151
    def missing_revisions(self, stop_revisions, check_revid):
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()
0.200.524 by Jelmer Vernooij
Simplify dpushing multiple heads.
156
            for revid, _ in graph.iter_ancestry(stop_revisions):
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
157
                pb.update("determining revisions to fetch", len(missing))
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
158
                if not check_revid(revid):
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
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):
0.200.438 by Jelmer Vernooij
Somewhat fix dpushing to remote repos.
165
        new_refs = {}
0.200.524 by Jelmer Vernooij
Simplify dpushing multiple heads.
166
        revidmap, gitidmap = self.dfetch(refs.values())
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
167
        for name, revid in refs.iteritems():
0.200.524 by Jelmer Vernooij
Simplify dpushing multiple heads.
168
            if revid in gitidmap:
169
                gitid = gitidmap[revid]
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
170
            else:
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
171
                gitid = self.source_store._lookup_revision_sha1(revid)
0.200.480 by Jelmer Vernooij
Cope with API changes in Dulwich.
172
            self.target._git.refs[name] = gitid
0.200.438 by Jelmer Vernooij
Somewhat fix dpushing to remote repos.
173
            new_refs[name] = gitid
174
        return revidmap, new_refs
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
175
0.200.524 by Jelmer Vernooij
Simplify dpushing multiple heads.
176
    def dfetch(self, stop_revisions):
0.200.357 by Jelmer Vernooij
Move push code to push.py.
177
        """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.
178
        gitidmap = {}
0.200.357 by Jelmer Vernooij
Move push code to push.py.
179
        revidmap = {}
0.200.367 by Jelmer Vernooij
In dfetch, skip fetching pushed revisions back, as cmd_dpush will already take care of that.
180
        self.source.lock_read()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
181
        try:
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
182
            target_store = self.target._git.object_store
183
            def check_revid(revid):
184
                if revid == NULL_REVISION:
185
                    return True
186
                return (self.source_store._lookup_revision_sha1(revid) in target_store)
187
            todo = list(self.missing_revisions(stop_revisions, check_revid))
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
188
            pb = ui.ui_factory.nested_progress_bar()
189
            try:
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
190
                object_generator = MissingObjectsIterator(self.source_store, self.source, pb)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
191
                for old_bzr_revid, git_commit in object_generator.import_revisions(
192
                    todo):
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
193
                    new_bzr_revid = self.mapping.revision_id_foreign_to_bzr(git_commit)
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
194
                    revidmap[old_bzr_revid] = new_bzr_revid
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
195
                    gitidmap[old_bzr_revid] = git_commit
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
196
                target_store.add_objects(object_generator) 
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
197
            finally:
198
                pb.finished()
0.200.357 by Jelmer Vernooij
Move push code to push.py.
199
        finally:
200
            self.source.unlock()
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
201
        return revidmap, gitidmap
0.200.357 by Jelmer Vernooij
Move push code to push.py.
202
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
203
    @staticmethod
204
    def is_compatible(source, target):
205
        """Be compatible with GitRepository."""
206
        return (not isinstance(source, GitRepository) and 
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
207
                isinstance(target, LocalGitRepository))
208
209
210
class InterToRemoteGitRepository(InterToGitRepository):
211
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
212
    def dfetch_refs(self, new_refs):
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
213
        """Import the gist of the ancestry of a particular revision."""
214
        revidmap = {}
0.200.452 by Jelmer Vernooij
Rename converter -> object_store, provide utility function for getting ObjectStore's.
215
        def determine_wants(refs):
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
216
            ret = {}
217
            for name, revid in new_refs.iteritems():
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
218
                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.
219
            return ret
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
220
        self.source.lock_read()
221
        try:
0.200.460 by Jelmer Vernooij
Somewhat fix commit in git working trees.
222
            new_refs = self.target.send_pack(determine_wants,
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
223
                    self.source_store.generate_pack_contents)
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
224
        finally:
225
            self.source.unlock()
0.200.438 by Jelmer Vernooij
Somewhat fix dpushing to remote repos.
226
        return revidmap, new_refs
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
227
228
    @staticmethod
229
    def is_compatible(source, target):
230
        """Be compatible with GitRepository."""
231
        return (not isinstance(source, GitRepository) and 
232
                isinstance(target, RemoteGitRepository))