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