/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.346 by Jelmer Vernooij
Track unusual file modes.
212
        else:
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.346 by Jelmer Vernooij
Track unusual file modes.
242
                if mode not in (DEFAULT_FILE_MODE, DEFAULT_FILE_MODE|0111):
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
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.346 by Jelmer Vernooij
Track unusual file modes.
246
                if mode != DEFAULT_SYMLINK_MODE:
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
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, 
0.200.346 by Jelmer Vernooij
Track unusual file modes.
252
                    lookup_object, bool(fs_mode & 0111), symlink)
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
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.346 by Jelmer Vernooij
Track unusual file modes.
333
        inv_delta, unusual_modes = import_git_tree(repo.texts, mapping, "", 
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
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)
0.200.346 by Jelmer Vernooij
Track unusual file modes.
336
        if unusual_modes != {}:
337
            ret = "unusual modes: \n"
338
            for item in unusual_modes.iteritems():
339
                ret += "\t%s: %o\n" % item
340
            raise AssertionError(ret)
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
341
        try:
342
            basis_id = rev.parent_ids[0]
343
        except IndexError:
344
            basis_id = NULL_REVISION
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
345
        rev.inventory_sha1, inv = repo.add_inventory_by_delta(basis_id,
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
346
                  inv_delta, rev.revision_id, rev.parent_ids)
0.200.301 by Jelmer Vernooij
Cache inventories created.
347
        parent_invs_cache[rev.revision_id] = inv
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
348
        repo.add_revision(rev.revision_id, rev)
0.200.272 by Jelmer Vernooij
Actually store idmap.
349
    target_git_object_retriever._idmap.commit()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
350
351
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
352
class InterGitNonGitRepository(InterRepository):
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
353
    """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.
354
    repository."""
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
355
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
356
    _matching_repo_format = GitRepositoryFormat()
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
357
358
    @staticmethod
359
    def _get_repo_format_to_test():
360
        return None
361
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
362
    def copy_content(self, revision_id=None, pb=None):
363
        """See InterRepository.copy_content."""
364
        self.fetch(revision_id, pb, find_ghosts=False)
365
0.200.295 by Jelmer Vernooij
Don't re-import revisions already fetched.
366
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, mapping=None,
367
            fetch_spec=None):
0.200.247 by Jelmer Vernooij
Fix git-import.
368
        self.fetch_refs(revision_id=revision_id, pb=pb, find_ghosts=find_ghosts,
369
                mapping=mapping, fetch_spec=fetch_spec)
370
371
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False, 
372
              mapping=None, fetch_spec=None):
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
373
        if mapping is None:
374
            mapping = self.source.get_mapping()
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
375
        if revision_id is not None:
376
            interesting_heads = [revision_id]
377
        elif fetch_spec is not None:
378
            interesting_heads = fetch_spec.heads
379
        else:
380
            interesting_heads = None
0.200.247 by Jelmer Vernooij
Fix git-import.
381
        self._refs = {}
382
        def determine_wants(refs):
383
            self._refs = refs
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
384
            if interesting_heads is None:
0.200.247 by Jelmer Vernooij
Fix git-import.
385
                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.
386
            else:
0.233.1 by Jelmer Vernooij
Don't attempt to fetch NULL_REVISION.
387
                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.
388
            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.
389
        self.fetch_objects(determine_wants, mapping, pb)
390
        return self._refs
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
391
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
392
393
394
class InterRemoteGitNonGitRepository(InterGitNonGitRepository):
395
    """InterRepository that copies revisions from a remote Git into a non-Git 
396
    repository."""
397
398
    def fetch_objects(self, determine_wants, mapping, pb=None):
399
        def progress(text):
400
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
401
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
402
        create_pb = None
403
        if pb is None:
404
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
405
        target_git_object_retriever = BazaarObjectStore(self.target, mapping)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
406
        recorded_wants = []
