/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
1
# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
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
0.200.292 by Jelmer Vernooij
Fix formatting.
17
from cStringIO import (
18
    StringIO,
19
    )
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
20
import dulwich as git
0.200.261 by Jelmer Vernooij
More formatting fixes.
21
from dulwich.client import (
22
    SimpleFetchGraphWalker,
23
    )
24
from dulwich.objects import (
25
    Commit,
0.200.303 by Jelmer Vernooij
Cope with tags during fetch.
26
    Tag,
0.200.261 by Jelmer Vernooij
More formatting fixes.
27
    )
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
28
29
from bzrlib import (
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
30
    debug,
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
31
    osutils,
0.200.261 by Jelmer Vernooij
More formatting fixes.
32
    trace,
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
33
    ui,
34
    urlutils,
35
    )
36
from bzrlib.errors import (
37
    InvalidRevisionId,
38
    NoSuchRevision,
39
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
40
from bzrlib.inventory import (
41
    Inventory,
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
42
    InventoryDirectory,
43
    InventoryFile,
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
44
    InventoryLink,
0.200.261 by Jelmer Vernooij
More formatting fixes.
45
    )
0.200.301 by Jelmer Vernooij
Cache inventories created.
46
from bzrlib.lru_cache import (
47
    LRUCache,
48
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
49
from bzrlib.repository import (
50
    InterRepository,
51
    )
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
52
from bzrlib.revision import (
53
    NULL_REVISION,
54
    )
0.200.292 by Jelmer Vernooij
Fix formatting.
55
from bzrlib.tsort import (
56
    topo_sort,
57
    )
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
58
0.200.261 by Jelmer Vernooij
More formatting fixes.
59
from bzrlib.plugins.git.converter import (
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
60
    BazaarObjectStore,
0.200.261 by Jelmer Vernooij
More formatting fixes.
61
    )
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
62
from bzrlib.plugins.git.mapping import (
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
63
    DEFAULT_FILE_MODE,
64
    DEFAULT_TREE_MODE,
65
    DEFAULT_SYMLINK_MODE,
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
66
    text_to_blob,
67
    )
0.200.169 by Jelmer Vernooij
Fix branch cloning.
68
from bzrlib.plugins.git.repository import (
0.200.261 by Jelmer Vernooij
More formatting fixes.
69
    LocalGitRepository, 
70
    GitRepository, 
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
71
    GitRepositoryFormat,
0.200.261 by Jelmer Vernooij
More formatting fixes.
72
    )
73
from bzrlib.plugins.git.remote import (
74
    RemoteGitRepository,
75
    )
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
76
77
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
78
class BzrFetchGraphWalker(object):
0.200.196 by Jelmer Vernooij
Add simple tests and docstrings for GraphWalker.
79
    """GraphWalker implementation that uses a Bazaar repository."""
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
80
81
    def __init__(self, repository, mapping):
82
        self.repository = repository
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
83
        self.mapping = mapping
84
        self.done = set()
85
        self.heads = set(repository.all_revision_ids())
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
86
        self.parents = {}
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
87
0.200.196 by Jelmer Vernooij
Add simple tests and docstrings for GraphWalker.
88
    def __iter__(self):
89
        return iter(self.next, None)
90
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
91
    def ack(self, sha):
92
        revid = self.mapping.revision_id_foreign_to_bzr(sha)
93
        self.remove(revid)
94
95
    def remove(self, revid):
96
        self.done.add(revid)
0.200.177 by Jelmer Vernooij
Add git-import command.
97
        if revid in self.heads:
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
98
            self.heads.remove(revid)
99
        if revid in self.parents:
100
            for p in self.parents[revid]:
101
                self.remove(p)
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
102
103
    def next(self):
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
104
        while self.heads:
105
            ret = self.heads.pop()
106
            ps = self.repository.get_parent_map([ret])[ret]
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
107
            self.parents[ret] = ps
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
108
            self.heads.update([p for p in ps if not p in self.done])
109
            try:
110
                self.done.add(ret)
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
111
                return self.mapping.revision_id_bzr_to_foreign(ret)[0]
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
112
            except InvalidRevisionId:
113
                pass
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
114
        return None
115
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
116
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
117
def import_git_blob(texts, mapping, path, hexsha, base_inv, parent_id, 
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
118
    revision_id, parent_invs, shagitmap, lookup_object, executable, symlink):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
119
    """Import a git blob object into a bzr repository.
120
0.200.261 by Jelmer Vernooij
More formatting fixes.
121
    :param texts: VersionedFiles to add to
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
122
    :param path: Path in the tree
123
    :param blob: A git blob
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
124
    :return: Inventory delta for this file
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
125
    """
126
    file_id = mapping.generate_file_id(path)
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
127
    if symlink:
128
        cls = InventoryLink
129
    else:
130
        cls = InventoryFile
131
    # We just have to hope this is indeed utf-8:
132
    ie = cls(file_id, urlutils.basename(path).decode("utf-8"), 
133
                parent_id)
134
    ie.executable = executable
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
135
    # See if this has changed at all
136
    try:
137
        base_sha = shagitmap.lookup_blob(file_id, base_inv.revision_id)
138
    except KeyError:
139
        base_sha = None
140
    else:
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
141
        if (base_sha == hexsha and base_inv[file_id].executable == ie.executable
142
            and base_inv[file_id].kind == ie.kind):
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
143
            # If nothing has changed since the base revision, we're done
144
            return []
145
    if base_sha == hexsha:
146
        ie.text_size = base_inv[file_id].text_size
147
        ie.text_sha1 = base_inv[file_id].text_sha1
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
148
        ie.symlink_target = base_inv[file_id].symlink_target
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
149
        ie.revision = base_inv[file_id].revision
150
    else:
151
        blob = lookup_object(hexsha)
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
152
        if ie.kind == "symlink":
153
            ie.symlink_target = blob.data
154
            ie.text_size = None
155
            ie.text_sha1 = None
156
        else:
157
            ie.text_size = len(blob.data)
158
            ie.text_sha1 = osutils.sha_string(blob.data)
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
159
    # Check what revision we should store
0.200.283 by Jelmer Vernooij
Avoid storing repeated texts for blobs.
160
    parent_keys = []
161
    for pinv in parent_invs:
0.200.285 by Jelmer Vernooij
Simplify blob import code.
162
        if not file_id in pinv:
163
            continue
164
        if pinv[file_id].text_sha1 == ie.text_sha1:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
165
            # found a revision in one of the parents to use
0.200.283 by Jelmer Vernooij
Avoid storing repeated texts for blobs.
166
            ie.revision = pinv[file_id].revision
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
167
            break
0.200.286 by Jelmer Vernooij
Prevent creating repeated directory texts.
168
        parent_keys.append((file_id, pinv[file_id].revision))
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
169
    if ie.revision is None:
170
        # Need to store a new revision
171
        ie.revision = revision_id
172
        assert file_id is not None
173
        assert ie.revision is not None
174
        texts.add_lines((file_id, ie.revision), parent_keys,
175
            osutils.split_lines(blob.data))
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
176
        if "verify" in debug.debug_flags:
177
            assert text_to_blob(blob.data).id == hexsha
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
178
        shagitmap.add_entry(hexsha, "blob", (ie.file_id, ie.revision))
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
179
    if file_id in base_inv:
180
        old_path = base_inv.id2path(file_id)
181
    else:
182
        old_path = None
183
    return [(old_path, path, file_id, ie)]
0.200.261 by Jelmer Vernooij
More formatting fixes.
184
185
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
186
def import_git_tree(texts, mapping, path, hexsha, base_inv, parent_id, 
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
187
    revision_id, parent_invs, shagitmap, lookup_object):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
188
    """Import a git tree object into a bzr repository.
189
0.200.261 by Jelmer Vernooij
More formatting fixes.
190
    :param texts: VersionedFiles object to add to
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
191
    :param path: Path in the tree
192
    :param tree: A git tree object
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
193
    :param base_inv: Base inventory against which to return inventory delta
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
194
    :return: Inventory delta for this subtree
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
195
    """
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
196
    invdelta = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
197
    file_id = mapping.generate_file_id(path)
0.200.297 by Jelmer Vernooij
Cope with non-ascii characters in filenames (needs a test..).
198
    # We just have to hope this is indeed utf-8:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
199
    ie = InventoryDirectory(file_id, urlutils.basename(path.decode("utf-8")), 
200
        parent_id)
201
    if not file_id in base_inv:
202
        # Newly appeared here
203
        ie.revision = revision_id
204
        texts.add_lines((file_id, ie.revision), [], [])
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
205
        invdelta.append((None, path, file_id, ie))
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
206
    else:
207
        # See if this has changed at all
0.200.287 by Jelmer Vernooij
Skip tree sha's already in the git sha map.
208
        try:
0.200.343 by Jelmer Vernooij
Use file ids consistently in map.
209
            base_sha = shagitmap.lookup_tree(file_id, base_inv.revision_id)
0.200.287 by Jelmer Vernooij
Skip tree sha's already in the git sha map.
210
        except KeyError:
211
            pass
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
212
        else:11):
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
213
            if base_sha == hexsha:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
214
                # If nothing has changed since the base revision, we're done
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
215
                return [], {}
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
216
    # Remember for next time
0.200.300 by Jelmer Vernooij
Fix recursive deletion of dirs.
217
    existing_children = set()
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
218
    if "verify" in debug.debug_flags:
219
        # FIXME:
220
        assert False
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
221
    shagitmap.add_entry(hexsha, "tree", (file_id, revision_id))
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
222
    child_modes = {}
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
223
    tree = lookup_object(hexsha)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
224
    for mode, name, hexsha in tree.entries():
225
        entry_kind = (mode & 0700000) / 0100000
226
        basename = name.decode("utf-8")
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
227
        existing_children.add(basename)
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
228
        child_path = osutils.pathjoin(path, name)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
229
        if entry_kind == 0:
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
230
            if mode != DEFAULT_TREE_MODE:
231
                child_modes[child_path] = mode
232
            subinvdelta, grandchildmodes = import_git_tree(texts, mapping, child_path, hexsha, 
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
233
                base_inv, file_id, revision_id, parent_invs, shagitmap, 
234
                lookup_object)
235
            invdelta.extend(subinvdelta)
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
236
            child_modes.update(grandchildmodes)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
237
        elif entry_kind == 1:
0.200.159 by Jelmer Vernooij
Fix branch tests.
238
            fs_mode = mode & 0777
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
239
            file_kind = (mode & 070000) / 010000
240
            if file_kind == 0: # regular file
241
                symlink = False
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
242
                if mode != DEFAULT_FILE_MODE:
243
                    child_modes[child_path] = mode
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
244
            elif file_kind == 2:
245
                symlink = True
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
246
                if mode not in (DEFAULT_SYMLINK_MODE, DEFAULT_TREE_MODE | 0111):
247
                    child_modes[child_path] = mode
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
248
            else:
249
                raise AssertionError("Unknown file kind, mode=%r" % (mode,))
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
250
            subinvdelta = import_git_blob(texts, mapping, child_path, hexsha,
251
                    base_inv, file_id, revision_id, parent_invs, shagitmap, 
252
                    lookup_object, bool(fs_mode & 0111), symlink))
253
            invdelta.extend(subinvdelta)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
254
        else:
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
255
            raise AssertionError("Unknown object kind, perms=%r." % (mode,))
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
256
    # Remove any children that have disappeared
257
    if file_id in base_inv:
0.200.300 by Jelmer Vernooij
Fix recursive deletion of dirs.
258
        deletable = [v for k,v in base_inv[file_id].children.iteritems() if k not in existing_children]
259
        while deletable:
260
            ie = deletable.pop()
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
261
            invdelta.append((base_inv.id2path(ie.file_id), None, ie.file_id, None))
0.200.300 by Jelmer Vernooij
Fix recursive deletion of dirs.
262
            if ie.kind == "directory":
263
                deletable.extend(ie.children.values())
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
264
    return invdelta, child_modes
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
265
266
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
267
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever, 
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
268
        heads, pb=None):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
269
    """Import a set of git objects into a bzr repository.
270
271
    :param repo: Bazaar repository
272
    :param mapping: Mapping to use
273
    :param object_iter: Iterator over Git objects.
274
    """
275
    # TODO: a more (memory-)efficient implementation of this
0.200.158 by Jelmer Vernooij
fetch works \o/
276
    graph = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
277
    root_trees = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
278
    revisions = {}
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
279
    checked = set()
280
    heads = list(heads)