407
408
        def record_determine_wants(heads):
409
            wants = determine_wants(heads)
410
            recorded_wants.extend(wants)
411
            return wants
412
        
413
        try:
414
            self.target.lock_write()
415
            try:
416
                self.target.start_write_group()
417
                try:
418
                    objects_iter = self.source.fetch_objects(
419
                                record_determine_wants, 
420
                                graph_walker, 
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
421
                                target_git_object_retriever.get_raw, 
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
422
                                progress)
423
                    import_git_objects(self.target, mapping, objects_iter, 
424
                            target_git_object_retriever, recorded_wants, pb)
425
                finally:
426
                    self.target.commit_write_group()
427
            finally:
428
                self.target.unlock()
429
        finally:
430
            if create_pb:
431
                create_pb.finished()
432
433
    @staticmethod
434
    def is_compatible(source, target):
435
        """Be compatible with GitRepository."""
436
        # FIXME: Also check target uses VersionedFile
437
        return (isinstance(source, RemoteGitRepository) and 
438
                target.supports_rich_root() and
439
                not isinstance(target, GitRepository))
440
441
442
class InterLocalGitNonGitRepository(InterGitNonGitRepository):
443
    """InterRepository that copies revisions from a remote Git into a non-Git 
444
    repository."""
445
446
    def fetch_objects(self, determine_wants, mapping, pb=None):
447
        wants = determine_wants(self.source._git.get_refs())
448
        create_pb = None
449
        if pb is None:
450
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
451
        target_git_object_retriever = BazaarObjectStore(self.target, mapping)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
452
        try:
453
            self.target.lock_write()
454
            try:
455
                self.target.start_write_group()
456
                try:
457
                    import_git_objects(self.target, mapping, 
458
                            self.source._git.object_store, 
459
                            target_git_object_retriever, wants, pb)
460
                finally:
461
                    self.target.commit_write_group()
462
            finally:
463
                self.target.unlock()
464
        finally:
465
            if create_pb:
466
                create_pb.finished()
467
468
    @staticmethod
469
    def is_compatible(source, target):
470
        """Be compatible with GitRepository."""
471
        # FIXME: Also check target uses VersionedFile
472
        return (isinstance(source, LocalGitRepository) and 
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
473
                target.supports_rich_root() and
474
                not isinstance(target, GitRepository))
475
476
477
class InterGitRepository(InterRepository):
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
478
    """InterRepository that copies between Git repositories."""
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
479
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
480
    _matching_repo_format = GitRepositoryFormat()
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
481
482
    @staticmethod
483
    def _get_repo_format_to_test():
484
        return None
485
486
    def copy_content(self, revision_id=None, pb=None):
487
        """See InterRepository.copy_content."""
488
        self.fetch(revision_id, pb, find_ghosts=False)
489
490
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
491
              mapping=None, fetch_spec=None):
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
492
        if mapping is None:
493
            mapping = self.source.get_mapping()
494
        def progress(text):
0.200.261 by Jelmer Vernooij
More formatting fixes.
495
            trace.info("git: %s", text)
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
496
        r = self.target._git
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
497
        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.
498
            args = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
499
        elif fetch_spec is not None:
500
            args = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in fetch_spec.heads]
0.200.247 by Jelmer Vernooij
Fix git-import.
501
        if fetch_spec is None and revision_id is None:
502
            determine_wants = r.object_store.determine_wants_all
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
503
        else:
0.200.247 by Jelmer Vernooij
Fix git-import.
504
            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.
505
506
        graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
507
        f, commit = r.object_store.add_thin_pack()
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
508
        try:
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
509
            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.
510
            commit()
511
        except:
512
            f.close()
513
            raise
514
515
    @staticmethod
516
    def is_compatible(source, target):
517
        """Be compatible with GitRepository."""
518
        return (isinstance(source, GitRepository) and 
519
                isinstance(target, GitRepository))