0.200.301 by Jelmer Vernooij
Cache inventories created.
281
    parent_invs_cache = LRUCache(50)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
282
    # Find and convert commit objects
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
283
    while heads:
284
        if pb is not None:
285
            pb.update("finding revisions to fetch", len(graph), None)
286
        head = heads.pop()
287
        assert isinstance(head, str)
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
288
        try:
289
            o = object_iter[head]
290
        except KeyError:
291
            continue
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
292
        if isinstance(o, Commit):
293
            rev = mapping.import_commit(o)
0.200.295 by Jelmer Vernooij
Don't re-import revisions already fetched.
294
            if repo.has_revision(rev.revision_id):
295
                continue
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
296
            root_trees[rev.revision_id] = o.tree
0.200.158 by Jelmer Vernooij
fetch works \o/
297
            revisions[rev.revision_id] = rev
298
            graph.append((rev.revision_id, rev.parent_ids))
0.200.261 by Jelmer Vernooij
More formatting fixes.
299
            target_git_object_retriever._idmap.add_entry(o.sha().hexdigest(),
300
                "commit", (rev.revision_id, o._tree))
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
301
            heads.extend([p for p in o.parents if p not in checked])
0.200.303 by Jelmer Vernooij
Cope with tags during fetch.
302
        elif isinstance(o, Tag):
303
            heads.append(o.object[1])
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
304
        else:
305
            trace.warning("Unable to import head object %r" % o)
306
        checked.add(head)
0.200.158 by Jelmer Vernooij
fetch works \o/
307
    # Order the revisions
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
308
    # Create the inventory objects
0.200.158 by Jelmer Vernooij
fetch works \o/
309
    for i, revid in enumerate(topo_sort(graph)):
310
        if pb is not None:
311
            pb.update("fetching revisions", i, len(graph))
312
        rev = revisions[revid]
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
313
        # We have to do this here, since we have to walk the tree and 
0.200.295 by Jelmer Vernooij
Don't re-import revisions already fetched.
314
        # we need to make sure to import the blobs / trees with the right 
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
315
        # path; this may involve adding them more than once.
316
        def lookup_object(sha):
0.200.301 by Jelmer Vernooij
Cache inventories created.
317
            try:
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
318
                return object_iter[sha]
0.200.301 by Jelmer Vernooij
Cache inventories created.
319
            except KeyError:
320
                return target_git_object_retriever[sha]
321
        parent_invs = []
322
        for parent_id in rev.parent_ids:
323
            try:
324
                parent_invs.append(parent_invs_cache[parent_id])
325
            except KeyError:
326
                parent_inv = repo.get_inventory(parent_id)
327
                parent_invs.append(parent_inv)
328
                parent_invs_cache[parent_id] = parent_inv
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
329
        if parent_invs == []:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
330
            base_inv = Inventory(root_id=None)
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
331
        else:
332
            base_inv = parent_invs[0]
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
333
        inv_delta = import_git_tree(repo.texts, mapping, "", 
334
            root_trees[revid], base_inv, None, revid, parent_invs, 
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
335
            target_git_object_retriever._idmap, lookup_object)
336
        try:
337
            basis_id = rev.parent_ids[0]
338
        except IndexError:
339
            basis_id = NULL_REVISION
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
340
        rev.inventory_sha1, inv = repo.add_inventory_by_delta(basis_id,
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
341
                  inv_delta, rev.revision_id, rev.parent_ids)
0.200.301 by Jelmer Vernooij
Cache inventories created.
342
        parent_invs_cache[rev.revision_id] = inv
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
343
        repo.add_revision(rev.revision_id, rev)
0.200.272 by Jelmer Vernooij
Actually store idmap.
344
    target_git_object_retriever._idmap.commit()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
345
346
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
347
class InterGitNonGitRepository(InterRepository):
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
348
    """Base InterRepository that copies revisions from a Git into a non-Git 
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
349
    repository."""
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
350
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
351
    _matching_repo_format = GitRepositoryFormat()
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
352
353
    @staticmethod
354
    def _get_repo_format_to_test():
355
        return None
356
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
357
    def copy_content(self, revision_id=None, pb=None):
358
        """See InterRepository.copy_content."""
359
        self.fetch(revision_id, pb, find_ghosts=False)
360
0.200.295 by Jelmer Vernooij
Don't re-import revisions already fetched.
361
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, mapping=None,
362
            fetch_spec=None):
0.200.247 by Jelmer Vernooij
Fix git-import.
363
        self.fetch_refs(revision_id=revision_id, pb=pb, find_ghosts=find_ghosts,
364
                mapping=mapping, fetch_spec=fetch_spec)
365
366
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False, 
367
              mapping=None, fetch_spec=None):
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
368
        if mapping is None:
369
            mapping = self.source.get_mapping()
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
370
        if revision_id is not None:
371
            interesting_heads = [revision_id]
372
        elif fetch_spec is not None:
373
            interesting_heads = fetch_spec.heads
374
        else:
375
            interesting_heads = None
0.200.247 by Jelmer Vernooij
Fix git-import.
376
        self._refs = {}
377
        def determine_wants(refs):
378
            self._refs = refs
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
379
            if interesting_heads is None:
0.200.247 by Jelmer Vernooij
Fix git-import.
380
                ret = [sha for (ref, sha) in refs.iteritems() if not ref.endswith("^{}")]
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
381
            else:
0.233.1 by Jelmer Vernooij
Don't attempt to fetch NULL_REVISION.
382
                ret = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in interesting_heads if revid != NULL_REVISION]
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
383
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
0.200.247 by Jelmer Vernooij
Fix git-import.
384
        self.fetch_objects(determine_wants, mapping, pb)
385
        return self._refs
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
386
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
387
388
389
class InterRemoteGitNonGitRepository(InterGitNonGitRepository):
390
    """InterRepository that copies revisions from a remote Git into a non-Git 
391
    repository."""
392
393
    def fetch_objects(self, determine_wants, mapping, pb=None):
394
        def progress(text):
395
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
396
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
397
        create_pb = None
398
        if pb is None:
399
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
400
        target_git_object_retriever = BazaarObjectStore(self.target, mapping)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
401
        recorded_wants = []
402
403
        def record_determine_wants(heads):
404
            wants = determine_wants(heads)
405
            recorded_wants.extend(wants)
406
            return wants
407
        
408
        try:
409
            self.target.lock_write()
410
            try:
411
                self.target.start_write_group()
412
                try:
413
                    objects_iter = self.source.fetch_objects(
414
                                record_determine_wants, 
415
                                graph_walker, 
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
416
                                target_git_object_retriever.get_raw, 
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
417
                                progress)
418
                    import_git_objects(self.target, mapping, objects_iter, 
419
                            target_git_object_retriever, recorded_wants, pb)
420
                finally:
421
                    self.target.commit_write_group()
422
            finally:
423
                self.target.unlock()
424
        finally:
425
            if create_pb:
426
                create_pb.finished()
427
428
    @staticmethod
429
    def is_compatible(source, target):
430
        """Be compatible with GitRepository."""
431
        # FIXME: Also check target uses VersionedFile
432
        return (isinstance(source, RemoteGitRepository) and 
433
                target.supports_rich_root() and
434
                not isinstance(target, GitRepository))
435
436
437
class InterLocalGitNonGitRepository(InterGitNonGitRepository):
438
    """InterRepository that copies revisions from a remote Git into a non-Git 
439
    repository."""
440
441
    def fetch_objects(self, determine_wants, mapping, pb=None):
442
        wants = determine_wants(self.source._git.get_refs())
443
        create_pb = None
444
        if pb is None:
445
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
446
        target_git_object_retriever = BazaarObjectStore(self.target, mapping)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
447
        try:
448
            self.target.lock_write()
449
            try:
450
                self.target.start_write_group()
451
                try:
452
                    import_git_objects(self.target, mapping, 
453
                            self.source._git.object_store, 
454
                            target_git_object_retriever, wants, pb)
455
                finally:
456
                    self.target.commit_write_group()
457
            finally:
458
                self.target.unlock()
459
        finally:
460
            if create_pb:
461
                create_pb.finished()
462
463
    @staticmethod
464
    def is_compatible(source, target):
465
        """Be compatible with GitRepository."""
466
        # FIXME: Also check target uses VersionedFile
467
        return (isinstance(source, LocalGitRepository) and 
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
468
                target.supports_rich_root() and
469
                not isinstance(target, GitRepository))
470
471
472
class InterGitRepository(InterRepository):
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
473
    """InterRepository that copies between Git repositories."""
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
474
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
475
    _matching_repo_format = GitRepositoryFormat()
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
476
477
    @staticmethod
478
    def _get_repo_format_to_test():
479
        return None
480
481
    def copy_content(self, revision_id=None, pb=None):
482
        """See InterRepository.copy_content."""
483
        self.fetch(revision_id, pb, find_ghosts=False)
484
485
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
486
              mapping=None, fetch_spec=None):
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
487
        if mapping is None:
488
            mapping = self.source.get_mapping()
489
        def progress(text):
0.200.261 by Jelmer Vernooij
More formatting fixes.
490
            trace.info("git: %s", text)
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
491
        r = self.target._git
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
492
        if revision_id is not None:
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
493
            args = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
494
        elif fetch_spec is not None:
495
            args = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in fetch_spec.heads]
0.200.247 by Jelmer Vernooij
Fix git-import.
496
        if fetch_spec is None and revision_id is None:
497
            determine_wants = r.object_store.determine_wants_all
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
498
        else:
0.200.247 by Jelmer Vernooij
Fix git-import.
499
            determine_wants = lambda x: [y for y in args if not y in r.object_store]
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
500
501
        graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
502
        f, commit = r.object_store.add_thin_pack()
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
503
        try:
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
504
            self.source.fetch_pack(determine_wants, graphwalker, f.write, progress)
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
505
            commit()
506
        except:
507
            f.close()
508
            raise
509
510
    @staticmethod
511
    def is_compatible(source, target):
512
        """Be compatible with GitRepository."""
513
        return (isinstance(source, GitRepository) and 
514
                isinstance(target, GitRepository))